-/* see copyright notice in squirrel.h */
-#include <squirrel.h>
-#include <sqstdstring.h>
-#include <string.h>
-#include <stdlib.h>
-#include <stdio.h>
-#include <ctype.h>
-#include <assert.h>
-
-#ifdef SQUNICODE
-#define scstrchr wcschr
-#define scsnprintf wsnprintf
-#define scatoi _wtoi
-#define scstrtok wcstok
-#else
-#define scstrchr strchr
-#define scsnprintf snprintf
-#define scatoi atoi
-#define scstrtok strtok
-#endif
-#define MAX_FORMAT_LEN 20
-#define MAX_WFORMAT_LEN 3
-#define ADDITIONAL_FORMAT_SPACE (100*sizeof(SQChar))
-
-static SQInteger validate_format(HSQUIRRELVM v, SQChar *fmt, const SQChar *src, SQInteger n,SQInteger &width)
-{
- SQChar swidth[MAX_WFORMAT_LEN];
- SQInteger wc = 0;
- SQInteger start = n;
- fmt[0] = '%';
- while (scstrchr(_SC("-+ #0"), src[n])) n++;
- while (scisdigit(src[n])) {
- swidth[wc] = src[n];
- n++;
- wc++;
- if(wc>=MAX_WFORMAT_LEN)
- return sq_throwerror(v,_SC("width format too long"));
- }
- swidth[wc] = '\0';
- if(wc > 0) {
- width = scatoi(swidth);
- }
- else
- width = 0;
- if (src[n] == '.') {
- n++;
-
- wc = 0;
- while (scisdigit(src[n])) {
- swidth[wc] = src[n];
- n++;
- wc++;
- if(wc>=MAX_WFORMAT_LEN)
- return sq_throwerror(v,_SC("precision format too long"));
- }
- swidth[wc] = '\0';
- if(wc > 0) {
- width += scatoi(swidth);
- }
- }
- if (n-start > MAX_FORMAT_LEN )
- return sq_throwerror(v,_SC("format too long"));
- memcpy(&fmt[1],&src[start],((n-start)+1)*sizeof(SQChar));
- fmt[(n-start)+2] = '\0';
- return n;
-}
-
-
-SQRESULT sqstd_format(HSQUIRRELVM v,SQInteger nformatstringidx,SQInteger *outlen,SQChar **output)
-{
- const SQChar *format;
- SQChar *dest;
- SQChar fmt[MAX_FORMAT_LEN];
- sq_getstring(v,nformatstringidx,&format);
- SQInteger allocated = (sq_getsize(v,nformatstringidx)+2)*sizeof(SQChar);
- dest = sq_getscratchpad(v,allocated);
- SQInteger n = 0,i = 0, nparam = nformatstringidx+1, w = 0;
- while(format[n] != '\0') {
- if(format[n] != '%') {
- assert(i < allocated);
- dest[i++] = format[n];
- n++;
- }
- else if(format[n+1] == '%') { //handles %%
- dest[i++] = '%';
- n += 2;
- }
- else {
- n++;
- if( nparam > sq_gettop(v) )
- return sq_throwerror(v,_SC("not enough paramters for the given format string"));
- n = validate_format(v,fmt,format,n,w);
- if(n < 0) return -1;
- SQInteger addlen = 0;
- SQInteger valtype = 0;
- const SQChar *ts;
- SQInteger ti;
- SQFloat tf;
- switch(format[n]) {
- case 's':
- if(SQ_FAILED(sq_getstring(v,nparam,&ts)))
- return sq_throwerror(v,_SC("string expected for the specified format"));
- addlen = (sq_getsize(v,nparam)*sizeof(SQChar))+((w+1)*sizeof(SQChar));
- valtype = 's';
- break;
- case 'i': case 'd': case 'c':case 'o': case 'u': case 'x': case 'X':
- if(SQ_FAILED(sq_getinteger(v,nparam,&ti)))
- return sq_throwerror(v,_SC("integer expected for the specified format"));
- addlen = (ADDITIONAL_FORMAT_SPACE)+((w+1)*sizeof(SQChar));
- valtype = 'i';
- break;
- case 'f': case 'g': case 'G': case 'e': case 'E':
- if(SQ_FAILED(sq_getfloat(v,nparam,&tf)))
- return sq_throwerror(v,_SC("float expected for the specified format"));
- addlen = (ADDITIONAL_FORMAT_SPACE)+((w+1)*sizeof(SQChar));
- valtype = 'f';
- break;
- default:
- return sq_throwerror(v,_SC("invalid format"));
- }
- n++;
- allocated += addlen + sizeof(SQChar);
- dest = sq_getscratchpad(v,allocated);
- switch(valtype) {
- case 's': i += scsprintf(&dest[i],fmt,ts); break;
- case 'i': i += scsprintf(&dest[i],fmt,ti); break;
- case 'f': i += scsprintf(&dest[i],fmt,tf); break;
- };
- nparam ++;
- }
- }
- *outlen = i;
- dest[i] = '\0';
- *output = dest;
- return SQ_OK;
-}
-
-static SQInteger _string_format(HSQUIRRELVM v)
-{
- SQChar *dest = NULL;
- SQInteger length = 0;
- if(SQ_FAILED(sqstd_format(v,2,&length,&dest)))
- return -1;
- sq_pushstring(v,dest,length);
- return 1;
-}
-
-static void __strip_l(const SQChar *str,const SQChar **start)
-{
- const SQChar *t = str;
- while(((*t) != '\0') && scisspace(*t)){ t++; }
- *start = t;
-}
-
-static void __strip_r(const SQChar *str,SQInteger len,const SQChar **end)
-{
- if(len == 0) {
- *end = str;
- return;
- }
- const SQChar *t = &str[len-1];
- while(t != str && scisspace(*t)) { t--; }
- *end = t+1;
-}
-
-static SQInteger _string_strip(HSQUIRRELVM v)
-{
- const SQChar *str,*start,*end;
- sq_getstring(v,2,&str);
- SQInteger len = sq_getsize(v,2);
- __strip_l(str,&start);
- __strip_r(str,len,&end);
- sq_pushstring(v,start,end - start);
- return 1;
-}
-
-static SQInteger _string_lstrip(HSQUIRRELVM v)
-{
- const SQChar *str,*start;
- sq_getstring(v,2,&str);
- __strip_l(str,&start);
- sq_pushstring(v,start,-1);
- return 1;
-}
-
-static SQInteger _string_rstrip(HSQUIRRELVM v)
-{
- const SQChar *str,*end;
- sq_getstring(v,2,&str);
- SQInteger len = sq_getsize(v,2);
- __strip_r(str,len,&end);
- sq_pushstring(v,str,end - str);
- return 1;
-}
-
-static SQInteger _string_split(HSQUIRRELVM v)
-{
- const SQChar *str,*seps;
- SQChar *stemp,*tok;
- sq_getstring(v,2,&str);
- sq_getstring(v,3,&seps);
- if(sq_getsize(v,3) == 0) return sq_throwerror(v,_SC("empty separators string"));
- SQInteger memsize = (sq_getsize(v,2)+1)*sizeof(SQChar);
- stemp = sq_getscratchpad(v,memsize);
- memcpy(stemp,str,memsize);
- tok = scstrtok(stemp,seps);
- sq_newarray(v,0);
- while( tok != NULL ) {
- sq_pushstring(v,tok,-1);
- sq_arrayappend(v,-2);
- tok = scstrtok( NULL, seps );
- }
- return 1;
-}
-
-#define SETUP_REX(v) \
- SQRex *self = NULL; \
- sq_getinstanceup(v,1,(SQUserPointer *)&self,0);
-
-static SQInteger _rexobj_releasehook(SQUserPointer p, SQInteger size)
-{
- SQRex *self = ((SQRex *)p);
- sqstd_rex_free(self);
- return 1;
-}
-
-static SQInteger _regexp_match(HSQUIRRELVM v)
-{
- SETUP_REX(v);
- const SQChar *str;
- sq_getstring(v,2,&str);
- if(sqstd_rex_match(self,str) == SQTrue)
- {
- sq_pushbool(v,SQTrue);
- return 1;
- }
- sq_pushbool(v,SQFalse);
- return 1;
-}
-
-static void _addrexmatch(HSQUIRRELVM v,const SQChar *str,const SQChar *begin,const SQChar *end)
-{
- sq_newtable(v);
- sq_pushstring(v,_SC("begin"),-1);
- sq_pushinteger(v,begin - str);
- sq_rawset(v,-3);
- sq_pushstring(v,_SC("end"),-1);
- sq_pushinteger(v,end - str);
- sq_rawset(v,-3);
-}
-
-static SQInteger _regexp_search(HSQUIRRELVM v)
-{
- SETUP_REX(v);
- const SQChar *str,*begin,*end;
- SQInteger start = 0;
- sq_getstring(v,2,&str);
- if(sq_gettop(v) > 2) sq_getinteger(v,3,&start);
- if(sqstd_rex_search(self,str+start,&begin,&end) == SQTrue) {
- _addrexmatch(v,str,begin,end);
- return 1;
- }
- return 0;
-}
-
-static SQInteger _regexp_capture(HSQUIRRELVM v)
-{
- SETUP_REX(v);
- const SQChar *str,*begin,*end;
- SQInteger start = 0;
- sq_getstring(v,2,&str);
- if(sq_gettop(v) > 2) sq_getinteger(v,3,&start);
- if(sqstd_rex_search(self,str+start,&begin,&end) == SQTrue) {
- SQInteger n = sqstd_rex_getsubexpcount(self);
- SQRexMatch match;
- sq_newarray(v,0);
- for(SQInteger i = 0;i < n; i++) {
- sqstd_rex_getsubexp(self,i,&match);
- if(match.len > 0)
- _addrexmatch(v,str,match.begin,match.begin+match.len);
- else
- _addrexmatch(v,str,str,str); //empty match
- sq_arrayappend(v,-2);
- }
- return 1;
- }
- return 0;
-}
-
-static SQInteger _regexp_subexpcount(HSQUIRRELVM v)
-{
- SETUP_REX(v);
- sq_pushinteger(v,sqstd_rex_getsubexpcount(self));
- return 1;
-}
-
-static SQInteger _regexp_constructor(HSQUIRRELVM v)
-{
- const SQChar *error,*pattern;
- sq_getstring(v,2,&pattern);
- SQRex *rex = sqstd_rex_compile(pattern,&error);
- if(!rex) return sq_throwerror(v,error);
- sq_setinstanceup(v,1,rex);
- sq_setreleasehook(v,1,_rexobj_releasehook);
- return 0;
-}
-
-static SQInteger _regexp__typeof(HSQUIRRELVM v)
-{
- sq_pushstring(v,_SC("regexp"),-1);
- return 1;
-}
-
-#define _DECL_REX_FUNC(name,nparams,pmask) {_SC(#name),_regexp_##name,nparams,pmask}
-static SQRegFunction rexobj_funcs[]={
- _DECL_REX_FUNC(constructor,2,_SC(".s")),
- _DECL_REX_FUNC(search,-2,_SC("xsn")),
- _DECL_REX_FUNC(match,2,_SC("xs")),
- _DECL_REX_FUNC(capture,-2,_SC("xsn")),
- _DECL_REX_FUNC(subexpcount,1,_SC("x")),
- _DECL_REX_FUNC(_typeof,1,_SC("x")),
- {0,0}
-};
-
-#define _DECL_FUNC(name,nparams,pmask) {_SC(#name),_string_##name,nparams,pmask}
-static SQRegFunction stringlib_funcs[]={
- _DECL_FUNC(format,-2,_SC(".s")),
- _DECL_FUNC(strip,2,_SC(".s")),
- _DECL_FUNC(lstrip,2,_SC(".s")),
- _DECL_FUNC(rstrip,2,_SC(".s")),
- _DECL_FUNC(split,3,_SC(".ss")),
- {0,0}
-};
-
-
-SQInteger sqstd_register_stringlib(HSQUIRRELVM v)
-{
- sq_pushstring(v,_SC("regexp"),-1);
- sq_newclass(v,SQFalse);
- SQInteger i = 0;
- while(rexobj_funcs[i].name != 0) {
- SQRegFunction &f = rexobj_funcs[i];
- sq_pushstring(v,f.name,-1);
- sq_newclosure(v,f.f,0);
- sq_setparamscheck(v,f.nparamscheck,f.typemask);
- sq_setnativeclosurename(v,-1,f.name);
- sq_createslot(v,-3);
- i++;
- }
- sq_createslot(v,-3);
-
- i = 0;
- while(stringlib_funcs[i].name!=0)
- {
- sq_pushstring(v,stringlib_funcs[i].name,-1);
- sq_newclosure(v,stringlib_funcs[i].f,0);
- sq_setparamscheck(v,stringlib_funcs[i].nparamscheck,stringlib_funcs[i].typemask);
- sq_setnativeclosurename(v,-1,stringlib_funcs[i].name);
- sq_createslot(v,-3);
- i++;
- }
- return 1;
-}
+/* see copyright notice in squirrel.h */\r
+#include <squirrel.h>\r
+#include <sqstdstring.h>\r
+#include <string.h>\r
+#include <stdlib.h>\r
+#include <stdio.h>\r
+#include <ctype.h>\r
+#include <assert.h>\r
+\r
+#ifdef SQUNICODE\r
+#define scstrchr wcschr\r
+#define scsnprintf wsnprintf\r
+#define scatoi _wtoi\r
+#define scstrtok wcstok\r
+#else\r
+#define scstrchr strchr\r
+#define scsnprintf snprintf\r
+#define scatoi atoi\r
+#define scstrtok strtok\r
+#endif\r
+#define MAX_FORMAT_LEN 20\r
+#define MAX_WFORMAT_LEN 3\r
+#define ADDITIONAL_FORMAT_SPACE (100*sizeof(SQChar))\r
+\r
+static SQInteger validate_format(HSQUIRRELVM v, SQChar *fmt, const SQChar *src, SQInteger n,SQInteger &width)\r
+{\r
+ SQChar swidth[MAX_WFORMAT_LEN];\r
+ SQInteger wc = 0;\r
+ SQInteger start = n;\r
+ fmt[0] = '%';\r
+ while (scstrchr(_SC("-+ #0"), src[n])) n++;\r
+ while (scisdigit(src[n])) {\r
+ swidth[wc] = src[n];\r
+ n++;\r
+ wc++;\r
+ if(wc>=MAX_WFORMAT_LEN)\r
+ return sq_throwerror(v,_SC("width format too long"));\r
+ }\r
+ swidth[wc] = '\0';\r
+ if(wc > 0) {\r
+ width = scatoi(swidth);\r
+ }\r
+ else\r
+ width = 0;\r
+ if (src[n] == '.') {\r
+ n++;\r
+ \r
+ wc = 0;\r
+ while (scisdigit(src[n])) {\r
+ swidth[wc] = src[n];\r
+ n++;\r
+ wc++;\r
+ if(wc>=MAX_WFORMAT_LEN)\r
+ return sq_throwerror(v,_SC("precision format too long"));\r
+ }\r
+ swidth[wc] = '\0';\r
+ if(wc > 0) {\r
+ width += scatoi(swidth);\r
+ }\r
+ }\r
+ if (n-start > MAX_FORMAT_LEN )\r
+ return sq_throwerror(v,_SC("format too long"));\r
+ memcpy(&fmt[1],&src[start],((n-start)+1)*sizeof(SQChar));\r
+ fmt[(n-start)+2] = '\0';\r
+ return n;\r
+}\r
+\r
+\r
+SQRESULT sqstd_format(HSQUIRRELVM v,SQInteger nformatstringidx,SQInteger *outlen,SQChar **output)\r
+{\r
+ const SQChar *format;\r
+ SQChar *dest;\r
+ SQChar fmt[MAX_FORMAT_LEN];\r
+ sq_getstring(v,nformatstringidx,&format);\r
+ SQInteger allocated = (sq_getsize(v,nformatstringidx)+2)*sizeof(SQChar);\r
+ dest = sq_getscratchpad(v,allocated);\r
+ SQInteger n = 0,i = 0, nparam = nformatstringidx+1, w = 0;\r
+ while(format[n] != '\0') {\r
+ if(format[n] != '%') {\r
+ assert(i < allocated);\r
+ dest[i++] = format[n];\r
+ n++;\r
+ }\r
+ else if(format[n+1] == '%') { //handles %%\r
+ dest[i++] = '%';\r
+ n += 2; \r
+ }\r
+ else {\r
+ n++;\r
+ if( nparam > sq_gettop(v) )\r
+ return sq_throwerror(v,_SC("not enough paramters for the given format string"));\r
+ n = validate_format(v,fmt,format,n,w);\r
+ if(n < 0) return -1;\r
+ SQInteger addlen = 0;\r
+ SQInteger valtype = 0;\r
+ const SQChar *ts;\r
+ SQInteger ti;\r
+ SQFloat tf;\r
+ switch(format[n]) {\r
+ case 's':\r
+ if(SQ_FAILED(sq_getstring(v,nparam,&ts))) \r
+ return sq_throwerror(v,_SC("string expected for the specified format"));\r
+ addlen = (sq_getsize(v,nparam)*sizeof(SQChar))+((w+1)*sizeof(SQChar));\r
+ valtype = 's';\r
+ break;\r
+ case 'i': case 'd': case 'c':case 'o': case 'u': case 'x': case 'X':\r
+ if(SQ_FAILED(sq_getinteger(v,nparam,&ti))) \r
+ return sq_throwerror(v,_SC("integer expected for the specified format"));\r
+ addlen = (ADDITIONAL_FORMAT_SPACE)+((w+1)*sizeof(SQChar));\r
+ valtype = 'i';\r
+ break;\r
+ case 'f': case 'g': case 'G': case 'e': case 'E':\r
+ if(SQ_FAILED(sq_getfloat(v,nparam,&tf))) \r
+ return sq_throwerror(v,_SC("float expected for the specified format"));\r
+ addlen = (ADDITIONAL_FORMAT_SPACE)+((w+1)*sizeof(SQChar));\r
+ valtype = 'f';\r
+ break;\r
+ default:\r
+ return sq_throwerror(v,_SC("invalid format"));\r
+ }\r
+ n++;\r
+ allocated += addlen + sizeof(SQChar);\r
+ dest = sq_getscratchpad(v,allocated);\r
+ switch(valtype) {\r
+ case 's': i += scsprintf(&dest[i],fmt,ts); break;\r
+ case 'i': i += scsprintf(&dest[i],fmt,ti); break;\r
+ case 'f': i += scsprintf(&dest[i],fmt,tf); break;\r
+ };\r
+ nparam ++;\r
+ }\r
+ }\r
+ *outlen = i;\r
+ dest[i] = '\0';\r
+ *output = dest;\r
+ return SQ_OK;\r
+}\r
+\r
+static SQInteger _string_format(HSQUIRRELVM v)\r
+{\r
+ SQChar *dest = NULL;\r
+ SQInteger length = 0;\r
+ if(SQ_FAILED(sqstd_format(v,2,&length,&dest)))\r
+ return -1;\r
+ sq_pushstring(v,dest,length);\r
+ return 1;\r
+}\r
+\r
+static void __strip_l(const SQChar *str,const SQChar **start)\r
+{\r
+ const SQChar *t = str;\r
+ while(((*t) != '\0') && scisspace(*t)){ t++; }\r
+ *start = t;\r
+}\r
+\r
+static void __strip_r(const SQChar *str,SQInteger len,const SQChar **end)\r
+{\r
+ if(len == 0) {\r
+ *end = str;\r
+ return;\r
+ }\r
+ const SQChar *t = &str[len-1];\r
+ while(t != str && scisspace(*t)) { t--; }\r
+ *end = t+1;\r
+}\r
+\r
+static SQInteger _string_strip(HSQUIRRELVM v)\r
+{\r
+ const SQChar *str,*start,*end;\r
+ sq_getstring(v,2,&str);\r
+ SQInteger len = sq_getsize(v,2);\r
+ __strip_l(str,&start);\r
+ __strip_r(str,len,&end);\r
+ sq_pushstring(v,start,end - start);\r
+ return 1;\r
+}\r
+\r
+static SQInteger _string_lstrip(HSQUIRRELVM v)\r
+{\r
+ const SQChar *str,*start;\r
+ sq_getstring(v,2,&str);\r
+ __strip_l(str,&start);\r
+ sq_pushstring(v,start,-1);\r
+ return 1;\r
+}\r
+\r
+static SQInteger _string_rstrip(HSQUIRRELVM v)\r
+{\r
+ const SQChar *str,*end;\r
+ sq_getstring(v,2,&str);\r
+ SQInteger len = sq_getsize(v,2);\r
+ __strip_r(str,len,&end);\r
+ sq_pushstring(v,str,end - str);\r
+ return 1;\r
+}\r
+\r
+static SQInteger _string_split(HSQUIRRELVM v)\r
+{\r
+ const SQChar *str,*seps;\r
+ SQChar *stemp,*tok;\r
+ sq_getstring(v,2,&str);\r
+ sq_getstring(v,3,&seps);\r
+ if(sq_getsize(v,3) == 0) return sq_throwerror(v,_SC("empty separators string"));\r
+ SQInteger memsize = (sq_getsize(v,2)+1)*sizeof(SQChar);\r
+ stemp = sq_getscratchpad(v,memsize);\r
+ memcpy(stemp,str,memsize);\r
+ tok = scstrtok(stemp,seps);\r
+ sq_newarray(v,0);\r
+ while( tok != NULL ) {\r
+ sq_pushstring(v,tok,-1);\r
+ sq_arrayappend(v,-2);\r
+ tok = scstrtok( NULL, seps );\r
+ }\r
+ return 1;\r
+}\r
+\r
+#define SETUP_REX(v) \\r
+ SQRex *self = NULL; \\r
+ sq_getinstanceup(v,1,(SQUserPointer *)&self,0); \r
+\r
+static SQInteger _rexobj_releasehook(SQUserPointer p, SQInteger size)\r
+{\r
+ SQRex *self = ((SQRex *)p);\r
+ sqstd_rex_free(self);\r
+ return 1;\r
+}\r
+\r
+static SQInteger _regexp_match(HSQUIRRELVM v)\r
+{\r
+ SETUP_REX(v);\r
+ const SQChar *str;\r
+ sq_getstring(v,2,&str);\r
+ if(sqstd_rex_match(self,str) == SQTrue)\r
+ {\r
+ sq_pushbool(v,SQTrue);\r
+ return 1;\r
+ }\r
+ sq_pushbool(v,SQFalse);\r
+ return 1;\r
+}\r
+\r
+static void _addrexmatch(HSQUIRRELVM v,const SQChar *str,const SQChar *begin,const SQChar *end)\r
+{\r
+ sq_newtable(v);\r
+ sq_pushstring(v,_SC("begin"),-1);\r
+ sq_pushinteger(v,begin - str);\r
+ sq_rawset(v,-3);\r
+ sq_pushstring(v,_SC("end"),-1);\r
+ sq_pushinteger(v,end - str);\r
+ sq_rawset(v,-3);\r
+}\r
+\r
+static SQInteger _regexp_search(HSQUIRRELVM v)\r
+{\r
+ SETUP_REX(v);\r
+ const SQChar *str,*begin,*end;\r
+ SQInteger start = 0;\r
+ sq_getstring(v,2,&str);\r
+ if(sq_gettop(v) > 2) sq_getinteger(v,3,&start);\r
+ if(sqstd_rex_search(self,str+start,&begin,&end) == SQTrue) {\r
+ _addrexmatch(v,str,begin,end);\r
+ return 1;\r
+ }\r
+ return 0;\r
+}\r
+\r
+static SQInteger _regexp_capture(HSQUIRRELVM v)\r
+{\r
+ SETUP_REX(v);\r
+ const SQChar *str,*begin,*end;\r
+ SQInteger start = 0;\r
+ sq_getstring(v,2,&str);\r
+ if(sq_gettop(v) > 2) sq_getinteger(v,3,&start);\r
+ if(sqstd_rex_search(self,str+start,&begin,&end) == SQTrue) {\r
+ SQInteger n = sqstd_rex_getsubexpcount(self);\r
+ SQRexMatch match;\r
+ sq_newarray(v,0);\r
+ for(SQInteger i = 0;i < n; i++) {\r
+ sqstd_rex_getsubexp(self,i,&match);\r
+ if(match.len > 0)\r
+ _addrexmatch(v,str,match.begin,match.begin+match.len);\r
+ else\r
+ _addrexmatch(v,str,str,str); //empty match\r
+ sq_arrayappend(v,-2);\r
+ }\r
+ return 1;\r
+ }\r
+ return 0;\r
+}\r
+\r
+static SQInteger _regexp_subexpcount(HSQUIRRELVM v)\r
+{\r
+ SETUP_REX(v);\r
+ sq_pushinteger(v,sqstd_rex_getsubexpcount(self));\r
+ return 1;\r
+}\r
+\r
+static SQInteger _regexp_constructor(HSQUIRRELVM v)\r
+{\r
+ const SQChar *error,*pattern;\r
+ sq_getstring(v,2,&pattern);\r
+ SQRex *rex = sqstd_rex_compile(pattern,&error);\r
+ if(!rex) return sq_throwerror(v,error);\r
+ sq_setinstanceup(v,1,rex);\r
+ sq_setreleasehook(v,1,_rexobj_releasehook);\r
+ return 0;\r
+}\r
+\r
+static SQInteger _regexp__typeof(HSQUIRRELVM v)\r
+{\r
+ sq_pushstring(v,_SC("regexp"),-1);\r
+ return 1;\r
+}\r
+\r
+#define _DECL_REX_FUNC(name,nparams,pmask) {_SC(#name),_regexp_##name,nparams,pmask}\r
+static SQRegFunction rexobj_funcs[]={\r
+ _DECL_REX_FUNC(constructor,2,_SC(".s")),\r
+ _DECL_REX_FUNC(search,-2,_SC("xsn")),\r
+ _DECL_REX_FUNC(match,2,_SC("xs")),\r
+ _DECL_REX_FUNC(capture,-2,_SC("xsn")),\r
+ _DECL_REX_FUNC(subexpcount,1,_SC("x")),\r
+ _DECL_REX_FUNC(_typeof,1,_SC("x")),\r
+ {0,0}\r
+};\r
+\r
+#define _DECL_FUNC(name,nparams,pmask) {_SC(#name),_string_##name,nparams,pmask}\r
+static SQRegFunction stringlib_funcs[]={\r
+ _DECL_FUNC(format,-2,_SC(".s")),\r
+ _DECL_FUNC(strip,2,_SC(".s")),\r
+ _DECL_FUNC(lstrip,2,_SC(".s")),\r
+ _DECL_FUNC(rstrip,2,_SC(".s")),\r
+ _DECL_FUNC(split,3,_SC(".ss")),\r
+ {0,0}\r
+};\r
+\r
+\r
+SQInteger sqstd_register_stringlib(HSQUIRRELVM v)\r
+{\r
+ sq_pushstring(v,_SC("regexp"),-1);\r
+ sq_newclass(v,SQFalse);\r
+ SQInteger i = 0;\r
+ while(rexobj_funcs[i].name != 0) {\r
+ SQRegFunction &f = rexobj_funcs[i];\r
+ sq_pushstring(v,f.name,-1);\r
+ sq_newclosure(v,f.f,0);\r
+ sq_setparamscheck(v,f.nparamscheck,f.typemask);\r
+ sq_setnativeclosurename(v,-1,f.name);\r
+ sq_createslot(v,-3);\r
+ i++;\r
+ }\r
+ sq_createslot(v,-3);\r
+\r
+ i = 0;\r
+ while(stringlib_funcs[i].name!=0)\r
+ {\r
+ sq_pushstring(v,stringlib_funcs[i].name,-1);\r
+ sq_newclosure(v,stringlib_funcs[i].f,0);\r
+ sq_setparamscheck(v,stringlib_funcs[i].nparamscheck,stringlib_funcs[i].typemask);\r
+ sq_setnativeclosurename(v,-1,stringlib_funcs[i].name);\r
+ sq_createslot(v,-3);\r
+ i++;\r
+ }\r
+ return 1;\r
+}\r