G:/ScriptBasic/source/variations/wx/scribawx.c

Go to the documentation of this file.
00001 /* 
00002 
00003 FILE:   scribawx.c
00004 HEADER: scribawx.h
00005 
00006 --GNU LGPL
00007 This library is free software; you can redistribute it and/or
00008 modify it under the terms of the GNU Lesser General Public
00009 License as published by the Free Software Foundation; either
00010 version 2.1 of the License, or (at your option) any later version.
00011 
00012 This library is distributed in the hope that it will be useful,
00013 but WITHOUT ANY WARRANTY; without even the implied warranty of
00014 MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
00015 Lesser General Public License for more details.
00016 
00017 You should have received a copy of the GNU Lesser General Public
00018 License along with this library; if not, write to the Free Software
00019 Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00020 
00021 TO_HEADER:
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   /* the maximal number of preprocessors that are applied in chain */
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 /*pSbData p,psb;
00075 SbData RetVale;*/
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   /* default values for command line options */
00090   szInputFile = NULL;
00091   szOutputFile = NULL;
00092   ConfCompile = 0; /* the default action is to run BASIC program and not configuration file compilation */
00093   iEPreprocIndex = 0; /* no external preprocessor by default */
00094   iIPreprocIndex = 0; /* no internal preprocessor by default */
00095   pszPreprocessedFileName = NULL;
00096   *pszEPreproc = NULL; 
00097   *pszIPreproc = NULL;
00098   giveusage  = 0; /* assume the command line is correct, we need not display usage and stop */
00099   binarycode = 0; /* input is not binary by default */
00100   execute    = 0; /* do not execute by default after binary format save */
00101   nocache   = 0; /* we use cached code if it exists */
00102   OptionIndex = 0;
00103   iscgi = 0; /* by default this is not a cgi script, not HTTP/1.0 ... when error message is sent */
00104   isCoutput = 0;
00105   isEoutput = 0;
00106   pszForcedConfigurationFileName = NULL;
00107   GlobalDebugDisplayFlag = 0;
00108 
00109   /* if this exe contains the code itself then jump over it */
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   /* This is to be a bit more safe with include files changed. Be sure to compile the final versio of the BASIC program. */
00258   if( isEoutput || isCoutput )nocache = 1;
00259   if( iIPreprocIndex )nocache = 1;
00260 /* NOTE: that external preprocessor effects can be cached!
00261   if( iEPreprocIndex )nocache = 1;
00262    On the other hand internal preprocessor provided on the
00263    command-line (and not in the source 'use' commands)
00264    is most probably a debugger or profiler, thus no caching
00265    should be done, because if we use the cache the program
00266    runs without having the preprocessor in effect.
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   /* If the user has specified the option -k then the input file is the configuration file.
00306      Now we compile the configuration file and do not run any program. This is more convenient
00307      then the older version using the external program cftc because cftc required two arguments:
00308 
00309      configuration file in text format
00310      compiled output configuration file name
00311 
00312      scriba -k on the other hand requires only the text configuration file name and saves
00313      the configuration file into the file name, where it will search for the configuration file
00314      when it runs a BASIC program.   */
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   {FILE *fb; fb = fopen("dumpcode.txt","w");
00403   build_pprint(pProgram->pBUILD,fb);fclose(fb);}
00404 */
00405 /*#define PRGSTR "print \"hello\\n\"\n\
00406 include \"test.bas\"\
00407 "
00408   scriba_LoadProgramString(pProgram,PRGSTR,strlen(PRGSTR));
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 unsigned long i=0;
00418 unsigned long min,max,act;
00419 pSbData pRetVale;
00420   while( 1 ){
00421     i++;
00422     if( i%10000 == 0 ){
00423       testa_ReportLeak();
00424 #define PRSEG(X)      alloc_GetStat(X,&min,&max,&act);printf("Segment %s is %d\n",#X,act);
00425       PRSEG(pProgram->pMEM);
00426       PRSEG(pProgram->pEXE->pMo);
00427       PRSEG(pProgram->pEXE->pMemorySegment);
00428       printf("kukk %d\n",i/10000);
00429       getchar();
00430       }
00431     pRetVale = scriba_NewSbData(pProgram);
00432     scriba_CallArgEx(pProgram,scriba_LookupFunctionByName(pProgram,"main::pred_1"),pRetVale,0,NULL);
00433     scriba_DestroySbData(pProgram,pRetVale);
00434     }
00435 }
00436 
00437   printf("testvar type is %d\n",scriba_GetVariableType(pProgram,
00438   scriba_LookupVariableByName(pProgram,"main::testvar")));
00439   scriba_GetVariable(pProgram,
00440                      scriba_LookupVariableByName(pProgram,"main::testvar"),
00441                      &psb
00442     );
00443   printf("testvar from C is %s\n",scriba_GetString(pProgram,*psb));
00444 
00445   scriba_SetVariable(pProgram,scriba_LookupVariableByName(pProgram,"main::testvar"),
00446                      SBT_ZCHAR,1,2.2,"kukac",4);
00447   scriba_CallArgEx(pProgram,scriba_LookupFunctionByName(pProgram,"main::thatfunc"),&RetVale,4,p);
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 

Generated on Sun Mar 12 23:56:32 2006 for ScriptBasic by  doxygen 1.4.6-NO