/* see copyright notice in squirrel.h */ #include #include #include #include #if defined(_MSC_VER) && defined(_DEBUG) #include #include #endif #include #include #include #include #include #include #include #define MAXINPUT 1024 int sq_main_argc = 0; char** sq_main_argv = 0; void PrintVersionInfos(void); #if defined(_MSC_VER) && defined(_DEBUG) int MemAllocHook( int allocType, void *userData, size_t size, int blockType, long requestNumber, const unsigned char *filename, int lineNumber) { //if(requestNumber==769)_asm int 3; return 1; } #endif static SQInteger quit(HSQUIRRELVM v) { int *done; sq_getuserpointer(v,-1,(SQUserPointer*)&done); *done=1; return 0; } //static void printfunc(HSQUIRRELVM v,const SQChar *s,...) __attribute__ ((__format__ (__printf__, 2, 3))); static void printfunc(HSQUIRRELVM v,const SQChar *s,...) { va_list vl; va_start(vl, s); scvprintf(stdout, s, vl); va_end(vl); (void)v; /* UNUSED */ } //static void errorfunc(HSQUIRRELVM v,const SQChar *s,...) __attribute__ ((__format__ (__printf__, 2, 3))); static void errorfunc(HSQUIRRELVM v,const SQChar *s,...) { va_list vl; va_start(vl, s); fflush(stdout); scvprintf(stderr, s, vl); va_end(vl); (void)v; /* UNUSED */ } void PrintVersionInfos() { scfprintf(stdout,_SC("%s %s (%d bits)\n"),SQUIRREL_VERSION,SQUIRREL_COPYRIGHT,((int)(sizeof(SQInteger)*8))); } static SQInteger push_program_args(HSQUIRRELVM v,SQInteger arg, SQInteger argc, char* argv[], int asArray){ SQInteger i, callargs = 0; if(asArray) { sq_newarray(v, 0); } for(i=arg;i .\n") _SC("Available options are:\n") _SC(" -s compiles the file to bytecode(default output 'out.cnut')\n") _SC(" -o specifies output file for the -c option\n") _SC(" -c compiles only\n") _SC(" -d generates debug infos\n") _SC(" -v displays version infos\n") _SC(" -p preload given script file\n") _SC(" -i set the include_path\n") _SC(" -D define a preprocesor named constant\n") _SC(" -h prints help\n")); } static void loadDefaultScript(HSQUIRRELVM v, const char *script) { FILE *fb = scfopen(script, "rb"); if (!fb) return; fclose(fb); SQChar srcBoot[256]; scsprintf(srcBoot, sizeof(srcBoot), _SC("dofile(\"%s\", false);"), script); if(SQ_SUCCEEDED(sq_compilebuffer(v,srcBoot, strlen(srcBoot), _SC("defaultScript"), SQTrue, SQTrue, SQ_MAX_INCLUDE_FILES))) { int callargs = 1; sq_pushroottable(v); callargs += push_program_args(v, 0, sq_main_argc, sq_main_argv, 0); sq_call(v, callargs,SQFalse, SQTrue); } } #define _INTERACTIVE 0 #define _DONE 2 #define _ERROR 3 //<> this func is a mess static int getargs(HSQUIRRELVM v,int argc, char* argv[],SQInteger *retval) { int compiles_only = 0; int compiles_as_source_only = 0; #ifdef SQUNICODE static SQChar temp[500]; #endif const char * output = NULL; const char * preload = NULL; *retval = 0; if(argc>1) { int arg=1,exitloop=0; while(arg < argc && !exitloop) { if(argv[arg][0]=='-') { switch(argv[arg][1]) { case 'd': //DEBUG(debug infos) sq_enabledebuginfo(v,1); break; case 'c': compiles_only = 1; break; case 's': compiles_as_source_only = 1; break; case 'o': if(arg < argc) { arg++; output = argv[arg]; } break; case 'p': if(arg < argc) { arg++; preload = argv[arg]; } break; case 'i': if(arg < argc) { arg++; sq_set_include_path(v, argv[arg]); } break; case 'D': if(arg < argc) { if(argv[arg][2]) { //printf("-D=%s\n", argv[arg]+2); sq_set_define_name(v, argv[arg]+2); } else //argument separated by spaces { arg++; sq_set_define_name(v, argv[arg]); } } break; case 'v': PrintVersionInfos(); return _DONE; case 'h': PrintVersionInfos(); PrintUsage(); return _DONE; default: PrintVersionInfos(); scprintf(_SC("unknown prameter '-%c'\n"),argv[arg][1]); PrintUsage(); *retval = -1; return _ERROR; } }else break; arg++; } if(preload) loadDefaultScript(v, preload); // src file if(arg")); for(;;) { int c; if(done)return; c = getchar(); if (c == _SC('\n')) { if (i>0 && buffer[i-1] == _SC('\\')) { buffer[i-1] = _SC('\n'); } else if(blocks==0)break; buffer[i++] = _SC('\n'); } else if (c==_SC('}')) {blocks--; buffer[i++] = (SQChar)c;} else if(c==_SC('{') && !string){ blocks++; buffer[i++] = (SQChar)c; } else if(c==_SC('"') || c==_SC('\'')){ string=!string; buffer[i++] = (SQChar)c; } else if (i >= MAXINPUT-1) { scfprintf(stderr, _SC("sq : input line too long\n")); break; } else{ buffer[i++] = (SQChar)c; } } buffer[i] = _SC('\0'); if(buffer[0]==_SC('=')){ #define FMT_STR _SC("return (%s)") #define MAX_INPUT_SIZE (MAXINPUT+sizeof(FMT_STR)) scsprintf(sq_getscratchpad(v,MAX_INPUT_SIZE),MAX_INPUT_SIZE,FMT_STR,&buffer[1]); memcpy(buffer,sq_getscratchpad(v,-1),(scstrlen(sq_getscratchpad(v,-1))+1)*sizeof(SQChar)); retval=1; #undef FMT_STR #undef MAX_INPUT_SIZE } i=scstrlen(buffer); if(i>0){ SQInteger oldtop=sq_gettop(v); if(SQ_SUCCEEDED(sq_compilebuffer(v,buffer,i,_SC("interactive console"),SQTrue, SQTrue, SQ_MAX_INCLUDE_FILES))){ sq_pushroottable(v); if(SQ_SUCCEEDED(sq_call(v,1,retval,SQTrue)) && retval){ scprintf(_SC("\n")); sq_pushroottable(v); sq_pushstring(v,_SC("print"),-1); sq_get(v,-2); sq_pushroottable(v); sq_push(v,-4); sq_call(v,2,SQFalse,SQTrue); retval=0; scprintf(_SC("\n")); } } sq_settop(v,oldtop); } } } #define SCRIPT_END_TAG "ooOo(^.^)oOoo" // end of file is 29: "ooOo(^.^)oOoo", script_len #define END_TAG_LEN 29 #if 0 static SQInteger LoadFrozenScript0(HSQUIRRELVM v, const SQChar* filename, int only_check) { SQInteger retval; // lots of debugging to make sure that everything is ok //printf("%s\n", filename); FILE *f = scfopen(filename, "rb"); if (!f) return -1; if (fseek(f, 0, SEEK_END)) { fclose(f); return -1; } int fileSize = ftell(f); //printf("%d\n", fileSize); if (fseek(f, fileSize-END_TAG_LEN, SEEK_SET )) { fclose(f); return -1; } // do some sanity checking before reading the script length char tag_buf[END_TAG_LEN+2] = {0}; memset(tag_buf, 0, sizeof(char)*(END_TAG_LEN+2)); long script_len = 0; if (fread((void*)tag_buf, 1, END_TAG_LEN, f) != END_TAG_LEN) { fclose(f); return -1; } //printf("%s\n", tag_buf); if (sscanf(tag_buf, SCRIPT_END_TAG, &script_len) != 1) { fclose(f); // they only wanted to know if the script exists, assume it's valid if (only_check) return -2; else return -1; } else if (fseek(f, fileSize-END_TAG_LEN - script_len, SEEK_SET )) { fclose(f); return -1; } // size should be valid from Seek statement char *script = (char*)sq_malloc(script_len+10); if (script) { memset(script, 0, sizeof(script_len+10)); fread(script, 1, script_len, f); script[script_len] = 0; //printf("%s", script); } fclose(f); // we finally have our script! //fwrite(script, 1, finalSize, f); //fclose(f); if(SQ_SUCCEEDED(sq_compilebuffer(v,script, script_len, _SC("frozenScript"), SQTrue))) { int callargs = 1; sq_pushroottable(v); callargs += push_program_args(v, 0, sq_main_argc, sq_main_argv, 0); if(SQ_SUCCEEDED(sq_call(v,callargs,SQTrue,SQTrue))) { SQObjectType type = sq_gettype(v,-1); if(type == OT_INTEGER) { sq_getinteger(v,-1, &retval); } return _DONE; } else{ return _ERROR; } } free(script); return 0; } #endif #ifndef SQUILU_ALONE static char *chngChar (char *str, char oldChar, char newChar) { char *strPtr = str; while ((strPtr = strchr (strPtr, oldChar)) != NULL) *strPtr++ = newChar; return str; } #endif static SQInteger LoadFrozenScript(HSQUIRRELVM v, const SQChar* filename, int only_check) { #ifndef SQUILU_ALONE // lots of debugging to make sure that everything is ok //printf("%s\n", filename); FILE *f = scfopen(filename, "rb"); if (!f) return -1; if (fseek(f, 0, SEEK_END)) { fclose(f); return -1; } int fileSize = ftell(f); //printf("%d\n", fileSize); if (fseek(f, fileSize-END_TAG_LEN, SEEK_SET )) { fclose(f); return -1; } // do some sanity checking before reading the script length char tag_buf[END_TAG_LEN+2] = {0}; memset(tag_buf, 0, sizeof(char)*(END_TAG_LEN+2)); long script_len = 0; if (fread((void*)tag_buf, 1, END_TAG_LEN, f) != END_TAG_LEN) { fclose(f); return -1; } //printf("%s\n", tag_buf); if (sscanf(tag_buf, SCRIPT_END_TAG, &script_len) != 1) { fclose(f); // they only wanted to know if the script exists, assume it's valid if (only_check) return -2; else return -1; } else if (fseek(f, fileSize-END_TAG_LEN - script_len, SEEK_SET )) { fclose(f); return -1; } fclose(f); SQChar srcBoot[256]; SQInteger scr_len = scsprintf(srcBoot, sizeof(srcBoot), _SC("local __fd=file(\"%s\", \"rb\");__fd.seek(%d, 'b');local __zsrc=__fd.read(%d);__fd.close();__zsrc=compilestring(zlib.inflate(__zsrc),\"zsrc\",false);__zsrc.acall2(this, vargv);"), filename, (int)(fileSize-END_TAG_LEN - script_len), (int)script_len); chngChar(srcBoot, '\\', '/'); if(SQ_SUCCEEDED(sq_compilebuffer(v,srcBoot, scr_len, _SC("bootScript"), SQTrue, SQTrue,SQ_MAX_INCLUDE_FILES))) { int callargs = 1; sq_pushroottable(v); callargs += push_program_args(v, 0, sq_main_argc, sq_main_argv, 0); if(SQ_SUCCEEDED(sq_call(v, callargs,SQFalse, SQTrue))) { return _DONE; } else{ return _ERROR; } } #endif //SQUILU_ALONE return 0; } SQRESULT sqext_register_sqfs(HSQUIRRELVM v); SQRESULT sqext_register_sq_zmq3(HSQUIRRELVM v); SQRESULT sqext_register_sq_socket(HSQUIRRELVM v); SQRESULT sqext_register_sq_zlib(HSQUIRRELVM v); SQRESULT sqext_register_sq_miniz(HSQUIRRELVM v); SQRESULT sqext_register_mongoose(HSQUIRRELVM v); SQRESULT sqrat_register_importlib(HSQUIRRELVM v); SQRESULT sqext_register_sq_slave_vm(HSQUIRRELVM v); SQRESULT sqext_register_axtls (HSQUIRRELVM v); SQRESULT sqext_register_openssl (HSQUIRRELVM v); SQRESULT sqext_register_base64(HSQUIRRELVM v); SQRESULT sqext_register_Sq_Fpdf(HSQUIRRELVM v); SQRESULT sqext_register_SQLite3(HSQUIRRELVM v); SQRESULT sqext_register_mix (HSQUIRRELVM sqvm); SQRESULT sqext_register_rs232(HSQUIRRELVM v); SQRESULT sqext_register_tinyxml2(HSQUIRRELVM v); SQRESULT sqext_register_decimal(HSQUIRRELVM v); SQRESULT sqext_register_markdown(HSQUIRRELVM v); SQRESULT sqext_register_PostgreSQL(HSQUIRRELVM v); SQRESULT sqext_register_MySQL(HSQUIRRELVM v); SQRESULT sqext_register_Java(HSQUIRRELVM v); SQRESULT sqext_register_ThreadObjects(HSQUIRRELVM v); SQRESULT sqext_register_csv_parser (HSQUIRRELVM v); SQRESULT sqext_register_fltklib(HSQUIRRELVM v); SQRESULT sqext_register_dad_utils(HSQUIRRELVM v); SQRESULT sqext_register_gumbo(HSQUIRRELVM v); SQRESULT sqext_register_sys(HSQUIRRELVM v); SQRESULT sqext_register_DNS_SD(HSQUIRRELVM v); SQRESULT sqext_register_ffi(HSQUIRRELVM v); SQRESULT sqext_register_xjd1(HSQUIRRELVM v); SQRESULT sqext_register_libclang(HSQUIRRELVM v); SQRESULT sqext_register_EasyCurl (HSQUIRRELVM v); SQRESULT sqext_register_tweetnacl(HSQUIRRELVM v); SQRESULT sqext_register_ipc (HSQUIRRELVM v); SQRESULT sqext_register_BitVector (HSQUIRRELVM v); //depends on sqlite3 SQRESULT sqext_register_pack(HSQUIRRELVM v); SQRESULT sqext_register_sq_blosc(HSQUIRRELVM v); SQRESULT sqext_register_pcre(HSQUIRRELVM v); SQRESULT sqext_register_pcre2(HSQUIRRELVM v); SQRESULT sqext_register_freetype(HSQUIRRELVM v); SQRESULT sqext_register_tre(HSQUIRRELVM v); SQRESULT sqext_register_hunspell(HSQUIRRELVM v); SQRESULT sqext_register_fossil (HSQUIRRELVM sqvm); SQRESULT sqext_register_sqpeg (HSQUIRRELVM sqvm); SQRESULT sqext_register_LmDB (HSQUIRRELVM v); SQRESULT sqext_register_fuzzy_hash (HSQUIRRELVM sqvm); SQRESULT sqext_register_nn (HSQUIRRELVM v); SQRESULT sqext_register_lapack (HSQUIRRELVM v); SQRESULT sqext_register_numarray (HSQUIRRELVM v); SQRESULT sqext_register_fann (HSQUIRRELVM v); SQRESULT sqext_register_numarray (HSQUIRRELVM v); SQRESULT sqext_register_Snowball (HSQUIRRELVM v); SQRESULT sqext_register_sq_spawnx(HSQUIRRELVM v); SQRESULT sqext_register_lpsolve(HSQUIRRELVM v); SQRESULT sqext_register_tree_sitter(HSQUIRRELVM v); static sq_modules_preload_st modules_preload[] = { {"blob", sqstd_register_bloblib}, {"io", sqstd_register_iolib}, {"math", sqstd_register_mathlib}, {"sys", sqstd_register_systemlib}, {"string", sqstd_register_stringlib}, #ifdef WITH_DAD_EXTRAS #ifndef SQUILU_ALONE {"sqlexer", sqext_register_SQLexer}, {"gumbo", sqext_register_gumbo}, {"base64", sqext_register_base64}, #ifndef NO_SQ_PDF {"fpdf", sqext_register_Sq_Fpdf}, #endif #ifdef SQ_USE_NUMARRAY {"numarray", sqext_register_numarray}, #endif #ifdef SQ_USE_SQFANN {"SQFann", sqext_register_fann}, #endif {"AnnRprop", sqext_register_nn}, {"sqlite3", sqext_register_SQLite3}, {"bitvector", sqext_register_BitVector}, //depends on sqlite3 //{"xdj1", sqext_register_xjd1}, {"mix", sqext_register_mix}, {"sqfs", sqext_register_sqfs}, //{"ipc", sqext_register_ipc}, {"socket", sqext_register_sq_socket}, {"tweetnacl", sqext_register_tweetnacl}, {"pack", sqext_register_pack}, {"sqfossil", sqext_register_fossil}, #if !defined(TARGET_IOS) #ifdef SQ_USE_PCRE {"sqpcre", sqext_register_pcre}, #endif // SQ_USE_PCRE #if defined(SQ_USE_PCRE2) || defined(SQ_USE_PCRE2_STATIC) {"sqpcre2", sqext_register_pcre2}, #endif // SQ_USE_PCRE2 #if defined(SQ_USE_TRE) || defined(SQ_USE_TRE_STATIC) {"sqtre", sqext_register_tre}, #endif // SQ_USE_TRE #if defined(SQ_USE_HUNSPELL) || defined(SQ_USE_HUNSPELL_STATIC) {"sqhunspell", sqext_register_hunspell}, #endif // SQ_USE_HUNSPELL #if defined(SQ_USE_LPSOLVE) || defined(SQ_USE_LPSOLVE_STATIC) {"sqlpsolve", sqext_register_lpsolve}, #endif // SQ_USE_LPSOLVE #ifdef SQ_USE_FREETYPE {"freetype", sqext_register_freetype}, #endif // SQ_USE_FREETYPE #ifdef SQ_USE_BLOSC {"blosc", sqext_register_sq_blosc}, #endif // SQ_USE_BLOSC #ifdef SQ_USE_SPAWNX {"sqspawnx", sqext_register_sq_spawnx}, #endif // SQ_USE_SPAWNX #ifdef SQ_USE_LAPACK {"lapack", sqext_register_lapack}, #endif // SQ_USE_LAPACK #endif #ifdef USE_AXTLS {"axtls", sqext_register_axtls}, #endif #ifdef WITH_FFI {"ffi", sqext_register_ffi}, #endif #ifdef USE_OPENSSL {"openssl", sqext_register_openssl}, #endif {"zlib", sqext_register_sq_zlib}, //{"miniz", sqext_register_sq_miniz}, {"mongoose", sqext_register_mongoose}, {"importlib", sqrat_register_importlib}, #ifndef NO_TINYXML2 {"tinyxml2", sqext_register_tinyxml2}, #endif #ifndef _WIN32_WCE #ifdef WITH_MPDECIMAL {"decimal", sqext_register_decimal}, #endif {"markdown", sqext_register_markdown}, #endif {"slave_vm", sqext_register_sq_slave_vm}, //{"thread", sqext_register_ThreadObjects}, #ifndef ANDROID_BUILD {"dad_utils", sqext_register_dad_utils}, #endif //{"sys_extra", sqext_register_sys}, #ifdef SQ_USE_EASYCURL {"easycurl", sqext_register_EasyCurl}, #endif // SQ_USE_EASYCURL #ifdef WITH_FULL_DAD_EXTRAS {"csv_parser", sqext_register_csv_parser}, //{"zmq3", sqext_register_sq_zmq3}, //{"java", sqext_register_Java}, #endif #ifdef WITH_LIBCLANG {"libclang", sqext_register_libclang}, #endif #ifdef WITH_POSTGRESQL {"postgresql", sqext_register_PostgreSQL}, #endif #ifdef WITH_MYSQL {"mysql", sqext_register_MySQL}, #endif #ifdef USE_SNOWBALL {"snowball", sqext_register_Snowball}, #endif #if !defined(ANDROID_BUILD) && !defined(NO_RS232) {"rs232", sqext_register_rs232}, #endif #ifdef WITH_FLTK {"fltk", sqext_register_fltklib}, #endif #ifdef WITH_DNS_SD {"dns_sd", sqext_register_DNS_SD}, #endif #ifdef SQ_USE_FUZZY_HASH {"sqfuzzy_hash", sqext_register_fuzzy_hash}, #endif // SQ_USE_FUZZY_HASH #ifdef SQ_USE_NUMARRAY {"numarray", sqext_register_numarray}, #endif // SQ_USE_FUZZY_HASH #endif //SQUILU_ALONE #endif // WITH_DAD_EXTRAS #if defined(SQ_USE_SQLEG) {"sqleg", sqext_register_sqpeg}, #endif // SQ_USE_PCRE2 #if defined(SQ_USE_LMDB) {"sqlmdb", sqext_register_LmDB}, #endif // SQ_USE_LMDB #ifdef SQ_USE_TREE_SITTER {"tree_sitter", sqext_register_tree_sitter}, #endif // SQ_USE_FREETYPE {NULL, NULL} }; int main(int argc, char* argv[]) { sq_main_argc = argc; sq_main_argv = argv; HSQUIRRELVM v; SQInteger retval = 0; //const SQChar *filename=NULL; #if defined(_MSC_VER) && defined(_DEBUG) _CrtSetAllocHook(MemAllocHook); #endif #ifndef SQ_OPEN_VM_SIZE #define SQ_OPEN_VM_SIZE 1024 #endif // SQ_OPEN_VM_SIZE v=sq_open(SQ_OPEN_VM_SIZE); const SQChar *include_path = scgetenv(_SC("SQUILU_PATH")); if(include_path) sq_set_include_path(v, include_path); sq_setprintfunc(v,printfunc,errorfunc); sq_pushroottable(v); /* sq_pushstring(v, _SC("sq_xinterpreter"), -1); sq_pushstring(v, argv[0], -1); sq_newslot(v,-3,SQFalse); */ sq_modules_preload_st *mp = modules_preload; sq_preload_modules(v, mp); while(mp->module_load_func){ mp->module_load_func(v); ++mp; } //aux library //sets error handlers sqstd_seterrorhandlers(v); //frozen script executed ? if(LoadFrozenScript(v, argv[0], 0) == _DONE) return 0; //gets arguments switch(getargs(v,argc,argv,&retval)) { case _INTERACTIVE: Interactive(v); break; case _DONE: case _ERROR: default: break; } sq_close(v); #if defined(_MSC_VER) && defined(_DEBUG) _getch(); _CrtMemDumpAllObjectsSince( NULL ); #endif return retval; }