瀏覽代碼

Added some new api functions and macros to easy writing native extensions.
Added difftime, exit, tmpname, setlocale to sqstdsystem and wrapped all on a table named "os" so they will not pollute the global namespace like in lua to access then we need to prefix with "os" ex: os.date().

mingodad 13 年之前
父節點
當前提交
46a2b2c9c3
共有 3 個文件被更改,包括 179 次插入1 次删除
  1. 62 1
      include/squirrel.h
  2. 77 0
      sqstdlib/sqstdsystem.cpp
  3. 40 0
      squirrel/sqapi.cpp

+ 62 - 1
include/squirrel.h

@@ -503,7 +503,68 @@ SQUIRREL_API void sq_setnativedebughook(HSQUIRRELVM v,SQDEBUGHOOK hook);
 #define SQ_ERROR (-1)
 
 #define SQ_FAILED(res) (res<0)
-#define SQ_SUCCEEDED(res) (res>=0)
+#define SQ_SUCCEEDED(res) (res>=0)
+
+/*DAD*/
+#define SQ_FUNC_VARS(v) \
+    SQRESULT _rc_; SQInteger _top_=sq_gettop(v);
+
+#define SQ_FUNC_VARS_NO_TOP(v) \
+    SQRESULT _rc_;
+
+#define SQ_GET_INSTANCE(v, idx, Klass, Klass_tag) \
+	Klass *self; \
+	if((_rc_ = sq_getinstanceup(v,idx,(SQUserPointer*)&self,(void*)Klass_tag)) < 0) return _rc_;
+
+#define SQ_GET_STRING(v, idx, var)\
+    const SQChar *var;\
+    SQInteger var##_size;\
+    if((_rc_ = sq_getstr_and_size(v,idx, &var, &var##_size)) < 0) return _rc_;
+
+#define SQ_OPT_STRING_STRLEN() static inline size_t sq_opt_strlen(const char *v) {return v ? scstrlen(v) : 0;}
+
+#define SQ_OPT_STRING(v, idx, var, dflt)\
+    const SQChar *var;\
+    SQInteger var##_size;\
+    if(_top_ >= idx)\
+        {if((_rc_ = sq_getstr_and_size(v,idx, &var, &var##_size)) < 0) return _rc_;}\
+    else {var=dflt; var##_size = sq_opt_strlen(dflt);}
+
+#define SQ_GET_BOOL(v, idx, var)\
+    SQBool var;\
+    if((_rc_ = sq_getbool(v,idx, &var)) < 0) return _rc_;
+
+#define SQ_OPT_BOOL(v, idx, var, dflt)\
+    SQBool var;\
+    if(_top_ >= idx)\
+        {if((_rc_ = sq_getbool(v,idx, &var)) < 0) return _rc_;}\
+    else {var=dflt;}
+
+#define SQ_GET_INTEGER(v, idx, var)\
+    SQInteger var;\
+    if((_rc_ = sq_getinteger(v,idx, &var)) < 0) return _rc_;
+
+#define SQ_OPT_INTEGER(v, idx, var, dflt)\
+    SQInteger var;\
+    if(_top_ >= idx)\
+        {if((_rc_ = sq_getinteger(v,idx, &var)) < 0) return _rc_;}\
+    else {var=dflt;}
+
+#define SQ_GET_FLOAT(v, idx, var)\
+    SQFloat var;\
+    if((_rc_ = sq_getfloat(v,idx, &var)) < 0) return _rc_;
+
+#define SQ_OPT_FLOAT(v, idx, var, dflt)\
+    SQFloat var;\
+    if(_top_ >= idx)\
+        {if((_rc_ = sq_getfloat(v,idx, &var)) < 0) return _rc_;}\
+    else {var=dflt;}
+
+#define sq_pushliteral(v, str) sq_pushstring(v, str, sizeof(str)-1)
+
+
+SQUIRREL_API void sq_insert_reg_funcs(HSQUIRRELVM sqvm, SQRegFunction *obj_funcs);
+SQUIRREL_API SQRESULT sq_getstr_and_size(HSQUIRRELVM v,SQInteger idx,const SQChar **c, SQInteger *size);
 
 #ifdef __cplusplus
 } /*extern "C"*/

+ 77 - 0
sqstdlib/sqstdsystem.cpp

@@ -56,6 +56,14 @@ static SQInteger _system_time(HSQUIRRELVM v)
 	return 1;
 }
 
+static SQRESULT _system_difftime (HSQUIRRELVM v) {
+    SQ_FUNC_VARS(v);
+    SQ_GET_FLOAT(v, 2, t1);
+    SQ_OPT_FLOAT(v, 3, t2, 0);
+    sq_pushfloat(v, difftime( (time_t)t1, (time_t)t2));
+  return 1;
+}
+
 static SQInteger _system_remove(HSQUIRRELVM v)
 {
 	const SQChar *s;
@@ -116,6 +124,66 @@ static SQInteger _system_date(HSQUIRRELVM v)
 	return 1;
 }
 
+static SQRESULT _system_exit (HSQUIRRELVM v) {
+  SQRESULT status = 0;
+  SQ_FUNC_VARS(v);
+  if(_top_ > 1){
+      SQObjectType ptype = sq_gettype(v, 1);
+      if (ptype == OT_BOOL){
+        SQ_GET_BOOL(v,2, b);
+        status = b ? EXIT_SUCCESS : EXIT_FAILURE;
+      }
+      else
+        sq_getinteger(v, 2, &status);
+      SQ_OPT_BOOL(v, 3, bclose, false);
+      if (bclose) sq_close(v);
+  }
+  exit(status);
+}
+
+#include <string.h>
+SQ_OPT_STRING_STRLEN();
+
+#if defined(SC_USE_MKSTEMP)
+#include <unistd.h>
+#define SQ_TMPNAMBUFSIZE	32
+#define sq_tmpnam(b,e)	{ \
+	strcpy(b, "/tmp/lua_XXXXXX"); \
+	e = mkstemp(b); \
+	if (e != -1) close(e); \
+	e = (e == -1); }
+
+#else
+#define SQ_TMPNAMBUFSIZE	L_tmpnam
+#define sq_tmpnam(b,e)		{ e = (tmpnam(b) == NULL); }
+#endif
+
+static SQRESULT _system_tmpname (HSQUIRRELVM v) {
+  char buff[SQ_TMPNAMBUFSIZE];
+  int err;
+  sq_tmpnam(buff, err);
+  if (err)
+    return sq_throwerror(v, "unable to generate a unique filename");
+  sq_pushstring(v, buff, -1);
+  return 1;
+}
+
+#include <locale.h>
+static SQRESULT _system_setlocale (HSQUIRRELVM v) {
+  static const int cat[] = {LC_ALL, LC_COLLATE, LC_CTYPE, LC_MONETARY,
+                      LC_NUMERIC, LC_TIME};
+  static const char *const catnames[] = {"all", "collate", "ctype", "monetary",
+     "numeric", "time", NULL};
+  SQ_FUNC_VARS(v);
+  SQ_OPT_STRING(v, 2, l, NULL);
+  SQ_OPT_STRING(v, 3, name, "all");
+  for (int i=0; catnames[i]; i++)
+    if (strcmp(catnames[i], name) == 0){
+        sq_pushstring(v, setlocale(cat[i], l), -1);
+        return 1;
+    }
+  return sq_throwerror(v, "invalid option %s for param %d", name, 3);
+}
 
 
 #define _DECL_FUNC(name,nparams,pmask) {_SC(#name),_system_##name,nparams,pmask}
@@ -124,15 +192,22 @@ static SQRegFunction systemlib_funcs[]={
 	_DECL_FUNC(system,2,_SC(".s")),
 	_DECL_FUNC(clock,0,NULL),
 	_DECL_FUNC(time,1,NULL),
+	_DECL_FUNC(difftime,-2,_SC(".nn")),
 	_DECL_FUNC(date,-1,_SC(".nn")),
 	_DECL_FUNC(remove,2,_SC(".s")),
 	_DECL_FUNC(rename,3,_SC(".ss")),
+	_DECL_FUNC(exit, 1,_SC(". b|i b")),
+	_DECL_FUNC(tmpname,1,_SC(".")),
+	_DECL_FUNC(setlocale,-1,_SC(".ss")),
 	{0,0}
 };
 #undef _DECL_FUNC
 
 SQInteger sqstd_register_systemlib(HSQUIRRELVM v)
 {
+    sq_pushstring(v,_SC("os"),-1);
+    sq_newclass(v,SQFalse);
+
 	SQInteger i=0;
 	while(systemlib_funcs[i].name!=0)
 	{
@@ -143,5 +218,7 @@ SQInteger sqstd_register_systemlib(HSQUIRRELVM v)
 		sq_newslot(v,-3,SQFalse);
 		i++;
 	}
+
+	sq_newslot(v,-3,SQTrue); //insert os
 	return 1;
 }

+ 40 - 0
squirrel/sqapi.cpp

@@ -625,6 +625,15 @@ SQRESULT sq_getstring(HSQUIRRELVM v,SQInteger idx,const SQChar **c)
 	return SQ_OK;
 }
 
+SQRESULT sq_getstr_and_size(HSQUIRRELVM v,SQInteger idx,const SQChar **c, SQInteger *size)
+{
+	SQObjectPtr *o = NULL;
+	_GETSAFE_OBJ(v, idx, OT_STRING,o);
+	*c = _stringval(*o);
+	*size = _string(*o)->_len;
+	return SQ_OK;
+}
+
 SQRESULT sq_getthread(HSQUIRRELVM v,SQInteger idx,HSQUIRRELVM *thread)
 {
 	SQObjectPtr *o = NULL;
@@ -1523,3 +1532,34 @@ void sq_free(void *p,SQUnsignedInteger size)
 {
 	SQ_FREE(p,size);
 }
+
+
+SQRESULT sq_optinteger(HSQUIRRELVM sqvm, SQInteger idx, SQInteger *value, SQInteger default_value){
+    if(sq_gettop(sqvm) >= idx){
+        return sq_getinteger(sqvm, idx, value);
+    }
+    *value = default_value;
+    return SQ_OK;
+}
+
+SQRESULT sq_optstr_and_size(HSQUIRRELVM sqvm, SQInteger idx, const SQChar **value, const SQChar *dflt, SQInteger *size){
+    if(sq_gettop(sqvm) >= idx){
+        return sq_getstr_and_size(sqvm, idx, value, size);
+    }
+    *value = dflt;
+    *size = strlen(dflt);
+    return SQ_OK;
+}
+
+void sq_insert_reg_funcs(HSQUIRRELVM sqvm, SQRegFunction *obj_funcs){
+	SQInteger i = 0;
+	while(obj_funcs[i].name != 0) {
+		SQRegFunction &f = obj_funcs[i];
+		sq_pushstring(sqvm,f.name,-1);
+		sq_newclosure(sqvm,f.f,0);
+		sq_setparamscheck(sqvm,f.nparamscheck,f.typemask);
+		sq_setnativeclosurename(sqvm,-1,f.name);
+		sq_newslot(sqvm,-3,SQFalse);
+		i++;
+	}
+}