Johan Wikman / SQUIRREL3

Dependents:   Squirrel

Embed: (wiki syntax)

« Back to documentation index

Show/hide line numbers sq.c Source File

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 vfwprintf
00024 #else
00025 #define scfprintf fprintf
00026 #define scfopen fopen
00027 #define scvprintf vfprintf
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==769)_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(stdout, s, vl);
00056     va_end(vl);
00057 }
00058 
00059 void errorfunc(HSQUIRRELVM v,const SQChar *s,...)
00060 {
00061     va_list vl;
00062     va_start(vl, s);
00063     scvprintf(stderr, s, vl);
00064     va_end(vl);
00065 }
00066 
00067 void PrintVersionInfos()
00068 {
00069     scfprintf(stdout,_SC("%s %s (%d bits)\n"),SQUIRREL_VERSION,SQUIRREL_COPYRIGHT,((int)(sizeof(SQInteger)*8)));
00070 }
00071 
00072 void PrintUsage()
00073 {
00074     scfprintf(stderr,_SC("usage: sq <options> <scriptpath [args]>.\n")
00075         _SC("Available options are:\n")
00076         _SC("   -c              compiles the file to bytecode(default output 'out.cnut')\n")
00077         _SC("   -o              specifies output file for the -c option\n")
00078         _SC("   -c              compiles only\n")
00079         _SC("   -d              generates debug infos\n")
00080         _SC("   -v              displays version infos\n")
00081         _SC("   -h              prints help\n"));
00082 }
00083 
00084 #define _INTERACTIVE 0
00085 #define _DONE 2
00086 #define _ERROR 3
00087 //<<FIXME>> this func is a mess
00088 int getargs(HSQUIRRELVM v,int argc, char* argv[],SQInteger *retval)
00089 {
00090     int i;
00091     int compiles_only = 0;
00092     static SQChar temp[500];
00093     const SQChar *ret=NULL;
00094     char * output = NULL;
00095     int lineinfo=0;
00096     *retval = 0;
00097     if(argc>1)
00098     {
00099         int arg=1,exitloop=0;
00100         
00101         while(arg < argc && !exitloop)
00102         {
00103 
00104             if(argv[arg][0]=='-')
00105             {
00106                 switch(argv[arg][1])
00107                 {
00108                 case 'd': //DEBUG(debug infos)
00109                     sq_enabledebuginfo(v,1);
00110                     break;
00111                 case 'c':
00112                     compiles_only = 1;
00113                     break;
00114                 case 'o':
00115                     if(arg < argc) {
00116                         arg++;
00117                         output = argv[arg];
00118                     }
00119                     break;
00120                 case 'v':
00121                     PrintVersionInfos();
00122                     return _DONE;
00123                 
00124                 case 'h':
00125                     PrintVersionInfos();
00126                     PrintUsage();
00127                     return _DONE;
00128                 default:
00129                     PrintVersionInfos();
00130                     scprintf(_SC("unknown prameter '-%c'\n"),argv[arg][1]);
00131                     PrintUsage();
00132                     *retval = -1;
00133                     return _ERROR;
00134                 }
00135             }else break;
00136             arg++;
00137         }
00138 
00139         // src file
00140         
00141         if(arg<argc) {
00142             const SQChar *filename=NULL;
00143 #ifdef SQUNICODE
00144             mbstowcs(temp,argv[arg],strlen(argv[arg]));
00145             filename=temp;
00146 #else
00147             filename=argv[arg];
00148 #endif
00149 
00150             arg++;
00151             
00152             //sq_pushstring(v,_SC("ARGS"),-1);
00153             //sq_newarray(v,0);
00154             
00155             //sq_createslot(v,-3);
00156             //sq_pop(v,1);
00157             if(compiles_only) {
00158                 if(SQ_SUCCEEDED(sqstd_loadfile(v,filename,SQTrue))){
00159                     const SQChar *outfile = _SC("out.cnut");
00160                     if(output) {
00161 #ifdef SQUNICODE
00162                         int len = (int)(strlen(output)+1);
00163                         mbstowcs(sq_getscratchpad(v,len*sizeof(SQChar)),output,len);
00164                         outfile = sq_getscratchpad(v,-1);
00165 #else
00166                         outfile = output;
00167 #endif
00168                     }
00169                     if(SQ_SUCCEEDED(sqstd_writeclosuretofile(v,outfile)))
00170                         return _DONE;
00171                 }
00172             }
00173             else {
00174                 //if(SQ_SUCCEEDED(sqstd_dofile(v,filename,SQFalse,SQTrue))) {
00175                     //return _DONE;
00176                 //}
00177                 if(SQ_SUCCEEDED(sqstd_loadfile(v,filename,SQTrue))) {
00178                     int callargs = 1;
00179                     sq_pushroottable(v);
00180                     for(i=arg;i<argc;i++)
00181                     {
00182                         const SQChar *a;
00183 #ifdef SQUNICODE
00184                         int alen=(int)strlen(argv[i]);
00185                         a=sq_getscratchpad(v,(int)(alen*sizeof(SQChar)));
00186                         mbstowcs(sq_getscratchpad(v,-1),argv[i],alen);
00187                         sq_getscratchpad(v,-1)[alen] = _SC('\0');
00188 #else
00189                         a=argv[i];
00190 #endif
00191                         sq_pushstring(v,a,-1);
00192                         callargs++;
00193                         //sq_arrayappend(v,-2);
00194                     }
00195                     if(SQ_SUCCEEDED(sq_call(v,callargs,SQTrue,SQTrue))) {
00196                         SQObjectType type = sq_gettype(v,-1);
00197                         if(type == OT_INTEGER) {
00198                             *retval = type;
00199                             sq_getinteger(v,-1,retval);
00200                         }
00201                         return _DONE;
00202                     }
00203                     else{
00204                         return _ERROR;
00205                     }
00206                     
00207                 }
00208             }
00209             //if this point is reached an error occured
00210             {
00211                 const SQChar *err;
00212                 sq_getlasterror(v);
00213                 if(SQ_SUCCEEDED(sq_getstring(v,-1,&err))) {
00214                     scprintf(_SC("Error [%s]\n"),err);
00215                     *retval = -2;
00216                     return _ERROR;
00217                 }
00218             }
00219             
00220         }
00221     }
00222 
00223     return _INTERACTIVE;
00224 }
00225 
00226 void Interactive(HSQUIRRELVM v)
00227 {
00228     
00229 #define MAXINPUT 1024
00230     SQChar buffer[MAXINPUT];
00231     SQInteger blocks =0;
00232     SQInteger string=0;
00233     SQInteger retval=0;
00234     SQInteger done=0;
00235     PrintVersionInfos();
00236         
00237     sq_pushroottable(v);
00238     sq_pushstring(v,_SC("quit"),-1);
00239     sq_pushuserpointer(v,&done);
00240     sq_newclosure(v,quit,1);
00241     sq_setparamscheck(v,1,NULL);
00242     sq_newslot(v,-3,SQFalse);
00243     sq_pop(v,1);
00244 
00245     while (!done) 
00246     {
00247         SQInteger i = 0;
00248         scprintf(_SC("\nsq>"));
00249         for(;;) {
00250             int c;
00251             if(done)return;
00252             c = getchar();
00253             if ((c == _SC('\n')) || (c == _SC('\r'))) {
00254                 if (i>0 && buffer[i-1] == _SC('\\'))
00255                 {
00256                     buffer[i-1] = _SC('\n');
00257                 }
00258                 else if(blocks==0)break;
00259                 buffer[i++] = _SC('\n');
00260             }
00261             else if (c==_SC('}')) {blocks--; buffer[i++] = (SQChar)c;}
00262             else if(c==_SC('{') && !string){
00263                     blocks++;
00264                     buffer[i++] = (SQChar)c;
00265             }
00266             else if(c==_SC('"') || c==_SC('\'')){
00267                     string=!string;
00268                     buffer[i++] = (SQChar)c;
00269             }
00270             else if (i >= MAXINPUT-1) {
00271                 scfprintf(stderr, _SC("sq : input line too long\n"));
00272                 break;
00273             }
00274             else{
00275                 buffer[i++] = (SQChar)c;
00276             }
00277         }
00278         buffer[i] = _SC('\0');
00279         
00280         if(buffer[0]==_SC('=')){
00281             scsprintf(sq_getscratchpad(v,MAXINPUT),_SC("return (%s)"),&buffer[1]);
00282             memcpy(buffer,sq_getscratchpad(v,-1),(scstrlen(sq_getscratchpad(v,-1))+1)*sizeof(SQChar));
00283             retval=1;
00284         }
00285         i=scstrlen(buffer);
00286         if(i>0){
00287             SQInteger oldtop=sq_gettop(v);
00288             if(SQ_SUCCEEDED(sq_compilebuffer(v,buffer,i,_SC("interactive console"),SQTrue))){
00289                 sq_pushroottable(v);
00290                 if(SQ_SUCCEEDED(sq_call(v,1,retval,SQTrue)) &&  retval){
00291                     scprintf(_SC("\n"));
00292                     sq_pushroottable(v);
00293                     sq_pushstring(v,_SC("print"),-1);
00294                     sq_get(v,-2);
00295                     sq_pushroottable(v);
00296                     sq_push(v,-4);
00297                     sq_call(v,2,SQFalse,SQTrue);
00298                     retval=0;
00299                     scprintf(_SC("\n"));
00300                 }
00301             }
00302             
00303             sq_settop(v,oldtop);
00304         }
00305     }
00306 }
00307 
00308 int main(int argc, char* argv[])
00309 {
00310     HSQUIRRELVM v;
00311     SQInteger retval = 0;
00312     const SQChar *filename=NULL;
00313 #if defined(_MSC_VER) && defined(_DEBUG)
00314     _CrtSetAllocHook(MemAllocHook);
00315 #endif
00316     
00317     v=sq_open(1024);
00318     sq_setprintfunc(v,printfunc,errorfunc);
00319 
00320     sq_pushroottable(v);
00321 
00322     sqstd_register_bloblib(v);
00323     sqstd_register_iolib(v);
00324     sqstd_register_systemlib(v);
00325     sqstd_register_mathlib(v);
00326     sqstd_register_stringlib(v);
00327 
00328 #if defined(__MBED__)
00329     void sq_bind_mbed(HSQUIRRELVM);
00330     
00331     sq_bind_mbed(v);
00332 #endif
00333     //aux library
00334     //sets error handlers
00335     sqstd_seterrorhandlers(v);
00336 
00337     //gets arguments
00338     switch(getargs(v,argc,argv,&retval))
00339     {
00340     case _INTERACTIVE:
00341         Interactive(v);
00342         break;
00343     case _DONE:
00344     case _ERROR:
00345     default: 
00346         break;
00347     }
00348 
00349     sq_close(v);
00350     
00351 #if defined(_MSC_VER) && defined(_DEBUG)
00352     _getch();
00353     _CrtMemDumpAllObjectsSince( NULL );
00354 #endif
00355     return retval;
00356 }
00357