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