00001
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
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
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':
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
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
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
00299
00300 sqstd_seterrorhandlers(v);
00301
00302
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