sq.c

00001 /*  see copyright notice in squirrel.h */
00002 
00003 #include <stdio.h>
00004 #include <stdlib.h>
00005 #include <string.h>
00006 #include <stdarg.h>
00007 
00008 #if defined(_MSC_VER) && defined(_DEBUG)
00009 #include <crtdbg.h>
00010 #include <conio.h>
00011 #endif
00012 #include <squirrel.h>
00013 #include <sqstdblob.h>
00014 #include <sqstdsystem.h>
00015 #include <sqstdio.h>
00016 #include <sqstdmath.h>
00017 #include <sqstdstring.h>
00018 #include <sqstdaux.h>
00019 
00020 #ifdef SQUNICODE
00021 #define scfprintf fwprintf
00022 #define scfopen _wfopen
00023 #define scvprintf vwprintf
00024 #else
00025 #define scfprintf fprintf
00026 #define scfopen fopen
00027 #define scvprintf vprintf
00028 #endif
00029 
00030 
00031 void PrintVersionInfos();
00032 
00033 #if defined(_MSC_VER) && defined(_DEBUG)
00034 int MemAllocHook( int allocType, void *userData, size_t size, int blockType,
00035    long requestNumber, const unsigned char *filename, int lineNumber)
00036 {
00037 //  if(requestNumber==585)_asm int 3;
00038   return 1;
00039 }
00040 #endif
00041 
00042 
00043 SQInteger quit(HSQUIRRELVM v)
00044 {
00045   int *done;
00046   sq_getuserpointer(v,-1,(SQUserPointer*)&done);
00047   *done=1;
00048   return 0;
00049 }
00050 
00051 void printfunc(HSQUIRRELVM v,const SQChar *s,...)
00052 {
00053   va_list vl;
00054   va_start(vl, s);
00055   scvprintf( s, vl);
00056   va_end(vl);
00057 }
00058 
00059 void PrintVersionInfos()
00060 {
00061   scfprintf(stdout,_SC("%s %s (%d bits)\n"),SQUIRREL_VERSION,SQUIRREL_COPYRIGHT,sizeof(SQInteger)*8);
00062 }
00063 
00064 void PrintUsage()
00065 {
00066   scfprintf(stderr,_SC("usage: sq <options> <scriptpath [args]>.\n")
00067     _SC("Available options are:\n")
00068     _SC("   -c              compiles the file to bytecode(default output 'out.cnut')\n")
00069     _SC("   -o              specifies output file for the -c option\n")
00070     _SC("   -c              compiles only\n")
00071     _SC("   -d              generates debug infos\n")
00072     _SC("   -v              displays version infos\n")
00073     _SC("   -h              prints help\n"));
00074 }
00075 
00076 #define _INTERACTIVE 0
00077 #define _DONE 2
00078 //<<FIXME>> this func is a mess
00079 int getargs(HSQUIRRELVM v,int argc, char* argv[])
00080 {
00081   int i;
00082   int compiles_only = 0;
00083   static SQChar temp[500];
00084   const SQChar *ret=NULL;
00085   char * output = NULL;
00086   int lineinfo=0;
00087   if(argc>1)
00088   {
00089     int arg=1,exitloop=0;
00090     while(arg < argc && !exitloop)
00091     {
00092 
00093       if(argv[arg][0]=='-')
00094       {
00095         switch(argv[arg][1])
00096         {
00097         case 'd': //DEBUG(debug infos)
00098           sq_enabledebuginfo(v,1);
00099           break;
00100         case 'c':
00101           compiles_only = 1;
00102           break;
00103         case 'o':
00104           if(arg < argc) {
00105             arg++;
00106             output = argv[arg];
00107           }
00108           break;
00109         case 'v':
00110           PrintVersionInfos();
00111           return _DONE;
00112 
00113         case 'h':
00114           PrintVersionInfos();
00115           PrintUsage();
00116           return _DONE;
00117         default:
00118           PrintVersionInfos();
00119           scprintf(_SC("unknown prameter '-%c'\n"),argv[arg][1]);
00120           PrintUsage();
00121           return _DONE;
00122         }
00123       }else break;
00124       arg++;
00125     }
00126 
00127     // src file
00128 
00129     if(arg<argc) {
00130       const SQChar *filename=NULL;
00131 #ifdef SQUNICODE
00132       mbstowcs(temp,argv[arg],strlen(argv[arg]));
00133       filename=temp;
00134 #else
00135       filename=argv[arg];
00136 #endif
00137 
00138       arg++;
00139       sq_pushroottable(v);
00140       sq_pushstring(v,_SC("ARGS"),-1);
00141       sq_newarray(v,0);
00142       for(i=arg;i<argc;i++)
00143       {
00144         const SQChar *a;
00145 #ifdef SQUNICODE
00146         int alen=(int)strlen(argv[i]);
00147         a=sq_getscratchpad(v,(int)(alen*sizeof(SQChar)));
00148         mbstowcs(sq_getscratchpad(v,-1),argv[i],alen);
00149         sq_getscratchpad(v,-1)[alen] = _SC('\0');
00150 #else
00151         a=argv[i];
00152 #endif
00153         sq_pushstring(v,a,-1);
00154 
00155         sq_arrayappend(v,-2);
00156       }
00157       sq_createslot(v,-3);
00158       sq_pop(v,1);
00159       if(compiles_only) {
00160         if(SQ_SUCCEEDED(sqstd_loadfile(v,filename,SQTrue))){
00161           SQChar *outfile = _SC("out.cnut");
00162           if(output) {
00163 #ifdef SQUNICODE
00164             int len = (int)(strlen(output)+1);
00165             mbstowcs(sq_getscratchpad(v,len*sizeof(SQChar)),output,len);
00166             outfile = sq_getscratchpad(v,-1);
00167 #else
00168             outfile = output;
00169 #endif
00170           }
00171           if(SQ_SUCCEEDED(sqstd_writeclosuretofile(v,outfile)))
00172             return _DONE;
00173         }
00174       }
00175       else {
00176         if(SQ_SUCCEEDED(sqstd_dofile(v,filename,SQFalse,SQTrue))) {
00177           return _DONE;
00178         }
00179       }
00180       //if this point is reached an error occured
00181       {
00182         const SQChar *err;
00183         sq_getlasterror(v);
00184         if(SQ_SUCCEEDED(sq_getstring(v,-1,&err))) {
00185           scprintf(_SC("Error [%s]\n"),err);
00186           return _DONE;
00187         }
00188       }
00189 
00190     }
00191   }
00192 
00193   return _INTERACTIVE;
00194 }
00195 
00196 void Interactive(HSQUIRRELVM v)
00197 {
00198 
00199 #define MAXINPUT 1024
00200   SQChar buffer[MAXINPUT];
00201   SQInteger blocks =0;
00202   SQInteger string=0;
00203   SQInteger retval=0;
00204   SQInteger done=0;
00205   PrintVersionInfos();
00206 
00207   sq_pushroottable(v);
00208   sq_pushstring(v,_SC("quit"),-1);
00209   sq_pushuserpointer(v,&done);
00210   sq_newclosure(v,quit,1);
00211   sq_setparamscheck(v,1,NULL);
00212   sq_createslot(v,-3);
00213   sq_pop(v,1);
00214 
00215     while (!done)
00216   {
00217     SQInteger i = 0;
00218     scprintf(_SC("\nsq>"));
00219     for(;;) {
00220       int c;
00221       if(done)return;
00222       c = getchar();
00223       if (c == _SC('\n')) {
00224         if (i>0 && buffer[i-1] == _SC('\\'))
00225         {
00226           buffer[i-1] = _SC('\n');
00227         }
00228         else if(blocks==0)break;
00229         buffer[i++] = _SC('\n');
00230       }
00231       else if (c==_SC('}')) {blocks--; buffer[i++] = (SQChar)c;}
00232       else if(c==_SC('{') && !string){
00233           blocks++;
00234           buffer[i++] = (SQChar)c;
00235       }
00236       else if(c==_SC('"') || c==_SC('\'')){
00237           string=!string;
00238           buffer[i++] = (SQChar)c;
00239       }
00240       else if (i >= MAXINPUT-1) {
00241         scfprintf(stderr, _SC("sq : input line too long\n"));
00242         break;
00243       }
00244       else{
00245         buffer[i++] = (SQChar)c;
00246       }
00247     }
00248     buffer[i] = _SC('\0');
00249 
00250     if(buffer[0]==_SC('=')){
00251       scsprintf(sq_getscratchpad(v,MAXINPUT),_SC("return (%s)"),&buffer[1]);
00252       memcpy(buffer,sq_getscratchpad(v,-1),(scstrlen(sq_getscratchpad(v,-1))+1)*sizeof(SQChar));
00253       retval=1;
00254     }
00255     i=scstrlen(buffer);
00256     if(i>0){
00257       SQInteger oldtop=sq_gettop(v);
00258       if(SQ_SUCCEEDED(sq_compilebuffer(v,buffer,i,_SC("interactive console"),SQTrue))){
00259         sq_pushroottable(v);
00260         if(SQ_SUCCEEDED(sq_call(v,1,retval,SQTrue)) &&  retval){
00261           scprintf(_SC("\n"));
00262           sq_pushroottable(v);
00263           sq_pushstring(v,_SC("print"),-1);
00264           sq_get(v,-2);
00265           sq_pushroottable(v);
00266           sq_push(v,-4);
00267           sq_call(v,2,SQFalse,SQTrue);
00268           retval=0;
00269           scprintf(_SC("\n"));
00270         }
00271       }
00272 
00273       sq_settop(v,oldtop);
00274     }
00275   }
00276 }
00277 
00278 int main(int argc, char* argv[])
00279 {
00280   HSQUIRRELVM v;
00281 
00282   const SQChar *filename=NULL;
00283 #if defined(_MSC_VER) && defined(_DEBUG)
00284   _CrtSetAllocHook(MemAllocHook);
00285 #endif
00286 
00287   v=sq_open(1024);
00288   sq_setprintfunc(v,printfunc);
00289 
00290   sq_pushroottable(v);
00291 
00292   sqstd_register_bloblib(v);
00293   sqstd_register_iolib(v);
00294   sqstd_register_systemlib(v);
00295   sqstd_register_mathlib(v);
00296   sqstd_register_stringlib(v);
00297 
00298   //aux library
00299   //sets error handlers
00300   sqstd_seterrorhandlers(v);
00301 
00302   //gets arguments
00303   switch(getargs(v,argc,argv))
00304   {
00305   case _INTERACTIVE:
00306     Interactive(v);
00307     break;
00308   case _DONE:
00309   default:
00310     break;
00311   }
00312 
00313   sq_close(v);
00314 
00315 #if defined(_MSC_VER) && defined(_DEBUG)
00316   _getch();
00317   _CrtMemDumpAllObjectsSince( NULL );
00318 #endif
00319   return 0;
00320 }
00321 

Generated on Wed Jul 15 20:35:55 2009 for OpenTTD by  doxygen 1.5.6