# 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