浏览代码

Add an initial implementation of using environment var SQUILU_PATH to search for include files, inspired and based on LUA_PATH

mingodad 8 年之前
父节点
当前提交
2e71442f5e

+ 28 - 0
SquiLu-ext/sq_slave_vm.cpp

@@ -309,6 +309,32 @@ static SQRESULT sq_slave_vm_close(HSQUIRRELVM v)
     return 0;
 }
 
+static SQRESULT sq_slave_vm_set_include_path(HSQUIRRELVM v)
+{
+    SQ_FUNC_VARS_NO_TOP(v);
+    GET_sq_slave_vm_INSTANCE(v, 1);
+#ifdef SLAVE_VM_WITH_OS_THREADS
+    if(checkTryLock(v, self)) return SQ_ERROR;
+    releaseSlaveThread(self);
+#endif // SLAVE_VM_WITH_OS_THREADS
+    SQ_GET_STRING(v, 2, include_path);
+    sq_set_include_path(svm, include_path);
+    return 0;
+}
+
+static SQRESULT sq_slave_vm_get_include_path(HSQUIRRELVM v)
+{
+    SQ_FUNC_VARS_NO_TOP(v);
+    GET_sq_slave_vm_INSTANCE(v, 1);
+#ifdef SLAVE_VM_WITH_OS_THREADS
+    if(checkTryLock(v, self)) return SQ_ERROR;
+    releaseSlaveThread(self);
+#endif // SLAVE_VM_WITH_OS_THREADS
+    const SQChar *include_path = sq_get_include_path(svm);
+    if(include_path) sq_pushstring(v, include_path, -1);
+    else sq_pushnull(v);
+    return 1;
+}
 static SQRESULT sq_slave_vm_call(HSQUIRRELVM v)
 {
     SQ_FUNC_VARS_NO_TOP(v);
@@ -681,6 +707,8 @@ extern "C" {
         sq_insertfunc(v, _SC("constructor"), sq_slave_vm_constructor, -1, _SC("xibb"), SQFalse);
         sq_insertfunc(v, _SC("_tostring"), sq_slave_vm__tostring, 1, _SC("x"), SQFalse);
         sq_insertfunc(v, _SC("close"), sq_slave_vm_close, 1, _SC("x"), SQFalse);
+        sq_insertfunc(v, _SC("set_include_path"), sq_slave_vm_set_include_path, 2, _SC("xs"), SQFalse);
+        sq_insertfunc(v, _SC("get_include_path"), sq_slave_vm_get_include_path, 1, _SC("x"), SQFalse);
         sq_insertfunc(v, _SC("set"), sq_slave_vm_set, 3, get_set_validation_mask, SQFalse);
         sq_insertfunc(v, _SC("_set"), sq_slave_vm_set, 3, get_set_validation_mask, SQFalse);
         sq_insertfunc(v, _SC("get"), sq_slave_vm_get, -2, get_set_validation_mask, SQFalse);

+ 2 - 0
SquiLu/include/sqapi.h

@@ -24,6 +24,8 @@ SQUIRREL_API_FUNC(SQRESULT, suspendvm, (HSQUIRRELVM v))
 SQUIRREL_API_FUNC(SQRESULT, wakeupvm, (HSQUIRRELVM v,SQBool resumedret,SQBool retval,SQBool raiseerror,SQBool throwerror))
 SQUIRREL_API_FUNC(SQInteger, getvmstate, (HSQUIRRELVM v))
 SQUIRREL_API_FUNC(SQInteger, getversion, ())
+SQUIRREL_API_FUNC(void, set_include_path, (HSQUIRRELVM v, const SQChar *include_path))
+SQUIRREL_API_FUNC(const SQChar*, get_include_path, (HSQUIRRELVM v))
 
 /*compiler*/
 #ifndef SQ_MAX_INCLUDE_FILES

+ 44 - 0
SquiLu/include/sqconfig.h

@@ -72,12 +72,24 @@ typedef unsigned wchar_t SQUChar;
 #define scfprintf fwprintf
 #define scvprintf vfwprintf
 #define scfopen	_wfopen
+#define scgetenv _wgetenv
+#define scsystem _wsystem
+#define scasctime _wasctime
+#define scstrftime _wstrftime
+#define scremove _wremove
+#define screname _wrename
 #else
 #define scsprintf   swprintf
 #define scvfprintf	vfwprintf
 #define scfprintf fwprintf
 #define scvprintf vfwprintf
 #define scfopen	wfopen
+#define scgetenv wgetenv
+#define scsystem wsystem
+#define scasctime wasctime
+#define scstrftime wstrftime
+#define scremove wremove
+#define screname wrename
 #endif
 #define scstrlen    wcslen
 #define scstrcpy    wcstrcpy
@@ -94,6 +106,12 @@ typedef unsigned wchar_t SQUChar;
 #define scstrpbrk	wcspbrk
 #define scstrtok	wcstrtok
 #define scprintf    wprintf
+#define scgetenv wgetenv
+#define scsystem wsystem
+#define scasctime wasctime
+#define scstrftime wstrftime
+#define scremove wremove
+#define screname wrename
 
 #ifdef _WIN32
 #define WCHAR_SIZE 2
@@ -118,6 +136,7 @@ typedef unsigned wchar_t SQUChar;
 
 
 #define sq_rsl(l) ((l)<<WCHAR_SHIFT_MUL)
+#define sq_str_sizeof(p) (sizeof(p)/WCHAR_SIZE)
 
 #else
 typedef char SQChar;
@@ -165,7 +184,14 @@ typedef unsigned char SQUChar;
 #define scprintf    printf
 #define MAX_CHAR 0xFF
 
+#define scgetenv getenv
+#define scsystem system
+#define scasctime asctime
+#define scstrftime strftime
+#define scremove remove
+#define screname rename
 #define sq_rsl(l) (l)
+#define sq_str_sizeof(p) (sizeof(p))
 
 #endif
 
@@ -175,3 +201,21 @@ typedef unsigned char SQUChar;
 #else
 #define _PRINT_INT_FMT _SC("%d")
 #endif
+
+#if !defined(SQUILU_MAX_PATH)
+#define SQUILU_MAX_PATH	1024
+#endif
+
+#if defined(_WIN32)
+#define SQUILU_DIRSEP	_SC("\\")
+#else
+#define SQUILU_DIRSEP	_SC("/")
+#endif
+
+#if !defined(SQUILU_PATH_VAR)
+#define SQUILU_PATH_VAR	_SC("SQUILU_PATH")
+#endif
+
+#if !defined (SQUILU_PATH_SEP)
+#define SQUILU_PATH_SEP		_SC(";")
+#endif

+ 2 - 0
SquiLu/include/sqstdio.h

@@ -42,6 +42,8 @@ SQUIRREL_API SQRESULT sqstd_createfile(HSQUIRRELVM v, SQFILE file,SQBool own);
 SQUIRREL_API SQRESULT sqstd_getfile(HSQUIRRELVM v, SQInteger idx, SQFILE *file);
 
 //compiler helpers
+SQUIRREL_API SQRESULT sqstd_loadfile_include_path(HSQUIRRELVM v,const SQChar *filename,SQBool printerror,
+                                                  SQBool show_warnings, const SQChar *include_path);
 SQUIRREL_API SQRESULT sqstd_loadfile(HSQUIRRELVM v,const SQChar *filename,SQBool printerror,SQBool show_warnings);
 SQUIRREL_API SQRESULT sqstd_dofile(HSQUIRRELVM v,const SQChar *filename,SQBool retval,SQBool printerror,SQBool show_warnings);
 SQUIRREL_API SQRESULT sqstd_writeclosuretofile(HSQUIRRELVM v,const SQChar *filename);

+ 23 - 8
SquiLu/sq/sq.c

@@ -100,6 +100,7 @@ void PrintUsage()
 		_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("   -h              prints help\n"));
 }
 
@@ -112,7 +113,8 @@ void loadDefaultScript(HSQUIRRELVM v, const char *script)
     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))) {
+    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);
@@ -164,7 +166,12 @@ int getargs(HSQUIRRELVM v,int argc, char* argv[],SQInteger *retval)
 					if(arg < argc) {
 						arg++;
 						preload = argv[arg];
-                        loadDefaultScript(v, preload);
+					}
+					break;
+				case 'i':
+					if(arg < argc) {
+						arg++;
+						sq_set_include_path(v, argv[arg]);
 					}
 					break;
 				case 'v':
@@ -185,6 +192,7 @@ int getargs(HSQUIRRELVM v,int argc, char* argv[],SQInteger *retval)
 			}else break;
 			arg++;
 		}
+		if(preload) loadDefaultScript(v, preload);
 
 		// src file
 
@@ -356,7 +364,8 @@ void Interactive(HSQUIRRELVM v)
 		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))){
+			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"));
@@ -535,7 +544,7 @@ static SQInteger LoadFrozenScript(HSQUIRRELVM v, const SQChar* filename, int onl
 
     chngChar(srcBoot, '\\', '/');
 
-    if(SQ_SUCCEEDED(sq_compilebuffer(v,srcBoot, scr_len, _SC("bootScript"), SQTrue, SQTrue, SQ_MAX_INCLUDE_FILES))) {
+    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);
@@ -615,12 +624,12 @@ static sq_modules_preload_st modules_preload[] = {
     {"socket", sqext_register_sq_socket},
     {"tweetnacl", sqext_register_tweetnacl},
     {"pack", sqext_register_pack},
-#ifndef TARGET_IOS
+#if !defined(TARGET_IOS)
 #ifdef SQ_USE_PCRE
-    {"pcre", sqext_register_pcre},
+    {"sqpcre", sqext_register_pcre},
 #endif // SQ_USE_PCRE
 #if defined(SQ_USE_PCRE2) || defined(SQ_USE_PCRE2_STATIC)
-    {"pcre2", sqext_register_pcre2},
+    {"sqpcre2", sqext_register_pcre2},
 #endif // SQ_USE_PCRE2
 #if defined(SQ_USE_TRE) || defined(SQ_USE_TRE_STATIC)
     {"sqtre", sqext_register_tre},
@@ -657,7 +666,9 @@ static sq_modules_preload_st modules_preload[] = {
 #endif
     {"slave_vm", sqext_register_sq_slave_vm},
     //{"thread", sqext_register_ThreadObjects},
+#if !defined(ANDROID_BUILD)
     {"dad_utils", sqext_register_dad_utils},
+#endif
     //{"sys_extra", sqext_register_sys},
 #ifdef SQ_USE_EASYCURL
     {"easycurl", sqext_register_EasyCurl},
@@ -677,7 +688,9 @@ static sq_modules_preload_st modules_preload[] = {
 #ifdef WITH_MYSQL
     {"mysql", sqext_register_MySQL},
 #endif
+#if !defined(ANDROID_BUILD)
     {"rs232", sqext_register_rs232},
+#endif
 #ifdef WITH_FLTK
     {"fltk", sqext_register_fltklib},
 #endif
@@ -686,7 +699,7 @@ static sq_modules_preload_st modules_preload[] = {
 #endif
 
 #endif //SQUILU_ALONE
-#endif
+#endif // WITH_DAD_EXTRAS
     {NULL, NULL}
 };
 
@@ -706,6 +719,8 @@ int main(int argc, char* argv[])
 #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);

+ 7 - 1
SquiLu/sqstdlib/sqstdio.cpp

@@ -426,7 +426,8 @@ SQRESULT sqstd_loadfile(HSQUIRRELVM v,const SQChar *filename,SQBool printerror,S
 			buffer.size = 0;
 			buffer.file = file;
 
-			if(SQ_SUCCEEDED(sq_compile(v,func,&buffer,filename,printerror,show_warnings, SQ_MAX_INCLUDE_FILES))){
+			if(SQ_SUCCEEDED(sq_compile(v,func,&buffer,filename,printerror,show_warnings,
+                              SQ_MAX_INCLUDE_FILES))){
 				sqstd_fclose(file);
 				return SQ_OK;
 			}
@@ -437,6 +438,11 @@ SQRESULT sqstd_loadfile(HSQUIRRELVM v,const SQChar *filename,SQBool printerror,S
 	return sq_throwerror(v,_SC("cannot open the file"));
 }
 
+SQRESULT sqstd_loadfile(HSQUIRRELVM v,const SQChar *filename,SQBool printerror,SQBool show_warnings)
+{
+    return sqstd_loadfile_include_path(v, filename, printerror, show_warnings, NULL);
+}
+
 SQRESULT sqstd_dofile(HSQUIRRELVM v,const SQChar *filename,SQBool retval,SQBool printerror,SQBool show_warnings)
 {
 	if(SQ_SUCCEEDED(sqstd_loadfile(v,filename,printerror,show_warnings))) {

+ 0 - 16
SquiLu/sqstdlib/sqstdsystem.cpp

@@ -18,22 +18,6 @@
 #include <unistd.h>
 #endif
 
-#ifdef SQUNICODE
-#include <wchar.h>
-#define scgetenv _wgetenv
-#define scsystem _wsystem
-#define scasctime _wasctime
-#define scstrftime _wstrftime
-#define scremove _wremove
-#define screname _wrename
-#else
-#define scgetenv getenv
-#define scsystem system
-#define scasctime asctime
-#define scstrftime strftime
-#define scremove remove
-#define screname rename
-#endif
 
 SQ_OPT_STRING_STRLEN();
 

+ 14 - 2
SquiLu/squirrel/sqapi.cpp

@@ -151,12 +151,23 @@ SQInteger sq_getversion()
 	return SQUIRREL_VERSION_NUMBER;
 }
 
+void sq_set_include_path(HSQUIRRELVM v, const SQChar *include_path)
+{
+	v->SetIncludePath(include_path);
+}
+
+const SQChar * sq_get_include_path(HSQUIRRELVM v)
+{
+	return v->GetIncludePath();
+}
+
 SQRESULT sq_compile(HSQUIRRELVM v,SQLEXREADFUNC read,SQUserPointer p,const SQChar *sourcename
                     ,SQBool raiseerror, SQBool show_warnings, SQInteger max_nested_includes)
 {
 	SQObjectPtr o;
 #ifndef SQ_NO_COMPILER
-	if(Compile(v, read, p, sourcename, o, raiseerror?true:false, _ss(v)->_debuginfo, show_warnings, max_nested_includes)) {
+	if(Compile(v, read, p, sourcename, o, raiseerror?true:false, _ss(v)->_debuginfo, show_warnings,
+                max_nested_includes)) {
 		v->Push(SQClosure::Create(_ss(v), _funcproto(o), _table(v->_roottable)->GetWeakRef(OT_TABLE)));
 		return SQ_OK;
 	}
@@ -1983,7 +1994,8 @@ SQRESULT sq_compilebuffer(HSQUIRRELVM v,const SQChar *s,SQInteger size,const SQC
 	buf.buf = s;
 	buf.size = size;
 	buf.ptr = 0;
-	return sq_compile(v, sq_strbuf_lexfeed, &buf, sourcename, raiseerror, show_warnings, max_nested_includes);
+	return sq_compile(v, sq_strbuf_lexfeed, &buf, sourcename, raiseerror, show_warnings,
+                   max_nested_includes);
 }
 
 void sq_move(HSQUIRRELVM dest,HSQUIRRELVM src,SQInteger idx)

+ 8 - 0
SquiLu/squirrel/sqbaselib.cpp

@@ -405,6 +405,13 @@ static SQRESULT base_str_from_chars (HSQUIRRELVM v) {
   return 1;
 }
 
+static SQRESULT base_getincludepath(HSQUIRRELVM v)
+{
+    const SQChar *include_path = v->GetIncludePath();
+    if(include_path) sq_pushstring(v, include_path, 1);
+    else sq_pushnull(v);
+	return 1;
+}
 /////////////////////////////////////////////////////////////////
 //TABLE BASE FUNCTIONS
 
@@ -559,6 +566,7 @@ static SQRegFunction base_funcs[]={
 #endif
 	{_SC("str_from_chars"),base_str_from_chars,-1, _SC(".i")},
 	{_SC("try_tostring"),base_try_tostring,-2, _SC("..s")},
+	{_SC("getincludepath"),base_getincludepath,1, _SC(".")},
 	{_SC("table_create"),bf_table_create,-1, _SC(".i")},
 	{_SC("table_new"),bf_table_create,-1, _SC(".i")},
 	{_SC("table_len"),bf_table_len,2, _SC(".t")},

+ 29 - 0
SquiLu/squirrel/sqcompiler.cpp

@@ -154,6 +154,7 @@ public:
         _max_nested_includes = max_nested_includes;
         _nested_includes_count = 0;
         _is_parsing_extern = false;
+        squilu_lib_path = NULL;
 	}
 	~SQCompiler(){
         _table(_globals)->Finalize();
@@ -465,7 +466,34 @@ public:
             //Warning(_SC("%s:%d:%d warning pragma include %s\n"),
             //        _stringval(_sourcename), line, column, _stringval(id));
 
+            const SQChar *lib_path = NULL;
+            //first try the filename alone
             FILE *fp = scfopen(_stringval(id), "r");
+            while(!fp)
+            {
+                //now if we have an environment path let's try it
+                if(!lib_path)
+                {
+                    if(!squilu_lib_path) squilu_lib_path = _vm->GetIncludePath();
+                    lib_path = squilu_lib_path;
+                    if(!lib_path) break;
+                }
+                while (*lib_path == *SQUILU_PATH_SEP) lib_path++;  /* skip separators */
+                if (*lib_path == '\0') break;  /* no more templates */
+                const SQChar *l = scstrchr(lib_path, *SQUILU_PATH_SEP);  /* find next separator */
+                if (l == NULL) l = lib_path + scstrlen(lib_path);
+                size_t path_len = l - lib_path;
+                SQChar file_path_name[SQUILU_MAX_PATH];
+                if(path_len < sizeof(file_path_name)) //enough room to work ?
+                {
+                    scsprintf(file_path_name, sizeof(file_path_name), "%s", lib_path);
+                    scsprintf(file_path_name + path_len, sizeof(file_path_name) - path_len,
+                              "%s%s", SQUILU_DIRSEP, _stringval(id));
+                    //printf("file_path_name = %s\n", file_path_name);
+                    fp = scfopen(file_path_name, "r");
+                    lib_path += path_len; //move the pointer to the next path
+                }
+            }
             if(fp != NULL)
             {
                 //increment nested count
@@ -2717,6 +2745,7 @@ private:
 	SQObjectPtr _extern_names; //to allow C/C++ style extern declarations
 	SQChar error_buf[MAX_COMPILER_ERROR_LEN];
 	SQInteger _max_nested_includes, _nested_includes_count;
+	const SQChar *squilu_lib_path;
 };
 
 bool Compile(SQVM *vm,SQLEXREADFUNC rg, SQUserPointer up, const SQChar *sourcename, SQObjectPtr &out,

+ 2 - 0
SquiLu/squirrel/sqvm.cpp

@@ -1993,6 +1993,8 @@ SQObjectPtr &SQVM::Top() { return _stack[_top-1]; }
 SQObjectPtr &SQVM::PopGet() { return _stack[--_top]; }
 SQObjectPtr &SQVM::GetUp(SQInteger n) { return _stack[_top+n]; }
 SQObjectPtr &SQVM::GetAt(SQInteger n) { return _stack[n]; }
+void SQVM::SetIncludePath(const SQChar *s){_include_path = SQString::Create(_ss(this), s);}
+const SQChar *SQVM::GetIncludePath(){return _stringval(_include_path);}
 
 #ifdef _DEBUG_DUMP
 void SQVM::dumpstack(SQInteger stackbase,bool dumpall)

+ 3 - 0
SquiLu/squirrel/sqvm.h

@@ -156,6 +156,8 @@ public:
 	SQObjectPtr &GetUp(SQInteger n);
 	SQObjectPtr &GetAt(SQInteger n);
 
+	void SetIncludePath(const SQChar *s);
+	const SQChar *GetIncludePath();
 	SQObjectPtrVec _stack;
 
 	SQInteger _top;
@@ -188,6 +190,7 @@ public:
 	SQInteger _nnativecalls;
 	SQInteger _nmetamethodscall;
     SQRELEASEHOOK _releasehook;
+    SQObjectPtr _include_path;
 	//suspend infos
 	SQBool _suspended;
 	SQBool _suspended_root;