00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00021
00022
00023
00024 #include <stdio.h>
00025 #include <stdlib.h>
00026 #include <string.h>
00027
00028 #include "../../getopt.h"
00029 #include "../../scriba.h"
00030 #include "../../basext.h"
00031 #include "../../confpile.h"
00032
00033 #if BCC32 || CYGWIN
00034 char *_pgmptr;
00035 #endif
00036
00037
00038 int GetC(void *f){ return getc((FILE *)f); }
00039
00040 #ifdef _DEBUG
00041 #define ERREXIT do{getchar();scriba_destroy(pProgram);exit(iError);}while(0)
00042 #else
00043 #define ERREXIT exit(iError)
00044 #endif
00045
00046 #ifdef WIN32
00047 main(int argc, char *argv[]){
00048 #else
00049 char **_environ;
00050 main(int argc, char *argv[], char *env[]){
00051 #endif
00052 int iError;
00053 int iErrorCounter;
00054 int OptionIndex;
00055 pSbProgram pProgram;
00056 char *pszForcedConfigurationFileName;
00057 unsigned long fErrorFlags;
00058 char *szInputFile,
00059 *szOutputFile;
00060 char *optarg,opt;
00061
00062 #define MAXPREPROC 100
00063 char *pszEPreproc[MAXPREPROC],*pszPreprocessedFileName;
00064 char *pszIPreproc[MAXPREPROC];
00065 int iEPreprocIndex,iIPreprocIndex;
00066 int giveusage,binarycode,nocache,iscgi,isCoutput,isEoutput;
00067 int execute,ConfCompile,ConfDump;
00068 #define FULL_PATH_BUFFER_LENGTH 256
00069 char CmdLinBuffer[FULL_PATH_BUFFER_LENGTH];
00070 extern int GlobalDebugDisplayFlag;
00071 long lOffset,lEOFfset;
00072 char *realArgv0;
00073
00074 #ifdef __MACOS__
00075 argc = ccommand(&argv);
00076 #endif
00077
00078
00079
00080 #ifndef WIN32
00081 _environ = env;
00082 #endif
00083
00084 #if BCC32 || CYGWIN
00085 _pgmptr = argv[0];
00086 #endif
00087
00088 #ifdef _DEBUG
00089 #define malloc testa_Alloc
00090 #define free testa_Free
00091 testa_InitSegment();
00092 #endif
00093
00094 szInputFile = NULL;
00095 szOutputFile = NULL;
00096 ConfCompile = 0;
00097 ConfDump = 0;
00098 iEPreprocIndex = 0;
00099 iIPreprocIndex = 0;
00100 pszPreprocessedFileName = NULL;
00101 *pszEPreproc = NULL;
00102 *pszIPreproc = NULL;
00103 giveusage = 0;
00104 binarycode = 0;
00105 execute = 0;
00106 nocache = 0;
00107 OptionIndex = 0;
00108 iscgi = 0;
00109 isCoutput = 0;
00110 isEoutput = 0;
00111 pszForcedConfigurationFileName = NULL;
00112 GlobalDebugDisplayFlag = 0;
00113
00114 #ifdef WIN32
00115 realArgv0 = _pgmptr;
00116 #else
00117 realArgv0 = argv[0];
00118 #endif
00119
00120
00121 if( build_GetExeCodeOffset(realArgv0,&lOffset,&lEOFfset) ){
00122 OptionIndex = 1;
00123 CmdLinBuffer[0] = (char)0;
00124 while( OptionIndex < argc ){
00125 strcat(CmdLinBuffer,argv[OptionIndex++]);
00126 if( OptionIndex < argc )
00127 strcat(CmdLinBuffer," ");
00128 }
00129 goto CmdLineFinished;
00130 }
00131 #define W(X) fprintf(stderr,"%s\n",X);
00132 while( (opt = getoptt(argc, argv, "Dkdf:p:i:CEcnvebo:",&optarg,&OptionIndex)) != ':'){
00133 switch( opt ){
00134 case 'k':
00135 if( ConfCompile ){
00136 giveusage = 1;
00137 W("Option -k was specified more than once.")
00138 }
00139 if( ConfDump ){
00140 giveusage = 1;
00141 W("Option -k can not be used together with -D")
00142 }
00143 ConfCompile = 1;
00144 break;
00145 case 'D':
00146 if( ConfCompile ){
00147 giveusage = 1;
00148 W("Option -k can not be used together with -D")
00149 }
00150 if( ConfDump ){
00151 giveusage = 1;
00152 W("Option -D was specified more than once.")
00153 }
00154 ConfDump = 1;
00155 break;
00156 case 'd' :
00157 if( GlobalDebugDisplayFlag ){
00158 giveusage = 1;
00159 W("Option -d was specified more than once.")
00160 }
00161 GlobalDebugDisplayFlag = 1;
00162 break;
00163 case 'p' :
00164 if( iEPreprocIndex >= MAXPREPROC-1 ){
00165 fprintf(stderr,"The maximum number of external preprocessors allowed on the command line is %d\nIt is exceeded.\n",MAXPREPROC);
00166 giveusage = 1;
00167 }else{
00168 pszEPreproc[iEPreprocIndex ++ ] = optarg;
00169 pszEPreproc[iEPreprocIndex] = NULL;
00170 }
00171 break;
00172 case 'i' :
00173 if( iIPreprocIndex >= MAXPREPROC-1 ){
00174 fprintf(stderr,"The maximum number of internal preprocessors allowed on the command line is %d\nIt is exceeded.\n",MAXPREPROC);
00175 giveusage = 1;
00176 }else{
00177 pszIPreproc[iIPreprocIndex ++ ] = optarg;
00178 pszIPreproc[iIPreprocIndex] = NULL;
00179 }
00180 break;
00181 case 'C' :
00182 if( isCoutput ){
00183 giveusage = 1;
00184 W("Option -C was specified more than once.")
00185 }
00186 isCoutput = 1;
00187 break;
00188 case 'E' :
00189 if( isEoutput ){
00190 giveusage = 1;
00191 W("Option -E was specified more than once.")
00192 }
00193 isEoutput = 1;
00194 break;
00195 case 'c' :
00196 if( iscgi ){
00197 giveusage = 1;
00198 W("Option -c was specified more than once.")
00199 }
00200 iscgi = 1;
00201 break;
00202 case 'n' :
00203 if( nocache ){
00204 giveusage = 1;
00205 W("Option -n was specified more than once.")
00206 }
00207 nocache = 1;
00208 break;
00209 case 'e' :
00210 if( execute ){
00211 giveusage = 1;
00212 W("Option -e was specified more than once.")
00213 }
00214 execute = 1;
00215 break;
00216 case 'f' :
00217 if( execute ){
00218 giveusage = 1;
00219 W("Option -f was specified more than once.")
00220 }
00221 pszForcedConfigurationFileName = optarg;
00222 break;
00223 case 'o' :
00224 if( szOutputFile || binarycode ){
00225 W("Using the option -o is invalid when the program is already binary.")
00226 giveusage = 1;
00227 }
00228 szOutputFile = optarg;
00229 break;
00230 case 'b':
00231 if( szOutputFile || binarycode ){
00232 W("Binary input file can not be used to produce output file.");
00233 giveusage = 1;
00234 }
00235 binarycode =1;
00236 break;
00237 case 'v':
00238 #define S fprintf(stderr,
00239 #define E );
00240 S "ScriptBasic v%ld.%ld\n",VERSION_HIGH,VERSION_LOW E
00241 S "Variation >>%s<< build %ld\n",VARIATION,SCRIPTBASIC_BUILD E
00242 S "Magic value %lu\n",build_MagicCode(NULL) E
00243 S "Node size is %d\n", sizeof(cNODE) E
00244 S "Extension interface version is %d\n",INTERFACE_VERSION E
00245 S "Compilation: %s %s\n", __DATE__,__TIME__ E
00246 #ifdef WIN32
00247 S "Executable: %s\n", _pgmptr E
00248 #endif
00249 exit(0);
00250 case '!' :
00251 W("Invalid option.");
00252 giveusage = 1;
00253 break;
00254 case '?':
00255 if( szInputFile ){
00256 W("Only one input file can be specified. YOu should not see this error message.");
00257 giveusage = 1;
00258 }
00259 szInputFile = optarg;
00260 CmdLinBuffer[0] = (char)0;
00261 while( OptionIndex < argc ){
00262 strcat(CmdLinBuffer,argv[OptionIndex++]);
00263 if( OptionIndex < argc )
00264 strcat(CmdLinBuffer," ");
00265 }
00266 goto CmdLineFinished;
00267 }
00268 }
00269
00270 CmdLineFinished:
00271 if( execute && binarycode ){
00272 W("The option -e and binary input file can not be used together.");
00273 giveusage=1;
00274 }
00275 if( isCoutput && !szOutputFile ){
00276 W("To generate C file an output file has to be specified.");
00277 giveusage=1;
00278 }
00279 if( isEoutput && !szOutputFile ){
00280 W("To generate executable file an output file has to be specified.");
00281 giveusage=1;
00282 }
00283
00284 if( isEoutput || isCoutput )nocache = 1;
00285 if( iIPreprocIndex )nocache = 1;
00286
00287
00288
00289
00290
00291
00292
00293
00294 if( (!lOffset) && (!ConfDump) && (!ConfCompile) && szInputFile == NULL || giveusage ){
00295 #define U(x) fprintf(stderr,"%s\n",(x));
00296 U("Usage: basic [options] program.bas")
00297 U("")
00298 U("options: -o file_name")
00299 U(" specify output file, save binary format to file but don't execute")
00300 U(" -b file_name")
00301 U(" load binary format from file and execute")
00302 U(" -n")
00303 U(" do not use cache (no save, no load)")
00304 U(" -e")
00305 U(" execute after binary format was saved")
00306 U(" -v")
00307 U(" print version info and stop")
00308 U(" -c")
00309 U(" inform scriba that this is a CGI script.")
00310 U(" -C");
00311 U(" save C program output.");
00312 U(" -E");
00313 U(" save executable output. (may not work under some OS)");
00314 U(" -p preprocessor");
00315 U(" specify external preprocessor.");
00316 U(" -i preprocessor");
00317 U(" specify internal preprocessor.");
00318 U(" -f configurationfile");
00319 U(" specify configuration file");
00320 U(" -d");
00321 U(" debug module error (UNIX only)");
00322 U(" -k text_config_file");
00323 U(" compile the configuration file to binary");
00324 U(" -D");
00325 U(" dump the configuration file in text format");
00326 exit(1);
00327 }
00328 pProgram = scriba_new(malloc,free);
00329 if( pProgram == NULL ){
00330 iError = COMMAND_ERROR_MEMORY_LOW;
00331 ERREXIT;
00332 }
00333
00334
00335 if( ConfDump ){
00336
00337 if( szOutputFile == NULL )
00338 szOutputFile = "STDOUT";
00339
00340 pProgram->pCONF = alloc_Alloc(sizeof(tConfigTree),pProgram->pMEM);
00341 if( pProgram->pCONF == NULL ){
00342 iError = COMMAND_ERROR_MEMORY_LOW;
00343 report_report(stderr,"",0,iError,REPORT_ERROR,&iErrorCounter,NULL,&fErrorFlags);
00344 exit(1);
00345 }
00346 iError = cft_init(pProgram->pCONF,NULL,NULL,NULL);
00347 if( iError ){
00348 report_report(stderr,"",0,iError,REPORT_ERROR,&iErrorCounter,NULL,&fErrorFlags);
00349 exit(1);
00350 }
00351 if( pszForcedConfigurationFileName == NULL ){
00352 iError = scriba_GetConfigFileName(pProgram,&pszForcedConfigurationFileName);
00353 if( iError ){
00354 report_report(stderr,"",0,iError,REPORT_ERROR,&iErrorCounter,NULL,&fErrorFlags);
00355 exit(1);
00356 }
00357 }
00358 iError = cft_ReadConfig(pProgram->pCONF,pszForcedConfigurationFileName);
00359 if( iError != 0 ){
00360 fprintf(stderr,"Configuration file %s can not be processed.\n",pszForcedConfigurationFileName);
00361 exit(1);
00362 }
00363 iError = cft_DumpConfig(pProgram->pCONF,szOutputFile);
00364 if( iError != 0 ){
00365 fprintf(stderr,"Output file %s can not be processed.\n",szOutputFile);
00366 exit(iError);
00367 }
00368 exit(0);
00369 }
00370
00371
00372
00373
00374
00375
00376
00377
00378
00379
00380 if( ConfCompile ){
00381 if( NULL == szInputFile ){
00382 fprintf(stderr,"The option '-k' needs argument (the name of the config text file)\n");
00383 exit(1);
00384 }
00385 pProgram->pCONF = alloc_Alloc(sizeof(tConfigTree),pProgram->pMEM);
00386 if( pProgram->pCONF == NULL ){
00387 iError = COMMAND_ERROR_MEMORY_LOW;
00388 report_report(stderr,"",0,iError,REPORT_ERROR,&iErrorCounter,NULL,&fErrorFlags);
00389 ERREXIT;
00390 }
00391 iError = cft_init(pProgram->pCONF,NULL,NULL,NULL);
00392 if( iError ){
00393 report_report(stderr,"",0,iError,REPORT_ERROR,&iErrorCounter,NULL,&fErrorFlags);
00394 ERREXIT;
00395 }
00396 if( pszForcedConfigurationFileName == NULL ){
00397 iError = scriba_GetConfigFileName(pProgram,&pszForcedConfigurationFileName);
00398 if( iError ){
00399 report_report(stderr,"",0,iError,REPORT_ERROR,&iErrorCounter,NULL,&fErrorFlags);
00400 ERREXIT;
00401 }
00402 }
00403 iError = cft_ReadTextConfig(pProgram->pCONF,szInputFile);
00404 switch( iError ){
00405 case CFT_ERROR_FILE:
00406 fprintf(stderr,"The file %s can not be read.\n",szInputFile);
00407 exit(1);
00408 case CFT_ERROR_EMPTY:
00409 fprintf(stderr,"The file %s contains no configuration information.\n",szInputFile);
00410 exit(1);
00411 case CFT_ERROR_SYNTAX:
00412 fprintf(stderr,"The file %s has syntax error in it.\n",szInputFile);
00413 exit(1);
00414 case CFT_ERROR_MEMORY:
00415 fprintf(stderr,"Memory exhausted while processing the file %s\n",szInputFile);
00416 exit(1);
00417 }
00418 iError = cft_WriteConfig(pProgram->pCONF,pszForcedConfigurationFileName);
00419 switch( iError ){
00420 case CFT_ERROR_FILE:
00421 fprintf(stderr,"The file %s can not be written\n",pszForcedConfigurationFileName);
00422 exit(1);
00423 case CFT_ERROR_MEMORY:
00424 fprintf(stderr,"Memory exhausted while writing the file %s\n",pszForcedConfigurationFileName);
00425 exit(1);
00426 }
00427 fprintf(stderr,"The configuration file '%s' was created.\n",pszForcedConfigurationFileName);
00428 exit(0);
00429 }
00430
00431 scriba_LoadConfiguration(pProgram,pszForcedConfigurationFileName);
00432
00433 #if _DEBUG
00434 testa_Assert0x80();
00435 #endif
00436 iError = scriba_LoadInternalPreprocessor(pProgram,pszIPreproc);
00437 #if _DEBUG
00438 testa_Assert0x80();
00439 #endif
00440 if( iError ){
00441 report_report(stderr,"",0,iError,REPORT_ERROR,&iErrorCounter,NULL,&fErrorFlags);
00442 ERREXIT;
00443 }
00444
00445 if( iscgi )scriba_SetCgiFlag(pProgram);
00446 #if _DEBUG
00447 testa_Assert0x80();
00448 #endif
00449 if( lOffset )
00450 scriba_SetFileName(pProgram,realArgv0);
00451 else
00452 scriba_SetFileName(pProgram,szInputFile);
00453 #if _DEBUG
00454 testa_Assert0x80();
00455 #endif
00456
00457 if( (!nocache) && scriba_UseCacheFile(pProgram) == SCRIBA_ERROR_SUCCESS )binarycode = 1;
00458 if( lOffset )binarycode = 1;
00459 if( binarycode || scriba_IsFileBinaryFormat(pProgram) ){
00460 if( (iError = scriba_LoadBinaryProgramWithOffset(pProgram,lOffset,lEOFfset)) != 0 ){
00461 ERREXIT;
00462 }
00463 }else{
00464 if( iError=scriba_RunExternalPreprocessor(pProgram,pszEPreproc) ){
00465 report_report(stderr,"",0,iError,REPORT_ERROR,&iErrorCounter,NULL,&fErrorFlags);
00466 ERREXIT;
00467 }
00468 if( scriba_LoadSourceProgram(pProgram) )ERREXIT;
00469 if( szOutputFile ){
00470 if( isCoutput )
00471 scriba_SaveCCode(pProgram,szOutputFile);
00472 else
00473 if( isEoutput )
00474 scriba_SaveECode(pProgram,realArgv0,szOutputFile);
00475 else
00476 scriba_SaveCode(pProgram,szOutputFile);
00477 if( !execute )exit(0);
00478 }
00479 if( ! nocache )scriba_SaveCacheFile(pProgram);
00480 }
00481
00482
00483
00484
00485
00486
00487
00488
00489
00490 if( iError=scriba_Run(pProgram,CmdLinBuffer) ){
00491 #if _DEBUG
00492 testa_Assert0x80();
00493 #endif
00494 if( iError > 0 )
00495 report_report(stderr,"",0,iError,REPORT_ERROR,&iErrorCounter,NULL,&fErrorFlags);
00496 else
00497 iError = -iError;
00498 ERREXIT;
00499 }
00500 #if _DEBUG
00501 testa_Assert0x80();
00502 #endif
00503
00504
00505
00506
00507
00508
00509
00510
00511
00512
00513
00514
00515
00516
00517
00518
00519
00520
00521
00522
00523
00524
00525
00526
00527
00528
00529
00530
00531
00532
00533
00534
00535
00536
00537
00538 scriba_destroy(pProgram);
00539
00540 #ifdef _DEBUG
00541 testa_AssertLeak();
00542 if( ! iscgi ){
00543 printf("\nPress any key to continue...\n");
00544 getchar();
00545 }
00546 #endif
00547 exit(iError);
00548 }
00549