00001 #include <stdio.h>
00002 #include <stdlib.h>
00003 #include <string.h>
00004
00005 #include "../../getopt.h"
00006 #include "../../report.h"
00007 #include "../../lexer.h"
00008 #include "../../sym.h"
00009 #include "../../expression.h"
00010 #include "../../syntax.h"
00011 #include "../../reader.h"
00012 #include "../../myalloc.h"
00013 #include "../../builder.h"
00014 #include "../../memory.h"
00015 #include "../../execute.h"
00016 #include "../../buildnum.h"
00017 #include "../../conftree.h"
00018 #include "../../filesys.h"
00019 #include "../../errcodes.h"
00020 #include "../../testalloc.h"
00021 #include "../../basext.h"
00022 #include "../../epreproc.h"
00023 #include "../../uniqfnam.h"
00024
00025 int GetC(void *f){ return getc((FILE *)f); }
00026
00027 #if BCC32
00028 char *_pgmptr;
00029 #endif
00030
00031 #ifdef WIN32
00032 main(int argc, char *argv[]){
00033 #else
00034 char **_environ;
00035 main(int argc, char *argv[], char *env[]){
00036 #endif
00037 int OptionIndex;
00038 LexObject MyLEX;
00039 ReadObject MyREAD;
00040 BuildObject MyBUILD;
00041 tConfigTree MyCONF;
00042 char *pszForcedConfigurationFileName;
00043 void *pMEM;
00044 eXobject MyEX;
00045 ExecuteObject MyEXE;
00046 peNODE_l CommandList;
00047 int iError,iErrorCounter;
00048 unsigned long fErrorFlags;
00049 char *szInputFile,
00050 *szOutputFile;
00051 char *optarg,opt;
00052
00053 #define MAXPREPROC 100
00054 char *pszEPreproc[MAXPREPROC],*pszPreprocessedFileName;
00055 int iPreprocIndex;
00056 int giveusage,binarycode,nocache,iscgi,isCoutput;
00057 int execute;
00058 #define FULL_PATH_BUFFER_LENGTH 256
00059 char CmdLinBuffer[FULL_PATH_BUFFER_LENGTH],*szCache,*s,*q;
00060 char Argv0[FULL_PATH_BUFFER_LENGTH];
00061 char CachedFileName[FULL_PATH_BUFFER_LENGTH];
00062 unsigned long FileTime,CacheTime;
00063 #ifndef WIN32
00064 _environ = env;
00065 #if BCC32
00066 _pgptr = argv[0];
00067 #endif
00068 #endif
00069
00070 #ifdef _DEBUG
00071 #define malloc testa_Alloc
00072 #define free testa_Free
00073 testa_InitSegment();
00074 #endif
00075
00076
00077 szInputFile = NULL;
00078 szOutputFile = NULL;
00079 iPreprocIndex = 0;
00080 pszPreprocessedFileName = NULL;
00081 *pszEPreproc = NULL;
00082 giveusage = 0;
00083 binarycode = 0;
00084 execute = 0;
00085 nocache = 0;
00086 OptionIndex = 0;
00087 iscgi = 0;
00088 isCoutput = 0;
00089 pszForcedConfigurationFileName = NULL;
00090
00091 while( (opt = getoptt(argc, argv, "f:pCcnvebo:",&optarg,&OptionIndex)) != ':'){
00092 switch( opt ){
00093 case 'p' :
00094 if( iPreprocIndex >= MAXPREPROC-1 )
00095 giveusage = 1;
00096 else{
00097 pszEPreproc[iPreprocIndex ++ ] = optarg;
00098 pszEPreproc[iPreprocIndex] = NULL;
00099 }
00100 break;
00101 case 'C' :
00102 if( isCoutput )giveusage = 1;
00103 isCoutput = 1;
00104 break;
00105 case 'c' :
00106 if( iscgi )giveusage = 1;
00107 iscgi = 1;
00108 break;
00109 case 'n' :
00110 if( nocache )giveusage = 1;
00111 nocache = 1;
00112 break;
00113 case 'e' :
00114 if( execute )giveusage = 1;
00115 execute = 1;
00116 break;
00117 case 'f' :
00118 if( pszForcedConfigurationFileName )giveusage = 1;
00119 pszForcedConfigurationFileName = optarg;
00120 break;
00121 case 'o' :
00122 if( szOutputFile || binarycode )giveusage = 1;
00123 szOutputFile = optarg;
00124 break;
00125 case 'b':
00126 if( szOutputFile || binarycode )giveusage = 1;
00127 binarycode =1;
00128 break;
00129 case 'v':
00130 #define S fprintf(stderr,
00131 #define E );
00132 S "ScriptBasic v%ld.%ld\n",VERSION_HIGH,VERSION_LOW E
00133 S "Variation >>%s<< build %ld\n",VARIATION,SCRIPTBASIC_BUILD E
00134 S "Magic value %lu\n",build_MagicCode(NULL) E
00135 S "Node size is %d\n", sizeof(cNODE) E
00136 S "Extension interface version is %d\n",INTERFACE_VERSION E
00137 S "Compilation: %s %s\n", __DATE__,__TIME__ E
00138 exit(0);
00139 case '!' :
00140 giveusage = 1;
00141 break;
00142 case '?':
00143 if( szInputFile )giveusage = 1;
00144 szInputFile = optarg;
00145 CmdLinBuffer[0] = (char)0;
00146 while( OptionIndex < argc ){
00147 strcat(CmdLinBuffer,argv[OptionIndex++]);
00148 if( OptionIndex < argc )
00149 strcat(CmdLinBuffer," ");
00150 }
00151 goto CmdLineFinished;
00152 }
00153 }
00154
00155 CmdLineFinished:
00156 if( execute && binarycode )giveusage=1;
00157 if( isCoutput && !szOutputFile )giveusage=1;
00158
00159 if( szInputFile == NULL || giveusage ){
00160 #define U(x) fprintf(stderr,"%s\n",(x));
00161 U("Usage: basic [options] program.bas")
00162 U("")
00163 U("options: -o file_name")
00164 U(" save binary format to file but don't execute")
00165 U(" -b file_name")
00166 U(" load binary format from file and execute")
00167 U(" -n")
00168 U(" do not use cache (no save, no load)")
00169 U(" -e")
00170 U(" execute after binary format was saved")
00171 U(" -v")
00172 U(" print version info and stop")
00173 U(" -c")
00174 U(" inform scriba that this is a CGI script.")
00175 U(" -C");
00176 U(" save C program output.");
00177 U(" -p preprocessor");
00178 U(" specify preprocessor.");
00179 U(" -f configurationfile");
00180 U(" specify configuration file");
00181 exit(1);
00182 }
00183
00184 pMEM = alloc_InitSegment(malloc,free);
00185 if( pMEM == NULL ){
00186 fprintf(stderr,"No memory\n");
00187 exit(1);
00188 }
00189
00190 cft_start(&MyCONF,alloc_Alloc,alloc_Free,pMEM,
00191 #ifdef WIN32
00192 "Software\\ScriptBasic\\config",
00193 "WINNT\\SCRIBA.INI",
00194 #else
00195 "SCRIBACONF",
00196 "/etc/scriba/basic.conf",
00197 #endif
00198 pszForcedConfigurationFileName);
00199
00200 szCache = nocache ? NULL : cft_GetString(&MyCONF,"cache");
00201 if( szCache ){
00202 strcpy(CachedFileName,szCache);
00203 s = CachedFileName + strlen(CachedFileName);
00204
00205 #ifdef WIN32
00206
00207 if( GetFullPathName(szInputFile,
00208 FULL_PATH_BUFFER_LENGTH-strlen(CachedFileName),s,&q)==0 )
00209 goto UseNoCache;
00210 #else
00211
00212 strcpy(s,szInputFile);
00213 #endif
00214 strcpy(Argv0,s);
00215 uniqfnam(s,s);
00216 FileTime = file_time_modified(szInputFile);
00217 CacheTime = file_time_modified(CachedFileName);
00218 if( FileTime && CacheTime && CacheTime > FileTime ){
00219 szInputFile = CachedFileName;
00220
00221
00222
00223
00224
00225
00226 binarycode = build_IsFileBinaryFormat(szInputFile);
00227 }
00228 }else{
00229 #ifdef WIN32
00230 if( GetFullPathName(szInputFile,
00231 FULL_PATH_BUFFER_LENGTH,Argv0,&q) == 0 )
00232 #endif
00233 strcpy(Argv0,szInputFile);
00234 }
00235 UseNoCache:
00236
00237
00238 if( binarycode || build_IsFileBinaryFormat(szInputFile) ){
00239
00240 MyBUILD.memory_allocating_function = malloc;
00241 MyBUILD.memory_releasing_function = free;
00242 MyBUILD.iErrorCounter = 0;
00243 MyBUILD.reportptr = (void *)stderr;
00244 MyBUILD.report = report_report;
00245 MyBUILD.fErrorFlags = iscgi ? REPORT_F_CGI : 0;
00246 build_LoadCode(&MyBUILD,szInputFile);
00247 if( MyBUILD.iErrorCounter ){
00248 #ifdef _DEBUG
00249 getchar();
00250 #endif
00251 exit(1);
00252 }
00253 binarycode = 1;
00254 }else{
00255 binarycode = 0;
00256
00257 fErrorFlags = iscgi ? REPORT_F_CGI : 0;
00258 iErrorCounter = 0;
00259 iError = epreproc(&MyCONF,szInputFile,&pszPreprocessedFileName,pszEPreproc,malloc,free);
00260 if( iError ){
00261 report_report(stderr,"",0,iError,REPORT_ERROR,&iErrorCounter,NULL,&fErrorFlags);
00262 #ifdef _DEBUG
00263 getchar();
00264 #endif
00265
00266 exit(1);
00267 }
00268
00269
00270 reader_InitStructure(&MyREAD);
00271 MyREAD.memory_allocating_function = alloc_Alloc;
00272 MyREAD.memory_releasing_function = alloc_Free;
00273 MyREAD.pMemorySegment = alloc_InitSegment(malloc,free);
00274 MyREAD.report = report_report;
00275 MyREAD.reportptr = (void *)stderr;
00276 MyREAD.iErrorCounter = 0;
00277 MyREAD.fErrorFlags = iscgi ? REPORT_F_CGI : 0;
00278 MyREAD.pConfig = &MyCONF;
00279 if( pszPreprocessedFileName )
00280 reader_ReadLines(&MyREAD,pszPreprocessedFileName);
00281 else
00282 reader_ReadLines(&MyREAD,szInputFile);
00283
00284
00285
00286 if( MyREAD.iErrorCounter ){
00287 #ifdef _DEBUG
00288 getchar();
00289 #endif
00290
00291 exit(1);
00292 }
00293
00294 reader_StartIteration(&MyREAD);
00295
00296 MyLEX.memory_allocating_function = alloc_Alloc;
00297 MyLEX.memory_releasing_function = alloc_Free;
00298 MyLEX.pMemorySegment = alloc_InitSegment(malloc,free);
00299 lex_InitStructure(&MyLEX);
00300
00301 MyLEX.pfGetCharacter = reader_NextCharacter;
00302 MyLEX.pfFileName = reader_FileName;
00303 MyLEX.pfLineNumber = reader_LineNumber;
00304
00305 MyLEX.pNASymbols = NASYMBOLS;
00306 MyLEX.pASymbols = ASYMBOLS;
00307 MyLEX.pCSymbols = CSYMBOLS;
00308 MyLEX.report = report_report;
00309 MyLEX.reportptr = (void *)stderr;
00310 MyLEX.fErrorFlags = MyREAD.fErrorFlags;
00311 MyLEX.iErrorCounter = 0;
00312 MyLEX.pLexResult = (void *)stderr;
00313
00314
00315 MyLEX.pvInput = (void *)&MyREAD;
00316 lex_ReadInput(&MyLEX);
00317
00318 if( MyLEX.iErrorCounter ){
00319 #ifdef _DEBUG
00320 getchar();
00321 #endif
00322
00323 exit(1);
00324 }
00325
00326 lex_RemoveComments(&MyLEX);
00327 lex_HandleContinuationLines(&MyLEX);
00328
00329 MyEX.memory_allocating_function = malloc;
00330 MyEX.memory_releasing_function = free;
00331 MyEX.cbBuffer = 1024;
00332 MyEX.cbCurrentNameSpace = 1024;
00333 MyEX.pLex = &MyLEX;
00334
00335 MyEX.Unaries = UNARIES;
00336 MyEX.Binaries = BINARIES;
00337 MyEX.BuiltInFunctions = INTERNALFUNCTIONS;
00338 MyEX.MAXPREC = MAX_BINARY_OPERATOR_PRECEDENCE;
00339 MyEX.PredeclaredLongConstants = PREDLCONSTS;
00340 MyEX.reportptr = (void *)stderr;
00341 MyEX.report = report_report;
00342 MyEX.fErrorFlags = MyLEX.fErrorFlags;
00343 MyEX.iErrorCounter = 0;
00344
00345 MyEX.Command = COMMANDS;
00346
00347 ex_init(&MyEX);
00348
00349 ex_Command_l(&MyEX,&CommandList);
00350
00351 if( MyEX.iErrorCounter ){
00352 #ifdef _DEBUG
00353 getchar();
00354 #endif
00355 exit(1);
00356 }
00357
00358 MyEX.pCommandList = CommandList;
00359
00360 MyBUILD.memory_allocating_function = malloc;
00361 MyBUILD.memory_releasing_function = free;
00362 MyBUILD.pEx = &MyEX;
00363 MyBUILD.iErrorCounter = 0;
00364 MyBUILD.fErrorFlags = MyEX.fErrorFlags;
00365 MyBUILD.FirstUNIXline = MyREAD.FirstUNIXline;
00366
00367 build_Build(&MyBUILD);
00368
00369
00370
00371
00372
00373
00374
00375 if( MyBUILD.iErrorCounter ){
00376 #ifdef _DEBUG
00377 getchar();
00378 #endif
00379 exit(1);
00380 }
00381
00382
00383
00384
00385 alloc_FinishSegment(MyLEX.pMemorySegment);
00386 ex_free(&MyEX);
00387
00388 if( szOutputFile ){
00389 if( isCoutput )
00390 build_SaveCCode(&MyBUILD,szOutputFile);
00391 else
00392 build_SaveCode(&MyBUILD,szOutputFile);
00393 if( !execute )exit(0);
00394 }
00395 if( szCache ){
00396 build_SaveCode(&MyBUILD,CachedFileName);
00397 }
00398
00399
00400 alloc_FinishSegment(MyREAD.pMemorySegment);
00401 }
00402
00403 MyEXE.memory_allocating_function = malloc;
00404 MyEXE.memory_releasing_function = free;
00405 MyEXE.reportptr = (void *)stderr;
00406 MyEXE.report = report_report;
00407 if( binarycode )
00408 MyEXE.fErrorFlags = iscgi ? REPORT_F_CGI : 0;
00409 else
00410 MyEXE.fErrorFlags = MyEX.fErrorFlags;
00411
00412 MyEXE.pConfig = &MyCONF;
00413
00414 build_MagicCode(&(MyEXE.Ver));
00415 if( execute_InitStructure(&MyEXE,&MyBUILD) ){
00416 MyEXE.report(MyEXE.reportptr,
00417 "",
00418 0,
00419 COMMAND_ERROR_MEMORY_LOW,
00420 REPORT_ERROR,
00421 &iError,
00422 "",
00423 &(MyEXE.fErrorFlags));
00424 #ifdef _DEBUG
00425 getchar();
00426 #endif
00427 exit(1);
00428 }
00429
00430
00431
00432
00433
00434 MyEXE.CmdLineArgument = CmdLinBuffer;
00435
00436 execute_Execute(&MyEXE,&iError);
00437 alloc_FinishSegment(MyEXE.pMo->pMemorySegment);
00438 alloc_FinishSegment(MyEXE.pMemorySegment);
00439 alloc_FinishSegment(MyBUILD.pMemorySegment);
00440 alloc_FinishSegment(MyCONF.pMemorySegment);
00441 if( pszPreprocessedFileName )free(pszPreprocessedFileName);
00442
00443 #ifdef _DEBUG
00444 testa_AssertLeak();
00445 printf("Press any key to continue...\n");
00446 getchar();
00447 #endif
00448 if( iError )exit(1); else exit(0);
00449 }
00450