From 92c59963f82f81aa3202657e7fdbb2592924ede3 Mon Sep 17 00:00:00 2001 From: "cedeel@gmail.com" Date: Thu, 14 Jun 2012 13:06:06 +0000 Subject: Attempt to bring sanity to newlines across systems. git-svn-id: http://mc-server.googlecode.com/svn/trunk@606 0a769ca7-a7f5-676a-18bf-c427514a06d6 --- squirrel_3_0_1_stable/sqstdlib/sqstdaux.cpp | 258 ++--- squirrel_3_0_1_stable/sqstdlib/sqstdblob.cpp | 550 +++++----- squirrel_3_0_1_stable/sqstdlib/sqstdblobimpl.h | 216 ++-- squirrel_3_0_1_stable/sqstdlib/sqstdio.cpp | 838 ++++++++-------- squirrel_3_0_1_stable/sqstdlib/sqstdmath.cpp | 214 ++-- squirrel_3_0_1_stable/sqstdlib/sqstdrex.cpp | 1276 ++++++++++++------------ squirrel_3_0_1_stable/sqstdlib/sqstdstream.cpp | 672 ++++++------- squirrel_3_0_1_stable/sqstdlib/sqstdstream.h | 36 +- squirrel_3_0_1_stable/sqstdlib/sqstdstring.cpp | 756 +++++++------- squirrel_3_0_1_stable/sqstdlib/sqstdsystem.cpp | 294 +++--- 10 files changed, 2555 insertions(+), 2555 deletions(-) (limited to 'squirrel_3_0_1_stable/sqstdlib') diff --git a/squirrel_3_0_1_stable/sqstdlib/sqstdaux.cpp b/squirrel_3_0_1_stable/sqstdlib/sqstdaux.cpp index e115770a8..804a1e4d1 100644 --- a/squirrel_3_0_1_stable/sqstdlib/sqstdaux.cpp +++ b/squirrel_3_0_1_stable/sqstdlib/sqstdaux.cpp @@ -1,129 +1,129 @@ -/* see copyright notice in squirrel.h */ -#include -#include -#include - -void sqstd_printcallstack(HSQUIRRELVM v) -{ - SQPRINTFUNCTION pf = sq_geterrorfunc(v); - if(pf) { - SQStackInfos si; - SQInteger i; - SQFloat f; - const SQChar *s; - SQInteger level=1; //1 is to skip this function that is level 0 - const SQChar *name=0; - SQInteger seq=0; - pf(v,_SC("\nCALLSTACK\n")); - while(SQ_SUCCEEDED(sq_stackinfos(v,level,&si))) - { - const SQChar *fn=_SC("unknown"); - const SQChar *src=_SC("unknown"); - if(si.funcname)fn=si.funcname; - if(si.source)src=si.source; - pf(v,_SC("*FUNCTION [%s()] %s line [%d]\n"),fn,src,si.line); - level++; - } - level=0; - pf(v,_SC("\nLOCALS\n")); - - for(level=0;level<10;level++){ - seq=0; - while((name = sq_getlocal(v,level,seq))) - { - seq++; - switch(sq_gettype(v,-1)) - { - case OT_NULL: - pf(v,_SC("[%s] NULL\n"),name); - break; - case OT_INTEGER: - sq_getinteger(v,-1,&i); - pf(v,_SC("[%s] %d\n"),name,i); - break; - case OT_FLOAT: - sq_getfloat(v,-1,&f); - pf(v,_SC("[%s] %.14g\n"),name,f); - break; - case OT_USERPOINTER: - pf(v,_SC("[%s] USERPOINTER\n"),name); - break; - case OT_STRING: - sq_getstring(v,-1,&s); - pf(v,_SC("[%s] \"%s\"\n"),name,s); - break; - case OT_TABLE: - pf(v,_SC("[%s] TABLE\n"),name); - break; - case OT_ARRAY: - pf(v,_SC("[%s] ARRAY\n"),name); - break; - case OT_CLOSURE: - pf(v,_SC("[%s] CLOSURE\n"),name); - break; - case OT_NATIVECLOSURE: - pf(v,_SC("[%s] NATIVECLOSURE\n"),name); - break; - case OT_GENERATOR: - pf(v,_SC("[%s] GENERATOR\n"),name); - break; - case OT_USERDATA: - pf(v,_SC("[%s] USERDATA\n"),name); - break; - case OT_THREAD: - pf(v,_SC("[%s] THREAD\n"),name); - break; - case OT_CLASS: - pf(v,_SC("[%s] CLASS\n"),name); - break; - case OT_INSTANCE: - pf(v,_SC("[%s] INSTANCE\n"),name); - break; - case OT_WEAKREF: - pf(v,_SC("[%s] WEAKREF\n"),name); - break; - case OT_BOOL:{ - sq_getinteger(v,-1,&i); - pf(v,_SC("[%s] %s\n"),name,i?_SC("true"):_SC("false")); - } - break; - default: assert(0); break; - } - sq_pop(v,1); - } - } - } -} - -static SQInteger _sqstd_aux_printerror(HSQUIRRELVM v) -{ - SQPRINTFUNCTION pf = sq_geterrorfunc(v); - if(pf) { - const SQChar *sErr = 0; - if(sq_gettop(v)>=1) { - if(SQ_SUCCEEDED(sq_getstring(v,2,&sErr))) { - pf(v,_SC("\nAN ERROR HAS OCCURED [%s]\n"),sErr); - } - else{ - pf(v,_SC("\nAN ERROR HAS OCCURED [unknown]\n")); - } - sqstd_printcallstack(v); - } - } - return 0; -} - -void _sqstd_compiler_error(HSQUIRRELVM v,const SQChar *sErr,const SQChar *sSource,SQInteger line,SQInteger column) -{ - SQPRINTFUNCTION pf = sq_geterrorfunc(v); - if(pf) { - pf(v,_SC("%s line = (%d) column = (%d) : error %s\n"),sSource,line,column,sErr); - } -} - -void sqstd_seterrorhandlers(HSQUIRRELVM v) -{ - sq_setcompilererrorhandler(v,_sqstd_compiler_error); - sq_newclosure(v,_sqstd_aux_printerror,0); - sq_seterrorhandler(v); -} +/* see copyright notice in squirrel.h */ +#include +#include +#include + +void sqstd_printcallstack(HSQUIRRELVM v) +{ + SQPRINTFUNCTION pf = sq_geterrorfunc(v); + if(pf) { + SQStackInfos si; + SQInteger i; + SQFloat f; + const SQChar *s; + SQInteger level=1; //1 is to skip this function that is level 0 + const SQChar *name=0; + SQInteger seq=0; + pf(v,_SC("\nCALLSTACK\n")); + while(SQ_SUCCEEDED(sq_stackinfos(v,level,&si))) + { + const SQChar *fn=_SC("unknown"); + const SQChar *src=_SC("unknown"); + if(si.funcname)fn=si.funcname; + if(si.source)src=si.source; + pf(v,_SC("*FUNCTION [%s()] %s line [%d]\n"),fn,src,si.line); + level++; + } + level=0; + pf(v,_SC("\nLOCALS\n")); + + for(level=0;level<10;level++){ + seq=0; + while((name = sq_getlocal(v,level,seq))) + { + seq++; + switch(sq_gettype(v,-1)) + { + case OT_NULL: + pf(v,_SC("[%s] NULL\n"),name); + break; + case OT_INTEGER: + sq_getinteger(v,-1,&i); + pf(v,_SC("[%s] %d\n"),name,i); + break; + case OT_FLOAT: + sq_getfloat(v,-1,&f); + pf(v,_SC("[%s] %.14g\n"),name,f); + break; + case OT_USERPOINTER: + pf(v,_SC("[%s] USERPOINTER\n"),name); + break; + case OT_STRING: + sq_getstring(v,-1,&s); + pf(v,_SC("[%s] \"%s\"\n"),name,s); + break; + case OT_TABLE: + pf(v,_SC("[%s] TABLE\n"),name); + break; + case OT_ARRAY: + pf(v,_SC("[%s] ARRAY\n"),name); + break; + case OT_CLOSURE: + pf(v,_SC("[%s] CLOSURE\n"),name); + break; + case OT_NATIVECLOSURE: + pf(v,_SC("[%s] NATIVECLOSURE\n"),name); + break; + case OT_GENERATOR: + pf(v,_SC("[%s] GENERATOR\n"),name); + break; + case OT_USERDATA: + pf(v,_SC("[%s] USERDATA\n"),name); + break; + case OT_THREAD: + pf(v,_SC("[%s] THREAD\n"),name); + break; + case OT_CLASS: + pf(v,_SC("[%s] CLASS\n"),name); + break; + case OT_INSTANCE: + pf(v,_SC("[%s] INSTANCE\n"),name); + break; + case OT_WEAKREF: + pf(v,_SC("[%s] WEAKREF\n"),name); + break; + case OT_BOOL:{ + sq_getinteger(v,-1,&i); + pf(v,_SC("[%s] %s\n"),name,i?_SC("true"):_SC("false")); + } + break; + default: assert(0); break; + } + sq_pop(v,1); + } + } + } +} + +static SQInteger _sqstd_aux_printerror(HSQUIRRELVM v) +{ + SQPRINTFUNCTION pf = sq_geterrorfunc(v); + if(pf) { + const SQChar *sErr = 0; + if(sq_gettop(v)>=1) { + if(SQ_SUCCEEDED(sq_getstring(v,2,&sErr))) { + pf(v,_SC("\nAN ERROR HAS OCCURED [%s]\n"),sErr); + } + else{ + pf(v,_SC("\nAN ERROR HAS OCCURED [unknown]\n")); + } + sqstd_printcallstack(v); + } + } + return 0; +} + +void _sqstd_compiler_error(HSQUIRRELVM v,const SQChar *sErr,const SQChar *sSource,SQInteger line,SQInteger column) +{ + SQPRINTFUNCTION pf = sq_geterrorfunc(v); + if(pf) { + pf(v,_SC("%s line = (%d) column = (%d) : error %s\n"),sSource,line,column,sErr); + } +} + +void sqstd_seterrorhandlers(HSQUIRRELVM v) +{ + sq_setcompilererrorhandler(v,_sqstd_compiler_error); + sq_newclosure(v,_sqstd_aux_printerror,0); + sq_seterrorhandler(v); +} diff --git a/squirrel_3_0_1_stable/sqstdlib/sqstdblob.cpp b/squirrel_3_0_1_stable/sqstdlib/sqstdblob.cpp index 11b593306..a856db5e7 100644 --- a/squirrel_3_0_1_stable/sqstdlib/sqstdblob.cpp +++ b/squirrel_3_0_1_stable/sqstdlib/sqstdblob.cpp @@ -1,275 +1,275 @@ -/* see copyright notice in squirrel.h */ -#include -#include -#include -#include -#include -#include "sqstdstream.h" -#include "sqstdblobimpl.h" - -#define SQSTD_BLOB_TYPE_TAG (SQSTD_STREAM_TYPE_TAG | 0x00000002) - -//Blob - - -#define SETUP_BLOB(v) \ - SQBlob *self = NULL; \ - { if(SQ_FAILED(sq_getinstanceup(v,1,(SQUserPointer*)&self,(SQUserPointer)SQSTD_BLOB_TYPE_TAG))) \ - return SQ_ERROR; } - - -static SQInteger _blob_resize(HSQUIRRELVM v) -{ - SETUP_BLOB(v); - SQInteger size; - sq_getinteger(v,2,&size); - if(!self->Resize(size)) - return sq_throwerror(v,_SC("resize failed")); - return 0; -} - -static void __swap_dword(unsigned int *n) -{ - *n=(unsigned int)(((*n&0xFF000000)>>24) | - ((*n&0x00FF0000)>>8) | - ((*n&0x0000FF00)<<8) | - ((*n&0x000000FF)<<24)); -} - -static void __swap_word(unsigned short *n) -{ - *n=(unsigned short)((*n>>8)&0x00FF)| ((*n<<8)&0xFF00); -} - -static SQInteger _blob_swap4(HSQUIRRELVM v) -{ - SETUP_BLOB(v); - SQInteger num=(self->Len()-(self->Len()%4))>>2; - unsigned int *t=(unsigned int *)self->GetBuf(); - for(SQInteger i = 0; i < num; i++) { - __swap_dword(&t[i]); - } - return 0; -} - -static SQInteger _blob_swap2(HSQUIRRELVM v) -{ - SETUP_BLOB(v); - SQInteger num=(self->Len()-(self->Len()%2))>>1; - unsigned short *t = (unsigned short *)self->GetBuf(); - for(SQInteger i = 0; i < num; i++) { - __swap_word(&t[i]); - } - return 0; -} - -static SQInteger _blob__set(HSQUIRRELVM v) -{ - SETUP_BLOB(v); - SQInteger idx,val; - sq_getinteger(v,2,&idx); - sq_getinteger(v,3,&val); - if(idx < 0 || idx >= self->Len()) - return sq_throwerror(v,_SC("index out of range")); - ((unsigned char *)self->GetBuf())[idx] = (unsigned char) val; - sq_push(v,3); - return 1; -} - -static SQInteger _blob__get(HSQUIRRELVM v) -{ - SETUP_BLOB(v); - SQInteger idx; - sq_getinteger(v,2,&idx); - if(idx < 0 || idx >= self->Len()) - return sq_throwerror(v,_SC("index out of range")); - sq_pushinteger(v,((unsigned char *)self->GetBuf())[idx]); - return 1; -} - -static SQInteger _blob__nexti(HSQUIRRELVM v) -{ - SETUP_BLOB(v); - if(sq_gettype(v,2) == OT_NULL) { - sq_pushinteger(v, 0); - return 1; - } - SQInteger idx; - if(SQ_SUCCEEDED(sq_getinteger(v, 2, &idx))) { - if(idx+1 < self->Len()) { - sq_pushinteger(v, idx+1); - return 1; - } - sq_pushnull(v); - return 1; - } - return sq_throwerror(v,_SC("internal error (_nexti) wrong argument type")); -} - -static SQInteger _blob__typeof(HSQUIRRELVM v) -{ - sq_pushstring(v,_SC("blob"),-1); - return 1; -} - -static SQInteger _blob_releasehook(SQUserPointer p, SQInteger size) -{ - SQBlob *self = (SQBlob*)p; - self->~SQBlob(); - sq_free(self,sizeof(SQBlob)); - return 1; -} - -static SQInteger _blob_constructor(HSQUIRRELVM v) -{ - SQInteger nparam = sq_gettop(v); - SQInteger size = 0; - if(nparam == 2) { - sq_getinteger(v, 2, &size); - } - if(size < 0) return sq_throwerror(v, _SC("cannot create blob with negative size")); - //SQBlob *b = new SQBlob(size); - - SQBlob *b = new (sq_malloc(sizeof(SQBlob)))SQBlob(size); - if(SQ_FAILED(sq_setinstanceup(v,1,b))) { - b->~SQBlob(); - sq_free(b,sizeof(SQBlob)); - return sq_throwerror(v, _SC("cannot create blob")); - } - sq_setreleasehook(v,1,_blob_releasehook); - return 0; -} - -static SQInteger _blob__cloned(HSQUIRRELVM v) -{ - SQBlob *other = NULL; - { - if(SQ_FAILED(sq_getinstanceup(v,2,(SQUserPointer*)&other,(SQUserPointer)SQSTD_BLOB_TYPE_TAG))) - return SQ_ERROR; - } - //SQBlob *thisone = new SQBlob(other->Len()); - SQBlob *thisone = new (sq_malloc(sizeof(SQBlob)))SQBlob(other->Len()); - memcpy(thisone->GetBuf(),other->GetBuf(),thisone->Len()); - if(SQ_FAILED(sq_setinstanceup(v,1,thisone))) { - thisone->~SQBlob(); - sq_free(thisone,sizeof(SQBlob)); - return sq_throwerror(v, _SC("cannot clone blob")); - } - sq_setreleasehook(v,1,_blob_releasehook); - return 0; -} - -#define _DECL_BLOB_FUNC(name,nparams,typecheck) {_SC(#name),_blob_##name,nparams,typecheck} -static SQRegFunction _blob_methods[] = { - _DECL_BLOB_FUNC(constructor,-1,_SC("xn")), - _DECL_BLOB_FUNC(resize,2,_SC("xn")), - _DECL_BLOB_FUNC(swap2,1,_SC("x")), - _DECL_BLOB_FUNC(swap4,1,_SC("x")), - _DECL_BLOB_FUNC(_set,3,_SC("xnn")), - _DECL_BLOB_FUNC(_get,2,_SC("xn")), - _DECL_BLOB_FUNC(_typeof,1,_SC("x")), - _DECL_BLOB_FUNC(_nexti,2,_SC("x")), - _DECL_BLOB_FUNC(_cloned,2,_SC("xx")), - {0,0,0,0} -}; - - - -//GLOBAL FUNCTIONS - -static SQInteger _g_blob_casti2f(HSQUIRRELVM v) -{ - SQInteger i; - sq_getinteger(v,2,&i); - sq_pushfloat(v,*((SQFloat *)&i)); - return 1; -} - -static SQInteger _g_blob_castf2i(HSQUIRRELVM v) -{ - SQFloat f; - sq_getfloat(v,2,&f); - sq_pushinteger(v,*((SQInteger *)&f)); - return 1; -} - -static SQInteger _g_blob_swap2(HSQUIRRELVM v) -{ - SQInteger i; - sq_getinteger(v,2,&i); - short s=(short)i; - sq_pushinteger(v,(s<<8)|((s>>8)&0x00FF)); - return 1; -} - -static SQInteger _g_blob_swap4(HSQUIRRELVM v) -{ - SQInteger i; - sq_getinteger(v,2,&i); - unsigned int t4 = (unsigned int)i; - __swap_dword(&t4); - sq_pushinteger(v,(SQInteger)t4); - return 1; -} - -static SQInteger _g_blob_swapfloat(HSQUIRRELVM v) -{ - SQFloat f; - sq_getfloat(v,2,&f); - __swap_dword((unsigned int *)&f); - sq_pushfloat(v,f); - return 1; -} - -#define _DECL_GLOBALBLOB_FUNC(name,nparams,typecheck) {_SC(#name),_g_blob_##name,nparams,typecheck} -static SQRegFunction bloblib_funcs[]={ - _DECL_GLOBALBLOB_FUNC(casti2f,2,_SC(".n")), - _DECL_GLOBALBLOB_FUNC(castf2i,2,_SC(".n")), - _DECL_GLOBALBLOB_FUNC(swap2,2,_SC(".n")), - _DECL_GLOBALBLOB_FUNC(swap4,2,_SC(".n")), - _DECL_GLOBALBLOB_FUNC(swapfloat,2,_SC(".n")), - {0,0} -}; - -SQRESULT sqstd_getblob(HSQUIRRELVM v,SQInteger idx,SQUserPointer *ptr) -{ - SQBlob *blob; - if(SQ_FAILED(sq_getinstanceup(v,idx,(SQUserPointer *)&blob,(SQUserPointer)SQSTD_BLOB_TYPE_TAG))) - return -1; - *ptr = blob->GetBuf(); - return SQ_OK; -} - -SQInteger sqstd_getblobsize(HSQUIRRELVM v,SQInteger idx) -{ - SQBlob *blob; - if(SQ_FAILED(sq_getinstanceup(v,idx,(SQUserPointer *)&blob,(SQUserPointer)SQSTD_BLOB_TYPE_TAG))) - return -1; - return blob->Len(); -} - -SQUserPointer sqstd_createblob(HSQUIRRELVM v, SQInteger size) -{ - SQInteger top = sq_gettop(v); - sq_pushregistrytable(v); - sq_pushstring(v,_SC("std_blob"),-1); - if(SQ_SUCCEEDED(sq_get(v,-2))) { - sq_remove(v,-2); //removes the registry - sq_push(v,1); // push the this - sq_pushinteger(v,size); //size - SQBlob *blob = NULL; - if(SQ_SUCCEEDED(sq_call(v,2,SQTrue,SQFalse)) - && SQ_SUCCEEDED(sq_getinstanceup(v,-1,(SQUserPointer *)&blob,(SQUserPointer)SQSTD_BLOB_TYPE_TAG))) { - sq_remove(v,-2); - return blob->GetBuf(); - } - } - sq_settop(v,top); - return NULL; -} - -SQRESULT sqstd_register_bloblib(HSQUIRRELVM v) -{ - return declare_stream(v,_SC("blob"),(SQUserPointer)SQSTD_BLOB_TYPE_TAG,_SC("std_blob"),_blob_methods,bloblib_funcs); -} - +/* see copyright notice in squirrel.h */ +#include +#include +#include +#include +#include +#include "sqstdstream.h" +#include "sqstdblobimpl.h" + +#define SQSTD_BLOB_TYPE_TAG (SQSTD_STREAM_TYPE_TAG | 0x00000002) + +//Blob + + +#define SETUP_BLOB(v) \ + SQBlob *self = NULL; \ + { if(SQ_FAILED(sq_getinstanceup(v,1,(SQUserPointer*)&self,(SQUserPointer)SQSTD_BLOB_TYPE_TAG))) \ + return SQ_ERROR; } + + +static SQInteger _blob_resize(HSQUIRRELVM v) +{ + SETUP_BLOB(v); + SQInteger size; + sq_getinteger(v,2,&size); + if(!self->Resize(size)) + return sq_throwerror(v,_SC("resize failed")); + return 0; +} + +static void __swap_dword(unsigned int *n) +{ + *n=(unsigned int)(((*n&0xFF000000)>>24) | + ((*n&0x00FF0000)>>8) | + ((*n&0x0000FF00)<<8) | + ((*n&0x000000FF)<<24)); +} + +static void __swap_word(unsigned short *n) +{ + *n=(unsigned short)((*n>>8)&0x00FF)| ((*n<<8)&0xFF00); +} + +static SQInteger _blob_swap4(HSQUIRRELVM v) +{ + SETUP_BLOB(v); + SQInteger num=(self->Len()-(self->Len()%4))>>2; + unsigned int *t=(unsigned int *)self->GetBuf(); + for(SQInteger i = 0; i < num; i++) { + __swap_dword(&t[i]); + } + return 0; +} + +static SQInteger _blob_swap2(HSQUIRRELVM v) +{ + SETUP_BLOB(v); + SQInteger num=(self->Len()-(self->Len()%2))>>1; + unsigned short *t = (unsigned short *)self->GetBuf(); + for(SQInteger i = 0; i < num; i++) { + __swap_word(&t[i]); + } + return 0; +} + +static SQInteger _blob__set(HSQUIRRELVM v) +{ + SETUP_BLOB(v); + SQInteger idx,val; + sq_getinteger(v,2,&idx); + sq_getinteger(v,3,&val); + if(idx < 0 || idx >= self->Len()) + return sq_throwerror(v,_SC("index out of range")); + ((unsigned char *)self->GetBuf())[idx] = (unsigned char) val; + sq_push(v,3); + return 1; +} + +static SQInteger _blob__get(HSQUIRRELVM v) +{ + SETUP_BLOB(v); + SQInteger idx; + sq_getinteger(v,2,&idx); + if(idx < 0 || idx >= self->Len()) + return sq_throwerror(v,_SC("index out of range")); + sq_pushinteger(v,((unsigned char *)self->GetBuf())[idx]); + return 1; +} + +static SQInteger _blob__nexti(HSQUIRRELVM v) +{ + SETUP_BLOB(v); + if(sq_gettype(v,2) == OT_NULL) { + sq_pushinteger(v, 0); + return 1; + } + SQInteger idx; + if(SQ_SUCCEEDED(sq_getinteger(v, 2, &idx))) { + if(idx+1 < self->Len()) { + sq_pushinteger(v, idx+1); + return 1; + } + sq_pushnull(v); + return 1; + } + return sq_throwerror(v,_SC("internal error (_nexti) wrong argument type")); +} + +static SQInteger _blob__typeof(HSQUIRRELVM v) +{ + sq_pushstring(v,_SC("blob"),-1); + return 1; +} + +static SQInteger _blob_releasehook(SQUserPointer p, SQInteger size) +{ + SQBlob *self = (SQBlob*)p; + self->~SQBlob(); + sq_free(self,sizeof(SQBlob)); + return 1; +} + +static SQInteger _blob_constructor(HSQUIRRELVM v) +{ + SQInteger nparam = sq_gettop(v); + SQInteger size = 0; + if(nparam == 2) { + sq_getinteger(v, 2, &size); + } + if(size < 0) return sq_throwerror(v, _SC("cannot create blob with negative size")); + //SQBlob *b = new SQBlob(size); + + SQBlob *b = new (sq_malloc(sizeof(SQBlob)))SQBlob(size); + if(SQ_FAILED(sq_setinstanceup(v,1,b))) { + b->~SQBlob(); + sq_free(b,sizeof(SQBlob)); + return sq_throwerror(v, _SC("cannot create blob")); + } + sq_setreleasehook(v,1,_blob_releasehook); + return 0; +} + +static SQInteger _blob__cloned(HSQUIRRELVM v) +{ + SQBlob *other = NULL; + { + if(SQ_FAILED(sq_getinstanceup(v,2,(SQUserPointer*)&other,(SQUserPointer)SQSTD_BLOB_TYPE_TAG))) + return SQ_ERROR; + } + //SQBlob *thisone = new SQBlob(other->Len()); + SQBlob *thisone = new (sq_malloc(sizeof(SQBlob)))SQBlob(other->Len()); + memcpy(thisone->GetBuf(),other->GetBuf(),thisone->Len()); + if(SQ_FAILED(sq_setinstanceup(v,1,thisone))) { + thisone->~SQBlob(); + sq_free(thisone,sizeof(SQBlob)); + return sq_throwerror(v, _SC("cannot clone blob")); + } + sq_setreleasehook(v,1,_blob_releasehook); + return 0; +} + +#define _DECL_BLOB_FUNC(name,nparams,typecheck) {_SC(#name),_blob_##name,nparams,typecheck} +static SQRegFunction _blob_methods[] = { + _DECL_BLOB_FUNC(constructor,-1,_SC("xn")), + _DECL_BLOB_FUNC(resize,2,_SC("xn")), + _DECL_BLOB_FUNC(swap2,1,_SC("x")), + _DECL_BLOB_FUNC(swap4,1,_SC("x")), + _DECL_BLOB_FUNC(_set,3,_SC("xnn")), + _DECL_BLOB_FUNC(_get,2,_SC("xn")), + _DECL_BLOB_FUNC(_typeof,1,_SC("x")), + _DECL_BLOB_FUNC(_nexti,2,_SC("x")), + _DECL_BLOB_FUNC(_cloned,2,_SC("xx")), + {0,0,0,0} +}; + + + +//GLOBAL FUNCTIONS + +static SQInteger _g_blob_casti2f(HSQUIRRELVM v) +{ + SQInteger i; + sq_getinteger(v,2,&i); + sq_pushfloat(v,*((SQFloat *)&i)); + return 1; +} + +static SQInteger _g_blob_castf2i(HSQUIRRELVM v) +{ + SQFloat f; + sq_getfloat(v,2,&f); + sq_pushinteger(v,*((SQInteger *)&f)); + return 1; +} + +static SQInteger _g_blob_swap2(HSQUIRRELVM v) +{ + SQInteger i; + sq_getinteger(v,2,&i); + short s=(short)i; + sq_pushinteger(v,(s<<8)|((s>>8)&0x00FF)); + return 1; +} + +static SQInteger _g_blob_swap4(HSQUIRRELVM v) +{ + SQInteger i; + sq_getinteger(v,2,&i); + unsigned int t4 = (unsigned int)i; + __swap_dword(&t4); + sq_pushinteger(v,(SQInteger)t4); + return 1; +} + +static SQInteger _g_blob_swapfloat(HSQUIRRELVM v) +{ + SQFloat f; + sq_getfloat(v,2,&f); + __swap_dword((unsigned int *)&f); + sq_pushfloat(v,f); + return 1; +} + +#define _DECL_GLOBALBLOB_FUNC(name,nparams,typecheck) {_SC(#name),_g_blob_##name,nparams,typecheck} +static SQRegFunction bloblib_funcs[]={ + _DECL_GLOBALBLOB_FUNC(casti2f,2,_SC(".n")), + _DECL_GLOBALBLOB_FUNC(castf2i,2,_SC(".n")), + _DECL_GLOBALBLOB_FUNC(swap2,2,_SC(".n")), + _DECL_GLOBALBLOB_FUNC(swap4,2,_SC(".n")), + _DECL_GLOBALBLOB_FUNC(swapfloat,2,_SC(".n")), + {0,0} +}; + +SQRESULT sqstd_getblob(HSQUIRRELVM v,SQInteger idx,SQUserPointer *ptr) +{ + SQBlob *blob; + if(SQ_FAILED(sq_getinstanceup(v,idx,(SQUserPointer *)&blob,(SQUserPointer)SQSTD_BLOB_TYPE_TAG))) + return -1; + *ptr = blob->GetBuf(); + return SQ_OK; +} + +SQInteger sqstd_getblobsize(HSQUIRRELVM v,SQInteger idx) +{ + SQBlob *blob; + if(SQ_FAILED(sq_getinstanceup(v,idx,(SQUserPointer *)&blob,(SQUserPointer)SQSTD_BLOB_TYPE_TAG))) + return -1; + return blob->Len(); +} + +SQUserPointer sqstd_createblob(HSQUIRRELVM v, SQInteger size) +{ + SQInteger top = sq_gettop(v); + sq_pushregistrytable(v); + sq_pushstring(v,_SC("std_blob"),-1); + if(SQ_SUCCEEDED(sq_get(v,-2))) { + sq_remove(v,-2); //removes the registry + sq_push(v,1); // push the this + sq_pushinteger(v,size); //size + SQBlob *blob = NULL; + if(SQ_SUCCEEDED(sq_call(v,2,SQTrue,SQFalse)) + && SQ_SUCCEEDED(sq_getinstanceup(v,-1,(SQUserPointer *)&blob,(SQUserPointer)SQSTD_BLOB_TYPE_TAG))) { + sq_remove(v,-2); + return blob->GetBuf(); + } + } + sq_settop(v,top); + return NULL; +} + +SQRESULT sqstd_register_bloblib(HSQUIRRELVM v) +{ + return declare_stream(v,_SC("blob"),(SQUserPointer)SQSTD_BLOB_TYPE_TAG,_SC("std_blob"),_blob_methods,bloblib_funcs); +} + diff --git a/squirrel_3_0_1_stable/sqstdlib/sqstdblobimpl.h b/squirrel_3_0_1_stable/sqstdlib/sqstdblobimpl.h index b2291b73c..9f22c0ae2 100644 --- a/squirrel_3_0_1_stable/sqstdlib/sqstdblobimpl.h +++ b/squirrel_3_0_1_stable/sqstdlib/sqstdblobimpl.h @@ -1,108 +1,108 @@ -/* see copyright notice in squirrel.h */ -#ifndef _SQSTD_BLOBIMPL_H_ -#define _SQSTD_BLOBIMPL_H_ - -struct SQBlob : public SQStream -{ - SQBlob(SQInteger size) { - _size = size; - _allocated = size; - _buf = (unsigned char *)sq_malloc(size); - memset(_buf, 0, _size); - _ptr = 0; - _owns = true; - } - virtual ~SQBlob() { - sq_free(_buf, _allocated); - } - SQInteger Write(void *buffer, SQInteger size) { - if(!CanAdvance(size)) { - GrowBufOf(_ptr + size - _size); - } - memcpy(&_buf[_ptr], buffer, size); - _ptr += size; - return size; - } - SQInteger Read(void *buffer,SQInteger size) { - SQInteger n = size; - if(!CanAdvance(size)) { - if((_size - _ptr) > 0) - n = _size - _ptr; - else return 0; - } - memcpy(buffer, &_buf[_ptr], n); - _ptr += n; - return n; - } - bool Resize(SQInteger n) { - if(!_owns) return false; - if(n != _allocated) { - unsigned char *newbuf = (unsigned char *)sq_malloc(n); - memset(newbuf,0,n); - if(_size > n) - memcpy(newbuf,_buf,n); - else - memcpy(newbuf,_buf,_size); - sq_free(_buf,_allocated); - _buf=newbuf; - _allocated = n; - if(_size > _allocated) - _size = _allocated; - if(_ptr > _allocated) - _ptr = _allocated; - } - return true; - } - bool GrowBufOf(SQInteger n) - { - bool ret = true; - if(_size + n > _allocated) { - if(_size + n > _size * 2) - ret = Resize(_size + n); - else - ret = Resize(_size * 2); - } - _size = _size + n; - return ret; - } - bool CanAdvance(SQInteger n) { - if(_ptr+n>_size)return false; - return true; - } - SQInteger Seek(SQInteger offset, SQInteger origin) { - switch(origin) { - case SQ_SEEK_SET: - if(offset > _size || offset < 0) return -1; - _ptr = offset; - break; - case SQ_SEEK_CUR: - if(_ptr + offset > _size || _ptr + offset < 0) return -1; - _ptr += offset; - break; - case SQ_SEEK_END: - if(_size + offset > _size || _size + offset < 0) return -1; - _ptr = _size + offset; - break; - default: return -1; - } - return 0; - } - bool IsValid() { - return _buf?true:false; - } - bool EOS() { - return _ptr == _size; - } - SQInteger Flush() { return 0; } - SQInteger Tell() { return _ptr; } - SQInteger Len() { return _size; } - SQUserPointer GetBuf(){ return _buf; } -private: - SQInteger _size; - SQInteger _allocated; - SQInteger _ptr; - unsigned char *_buf; - bool _owns; -}; - -#endif //_SQSTD_BLOBIMPL_H_ +/* see copyright notice in squirrel.h */ +#ifndef _SQSTD_BLOBIMPL_H_ +#define _SQSTD_BLOBIMPL_H_ + +struct SQBlob : public SQStream +{ + SQBlob(SQInteger size) { + _size = size; + _allocated = size; + _buf = (unsigned char *)sq_malloc(size); + memset(_buf, 0, _size); + _ptr = 0; + _owns = true; + } + virtual ~SQBlob() { + sq_free(_buf, _allocated); + } + SQInteger Write(void *buffer, SQInteger size) { + if(!CanAdvance(size)) { + GrowBufOf(_ptr + size - _size); + } + memcpy(&_buf[_ptr], buffer, size); + _ptr += size; + return size; + } + SQInteger Read(void *buffer,SQInteger size) { + SQInteger n = size; + if(!CanAdvance(size)) { + if((_size - _ptr) > 0) + n = _size - _ptr; + else return 0; + } + memcpy(buffer, &_buf[_ptr], n); + _ptr += n; + return n; + } + bool Resize(SQInteger n) { + if(!_owns) return false; + if(n != _allocated) { + unsigned char *newbuf = (unsigned char *)sq_malloc(n); + memset(newbuf,0,n); + if(_size > n) + memcpy(newbuf,_buf,n); + else + memcpy(newbuf,_buf,_size); + sq_free(_buf,_allocated); + _buf=newbuf; + _allocated = n; + if(_size > _allocated) + _size = _allocated; + if(_ptr > _allocated) + _ptr = _allocated; + } + return true; + } + bool GrowBufOf(SQInteger n) + { + bool ret = true; + if(_size + n > _allocated) { + if(_size + n > _size * 2) + ret = Resize(_size + n); + else + ret = Resize(_size * 2); + } + _size = _size + n; + return ret; + } + bool CanAdvance(SQInteger n) { + if(_ptr+n>_size)return false; + return true; + } + SQInteger Seek(SQInteger offset, SQInteger origin) { + switch(origin) { + case SQ_SEEK_SET: + if(offset > _size || offset < 0) return -1; + _ptr = offset; + break; + case SQ_SEEK_CUR: + if(_ptr + offset > _size || _ptr + offset < 0) return -1; + _ptr += offset; + break; + case SQ_SEEK_END: + if(_size + offset > _size || _size + offset < 0) return -1; + _ptr = _size + offset; + break; + default: return -1; + } + return 0; + } + bool IsValid() { + return _buf?true:false; + } + bool EOS() { + return _ptr == _size; + } + SQInteger Flush() { return 0; } + SQInteger Tell() { return _ptr; } + SQInteger Len() { return _size; } + SQUserPointer GetBuf(){ return _buf; } +private: + SQInteger _size; + SQInteger _allocated; + SQInteger _ptr; + unsigned char *_buf; + bool _owns; +}; + +#endif //_SQSTD_BLOBIMPL_H_ diff --git a/squirrel_3_0_1_stable/sqstdlib/sqstdio.cpp b/squirrel_3_0_1_stable/sqstdlib/sqstdio.cpp index 241864bb2..cd88bb0b7 100644 --- a/squirrel_3_0_1_stable/sqstdlib/sqstdio.cpp +++ b/squirrel_3_0_1_stable/sqstdlib/sqstdio.cpp @@ -1,419 +1,419 @@ -/* see copyright notice in squirrel.h */ -#include -#include -#include -#include -#include "sqstdstream.h" - -#define SQSTD_FILE_TYPE_TAG (SQSTD_STREAM_TYPE_TAG | 0x00000001) -//basic API -SQFILE sqstd_fopen(const SQChar *filename ,const SQChar *mode) -{ -#ifndef SQUNICODE - return (SQFILE)fopen(filename,mode); -#else - return (SQFILE)_wfopen(filename,mode); -#endif -} - -SQInteger sqstd_fread(void* buffer, SQInteger size, SQInteger count, SQFILE file) -{ - return (SQInteger)fread(buffer,size,count,(FILE *)file); -} - -SQInteger sqstd_fwrite(const SQUserPointer buffer, SQInteger size, SQInteger count, SQFILE file) -{ - return (SQInteger)fwrite(buffer,size,count,(FILE *)file); -} - -SQInteger sqstd_fseek(SQFILE file, SQInteger offset, SQInteger origin) -{ - SQInteger realorigin; - switch(origin) { - case SQ_SEEK_CUR: realorigin = SEEK_CUR; break; - case SQ_SEEK_END: realorigin = SEEK_END; break; - case SQ_SEEK_SET: realorigin = SEEK_SET; break; - default: return -1; //failed - } - return fseek((FILE *)file,(long)offset,(int)realorigin); -} - -SQInteger sqstd_ftell(SQFILE file) -{ - return ftell((FILE *)file); -} - -SQInteger sqstd_fflush(SQFILE file) -{ - return fflush((FILE *)file); -} - -SQInteger sqstd_fclose(SQFILE file) -{ - return fclose((FILE *)file); -} - -SQInteger sqstd_feof(SQFILE file) -{ - return feof((FILE *)file); -} - -//File -struct SQFile : public SQStream { - SQFile() { _handle = NULL; _owns = false;} - SQFile(SQFILE file, bool owns) { _handle = file; _owns = owns;} - virtual ~SQFile() { Close(); } - bool Open(const SQChar *filename ,const SQChar *mode) { - Close(); - if( (_handle = sqstd_fopen(filename,mode)) ) { - _owns = true; - return true; - } - return false; - } - void Close() { - if(_handle && _owns) { - sqstd_fclose(_handle); - _handle = NULL; - _owns = false; - } - } - SQInteger Read(void *buffer,SQInteger size) { - return sqstd_fread(buffer,1,size,_handle); - } - SQInteger Write(void *buffer,SQInteger size) { - return sqstd_fwrite(buffer,1,size,_handle); - } - SQInteger Flush() { - return sqstd_fflush(_handle); - } - SQInteger Tell() { - return sqstd_ftell(_handle); - } - SQInteger Len() { - SQInteger prevpos=Tell(); - Seek(0,SQ_SEEK_END); - SQInteger size=Tell(); - Seek(prevpos,SQ_SEEK_SET); - return size; - } - SQInteger Seek(SQInteger offset, SQInteger origin) { - return sqstd_fseek(_handle,offset,origin); - } - bool IsValid() { return _handle?true:false; } - bool EOS() { return Tell()==Len()?true:false;} - SQFILE GetHandle() {return _handle;} -private: - SQFILE _handle; - bool _owns; -}; - -static SQInteger _file__typeof(HSQUIRRELVM v) -{ - sq_pushstring(v,_SC("file"),-1); - return 1; -} - -static SQInteger _file_releasehook(SQUserPointer p, SQInteger size) -{ - SQFile *self = (SQFile*)p; - self->~SQFile(); - sq_free(self,sizeof(SQFile)); - return 1; -} - -static SQInteger _file_constructor(HSQUIRRELVM v) -{ - const SQChar *filename,*mode; - bool owns = true; - SQFile *f; - SQFILE newf; - if(sq_gettype(v,2) == OT_STRING && sq_gettype(v,3) == OT_STRING) { - sq_getstring(v, 2, &filename); - sq_getstring(v, 3, &mode); - newf = sqstd_fopen(filename, mode); - if(!newf) return sq_throwerror(v, _SC("cannot open file")); - } else if(sq_gettype(v,2) == OT_USERPOINTER) { - owns = !(sq_gettype(v,3) == OT_NULL); - sq_getuserpointer(v,2,&newf); - } else { - return sq_throwerror(v,_SC("wrong parameter")); - } - - f = new (sq_malloc(sizeof(SQFile)))SQFile(newf,owns); - if(SQ_FAILED(sq_setinstanceup(v,1,f))) { - f->~SQFile(); - sq_free(f,sizeof(SQFile)); - return sq_throwerror(v, _SC("cannot create blob with negative size")); - } - sq_setreleasehook(v,1,_file_releasehook); - return 0; -} - -//bindings -#define _DECL_FILE_FUNC(name,nparams,typecheck) {_SC(#name),_file_##name,nparams,typecheck} -static SQRegFunction _file_methods[] = { - _DECL_FILE_FUNC(constructor,3,_SC("x")), - _DECL_FILE_FUNC(_typeof,1,_SC("x")), - {0,0,0,0}, -}; - - - -SQRESULT sqstd_createfile(HSQUIRRELVM v, SQFILE file,SQBool own) -{ - SQInteger top = sq_gettop(v); - sq_pushregistrytable(v); - sq_pushstring(v,_SC("std_file"),-1); - if(SQ_SUCCEEDED(sq_get(v,-2))) { - sq_remove(v,-2); //removes the registry - sq_pushroottable(v); // push the this - sq_pushuserpointer(v,file); //file - if(own){ - sq_pushinteger(v,1); //true - } - else{ - sq_pushnull(v); //false - } - if(SQ_SUCCEEDED( sq_call(v,3,SQTrue,SQFalse) )) { - sq_remove(v,-2); - return SQ_OK; - } - } - sq_settop(v,top); - return SQ_OK; -} - -SQRESULT sqstd_getfile(HSQUIRRELVM v, SQInteger idx, SQFILE *file) -{ - SQFile *fileobj = NULL; - if(SQ_SUCCEEDED(sq_getinstanceup(v,idx,(SQUserPointer*)&fileobj,(SQUserPointer)SQSTD_FILE_TYPE_TAG))) { - *file = fileobj->GetHandle(); - return SQ_OK; - } - return sq_throwerror(v,_SC("not a file")); -} - - - -static SQInteger _io_file_lexfeed_PLAIN(SQUserPointer file) -{ - SQInteger ret; - char c; - if( ( ret=sqstd_fread(&c,sizeof(c),1,(FILE *)file )>0) ) - return c; - return 0; -} - -#ifdef SQUNICODE -static SQInteger _io_file_lexfeed_UTF8(SQUserPointer file) -{ -#define READ() \ - if(sqstd_fread(&inchar,sizeof(inchar),1,(FILE *)file) != 1) \ - return 0; - - static const SQInteger utf8_lengths[16] = - { - 1,1,1,1,1,1,1,1, /* 0000 to 0111 : 1 byte (plain ASCII) */ - 0,0,0,0, /* 1000 to 1011 : not valid */ - 2,2, /* 1100, 1101 : 2 bytes */ - 3, /* 1110 : 3 bytes */ - 4 /* 1111 :4 bytes */ - }; - static unsigned char byte_masks[5] = {0,0,0x1f,0x0f,0x07}; - unsigned char inchar; - SQInteger c = 0; - READ(); - c = inchar; - // - if(c >= 0x80) { - SQInteger tmp; - SQInteger codelen = utf8_lengths[c>>4]; - if(codelen == 0) - return 0; - //"invalid UTF-8 stream"; - tmp = c&byte_masks[codelen]; - for(SQInteger n = 0; n < codelen-1; n++) { - tmp<<=6; - READ(); - tmp |= inchar & 0x3F; - } - c = tmp; - } - return c; -} -#endif - -static SQInteger _io_file_lexfeed_UCS2_LE(SQUserPointer file) -{ - SQInteger ret; - wchar_t c; - if( ( ret=sqstd_fread(&c,sizeof(c),1,(FILE *)file )>0) ) - return (SQChar)c; - return 0; -} - -static SQInteger _io_file_lexfeed_UCS2_BE(SQUserPointer file) -{ - SQInteger ret; - unsigned short c; - if( ( ret=sqstd_fread(&c,sizeof(c),1,(FILE *)file )>0) ) { - c = ((c>>8)&0x00FF)| ((c<<8)&0xFF00); - return (SQChar)c; - } - return 0; -} - -SQInteger file_read(SQUserPointer file,SQUserPointer buf,SQInteger size) -{ - SQInteger ret; - if( ( ret = sqstd_fread(buf,1,size,(SQFILE)file ))!=0 )return ret; - return -1; -} - -SQInteger file_write(SQUserPointer file,SQUserPointer p,SQInteger size) -{ - return sqstd_fwrite(p,1,size,(SQFILE)file); -} - -SQRESULT sqstd_loadfile(HSQUIRRELVM v,const SQChar *filename,SQBool printerror) -{ - SQFILE file = sqstd_fopen(filename,_SC("rb")); - SQInteger ret; - unsigned short us; - unsigned char uc; - SQLEXREADFUNC func = _io_file_lexfeed_PLAIN; - if(file){ - ret = sqstd_fread(&us,1,2,file); - if(ret != 2) { - //probably an empty file - us = 0; - } - if(us == SQ_BYTECODE_STREAM_TAG) { //BYTECODE - sqstd_fseek(file,0,SQ_SEEK_SET); - if(SQ_SUCCEEDED(sq_readclosure(v,file_read,file))) { - sqstd_fclose(file); - return SQ_OK; - } - } - else { //SCRIPT - switch(us) - { - //gotta swap the next 2 lines on BIG endian machines - case 0xFFFE: func = _io_file_lexfeed_UCS2_BE; break;//UTF-16 little endian; - case 0xFEFF: func = _io_file_lexfeed_UCS2_LE; break;//UTF-16 big endian; - case 0xBBEF: - if(sqstd_fread(&uc,1,sizeof(uc),file) == 0) { - sqstd_fclose(file); - return sq_throwerror(v,_SC("io error")); - } - if(uc != 0xBF) { - sqstd_fclose(file); - return sq_throwerror(v,_SC("Unrecognozed ecoding")); - } -#ifdef SQUNICODE - func = _io_file_lexfeed_UTF8; -#else - func = _io_file_lexfeed_PLAIN; -#endif - break;//UTF-8 ; - default: sqstd_fseek(file,0,SQ_SEEK_SET); break; // ascii - } - - if(SQ_SUCCEEDED(sq_compile(v,func,file,filename,printerror))){ - sqstd_fclose(file); - return SQ_OK; - } - } - sqstd_fclose(file); - return SQ_ERROR; - } - return sq_throwerror(v,_SC("cannot open the file")); -} - -SQRESULT sqstd_dofile(HSQUIRRELVM v,const SQChar *filename,SQBool retval,SQBool printerror) -{ - if(SQ_SUCCEEDED(sqstd_loadfile(v,filename,printerror))) { - sq_push(v,-2); - if(SQ_SUCCEEDED(sq_call(v,1,retval,SQTrue))) { - sq_remove(v,retval?-2:-1); //removes the closure - return 1; - } - sq_pop(v,1); //removes the closure - } - return SQ_ERROR; -} - -SQRESULT sqstd_writeclosuretofile(HSQUIRRELVM v,const SQChar *filename) -{ - SQFILE file = sqstd_fopen(filename,_SC("wb+")); - if(!file) return sq_throwerror(v,_SC("cannot open the file")); - if(SQ_SUCCEEDED(sq_writeclosure(v,file_write,file))) { - sqstd_fclose(file); - return SQ_OK; - } - sqstd_fclose(file); - return SQ_ERROR; //forward the error -} - -SQInteger _g_io_loadfile(HSQUIRRELVM v) -{ - const SQChar *filename; - SQBool printerror = SQFalse; - sq_getstring(v,2,&filename); - if(sq_gettop(v) >= 3) { - sq_getbool(v,3,&printerror); - } - if(SQ_SUCCEEDED(sqstd_loadfile(v,filename,printerror))) - return 1; - return SQ_ERROR; //propagates the error -} - -SQInteger _g_io_writeclosuretofile(HSQUIRRELVM v) -{ - const SQChar *filename; - sq_getstring(v,2,&filename); - if(SQ_SUCCEEDED(sqstd_writeclosuretofile(v,filename))) - return 1; - return SQ_ERROR; //propagates the error -} - -SQInteger _g_io_dofile(HSQUIRRELVM v) -{ - const SQChar *filename; - SQBool printerror = SQFalse; - sq_getstring(v,2,&filename); - if(sq_gettop(v) >= 3) { - sq_getbool(v,3,&printerror); - } - sq_push(v,1); //repush the this - if(SQ_SUCCEEDED(sqstd_dofile(v,filename,SQTrue,printerror))) - return 1; - return SQ_ERROR; //propagates the error -} - -#define _DECL_GLOBALIO_FUNC(name,nparams,typecheck) {_SC(#name),_g_io_##name,nparams,typecheck} -static SQRegFunction iolib_funcs[]={ - _DECL_GLOBALIO_FUNC(loadfile,-2,_SC(".sb")), - _DECL_GLOBALIO_FUNC(dofile,-2,_SC(".sb")), - _DECL_GLOBALIO_FUNC(writeclosuretofile,3,_SC(".sc")), - {0,0} -}; - -SQRESULT sqstd_register_iolib(HSQUIRRELVM v) -{ - SQInteger top = sq_gettop(v); - //create delegate - declare_stream(v,_SC("file"),(SQUserPointer)SQSTD_FILE_TYPE_TAG,_SC("std_file"),_file_methods,iolib_funcs); - sq_pushstring(v,_SC("stdout"),-1); - sqstd_createfile(v,stdout,SQFalse); - sq_newslot(v,-3,SQFalse); - sq_pushstring(v,_SC("stdin"),-1); - sqstd_createfile(v,stdin,SQFalse); - sq_newslot(v,-3,SQFalse); - sq_pushstring(v,_SC("stderr"),-1); - sqstd_createfile(v,stderr,SQFalse); - sq_newslot(v,-3,SQFalse); - sq_settop(v,top); - return SQ_OK; -} +/* see copyright notice in squirrel.h */ +#include +#include +#include +#include +#include "sqstdstream.h" + +#define SQSTD_FILE_TYPE_TAG (SQSTD_STREAM_TYPE_TAG | 0x00000001) +//basic API +SQFILE sqstd_fopen(const SQChar *filename ,const SQChar *mode) +{ +#ifndef SQUNICODE + return (SQFILE)fopen(filename,mode); +#else + return (SQFILE)_wfopen(filename,mode); +#endif +} + +SQInteger sqstd_fread(void* buffer, SQInteger size, SQInteger count, SQFILE file) +{ + return (SQInteger)fread(buffer,size,count,(FILE *)file); +} + +SQInteger sqstd_fwrite(const SQUserPointer buffer, SQInteger size, SQInteger count, SQFILE file) +{ + return (SQInteger)fwrite(buffer,size,count,(FILE *)file); +} + +SQInteger sqstd_fseek(SQFILE file, SQInteger offset, SQInteger origin) +{ + SQInteger realorigin; + switch(origin) { + case SQ_SEEK_CUR: realorigin = SEEK_CUR; break; + case SQ_SEEK_END: realorigin = SEEK_END; break; + case SQ_SEEK_SET: realorigin = SEEK_SET; break; + default: return -1; //failed + } + return fseek((FILE *)file,(long)offset,(int)realorigin); +} + +SQInteger sqstd_ftell(SQFILE file) +{ + return ftell((FILE *)file); +} + +SQInteger sqstd_fflush(SQFILE file) +{ + return fflush((FILE *)file); +} + +SQInteger sqstd_fclose(SQFILE file) +{ + return fclose((FILE *)file); +} + +SQInteger sqstd_feof(SQFILE file) +{ + return feof((FILE *)file); +} + +//File +struct SQFile : public SQStream { + SQFile() { _handle = NULL; _owns = false;} + SQFile(SQFILE file, bool owns) { _handle = file; _owns = owns;} + virtual ~SQFile() { Close(); } + bool Open(const SQChar *filename ,const SQChar *mode) { + Close(); + if( (_handle = sqstd_fopen(filename,mode)) ) { + _owns = true; + return true; + } + return false; + } + void Close() { + if(_handle && _owns) { + sqstd_fclose(_handle); + _handle = NULL; + _owns = false; + } + } + SQInteger Read(void *buffer,SQInteger size) { + return sqstd_fread(buffer,1,size,_handle); + } + SQInteger Write(void *buffer,SQInteger size) { + return sqstd_fwrite(buffer,1,size,_handle); + } + SQInteger Flush() { + return sqstd_fflush(_handle); + } + SQInteger Tell() { + return sqstd_ftell(_handle); + } + SQInteger Len() { + SQInteger prevpos=Tell(); + Seek(0,SQ_SEEK_END); + SQInteger size=Tell(); + Seek(prevpos,SQ_SEEK_SET); + return size; + } + SQInteger Seek(SQInteger offset, SQInteger origin) { + return sqstd_fseek(_handle,offset,origin); + } + bool IsValid() { return _handle?true:false; } + bool EOS() { return Tell()==Len()?true:false;} + SQFILE GetHandle() {return _handle;} +private: + SQFILE _handle; + bool _owns; +}; + +static SQInteger _file__typeof(HSQUIRRELVM v) +{ + sq_pushstring(v,_SC("file"),-1); + return 1; +} + +static SQInteger _file_releasehook(SQUserPointer p, SQInteger size) +{ + SQFile *self = (SQFile*)p; + self->~SQFile(); + sq_free(self,sizeof(SQFile)); + return 1; +} + +static SQInteger _file_constructor(HSQUIRRELVM v) +{ + const SQChar *filename,*mode; + bool owns = true; + SQFile *f; + SQFILE newf; + if(sq_gettype(v,2) == OT_STRING && sq_gettype(v,3) == OT_STRING) { + sq_getstring(v, 2, &filename); + sq_getstring(v, 3, &mode); + newf = sqstd_fopen(filename, mode); + if(!newf) return sq_throwerror(v, _SC("cannot open file")); + } else if(sq_gettype(v,2) == OT_USERPOINTER) { + owns = !(sq_gettype(v,3) == OT_NULL); + sq_getuserpointer(v,2,&newf); + } else { + return sq_throwerror(v,_SC("wrong parameter")); + } + + f = new (sq_malloc(sizeof(SQFile)))SQFile(newf,owns); + if(SQ_FAILED(sq_setinstanceup(v,1,f))) { + f->~SQFile(); + sq_free(f,sizeof(SQFile)); + return sq_throwerror(v, _SC("cannot create blob with negative size")); + } + sq_setreleasehook(v,1,_file_releasehook); + return 0; +} + +//bindings +#define _DECL_FILE_FUNC(name,nparams,typecheck) {_SC(#name),_file_##name,nparams,typecheck} +static SQRegFunction _file_methods[] = { + _DECL_FILE_FUNC(constructor,3,_SC("x")), + _DECL_FILE_FUNC(_typeof,1,_SC("x")), + {0,0,0,0}, +}; + + + +SQRESULT sqstd_createfile(HSQUIRRELVM v, SQFILE file,SQBool own) +{ + SQInteger top = sq_gettop(v); + sq_pushregistrytable(v); + sq_pushstring(v,_SC("std_file"),-1); + if(SQ_SUCCEEDED(sq_get(v,-2))) { + sq_remove(v,-2); //removes the registry + sq_pushroottable(v); // push the this + sq_pushuserpointer(v,file); //file + if(own){ + sq_pushinteger(v,1); //true + } + else{ + sq_pushnull(v); //false + } + if(SQ_SUCCEEDED( sq_call(v,3,SQTrue,SQFalse) )) { + sq_remove(v,-2); + return SQ_OK; + } + } + sq_settop(v,top); + return SQ_OK; +} + +SQRESULT sqstd_getfile(HSQUIRRELVM v, SQInteger idx, SQFILE *file) +{ + SQFile *fileobj = NULL; + if(SQ_SUCCEEDED(sq_getinstanceup(v,idx,(SQUserPointer*)&fileobj,(SQUserPointer)SQSTD_FILE_TYPE_TAG))) { + *file = fileobj->GetHandle(); + return SQ_OK; + } + return sq_throwerror(v,_SC("not a file")); +} + + + +static SQInteger _io_file_lexfeed_PLAIN(SQUserPointer file) +{ + SQInteger ret; + char c; + if( ( ret=sqstd_fread(&c,sizeof(c),1,(FILE *)file )>0) ) + return c; + return 0; +} + +#ifdef SQUNICODE +static SQInteger _io_file_lexfeed_UTF8(SQUserPointer file) +{ +#define READ() \ + if(sqstd_fread(&inchar,sizeof(inchar),1,(FILE *)file) != 1) \ + return 0; + + static const SQInteger utf8_lengths[16] = + { + 1,1,1,1,1,1,1,1, /* 0000 to 0111 : 1 byte (plain ASCII) */ + 0,0,0,0, /* 1000 to 1011 : not valid */ + 2,2, /* 1100, 1101 : 2 bytes */ + 3, /* 1110 : 3 bytes */ + 4 /* 1111 :4 bytes */ + }; + static unsigned char byte_masks[5] = {0,0,0x1f,0x0f,0x07}; + unsigned char inchar; + SQInteger c = 0; + READ(); + c = inchar; + // + if(c >= 0x80) { + SQInteger tmp; + SQInteger codelen = utf8_lengths[c>>4]; + if(codelen == 0) + return 0; + //"invalid UTF-8 stream"; + tmp = c&byte_masks[codelen]; + for(SQInteger n = 0; n < codelen-1; n++) { + tmp<<=6; + READ(); + tmp |= inchar & 0x3F; + } + c = tmp; + } + return c; +} +#endif + +static SQInteger _io_file_lexfeed_UCS2_LE(SQUserPointer file) +{ + SQInteger ret; + wchar_t c; + if( ( ret=sqstd_fread(&c,sizeof(c),1,(FILE *)file )>0) ) + return (SQChar)c; + return 0; +} + +static SQInteger _io_file_lexfeed_UCS2_BE(SQUserPointer file) +{ + SQInteger ret; + unsigned short c; + if( ( ret=sqstd_fread(&c,sizeof(c),1,(FILE *)file )>0) ) { + c = ((c>>8)&0x00FF)| ((c<<8)&0xFF00); + return (SQChar)c; + } + return 0; +} + +SQInteger file_read(SQUserPointer file,SQUserPointer buf,SQInteger size) +{ + SQInteger ret; + if( ( ret = sqstd_fread(buf,1,size,(SQFILE)file ))!=0 )return ret; + return -1; +} + +SQInteger file_write(SQUserPointer file,SQUserPointer p,SQInteger size) +{ + return sqstd_fwrite(p,1,size,(SQFILE)file); +} + +SQRESULT sqstd_loadfile(HSQUIRRELVM v,const SQChar *filename,SQBool printerror) +{ + SQFILE file = sqstd_fopen(filename,_SC("rb")); + SQInteger ret; + unsigned short us; + unsigned char uc; + SQLEXREADFUNC func = _io_file_lexfeed_PLAIN; + if(file){ + ret = sqstd_fread(&us,1,2,file); + if(ret != 2) { + //probably an empty file + us = 0; + } + if(us == SQ_BYTECODE_STREAM_TAG) { //BYTECODE + sqstd_fseek(file,0,SQ_SEEK_SET); + if(SQ_SUCCEEDED(sq_readclosure(v,file_read,file))) { + sqstd_fclose(file); + return SQ_OK; + } + } + else { //SCRIPT + switch(us) + { + //gotta swap the next 2 lines on BIG endian machines + case 0xFFFE: func = _io_file_lexfeed_UCS2_BE; break;//UTF-16 little endian; + case 0xFEFF: func = _io_file_lexfeed_UCS2_LE; break;//UTF-16 big endian; + case 0xBBEF: + if(sqstd_fread(&uc,1,sizeof(uc),file) == 0) { + sqstd_fclose(file); + return sq_throwerror(v,_SC("io error")); + } + if(uc != 0xBF) { + sqstd_fclose(file); + return sq_throwerror(v,_SC("Unrecognozed ecoding")); + } +#ifdef SQUNICODE + func = _io_file_lexfeed_UTF8; +#else + func = _io_file_lexfeed_PLAIN; +#endif + break;//UTF-8 ; + default: sqstd_fseek(file,0,SQ_SEEK_SET); break; // ascii + } + + if(SQ_SUCCEEDED(sq_compile(v,func,file,filename,printerror))){ + sqstd_fclose(file); + return SQ_OK; + } + } + sqstd_fclose(file); + return SQ_ERROR; + } + return sq_throwerror(v,_SC("cannot open the file")); +} + +SQRESULT sqstd_dofile(HSQUIRRELVM v,const SQChar *filename,SQBool retval,SQBool printerror) +{ + if(SQ_SUCCEEDED(sqstd_loadfile(v,filename,printerror))) { + sq_push(v,-2); + if(SQ_SUCCEEDED(sq_call(v,1,retval,SQTrue))) { + sq_remove(v,retval?-2:-1); //removes the closure + return 1; + } + sq_pop(v,1); //removes the closure + } + return SQ_ERROR; +} + +SQRESULT sqstd_writeclosuretofile(HSQUIRRELVM v,const SQChar *filename) +{ + SQFILE file = sqstd_fopen(filename,_SC("wb+")); + if(!file) return sq_throwerror(v,_SC("cannot open the file")); + if(SQ_SUCCEEDED(sq_writeclosure(v,file_write,file))) { + sqstd_fclose(file); + return SQ_OK; + } + sqstd_fclose(file); + return SQ_ERROR; //forward the error +} + +SQInteger _g_io_loadfile(HSQUIRRELVM v) +{ + const SQChar *filename; + SQBool printerror = SQFalse; + sq_getstring(v,2,&filename); + if(sq_gettop(v) >= 3) { + sq_getbool(v,3,&printerror); + } + if(SQ_SUCCEEDED(sqstd_loadfile(v,filename,printerror))) + return 1; + return SQ_ERROR; //propagates the error +} + +SQInteger _g_io_writeclosuretofile(HSQUIRRELVM v) +{ + const SQChar *filename; + sq_getstring(v,2,&filename); + if(SQ_SUCCEEDED(sqstd_writeclosuretofile(v,filename))) + return 1; + return SQ_ERROR; //propagates the error +} + +SQInteger _g_io_dofile(HSQUIRRELVM v) +{ + const SQChar *filename; + SQBool printerror = SQFalse; + sq_getstring(v,2,&filename); + if(sq_gettop(v) >= 3) { + sq_getbool(v,3,&printerror); + } + sq_push(v,1); //repush the this + if(SQ_SUCCEEDED(sqstd_dofile(v,filename,SQTrue,printerror))) + return 1; + return SQ_ERROR; //propagates the error +} + +#define _DECL_GLOBALIO_FUNC(name,nparams,typecheck) {_SC(#name),_g_io_##name,nparams,typecheck} +static SQRegFunction iolib_funcs[]={ + _DECL_GLOBALIO_FUNC(loadfile,-2,_SC(".sb")), + _DECL_GLOBALIO_FUNC(dofile,-2,_SC(".sb")), + _DECL_GLOBALIO_FUNC(writeclosuretofile,3,_SC(".sc")), + {0,0} +}; + +SQRESULT sqstd_register_iolib(HSQUIRRELVM v) +{ + SQInteger top = sq_gettop(v); + //create delegate + declare_stream(v,_SC("file"),(SQUserPointer)SQSTD_FILE_TYPE_TAG,_SC("std_file"),_file_methods,iolib_funcs); + sq_pushstring(v,_SC("stdout"),-1); + sqstd_createfile(v,stdout,SQFalse); + sq_newslot(v,-3,SQFalse); + sq_pushstring(v,_SC("stdin"),-1); + sqstd_createfile(v,stdin,SQFalse); + sq_newslot(v,-3,SQFalse); + sq_pushstring(v,_SC("stderr"),-1); + sqstd_createfile(v,stderr,SQFalse); + sq_newslot(v,-3,SQFalse); + sq_settop(v,top); + return SQ_OK; +} diff --git a/squirrel_3_0_1_stable/sqstdlib/sqstdmath.cpp b/squirrel_3_0_1_stable/sqstdlib/sqstdmath.cpp index ef50359bd..8d8a1917b 100644 --- a/squirrel_3_0_1_stable/sqstdlib/sqstdmath.cpp +++ b/squirrel_3_0_1_stable/sqstdlib/sqstdmath.cpp @@ -1,107 +1,107 @@ -/* see copyright notice in squirrel.h */ -#include -#include -#include -#include - -#define SINGLE_ARG_FUNC(_funcname) static SQInteger math_##_funcname(HSQUIRRELVM v){ \ - SQFloat f; \ - sq_getfloat(v,2,&f); \ - sq_pushfloat(v,(SQFloat)_funcname(f)); \ - return 1; \ -} - -#define TWO_ARGS_FUNC(_funcname) static SQInteger math_##_funcname(HSQUIRRELVM v){ \ - SQFloat p1,p2; \ - sq_getfloat(v,2,&p1); \ - sq_getfloat(v,3,&p2); \ - sq_pushfloat(v,(SQFloat)_funcname(p1,p2)); \ - return 1; \ -} - -static SQInteger math_srand(HSQUIRRELVM v) -{ - SQInteger i; - if(SQ_FAILED(sq_getinteger(v,2,&i))) - return sq_throwerror(v,_SC("invalid param")); - srand((unsigned int)i); - return 0; -} - -static SQInteger math_rand(HSQUIRRELVM v) -{ - sq_pushinteger(v,rand()); - return 1; -} - -static SQInteger math_abs(HSQUIRRELVM v) -{ - SQInteger n; - sq_getinteger(v,2,&n); - sq_pushinteger(v,(SQInteger)abs((int)n)); - return 1; -} - -SINGLE_ARG_FUNC(sqrt) -SINGLE_ARG_FUNC(fabs) -SINGLE_ARG_FUNC(sin) -SINGLE_ARG_FUNC(cos) -SINGLE_ARG_FUNC(asin) -SINGLE_ARG_FUNC(acos) -SINGLE_ARG_FUNC(log) -SINGLE_ARG_FUNC(log10) -SINGLE_ARG_FUNC(tan) -SINGLE_ARG_FUNC(atan) -TWO_ARGS_FUNC(atan2) -TWO_ARGS_FUNC(pow) -SINGLE_ARG_FUNC(floor) -SINGLE_ARG_FUNC(ceil) -SINGLE_ARG_FUNC(exp) - -#define _DECL_FUNC(name,nparams,tycheck) {_SC(#name),math_##name,nparams,tycheck} -static SQRegFunction mathlib_funcs[] = { - _DECL_FUNC(sqrt,2,_SC(".n")), - _DECL_FUNC(sin,2,_SC(".n")), - _DECL_FUNC(cos,2,_SC(".n")), - _DECL_FUNC(asin,2,_SC(".n")), - _DECL_FUNC(acos,2,_SC(".n")), - _DECL_FUNC(log,2,_SC(".n")), - _DECL_FUNC(log10,2,_SC(".n")), - _DECL_FUNC(tan,2,_SC(".n")), - _DECL_FUNC(atan,2,_SC(".n")), - _DECL_FUNC(atan2,3,_SC(".nn")), - _DECL_FUNC(pow,3,_SC(".nn")), - _DECL_FUNC(floor,2,_SC(".n")), - _DECL_FUNC(ceil,2,_SC(".n")), - _DECL_FUNC(exp,2,_SC(".n")), - _DECL_FUNC(srand,2,_SC(".n")), - _DECL_FUNC(rand,1,NULL), - _DECL_FUNC(fabs,2,_SC(".n")), - _DECL_FUNC(abs,2,_SC(".n")), - {0,0}, -}; -#undef _DECL_FUNC - -#ifndef M_PI -#define M_PI (3.14159265358979323846) -#endif - -SQRESULT sqstd_register_mathlib(HSQUIRRELVM v) -{ - SQInteger i=0; - while(mathlib_funcs[i].name!=0) { - sq_pushstring(v,mathlib_funcs[i].name,-1); - sq_newclosure(v,mathlib_funcs[i].f,0); - sq_setparamscheck(v,mathlib_funcs[i].nparamscheck,mathlib_funcs[i].typemask); - sq_setnativeclosurename(v,-1,mathlib_funcs[i].name); - sq_newslot(v,-3,SQFalse); - i++; - } - sq_pushstring(v,_SC("RAND_MAX"),-1); - sq_pushinteger(v,RAND_MAX); - sq_newslot(v,-3,SQFalse); - sq_pushstring(v,_SC("PI"),-1); - sq_pushfloat(v,(SQFloat)M_PI); - sq_newslot(v,-3,SQFalse); - return SQ_OK; -} +/* see copyright notice in squirrel.h */ +#include +#include +#include +#include + +#define SINGLE_ARG_FUNC(_funcname) static SQInteger math_##_funcname(HSQUIRRELVM v){ \ + SQFloat f; \ + sq_getfloat(v,2,&f); \ + sq_pushfloat(v,(SQFloat)_funcname(f)); \ + return 1; \ +} + +#define TWO_ARGS_FUNC(_funcname) static SQInteger math_##_funcname(HSQUIRRELVM v){ \ + SQFloat p1,p2; \ + sq_getfloat(v,2,&p1); \ + sq_getfloat(v,3,&p2); \ + sq_pushfloat(v,(SQFloat)_funcname(p1,p2)); \ + return 1; \ +} + +static SQInteger math_srand(HSQUIRRELVM v) +{ + SQInteger i; + if(SQ_FAILED(sq_getinteger(v,2,&i))) + return sq_throwerror(v,_SC("invalid param")); + srand((unsigned int)i); + return 0; +} + +static SQInteger math_rand(HSQUIRRELVM v) +{ + sq_pushinteger(v,rand()); + return 1; +} + +static SQInteger math_abs(HSQUIRRELVM v) +{ + SQInteger n; + sq_getinteger(v,2,&n); + sq_pushinteger(v,(SQInteger)abs((int)n)); + return 1; +} + +SINGLE_ARG_FUNC(sqrt) +SINGLE_ARG_FUNC(fabs) +SINGLE_ARG_FUNC(sin) +SINGLE_ARG_FUNC(cos) +SINGLE_ARG_FUNC(asin) +SINGLE_ARG_FUNC(acos) +SINGLE_ARG_FUNC(log) +SINGLE_ARG_FUNC(log10) +SINGLE_ARG_FUNC(tan) +SINGLE_ARG_FUNC(atan) +TWO_ARGS_FUNC(atan2) +TWO_ARGS_FUNC(pow) +SINGLE_ARG_FUNC(floor) +SINGLE_ARG_FUNC(ceil) +SINGLE_ARG_FUNC(exp) + +#define _DECL_FUNC(name,nparams,tycheck) {_SC(#name),math_##name,nparams,tycheck} +static SQRegFunction mathlib_funcs[] = { + _DECL_FUNC(sqrt,2,_SC(".n")), + _DECL_FUNC(sin,2,_SC(".n")), + _DECL_FUNC(cos,2,_SC(".n")), + _DECL_FUNC(asin,2,_SC(".n")), + _DECL_FUNC(acos,2,_SC(".n")), + _DECL_FUNC(log,2,_SC(".n")), + _DECL_FUNC(log10,2,_SC(".n")), + _DECL_FUNC(tan,2,_SC(".n")), + _DECL_FUNC(atan,2,_SC(".n")), + _DECL_FUNC(atan2,3,_SC(".nn")), + _DECL_FUNC(pow,3,_SC(".nn")), + _DECL_FUNC(floor,2,_SC(".n")), + _DECL_FUNC(ceil,2,_SC(".n")), + _DECL_FUNC(exp,2,_SC(".n")), + _DECL_FUNC(srand,2,_SC(".n")), + _DECL_FUNC(rand,1,NULL), + _DECL_FUNC(fabs,2,_SC(".n")), + _DECL_FUNC(abs,2,_SC(".n")), + {0,0}, +}; +#undef _DECL_FUNC + +#ifndef M_PI +#define M_PI (3.14159265358979323846) +#endif + +SQRESULT sqstd_register_mathlib(HSQUIRRELVM v) +{ + SQInteger i=0; + while(mathlib_funcs[i].name!=0) { + sq_pushstring(v,mathlib_funcs[i].name,-1); + sq_newclosure(v,mathlib_funcs[i].f,0); + sq_setparamscheck(v,mathlib_funcs[i].nparamscheck,mathlib_funcs[i].typemask); + sq_setnativeclosurename(v,-1,mathlib_funcs[i].name); + sq_newslot(v,-3,SQFalse); + i++; + } + sq_pushstring(v,_SC("RAND_MAX"),-1); + sq_pushinteger(v,RAND_MAX); + sq_newslot(v,-3,SQFalse); + sq_pushstring(v,_SC("PI"),-1); + sq_pushfloat(v,(SQFloat)M_PI); + sq_newslot(v,-3,SQFalse); + return SQ_OK; +} diff --git a/squirrel_3_0_1_stable/sqstdlib/sqstdrex.cpp b/squirrel_3_0_1_stable/sqstdlib/sqstdrex.cpp index 921597fed..a044d19dc 100644 --- a/squirrel_3_0_1_stable/sqstdlib/sqstdrex.cpp +++ b/squirrel_3_0_1_stable/sqstdlib/sqstdrex.cpp @@ -1,638 +1,638 @@ -/* see copyright notice in squirrel.h */ -#include -#include -#include -#include -#include - -#ifdef _UINCODE -#define scisprint iswprint -#else -#define scisprint isprint -#endif - -#ifdef _DEBUG -#include - -static const SQChar *g_nnames[] = -{ - _SC("NONE"),_SC("OP_GREEDY"), _SC("OP_OR"), - _SC("OP_EXPR"),_SC("OP_NOCAPEXPR"),_SC("OP_DOT"), _SC("OP_CLASS"), - _SC("OP_CCLASS"),_SC("OP_NCLASS"),_SC("OP_RANGE"),_SC("OP_CHAR"), - _SC("OP_EOL"),_SC("OP_BOL"),_SC("OP_WB") -}; - -#endif - -#define OP_GREEDY (MAX_CHAR+1) // * + ? {n} -#define OP_OR (MAX_CHAR+2) -#define OP_EXPR (MAX_CHAR+3) //parentesis () -#define OP_NOCAPEXPR (MAX_CHAR+4) //parentesis (?:) -#define OP_DOT (MAX_CHAR+5) -#define OP_CLASS (MAX_CHAR+6) -#define OP_CCLASS (MAX_CHAR+7) -#define OP_NCLASS (MAX_CHAR+8) //negates class the [^ -#define OP_RANGE (MAX_CHAR+9) -#define OP_CHAR (MAX_CHAR+10) -#define OP_EOL (MAX_CHAR+11) -#define OP_BOL (MAX_CHAR+12) -#define OP_WB (MAX_CHAR+13) - -#define SQREX_SYMBOL_ANY_CHAR ('.') -#define SQREX_SYMBOL_GREEDY_ONE_OR_MORE ('+') -#define SQREX_SYMBOL_GREEDY_ZERO_OR_MORE ('*') -#define SQREX_SYMBOL_GREEDY_ZERO_OR_ONE ('?') -#define SQREX_SYMBOL_BRANCH ('|') -#define SQREX_SYMBOL_END_OF_STRING ('$') -#define SQREX_SYMBOL_BEGINNING_OF_STRING ('^') -#define SQREX_SYMBOL_ESCAPE_CHAR ('\\') - - -typedef int SQRexNodeType; - -typedef struct tagSQRexNode{ - SQRexNodeType type; - SQInteger left; - SQInteger right; - SQInteger next; -}SQRexNode; - -struct SQRex{ - const SQChar *_eol; - const SQChar *_bol; - const SQChar *_p; - SQInteger _first; - SQInteger _op; - SQRexNode *_nodes; - SQInteger _nallocated; - SQInteger _nsize; - SQInteger _nsubexpr; - SQRexMatch *_matches; - SQInteger _currsubexp; - void *_jmpbuf; - const SQChar **_error; -}; - -static SQInteger sqstd_rex_list(SQRex *exp); - -static SQInteger sqstd_rex_newnode(SQRex *exp, SQRexNodeType type) -{ - SQRexNode n; - n.type = type; - n.next = n.right = n.left = -1; - if(type == OP_EXPR) - n.right = exp->_nsubexpr++; - if(exp->_nallocated < (exp->_nsize + 1)) { - SQInteger oldsize = exp->_nallocated; - exp->_nallocated *= 2; - exp->_nodes = (SQRexNode *)sq_realloc(exp->_nodes, oldsize * sizeof(SQRexNode) ,exp->_nallocated * sizeof(SQRexNode)); - } - exp->_nodes[exp->_nsize++] = n; - SQInteger newid = exp->_nsize - 1; - return (SQInteger)newid; -} - -static void sqstd_rex_error(SQRex *exp,const SQChar *error) -{ - if(exp->_error) *exp->_error = error; - longjmp(*((jmp_buf*)exp->_jmpbuf),-1); -} - -static void sqstd_rex_expect(SQRex *exp, SQInteger n){ - if((*exp->_p) != n) - sqstd_rex_error(exp, _SC("expected paren")); - exp->_p++; -} - -static SQChar sqstd_rex_escapechar(SQRex *exp) -{ - if(*exp->_p == SQREX_SYMBOL_ESCAPE_CHAR){ - exp->_p++; - switch(*exp->_p) { - case 'v': exp->_p++; return '\v'; - case 'n': exp->_p++; return '\n'; - case 't': exp->_p++; return '\t'; - case 'r': exp->_p++; return '\r'; - case 'f': exp->_p++; return '\f'; - default: return (*exp->_p++); - } - } else if(!scisprint(*exp->_p)) sqstd_rex_error(exp,_SC("letter expected")); - return (*exp->_p++); -} - -static SQInteger sqstd_rex_charclass(SQRex *exp,SQInteger classid) -{ - SQInteger n = sqstd_rex_newnode(exp,OP_CCLASS); - exp->_nodes[n].left = classid; - return n; -} - -static SQInteger sqstd_rex_charnode(SQRex *exp,SQBool isclass) -{ - SQChar t; - if(*exp->_p == SQREX_SYMBOL_ESCAPE_CHAR) { - exp->_p++; - switch(*exp->_p) { - case 'n': exp->_p++; return sqstd_rex_newnode(exp,'\n'); - case 't': exp->_p++; return sqstd_rex_newnode(exp,'\t'); - case 'r': exp->_p++; return sqstd_rex_newnode(exp,'\r'); - case 'f': exp->_p++; return sqstd_rex_newnode(exp,'\f'); - case 'v': exp->_p++; return sqstd_rex_newnode(exp,'\v'); - case 'a': case 'A': case 'w': case 'W': case 's': case 'S': - case 'd': case 'D': case 'x': case 'X': case 'c': case 'C': - case 'p': case 'P': case 'l': case 'u': - { - t = *exp->_p; exp->_p++; - return sqstd_rex_charclass(exp,t); - } - case 'b': - case 'B': - if(!isclass) { - SQInteger node = sqstd_rex_newnode(exp,OP_WB); - exp->_nodes[node].left = *exp->_p; - exp->_p++; - return node; - } //else default - default: - t = *exp->_p; exp->_p++; - return sqstd_rex_newnode(exp,t); - } - } - else if(!scisprint(*exp->_p)) { - - sqstd_rex_error(exp,_SC("letter expected")); - } - t = *exp->_p; exp->_p++; - return sqstd_rex_newnode(exp,t); -} -static SQInteger sqstd_rex_class(SQRex *exp) -{ - SQInteger ret = -1; - SQInteger first = -1,chain; - if(*exp->_p == SQREX_SYMBOL_BEGINNING_OF_STRING){ - ret = sqstd_rex_newnode(exp,OP_NCLASS); - exp->_p++; - }else ret = sqstd_rex_newnode(exp,OP_CLASS); - - if(*exp->_p == ']') sqstd_rex_error(exp,_SC("empty class")); - chain = ret; - while(*exp->_p != ']' && exp->_p != exp->_eol) { - if(*exp->_p == '-' && first != -1){ - SQInteger r; - if(*exp->_p++ == ']') sqstd_rex_error(exp,_SC("unfinished range")); - r = sqstd_rex_newnode(exp,OP_RANGE); - if(exp->_nodes[first].type>*exp->_p) sqstd_rex_error(exp,_SC("invalid range")); - if(exp->_nodes[first].type == OP_CCLASS) sqstd_rex_error(exp,_SC("cannot use character classes in ranges")); - exp->_nodes[r].left = exp->_nodes[first].type; - SQInteger t = sqstd_rex_escapechar(exp); - exp->_nodes[r].right = t; - exp->_nodes[chain].next = r; - chain = r; - first = -1; - } - else{ - if(first!=-1){ - SQInteger c = first; - exp->_nodes[chain].next = c; - chain = c; - first = sqstd_rex_charnode(exp,SQTrue); - } - else{ - first = sqstd_rex_charnode(exp,SQTrue); - } - } - } - if(first!=-1){ - SQInteger c = first; - exp->_nodes[chain].next = c; - chain = c; - first = -1; - } - /* hack? */ - exp->_nodes[ret].left = exp->_nodes[ret].next; - exp->_nodes[ret].next = -1; - return ret; -} - -static SQInteger sqstd_rex_parsenumber(SQRex *exp) -{ - SQInteger ret = *exp->_p-'0'; - SQInteger positions = 10; - exp->_p++; - while(isdigit(*exp->_p)) { - ret = ret*10+(*exp->_p++-'0'); - if(positions==1000000000) sqstd_rex_error(exp,_SC("overflow in numeric constant")); - positions *= 10; - }; - return ret; -} - -static SQInteger sqstd_rex_element(SQRex *exp) -{ - SQInteger ret = -1; - switch(*exp->_p) - { - case '(': { - SQInteger expr; - exp->_p++; - - - if(*exp->_p =='?') { - exp->_p++; - sqstd_rex_expect(exp,':'); - expr = sqstd_rex_newnode(exp,OP_NOCAPEXPR); - } - else - expr = sqstd_rex_newnode(exp,OP_EXPR); - SQInteger newn = sqstd_rex_list(exp); - exp->_nodes[expr].left = newn; - ret = expr; - sqstd_rex_expect(exp,')'); - } - break; - case '[': - exp->_p++; - ret = sqstd_rex_class(exp); - sqstd_rex_expect(exp,']'); - break; - case SQREX_SYMBOL_END_OF_STRING: exp->_p++; ret = sqstd_rex_newnode(exp,OP_EOL);break; - case SQREX_SYMBOL_ANY_CHAR: exp->_p++; ret = sqstd_rex_newnode(exp,OP_DOT);break; - default: - ret = sqstd_rex_charnode(exp,SQFalse); - break; - } - - - SQInteger op; - SQBool isgreedy = SQFalse; - unsigned short p0 = 0, p1 = 0; - switch(*exp->_p){ - case SQREX_SYMBOL_GREEDY_ZERO_OR_MORE: p0 = 0; p1 = 0xFFFF; exp->_p++; isgreedy = SQTrue; break; - case SQREX_SYMBOL_GREEDY_ONE_OR_MORE: p0 = 1; p1 = 0xFFFF; exp->_p++; isgreedy = SQTrue; break; - case SQREX_SYMBOL_GREEDY_ZERO_OR_ONE: p0 = 0; p1 = 1; exp->_p++; isgreedy = SQTrue; break; - case '{': - exp->_p++; - if(!isdigit(*exp->_p)) sqstd_rex_error(exp,_SC("number expected")); - p0 = (unsigned short)sqstd_rex_parsenumber(exp); - /*******************************/ - switch(*exp->_p) { - case '}': - p1 = p0; exp->_p++; - break; - case ',': - exp->_p++; - p1 = 0xFFFF; - if(isdigit(*exp->_p)){ - p1 = (unsigned short)sqstd_rex_parsenumber(exp); - } - sqstd_rex_expect(exp,'}'); - break; - default: - sqstd_rex_error(exp,_SC(", or } expected")); - } - /*******************************/ - isgreedy = SQTrue; - break; - - } - if(isgreedy) { - SQInteger nnode = sqstd_rex_newnode(exp,OP_GREEDY); - op = OP_GREEDY; - exp->_nodes[nnode].left = ret; - exp->_nodes[nnode].right = ((p0)<<16)|p1; - ret = nnode; - } - - if((*exp->_p != SQREX_SYMBOL_BRANCH) && (*exp->_p != ')') && (*exp->_p != SQREX_SYMBOL_GREEDY_ZERO_OR_MORE) && (*exp->_p != SQREX_SYMBOL_GREEDY_ONE_OR_MORE) && (*exp->_p != '\0')) { - SQInteger nnode = sqstd_rex_element(exp); - exp->_nodes[ret].next = nnode; - } - - return ret; -} - -static SQInteger sqstd_rex_list(SQRex *exp) -{ - SQInteger ret=-1,e; - if(*exp->_p == SQREX_SYMBOL_BEGINNING_OF_STRING) { - exp->_p++; - ret = sqstd_rex_newnode(exp,OP_BOL); - } - e = sqstd_rex_element(exp); - if(ret != -1) { - exp->_nodes[ret].next = e; - } - else ret = e; - - if(*exp->_p == SQREX_SYMBOL_BRANCH) { - SQInteger temp,tright; - exp->_p++; - temp = sqstd_rex_newnode(exp,OP_OR); - exp->_nodes[temp].left = ret; - tright = sqstd_rex_list(exp); - exp->_nodes[temp].right = tright; - ret = temp; - } - return ret; -} - -static SQBool sqstd_rex_matchcclass(SQInteger cclass,SQChar c) -{ - switch(cclass) { - case 'a': return isalpha(c)?SQTrue:SQFalse; - case 'A': return !isalpha(c)?SQTrue:SQFalse; - case 'w': return (isalnum(c) || c == '_')?SQTrue:SQFalse; - case 'W': return (!isalnum(c) && c != '_')?SQTrue:SQFalse; - case 's': return isspace(c)?SQTrue:SQFalse; - case 'S': return !isspace(c)?SQTrue:SQFalse; - case 'd': return isdigit(c)?SQTrue:SQFalse; - case 'D': return !isdigit(c)?SQTrue:SQFalse; - case 'x': return isxdigit(c)?SQTrue:SQFalse; - case 'X': return !isxdigit(c)?SQTrue:SQFalse; - case 'c': return iscntrl(c)?SQTrue:SQFalse; - case 'C': return !iscntrl(c)?SQTrue:SQFalse; - case 'p': return ispunct(c)?SQTrue:SQFalse; - case 'P': return !ispunct(c)?SQTrue:SQFalse; - case 'l': return islower(c)?SQTrue:SQFalse; - case 'u': return isupper(c)?SQTrue:SQFalse; - } - return SQFalse; /*cannot happen*/ -} - -static SQBool sqstd_rex_matchclass(SQRex* exp,SQRexNode *node,SQChar c) -{ - do { - switch(node->type) { - case OP_RANGE: - if(c >= node->left && c <= node->right) return SQTrue; - break; - case OP_CCLASS: - if(sqstd_rex_matchcclass(node->left,c)) return SQTrue; - break; - default: - if(c == node->type)return SQTrue; - } - } while((node->next != -1) && (node = &exp->_nodes[node->next])); - return SQFalse; -} - -static const SQChar *sqstd_rex_matchnode(SQRex* exp,SQRexNode *node,const SQChar *str,SQRexNode *next) -{ - - SQRexNodeType type = node->type; - switch(type) { - case OP_GREEDY: { - //SQRexNode *greedystop = (node->next != -1) ? &exp->_nodes[node->next] : NULL; - SQRexNode *greedystop = NULL; - SQInteger p0 = (node->right >> 16)&0x0000FFFF, p1 = node->right&0x0000FFFF, nmaches = 0; - const SQChar *s=str, *good = str; - - if(node->next != -1) { - greedystop = &exp->_nodes[node->next]; - } - else { - greedystop = next; - } - - while((nmaches == 0xFFFF || nmaches < p1)) { - - const SQChar *stop; - if(!(s = sqstd_rex_matchnode(exp,&exp->_nodes[node->left],s,greedystop))) - break; - nmaches++; - good=s; - if(greedystop) { - //checks that 0 matches satisfy the expression(if so skips) - //if not would always stop(for instance if is a '?') - if(greedystop->type != OP_GREEDY || - (greedystop->type == OP_GREEDY && ((greedystop->right >> 16)&0x0000FFFF) != 0)) - { - SQRexNode *gnext = NULL; - if(greedystop->next != -1) { - gnext = &exp->_nodes[greedystop->next]; - }else if(next && next->next != -1){ - gnext = &exp->_nodes[next->next]; - } - stop = sqstd_rex_matchnode(exp,greedystop,s,gnext); - if(stop) { - //if satisfied stop it - if(p0 == p1 && p0 == nmaches) break; - else if(nmaches >= p0 && p1 == 0xFFFF) break; - else if(nmaches >= p0 && nmaches <= p1) break; - } - } - } - - if(s >= exp->_eol) - break; - } - if(p0 == p1 && p0 == nmaches) return good; - else if(nmaches >= p0 && p1 == 0xFFFF) return good; - else if(nmaches >= p0 && nmaches <= p1) return good; - return NULL; - } - case OP_OR: { - const SQChar *asd = str; - SQRexNode *temp=&exp->_nodes[node->left]; - while( (asd = sqstd_rex_matchnode(exp,temp,asd,NULL)) ) { - if(temp->next != -1) - temp = &exp->_nodes[temp->next]; - else - return asd; - } - asd = str; - temp = &exp->_nodes[node->right]; - while( (asd = sqstd_rex_matchnode(exp,temp,asd,NULL)) ) { - if(temp->next != -1) - temp = &exp->_nodes[temp->next]; - else - return asd; - } - return NULL; - break; - } - case OP_EXPR: - case OP_NOCAPEXPR:{ - SQRexNode *n = &exp->_nodes[node->left]; - const SQChar *cur = str; - SQInteger capture = -1; - if(node->type != OP_NOCAPEXPR && node->right == exp->_currsubexp) { - capture = exp->_currsubexp; - exp->_matches[capture].begin = cur; - exp->_currsubexp++; - } - int tempcap = exp->_currsubexp; - do { - SQRexNode *subnext = NULL; - if(n->next != -1) { - subnext = &exp->_nodes[n->next]; - }else { - subnext = next; - } - if(!(cur = sqstd_rex_matchnode(exp,n,cur,subnext))) { - if(capture != -1){ - exp->_matches[capture].begin = 0; - exp->_matches[capture].len = 0; - } - return NULL; - } - } while((n->next != -1) && (n = &exp->_nodes[n->next])); - - exp->_currsubexp = tempcap; - if(capture != -1) - exp->_matches[capture].len = cur - exp->_matches[capture].begin; - return cur; - } - case OP_WB: - if((str == exp->_bol && !isspace(*str)) - || (str == exp->_eol && !isspace(*(str-1))) - || (!isspace(*str) && isspace(*(str+1))) - || (isspace(*str) && !isspace(*(str+1))) ) { - return (node->left == 'b')?str:NULL; - } - return (node->left == 'b')?NULL:str; - case OP_BOL: - if(str == exp->_bol) return str; - return NULL; - case OP_EOL: - if(str == exp->_eol) return str; - return NULL; - case OP_DOT:{ - *str++; - } - return str; - case OP_NCLASS: - case OP_CLASS: - if(sqstd_rex_matchclass(exp,&exp->_nodes[node->left],*str)?(type == OP_CLASS?SQTrue:SQFalse):(type == OP_NCLASS?SQTrue:SQFalse)) { - *str++; - return str; - } - return NULL; - case OP_CCLASS: - if(sqstd_rex_matchcclass(node->left,*str)) { - *str++; - return str; - } - return NULL; - default: /* char */ - if(*str != node->type) return NULL; - *str++; - return str; - } - return NULL; -} - -/* public api */ -SQRex *sqstd_rex_compile(const SQChar *pattern,const SQChar **error) -{ - SQRex *exp = (SQRex *)sq_malloc(sizeof(SQRex)); - exp->_eol = exp->_bol = NULL; - exp->_p = pattern; - exp->_nallocated = (SQInteger)scstrlen(pattern) * sizeof(SQChar); - exp->_nodes = (SQRexNode *)sq_malloc(exp->_nallocated * sizeof(SQRexNode)); - exp->_nsize = 0; - exp->_matches = 0; - exp->_nsubexpr = 0; - exp->_first = sqstd_rex_newnode(exp,OP_EXPR); - exp->_error = error; - exp->_jmpbuf = sq_malloc(sizeof(jmp_buf)); - if(setjmp(*((jmp_buf*)exp->_jmpbuf)) == 0) { - SQInteger res = sqstd_rex_list(exp); - exp->_nodes[exp->_first].left = res; - if(*exp->_p!='\0') - sqstd_rex_error(exp,_SC("unexpected character")); -#ifdef _DEBUG - { - SQInteger nsize,i; - SQRexNode *t; - nsize = exp->_nsize; - t = &exp->_nodes[0]; - scprintf(_SC("\n")); - for(i = 0;i < nsize; i++) { - if(exp->_nodes[i].type>MAX_CHAR) - scprintf(_SC("[%02d] %10s "),i,g_nnames[exp->_nodes[i].type-MAX_CHAR]); - else - scprintf(_SC("[%02d] %10c "),i,exp->_nodes[i].type); - scprintf(_SC("left %02d right %02d next %02d\n"),exp->_nodes[i].left,exp->_nodes[i].right,exp->_nodes[i].next); - } - scprintf(_SC("\n")); - } -#endif - exp->_matches = (SQRexMatch *) sq_malloc(exp->_nsubexpr * sizeof(SQRexMatch)); - memset(exp->_matches,0,exp->_nsubexpr * sizeof(SQRexMatch)); - } - else{ - sqstd_rex_free(exp); - return NULL; - } - return exp; -} - -void sqstd_rex_free(SQRex *exp) -{ - if(exp) { - if(exp->_nodes) sq_free(exp->_nodes,exp->_nallocated * sizeof(SQRexNode)); - if(exp->_jmpbuf) sq_free(exp->_jmpbuf,sizeof(jmp_buf)); - if(exp->_matches) sq_free(exp->_matches,exp->_nsubexpr * sizeof(SQRexMatch)); - sq_free(exp,sizeof(SQRex)); - } -} - -SQBool sqstd_rex_match(SQRex* exp,const SQChar* text) -{ - const SQChar* res = NULL; - exp->_bol = text; - exp->_eol = text + scstrlen(text); - exp->_currsubexp = 0; - res = sqstd_rex_matchnode(exp,exp->_nodes,text,NULL); - if(res == NULL || res != exp->_eol) - return SQFalse; - return SQTrue; -} - -SQBool sqstd_rex_searchrange(SQRex* exp,const SQChar* text_begin,const SQChar* text_end,const SQChar** out_begin, const SQChar** out_end) -{ - const SQChar *cur = NULL; - SQInteger node = exp->_first; - if(text_begin >= text_end) return SQFalse; - exp->_bol = text_begin; - exp->_eol = text_end; - do { - cur = text_begin; - while(node != -1) { - exp->_currsubexp = 0; - cur = sqstd_rex_matchnode(exp,&exp->_nodes[node],cur,NULL); - if(!cur) - break; - node = exp->_nodes[node].next; - } - *text_begin++; - } while(cur == NULL && text_begin != text_end); - - if(cur == NULL) - return SQFalse; - - --text_begin; - - if(out_begin) *out_begin = text_begin; - if(out_end) *out_end = cur; - return SQTrue; -} - -SQBool sqstd_rex_search(SQRex* exp,const SQChar* text, const SQChar** out_begin, const SQChar** out_end) -{ - return sqstd_rex_searchrange(exp,text,text + scstrlen(text),out_begin,out_end); -} - -SQInteger sqstd_rex_getsubexpcount(SQRex* exp) -{ - return exp->_nsubexpr; -} - -SQBool sqstd_rex_getsubexp(SQRex* exp, SQInteger n, SQRexMatch *subexp) -{ - if( n<0 || n >= exp->_nsubexpr) return SQFalse; - *subexp = exp->_matches[n]; - return SQTrue; -} - +/* see copyright notice in squirrel.h */ +#include +#include +#include +#include +#include + +#ifdef _UINCODE +#define scisprint iswprint +#else +#define scisprint isprint +#endif + +#ifdef _DEBUG +#include + +static const SQChar *g_nnames[] = +{ + _SC("NONE"),_SC("OP_GREEDY"), _SC("OP_OR"), + _SC("OP_EXPR"),_SC("OP_NOCAPEXPR"),_SC("OP_DOT"), _SC("OP_CLASS"), + _SC("OP_CCLASS"),_SC("OP_NCLASS"),_SC("OP_RANGE"),_SC("OP_CHAR"), + _SC("OP_EOL"),_SC("OP_BOL"),_SC("OP_WB") +}; + +#endif + +#define OP_GREEDY (MAX_CHAR+1) // * + ? {n} +#define OP_OR (MAX_CHAR+2) +#define OP_EXPR (MAX_CHAR+3) //parentesis () +#define OP_NOCAPEXPR (MAX_CHAR+4) //parentesis (?:) +#define OP_DOT (MAX_CHAR+5) +#define OP_CLASS (MAX_CHAR+6) +#define OP_CCLASS (MAX_CHAR+7) +#define OP_NCLASS (MAX_CHAR+8) //negates class the [^ +#define OP_RANGE (MAX_CHAR+9) +#define OP_CHAR (MAX_CHAR+10) +#define OP_EOL (MAX_CHAR+11) +#define OP_BOL (MAX_CHAR+12) +#define OP_WB (MAX_CHAR+13) + +#define SQREX_SYMBOL_ANY_CHAR ('.') +#define SQREX_SYMBOL_GREEDY_ONE_OR_MORE ('+') +#define SQREX_SYMBOL_GREEDY_ZERO_OR_MORE ('*') +#define SQREX_SYMBOL_GREEDY_ZERO_OR_ONE ('?') +#define SQREX_SYMBOL_BRANCH ('|') +#define SQREX_SYMBOL_END_OF_STRING ('$') +#define SQREX_SYMBOL_BEGINNING_OF_STRING ('^') +#define SQREX_SYMBOL_ESCAPE_CHAR ('\\') + + +typedef int SQRexNodeType; + +typedef struct tagSQRexNode{ + SQRexNodeType type; + SQInteger left; + SQInteger right; + SQInteger next; +}SQRexNode; + +struct SQRex{ + const SQChar *_eol; + const SQChar *_bol; + const SQChar *_p; + SQInteger _first; + SQInteger _op; + SQRexNode *_nodes; + SQInteger _nallocated; + SQInteger _nsize; + SQInteger _nsubexpr; + SQRexMatch *_matches; + SQInteger _currsubexp; + void *_jmpbuf; + const SQChar **_error; +}; + +static SQInteger sqstd_rex_list(SQRex *exp); + +static SQInteger sqstd_rex_newnode(SQRex *exp, SQRexNodeType type) +{ + SQRexNode n; + n.type = type; + n.next = n.right = n.left = -1; + if(type == OP_EXPR) + n.right = exp->_nsubexpr++; + if(exp->_nallocated < (exp->_nsize + 1)) { + SQInteger oldsize = exp->_nallocated; + exp->_nallocated *= 2; + exp->_nodes = (SQRexNode *)sq_realloc(exp->_nodes, oldsize * sizeof(SQRexNode) ,exp->_nallocated * sizeof(SQRexNode)); + } + exp->_nodes[exp->_nsize++] = n; + SQInteger newid = exp->_nsize - 1; + return (SQInteger)newid; +} + +static void sqstd_rex_error(SQRex *exp,const SQChar *error) +{ + if(exp->_error) *exp->_error = error; + longjmp(*((jmp_buf*)exp->_jmpbuf),-1); +} + +static void sqstd_rex_expect(SQRex *exp, SQInteger n){ + if((*exp->_p) != n) + sqstd_rex_error(exp, _SC("expected paren")); + exp->_p++; +} + +static SQChar sqstd_rex_escapechar(SQRex *exp) +{ + if(*exp->_p == SQREX_SYMBOL_ESCAPE_CHAR){ + exp->_p++; + switch(*exp->_p) { + case 'v': exp->_p++; return '\v'; + case 'n': exp->_p++; return '\n'; + case 't': exp->_p++; return '\t'; + case 'r': exp->_p++; return '\r'; + case 'f': exp->_p++; return '\f'; + default: return (*exp->_p++); + } + } else if(!scisprint(*exp->_p)) sqstd_rex_error(exp,_SC("letter expected")); + return (*exp->_p++); +} + +static SQInteger sqstd_rex_charclass(SQRex *exp,SQInteger classid) +{ + SQInteger n = sqstd_rex_newnode(exp,OP_CCLASS); + exp->_nodes[n].left = classid; + return n; +} + +static SQInteger sqstd_rex_charnode(SQRex *exp,SQBool isclass) +{ + SQChar t; + if(*exp->_p == SQREX_SYMBOL_ESCAPE_CHAR) { + exp->_p++; + switch(*exp->_p) { + case 'n': exp->_p++; return sqstd_rex_newnode(exp,'\n'); + case 't': exp->_p++; return sqstd_rex_newnode(exp,'\t'); + case 'r': exp->_p++; return sqstd_rex_newnode(exp,'\r'); + case 'f': exp->_p++; return sqstd_rex_newnode(exp,'\f'); + case 'v': exp->_p++; return sqstd_rex_newnode(exp,'\v'); + case 'a': case 'A': case 'w': case 'W': case 's': case 'S': + case 'd': case 'D': case 'x': case 'X': case 'c': case 'C': + case 'p': case 'P': case 'l': case 'u': + { + t = *exp->_p; exp->_p++; + return sqstd_rex_charclass(exp,t); + } + case 'b': + case 'B': + if(!isclass) { + SQInteger node = sqstd_rex_newnode(exp,OP_WB); + exp->_nodes[node].left = *exp->_p; + exp->_p++; + return node; + } //else default + default: + t = *exp->_p; exp->_p++; + return sqstd_rex_newnode(exp,t); + } + } + else if(!scisprint(*exp->_p)) { + + sqstd_rex_error(exp,_SC("letter expected")); + } + t = *exp->_p; exp->_p++; + return sqstd_rex_newnode(exp,t); +} +static SQInteger sqstd_rex_class(SQRex *exp) +{ + SQInteger ret = -1; + SQInteger first = -1,chain; + if(*exp->_p == SQREX_SYMBOL_BEGINNING_OF_STRING){ + ret = sqstd_rex_newnode(exp,OP_NCLASS); + exp->_p++; + }else ret = sqstd_rex_newnode(exp,OP_CLASS); + + if(*exp->_p == ']') sqstd_rex_error(exp,_SC("empty class")); + chain = ret; + while(*exp->_p != ']' && exp->_p != exp->_eol) { + if(*exp->_p == '-' && first != -1){ + SQInteger r; + if(*exp->_p++ == ']') sqstd_rex_error(exp,_SC("unfinished range")); + r = sqstd_rex_newnode(exp,OP_RANGE); + if(exp->_nodes[first].type>*exp->_p) sqstd_rex_error(exp,_SC("invalid range")); + if(exp->_nodes[first].type == OP_CCLASS) sqstd_rex_error(exp,_SC("cannot use character classes in ranges")); + exp->_nodes[r].left = exp->_nodes[first].type; + SQInteger t = sqstd_rex_escapechar(exp); + exp->_nodes[r].right = t; + exp->_nodes[chain].next = r; + chain = r; + first = -1; + } + else{ + if(first!=-1){ + SQInteger c = first; + exp->_nodes[chain].next = c; + chain = c; + first = sqstd_rex_charnode(exp,SQTrue); + } + else{ + first = sqstd_rex_charnode(exp,SQTrue); + } + } + } + if(first!=-1){ + SQInteger c = first; + exp->_nodes[chain].next = c; + chain = c; + first = -1; + } + /* hack? */ + exp->_nodes[ret].left = exp->_nodes[ret].next; + exp->_nodes[ret].next = -1; + return ret; +} + +static SQInteger sqstd_rex_parsenumber(SQRex *exp) +{ + SQInteger ret = *exp->_p-'0'; + SQInteger positions = 10; + exp->_p++; + while(isdigit(*exp->_p)) { + ret = ret*10+(*exp->_p++-'0'); + if(positions==1000000000) sqstd_rex_error(exp,_SC("overflow in numeric constant")); + positions *= 10; + }; + return ret; +} + +static SQInteger sqstd_rex_element(SQRex *exp) +{ + SQInteger ret = -1; + switch(*exp->_p) + { + case '(': { + SQInteger expr; + exp->_p++; + + + if(*exp->_p =='?') { + exp->_p++; + sqstd_rex_expect(exp,':'); + expr = sqstd_rex_newnode(exp,OP_NOCAPEXPR); + } + else + expr = sqstd_rex_newnode(exp,OP_EXPR); + SQInteger newn = sqstd_rex_list(exp); + exp->_nodes[expr].left = newn; + ret = expr; + sqstd_rex_expect(exp,')'); + } + break; + case '[': + exp->_p++; + ret = sqstd_rex_class(exp); + sqstd_rex_expect(exp,']'); + break; + case SQREX_SYMBOL_END_OF_STRING: exp->_p++; ret = sqstd_rex_newnode(exp,OP_EOL);break; + case SQREX_SYMBOL_ANY_CHAR: exp->_p++; ret = sqstd_rex_newnode(exp,OP_DOT);break; + default: + ret = sqstd_rex_charnode(exp,SQFalse); + break; + } + + + SQInteger op; + SQBool isgreedy = SQFalse; + unsigned short p0 = 0, p1 = 0; + switch(*exp->_p){ + case SQREX_SYMBOL_GREEDY_ZERO_OR_MORE: p0 = 0; p1 = 0xFFFF; exp->_p++; isgreedy = SQTrue; break; + case SQREX_SYMBOL_GREEDY_ONE_OR_MORE: p0 = 1; p1 = 0xFFFF; exp->_p++; isgreedy = SQTrue; break; + case SQREX_SYMBOL_GREEDY_ZERO_OR_ONE: p0 = 0; p1 = 1; exp->_p++; isgreedy = SQTrue; break; + case '{': + exp->_p++; + if(!isdigit(*exp->_p)) sqstd_rex_error(exp,_SC("number expected")); + p0 = (unsigned short)sqstd_rex_parsenumber(exp); + /*******************************/ + switch(*exp->_p) { + case '}': + p1 = p0; exp->_p++; + break; + case ',': + exp->_p++; + p1 = 0xFFFF; + if(isdigit(*exp->_p)){ + p1 = (unsigned short)sqstd_rex_parsenumber(exp); + } + sqstd_rex_expect(exp,'}'); + break; + default: + sqstd_rex_error(exp,_SC(", or } expected")); + } + /*******************************/ + isgreedy = SQTrue; + break; + + } + if(isgreedy) { + SQInteger nnode = sqstd_rex_newnode(exp,OP_GREEDY); + op = OP_GREEDY; + exp->_nodes[nnode].left = ret; + exp->_nodes[nnode].right = ((p0)<<16)|p1; + ret = nnode; + } + + if((*exp->_p != SQREX_SYMBOL_BRANCH) && (*exp->_p != ')') && (*exp->_p != SQREX_SYMBOL_GREEDY_ZERO_OR_MORE) && (*exp->_p != SQREX_SYMBOL_GREEDY_ONE_OR_MORE) && (*exp->_p != '\0')) { + SQInteger nnode = sqstd_rex_element(exp); + exp->_nodes[ret].next = nnode; + } + + return ret; +} + +static SQInteger sqstd_rex_list(SQRex *exp) +{ + SQInteger ret=-1,e; + if(*exp->_p == SQREX_SYMBOL_BEGINNING_OF_STRING) { + exp->_p++; + ret = sqstd_rex_newnode(exp,OP_BOL); + } + e = sqstd_rex_element(exp); + if(ret != -1) { + exp->_nodes[ret].next = e; + } + else ret = e; + + if(*exp->_p == SQREX_SYMBOL_BRANCH) { + SQInteger temp,tright; + exp->_p++; + temp = sqstd_rex_newnode(exp,OP_OR); + exp->_nodes[temp].left = ret; + tright = sqstd_rex_list(exp); + exp->_nodes[temp].right = tright; + ret = temp; + } + return ret; +} + +static SQBool sqstd_rex_matchcclass(SQInteger cclass,SQChar c) +{ + switch(cclass) { + case 'a': return isalpha(c)?SQTrue:SQFalse; + case 'A': return !isalpha(c)?SQTrue:SQFalse; + case 'w': return (isalnum(c) || c == '_')?SQTrue:SQFalse; + case 'W': return (!isalnum(c) && c != '_')?SQTrue:SQFalse; + case 's': return isspace(c)?SQTrue:SQFalse; + case 'S': return !isspace(c)?SQTrue:SQFalse; + case 'd': return isdigit(c)?SQTrue:SQFalse; + case 'D': return !isdigit(c)?SQTrue:SQFalse; + case 'x': return isxdigit(c)?SQTrue:SQFalse; + case 'X': return !isxdigit(c)?SQTrue:SQFalse; + case 'c': return iscntrl(c)?SQTrue:SQFalse; + case 'C': return !iscntrl(c)?SQTrue:SQFalse; + case 'p': return ispunct(c)?SQTrue:SQFalse; + case 'P': return !ispunct(c)?SQTrue:SQFalse; + case 'l': return islower(c)?SQTrue:SQFalse; + case 'u': return isupper(c)?SQTrue:SQFalse; + } + return SQFalse; /*cannot happen*/ +} + +static SQBool sqstd_rex_matchclass(SQRex* exp,SQRexNode *node,SQChar c) +{ + do { + switch(node->type) { + case OP_RANGE: + if(c >= node->left && c <= node->right) return SQTrue; + break; + case OP_CCLASS: + if(sqstd_rex_matchcclass(node->left,c)) return SQTrue; + break; + default: + if(c == node->type)return SQTrue; + } + } while((node->next != -1) && (node = &exp->_nodes[node->next])); + return SQFalse; +} + +static const SQChar *sqstd_rex_matchnode(SQRex* exp,SQRexNode *node,const SQChar *str,SQRexNode *next) +{ + + SQRexNodeType type = node->type; + switch(type) { + case OP_GREEDY: { + //SQRexNode *greedystop = (node->next != -1) ? &exp->_nodes[node->next] : NULL; + SQRexNode *greedystop = NULL; + SQInteger p0 = (node->right >> 16)&0x0000FFFF, p1 = node->right&0x0000FFFF, nmaches = 0; + const SQChar *s=str, *good = str; + + if(node->next != -1) { + greedystop = &exp->_nodes[node->next]; + } + else { + greedystop = next; + } + + while((nmaches == 0xFFFF || nmaches < p1)) { + + const SQChar *stop; + if(!(s = sqstd_rex_matchnode(exp,&exp->_nodes[node->left],s,greedystop))) + break; + nmaches++; + good=s; + if(greedystop) { + //checks that 0 matches satisfy the expression(if so skips) + //if not would always stop(for instance if is a '?') + if(greedystop->type != OP_GREEDY || + (greedystop->type == OP_GREEDY && ((greedystop->right >> 16)&0x0000FFFF) != 0)) + { + SQRexNode *gnext = NULL; + if(greedystop->next != -1) { + gnext = &exp->_nodes[greedystop->next]; + }else if(next && next->next != -1){ + gnext = &exp->_nodes[next->next]; + } + stop = sqstd_rex_matchnode(exp,greedystop,s,gnext); + if(stop) { + //if satisfied stop it + if(p0 == p1 && p0 == nmaches) break; + else if(nmaches >= p0 && p1 == 0xFFFF) break; + else if(nmaches >= p0 && nmaches <= p1) break; + } + } + } + + if(s >= exp->_eol) + break; + } + if(p0 == p1 && p0 == nmaches) return good; + else if(nmaches >= p0 && p1 == 0xFFFF) return good; + else if(nmaches >= p0 && nmaches <= p1) return good; + return NULL; + } + case OP_OR: { + const SQChar *asd = str; + SQRexNode *temp=&exp->_nodes[node->left]; + while( (asd = sqstd_rex_matchnode(exp,temp,asd,NULL)) ) { + if(temp->next != -1) + temp = &exp->_nodes[temp->next]; + else + return asd; + } + asd = str; + temp = &exp->_nodes[node->right]; + while( (asd = sqstd_rex_matchnode(exp,temp,asd,NULL)) ) { + if(temp->next != -1) + temp = &exp->_nodes[temp->next]; + else + return asd; + } + return NULL; + break; + } + case OP_EXPR: + case OP_NOCAPEXPR:{ + SQRexNode *n = &exp->_nodes[node->left]; + const SQChar *cur = str; + SQInteger capture = -1; + if(node->type != OP_NOCAPEXPR && node->right == exp->_currsubexp) { + capture = exp->_currsubexp; + exp->_matches[capture].begin = cur; + exp->_currsubexp++; + } + int tempcap = exp->_currsubexp; + do { + SQRexNode *subnext = NULL; + if(n->next != -1) { + subnext = &exp->_nodes[n->next]; + }else { + subnext = next; + } + if(!(cur = sqstd_rex_matchnode(exp,n,cur,subnext))) { + if(capture != -1){ + exp->_matches[capture].begin = 0; + exp->_matches[capture].len = 0; + } + return NULL; + } + } while((n->next != -1) && (n = &exp->_nodes[n->next])); + + exp->_currsubexp = tempcap; + if(capture != -1) + exp->_matches[capture].len = cur - exp->_matches[capture].begin; + return cur; + } + case OP_WB: + if((str == exp->_bol && !isspace(*str)) + || (str == exp->_eol && !isspace(*(str-1))) + || (!isspace(*str) && isspace(*(str+1))) + || (isspace(*str) && !isspace(*(str+1))) ) { + return (node->left == 'b')?str:NULL; + } + return (node->left == 'b')?NULL:str; + case OP_BOL: + if(str == exp->_bol) return str; + return NULL; + case OP_EOL: + if(str == exp->_eol) return str; + return NULL; + case OP_DOT:{ + *str++; + } + return str; + case OP_NCLASS: + case OP_CLASS: + if(sqstd_rex_matchclass(exp,&exp->_nodes[node->left],*str)?(type == OP_CLASS?SQTrue:SQFalse):(type == OP_NCLASS?SQTrue:SQFalse)) { + *str++; + return str; + } + return NULL; + case OP_CCLASS: + if(sqstd_rex_matchcclass(node->left,*str)) { + *str++; + return str; + } + return NULL; + default: /* char */ + if(*str != node->type) return NULL; + *str++; + return str; + } + return NULL; +} + +/* public api */ +SQRex *sqstd_rex_compile(const SQChar *pattern,const SQChar **error) +{ + SQRex *exp = (SQRex *)sq_malloc(sizeof(SQRex)); + exp->_eol = exp->_bol = NULL; + exp->_p = pattern; + exp->_nallocated = (SQInteger)scstrlen(pattern) * sizeof(SQChar); + exp->_nodes = (SQRexNode *)sq_malloc(exp->_nallocated * sizeof(SQRexNode)); + exp->_nsize = 0; + exp->_matches = 0; + exp->_nsubexpr = 0; + exp->_first = sqstd_rex_newnode(exp,OP_EXPR); + exp->_error = error; + exp->_jmpbuf = sq_malloc(sizeof(jmp_buf)); + if(setjmp(*((jmp_buf*)exp->_jmpbuf)) == 0) { + SQInteger res = sqstd_rex_list(exp); + exp->_nodes[exp->_first].left = res; + if(*exp->_p!='\0') + sqstd_rex_error(exp,_SC("unexpected character")); +#ifdef _DEBUG + { + SQInteger nsize,i; + SQRexNode *t; + nsize = exp->_nsize; + t = &exp->_nodes[0]; + scprintf(_SC("\n")); + for(i = 0;i < nsize; i++) { + if(exp->_nodes[i].type>MAX_CHAR) + scprintf(_SC("[%02d] %10s "),i,g_nnames[exp->_nodes[i].type-MAX_CHAR]); + else + scprintf(_SC("[%02d] %10c "),i,exp->_nodes[i].type); + scprintf(_SC("left %02d right %02d next %02d\n"),exp->_nodes[i].left,exp->_nodes[i].right,exp->_nodes[i].next); + } + scprintf(_SC("\n")); + } +#endif + exp->_matches = (SQRexMatch *) sq_malloc(exp->_nsubexpr * sizeof(SQRexMatch)); + memset(exp->_matches,0,exp->_nsubexpr * sizeof(SQRexMatch)); + } + else{ + sqstd_rex_free(exp); + return NULL; + } + return exp; +} + +void sqstd_rex_free(SQRex *exp) +{ + if(exp) { + if(exp->_nodes) sq_free(exp->_nodes,exp->_nallocated * sizeof(SQRexNode)); + if(exp->_jmpbuf) sq_free(exp->_jmpbuf,sizeof(jmp_buf)); + if(exp->_matches) sq_free(exp->_matches,exp->_nsubexpr * sizeof(SQRexMatch)); + sq_free(exp,sizeof(SQRex)); + } +} + +SQBool sqstd_rex_match(SQRex* exp,const SQChar* text) +{ + const SQChar* res = NULL; + exp->_bol = text; + exp->_eol = text + scstrlen(text); + exp->_currsubexp = 0; + res = sqstd_rex_matchnode(exp,exp->_nodes,text,NULL); + if(res == NULL || res != exp->_eol) + return SQFalse; + return SQTrue; +} + +SQBool sqstd_rex_searchrange(SQRex* exp,const SQChar* text_begin,const SQChar* text_end,const SQChar** out_begin, const SQChar** out_end) +{ + const SQChar *cur = NULL; + SQInteger node = exp->_first; + if(text_begin >= text_end) return SQFalse; + exp->_bol = text_begin; + exp->_eol = text_end; + do { + cur = text_begin; + while(node != -1) { + exp->_currsubexp = 0; + cur = sqstd_rex_matchnode(exp,&exp->_nodes[node],cur,NULL); + if(!cur) + break; + node = exp->_nodes[node].next; + } + *text_begin++; + } while(cur == NULL && text_begin != text_end); + + if(cur == NULL) + return SQFalse; + + --text_begin; + + if(out_begin) *out_begin = text_begin; + if(out_end) *out_end = cur; + return SQTrue; +} + +SQBool sqstd_rex_search(SQRex* exp,const SQChar* text, const SQChar** out_begin, const SQChar** out_end) +{ + return sqstd_rex_searchrange(exp,text,text + scstrlen(text),out_begin,out_end); +} + +SQInteger sqstd_rex_getsubexpcount(SQRex* exp) +{ + return exp->_nsubexpr; +} + +SQBool sqstd_rex_getsubexp(SQRex* exp, SQInteger n, SQRexMatch *subexp) +{ + if( n<0 || n >= exp->_nsubexpr) return SQFalse; + *subexp = exp->_matches[n]; + return SQTrue; +} + diff --git a/squirrel_3_0_1_stable/sqstdlib/sqstdstream.cpp b/squirrel_3_0_1_stable/sqstdlib/sqstdstream.cpp index 29fbdd601..56140f6ad 100644 --- a/squirrel_3_0_1_stable/sqstdlib/sqstdstream.cpp +++ b/squirrel_3_0_1_stable/sqstdlib/sqstdstream.cpp @@ -1,336 +1,336 @@ -/* see copyright notice in squirrel.h */ -#include -#include -#include -#include -#include -#include -#include -#include "sqstdstream.h" -#include "sqstdblobimpl.h" - -#define SETUP_STREAM(v) \ - SQStream *self = NULL; \ - if(SQ_FAILED(sq_getinstanceup(v,1,(SQUserPointer*)&self,(SQUserPointer)SQSTD_STREAM_TYPE_TAG))) \ - return sq_throwerror(v,_SC("invalid type tag")); \ - if(!self->IsValid()) \ - return sq_throwerror(v,_SC("the stream is invalid")); - -SQInteger _stream_readblob(HSQUIRRELVM v) -{ - SETUP_STREAM(v); - SQUserPointer data,blobp; - SQInteger size,res; - sq_getinteger(v,2,&size); - if(size > self->Len()) { - size = self->Len(); - } - data = sq_getscratchpad(v,size); - res = self->Read(data,size); - if(res <= 0) - return sq_throwerror(v,_SC("no data left to read")); - blobp = sqstd_createblob(v,res); - memcpy(blobp,data,res); - return 1; -} - -#define SAFE_READN(ptr,len) { \ - if(self->Read(ptr,len) != len) return sq_throwerror(v,_SC("io error")); \ - } -SQInteger _stream_readn(HSQUIRRELVM v) -{ - SETUP_STREAM(v); - SQInteger format; - sq_getinteger(v, 2, &format); - switch(format) { - case 'l': { - SQInteger i; - SAFE_READN(&i, sizeof(i)); - sq_pushinteger(v, i); - } - break; - case 'i': { - SQInt32 i; - SAFE_READN(&i, sizeof(i)); - sq_pushinteger(v, i); - } - break; - case 's': { - short s; - SAFE_READN(&s, sizeof(short)); - sq_pushinteger(v, s); - } - break; - case 'w': { - unsigned short w; - SAFE_READN(&w, sizeof(unsigned short)); - sq_pushinteger(v, w); - } - break; - case 'c': { - char c; - SAFE_READN(&c, sizeof(char)); - sq_pushinteger(v, c); - } - break; - case 'b': { - unsigned char c; - SAFE_READN(&c, sizeof(unsigned char)); - sq_pushinteger(v, c); - } - break; - case 'f': { - float f; - SAFE_READN(&f, sizeof(float)); - sq_pushfloat(v, f); - } - break; - case 'd': { - double d; - SAFE_READN(&d, sizeof(double)); - sq_pushfloat(v, (SQFloat)d); - } - break; - default: - return sq_throwerror(v, _SC("invalid format")); - } - return 1; -} - -SQInteger _stream_writeblob(HSQUIRRELVM v) -{ - SQUserPointer data; - SQInteger size; - SETUP_STREAM(v); - if(SQ_FAILED(sqstd_getblob(v,2,&data))) - return sq_throwerror(v,_SC("invalid parameter")); - size = sqstd_getblobsize(v,2); - if(self->Write(data,size) != size) - return sq_throwerror(v,_SC("io error")); - sq_pushinteger(v,size); - return 1; -} - -SQInteger _stream_writen(HSQUIRRELVM v) -{ - SETUP_STREAM(v); - SQInteger format, ti; - SQFloat tf; - sq_getinteger(v, 3, &format); - switch(format) { - case 'l': { - SQInteger i; - sq_getinteger(v, 2, &ti); - i = ti; - self->Write(&i, sizeof(SQInteger)); - } - break; - case 'i': { - SQInt32 i; - sq_getinteger(v, 2, &ti); - i = (SQInt32)ti; - self->Write(&i, sizeof(SQInt32)); - } - break; - case 's': { - short s; - sq_getinteger(v, 2, &ti); - s = (short)ti; - self->Write(&s, sizeof(short)); - } - break; - case 'w': { - unsigned short w; - sq_getinteger(v, 2, &ti); - w = (unsigned short)ti; - self->Write(&w, sizeof(unsigned short)); - } - break; - case 'c': { - char c; - sq_getinteger(v, 2, &ti); - c = (char)ti; - self->Write(&c, sizeof(char)); - } - break; - case 'b': { - unsigned char b; - sq_getinteger(v, 2, &ti); - b = (unsigned char)ti; - self->Write(&b, sizeof(unsigned char)); - } - break; - case 'f': { - float f; - sq_getfloat(v, 2, &tf); - f = (float)tf; - self->Write(&f, sizeof(float)); - } - break; - case 'd': { - double d; - sq_getfloat(v, 2, &tf); - d = tf; - self->Write(&d, sizeof(double)); - } - break; - default: - return sq_throwerror(v, _SC("invalid format")); - } - return 0; -} - -SQInteger _stream_seek(HSQUIRRELVM v) -{ - SETUP_STREAM(v); - SQInteger offset, origin = SQ_SEEK_SET; - sq_getinteger(v, 2, &offset); - if(sq_gettop(v) > 2) { - SQInteger t; - sq_getinteger(v, 3, &t); - switch(t) { - case 'b': origin = SQ_SEEK_SET; break; - case 'c': origin = SQ_SEEK_CUR; break; - case 'e': origin = SQ_SEEK_END; break; - default: return sq_throwerror(v,_SC("invalid origin")); - } - } - sq_pushinteger(v, self->Seek(offset, origin)); - return 1; -} - -SQInteger _stream_tell(HSQUIRRELVM v) -{ - SETUP_STREAM(v); - sq_pushinteger(v, self->Tell()); - return 1; -} - -SQInteger _stream_len(HSQUIRRELVM v) -{ - SETUP_STREAM(v); - sq_pushinteger(v, self->Len()); - return 1; -} - -SQInteger _stream_flush(HSQUIRRELVM v) -{ - SETUP_STREAM(v); - if(!self->Flush()) - sq_pushinteger(v, 1); - else - sq_pushnull(v); - return 1; -} - -SQInteger _stream_eos(HSQUIRRELVM v) -{ - SETUP_STREAM(v); - if(self->EOS()) - sq_pushinteger(v, 1); - else - sq_pushnull(v); - return 1; -} - - SQInteger _stream__cloned(HSQUIRRELVM v) - { - return sq_throwerror(v,_SC("this object cannot be cloned")); - } - -static SQRegFunction _stream_methods[] = { - _DECL_STREAM_FUNC(readblob,2,_SC("xn")), - _DECL_STREAM_FUNC(readn,2,_SC("xn")), - _DECL_STREAM_FUNC(writeblob,-2,_SC("xx")), - _DECL_STREAM_FUNC(writen,3,_SC("xnn")), - _DECL_STREAM_FUNC(seek,-2,_SC("xnn")), - _DECL_STREAM_FUNC(tell,1,_SC("x")), - _DECL_STREAM_FUNC(len,1,_SC("x")), - _DECL_STREAM_FUNC(eos,1,_SC("x")), - _DECL_STREAM_FUNC(flush,1,_SC("x")), - _DECL_STREAM_FUNC(_cloned,0,NULL), - {0,0} -}; - -void init_streamclass(HSQUIRRELVM v) -{ - sq_pushregistrytable(v); - sq_pushstring(v,_SC("std_stream"),-1); - if(SQ_FAILED(sq_get(v,-2))) { - sq_pushstring(v,_SC("std_stream"),-1); - sq_newclass(v,SQFalse); - sq_settypetag(v,-1,(SQUserPointer)SQSTD_STREAM_TYPE_TAG); - SQInteger i = 0; - while(_stream_methods[i].name != 0) { - SQRegFunction &f = _stream_methods[i]; - sq_pushstring(v,f.name,-1); - sq_newclosure(v,f.f,0); - sq_setparamscheck(v,f.nparamscheck,f.typemask); - sq_newslot(v,-3,SQFalse); - i++; - } - sq_newslot(v,-3,SQFalse); - sq_pushroottable(v); - sq_pushstring(v,_SC("stream"),-1); - sq_pushstring(v,_SC("std_stream"),-1); - sq_get(v,-4); - sq_newslot(v,-3,SQFalse); - sq_pop(v,1); - } - else { - sq_pop(v,1); //result - } - sq_pop(v,1); -} - -SQRESULT declare_stream(HSQUIRRELVM v,const SQChar* name,SQUserPointer typetag,const SQChar* reg_name,SQRegFunction *methods,SQRegFunction *globals) -{ - if(sq_gettype(v,-1) != OT_TABLE) - return sq_throwerror(v,_SC("table expected")); - SQInteger top = sq_gettop(v); - //create delegate - init_streamclass(v); - sq_pushregistrytable(v); - sq_pushstring(v,reg_name,-1); - sq_pushstring(v,_SC("std_stream"),-1); - if(SQ_SUCCEEDED(sq_get(v,-3))) { - sq_newclass(v,SQTrue); - sq_settypetag(v,-1,typetag); - SQInteger i = 0; - while(methods[i].name != 0) { - SQRegFunction &f = methods[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_newslot(v,-3,SQFalse); - i++; - } - sq_newslot(v,-3,SQFalse); - sq_pop(v,1); - - i = 0; - while(globals[i].name!=0) - { - SQRegFunction &f = globals[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_newslot(v,-3,SQFalse); - i++; - } - //register the class in the target table - sq_pushstring(v,name,-1); - sq_pushregistrytable(v); - sq_pushstring(v,reg_name,-1); - sq_get(v,-2); - sq_remove(v,-2); - sq_newslot(v,-3,SQFalse); - - sq_settop(v,top); - return SQ_OK; - } - sq_settop(v,top); - return SQ_ERROR; -} +/* see copyright notice in squirrel.h */ +#include +#include +#include +#include +#include +#include +#include +#include "sqstdstream.h" +#include "sqstdblobimpl.h" + +#define SETUP_STREAM(v) \ + SQStream *self = NULL; \ + if(SQ_FAILED(sq_getinstanceup(v,1,(SQUserPointer*)&self,(SQUserPointer)SQSTD_STREAM_TYPE_TAG))) \ + return sq_throwerror(v,_SC("invalid type tag")); \ + if(!self->IsValid()) \ + return sq_throwerror(v,_SC("the stream is invalid")); + +SQInteger _stream_readblob(HSQUIRRELVM v) +{ + SETUP_STREAM(v); + SQUserPointer data,blobp; + SQInteger size,res; + sq_getinteger(v,2,&size); + if(size > self->Len()) { + size = self->Len(); + } + data = sq_getscratchpad(v,size); + res = self->Read(data,size); + if(res <= 0) + return sq_throwerror(v,_SC("no data left to read")); + blobp = sqstd_createblob(v,res); + memcpy(blobp,data,res); + return 1; +} + +#define SAFE_READN(ptr,len) { \ + if(self->Read(ptr,len) != len) return sq_throwerror(v,_SC("io error")); \ + } +SQInteger _stream_readn(HSQUIRRELVM v) +{ + SETUP_STREAM(v); + SQInteger format; + sq_getinteger(v, 2, &format); + switch(format) { + case 'l': { + SQInteger i; + SAFE_READN(&i, sizeof(i)); + sq_pushinteger(v, i); + } + break; + case 'i': { + SQInt32 i; + SAFE_READN(&i, sizeof(i)); + sq_pushinteger(v, i); + } + break; + case 's': { + short s; + SAFE_READN(&s, sizeof(short)); + sq_pushinteger(v, s); + } + break; + case 'w': { + unsigned short w; + SAFE_READN(&w, sizeof(unsigned short)); + sq_pushinteger(v, w); + } + break; + case 'c': { + char c; + SAFE_READN(&c, sizeof(char)); + sq_pushinteger(v, c); + } + break; + case 'b': { + unsigned char c; + SAFE_READN(&c, sizeof(unsigned char)); + sq_pushinteger(v, c); + } + break; + case 'f': { + float f; + SAFE_READN(&f, sizeof(float)); + sq_pushfloat(v, f); + } + break; + case 'd': { + double d; + SAFE_READN(&d, sizeof(double)); + sq_pushfloat(v, (SQFloat)d); + } + break; + default: + return sq_throwerror(v, _SC("invalid format")); + } + return 1; +} + +SQInteger _stream_writeblob(HSQUIRRELVM v) +{ + SQUserPointer data; + SQInteger size; + SETUP_STREAM(v); + if(SQ_FAILED(sqstd_getblob(v,2,&data))) + return sq_throwerror(v,_SC("invalid parameter")); + size = sqstd_getblobsize(v,2); + if(self->Write(data,size) != size) + return sq_throwerror(v,_SC("io error")); + sq_pushinteger(v,size); + return 1; +} + +SQInteger _stream_writen(HSQUIRRELVM v) +{ + SETUP_STREAM(v); + SQInteger format, ti; + SQFloat tf; + sq_getinteger(v, 3, &format); + switch(format) { + case 'l': { + SQInteger i; + sq_getinteger(v, 2, &ti); + i = ti; + self->Write(&i, sizeof(SQInteger)); + } + break; + case 'i': { + SQInt32 i; + sq_getinteger(v, 2, &ti); + i = (SQInt32)ti; + self->Write(&i, sizeof(SQInt32)); + } + break; + case 's': { + short s; + sq_getinteger(v, 2, &ti); + s = (short)ti; + self->Write(&s, sizeof(short)); + } + break; + case 'w': { + unsigned short w; + sq_getinteger(v, 2, &ti); + w = (unsigned short)ti; + self->Write(&w, sizeof(unsigned short)); + } + break; + case 'c': { + char c; + sq_getinteger(v, 2, &ti); + c = (char)ti; + self->Write(&c, sizeof(char)); + } + break; + case 'b': { + unsigned char b; + sq_getinteger(v, 2, &ti); + b = (unsigned char)ti; + self->Write(&b, sizeof(unsigned char)); + } + break; + case 'f': { + float f; + sq_getfloat(v, 2, &tf); + f = (float)tf; + self->Write(&f, sizeof(float)); + } + break; + case 'd': { + double d; + sq_getfloat(v, 2, &tf); + d = tf; + self->Write(&d, sizeof(double)); + } + break; + default: + return sq_throwerror(v, _SC("invalid format")); + } + return 0; +} + +SQInteger _stream_seek(HSQUIRRELVM v) +{ + SETUP_STREAM(v); + SQInteger offset, origin = SQ_SEEK_SET; + sq_getinteger(v, 2, &offset); + if(sq_gettop(v) > 2) { + SQInteger t; + sq_getinteger(v, 3, &t); + switch(t) { + case 'b': origin = SQ_SEEK_SET; break; + case 'c': origin = SQ_SEEK_CUR; break; + case 'e': origin = SQ_SEEK_END; break; + default: return sq_throwerror(v,_SC("invalid origin")); + } + } + sq_pushinteger(v, self->Seek(offset, origin)); + return 1; +} + +SQInteger _stream_tell(HSQUIRRELVM v) +{ + SETUP_STREAM(v); + sq_pushinteger(v, self->Tell()); + return 1; +} + +SQInteger _stream_len(HSQUIRRELVM v) +{ + SETUP_STREAM(v); + sq_pushinteger(v, self->Len()); + return 1; +} + +SQInteger _stream_flush(HSQUIRRELVM v) +{ + SETUP_STREAM(v); + if(!self->Flush()) + sq_pushinteger(v, 1); + else + sq_pushnull(v); + return 1; +} + +SQInteger _stream_eos(HSQUIRRELVM v) +{ + SETUP_STREAM(v); + if(self->EOS()) + sq_pushinteger(v, 1); + else + sq_pushnull(v); + return 1; +} + + SQInteger _stream__cloned(HSQUIRRELVM v) + { + return sq_throwerror(v,_SC("this object cannot be cloned")); + } + +static SQRegFunction _stream_methods[] = { + _DECL_STREAM_FUNC(readblob,2,_SC("xn")), + _DECL_STREAM_FUNC(readn,2,_SC("xn")), + _DECL_STREAM_FUNC(writeblob,-2,_SC("xx")), + _DECL_STREAM_FUNC(writen,3,_SC("xnn")), + _DECL_STREAM_FUNC(seek,-2,_SC("xnn")), + _DECL_STREAM_FUNC(tell,1,_SC("x")), + _DECL_STREAM_FUNC(len,1,_SC("x")), + _DECL_STREAM_FUNC(eos,1,_SC("x")), + _DECL_STREAM_FUNC(flush,1,_SC("x")), + _DECL_STREAM_FUNC(_cloned,0,NULL), + {0,0} +}; + +void init_streamclass(HSQUIRRELVM v) +{ + sq_pushregistrytable(v); + sq_pushstring(v,_SC("std_stream"),-1); + if(SQ_FAILED(sq_get(v,-2))) { + sq_pushstring(v,_SC("std_stream"),-1); + sq_newclass(v,SQFalse); + sq_settypetag(v,-1,(SQUserPointer)SQSTD_STREAM_TYPE_TAG); + SQInteger i = 0; + while(_stream_methods[i].name != 0) { + SQRegFunction &f = _stream_methods[i]; + sq_pushstring(v,f.name,-1); + sq_newclosure(v,f.f,0); + sq_setparamscheck(v,f.nparamscheck,f.typemask); + sq_newslot(v,-3,SQFalse); + i++; + } + sq_newslot(v,-3,SQFalse); + sq_pushroottable(v); + sq_pushstring(v,_SC("stream"),-1); + sq_pushstring(v,_SC("std_stream"),-1); + sq_get(v,-4); + sq_newslot(v,-3,SQFalse); + sq_pop(v,1); + } + else { + sq_pop(v,1); //result + } + sq_pop(v,1); +} + +SQRESULT declare_stream(HSQUIRRELVM v,const SQChar* name,SQUserPointer typetag,const SQChar* reg_name,SQRegFunction *methods,SQRegFunction *globals) +{ + if(sq_gettype(v,-1) != OT_TABLE) + return sq_throwerror(v,_SC("table expected")); + SQInteger top = sq_gettop(v); + //create delegate + init_streamclass(v); + sq_pushregistrytable(v); + sq_pushstring(v,reg_name,-1); + sq_pushstring(v,_SC("std_stream"),-1); + if(SQ_SUCCEEDED(sq_get(v,-3))) { + sq_newclass(v,SQTrue); + sq_settypetag(v,-1,typetag); + SQInteger i = 0; + while(methods[i].name != 0) { + SQRegFunction &f = methods[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_newslot(v,-3,SQFalse); + i++; + } + sq_newslot(v,-3,SQFalse); + sq_pop(v,1); + + i = 0; + while(globals[i].name!=0) + { + SQRegFunction &f = globals[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_newslot(v,-3,SQFalse); + i++; + } + //register the class in the target table + sq_pushstring(v,name,-1); + sq_pushregistrytable(v); + sq_pushstring(v,reg_name,-1); + sq_get(v,-2); + sq_remove(v,-2); + sq_newslot(v,-3,SQFalse); + + sq_settop(v,top); + return SQ_OK; + } + sq_settop(v,top); + return SQ_ERROR; +} diff --git a/squirrel_3_0_1_stable/sqstdlib/sqstdstream.h b/squirrel_3_0_1_stable/sqstdlib/sqstdstream.h index 1595251e7..4dcc00054 100644 --- a/squirrel_3_0_1_stable/sqstdlib/sqstdstream.h +++ b/squirrel_3_0_1_stable/sqstdlib/sqstdstream.h @@ -1,18 +1,18 @@ -/* see copyright notice in squirrel.h */ -#ifndef _SQSTD_STREAM_H_ -#define _SQSTD_STREAM_H_ - -SQInteger _stream_readblob(HSQUIRRELVM v); -SQInteger _stream_readline(HSQUIRRELVM v); -SQInteger _stream_readn(HSQUIRRELVM v); -SQInteger _stream_writeblob(HSQUIRRELVM v); -SQInteger _stream_writen(HSQUIRRELVM v); -SQInteger _stream_seek(HSQUIRRELVM v); -SQInteger _stream_tell(HSQUIRRELVM v); -SQInteger _stream_len(HSQUIRRELVM v); -SQInteger _stream_eos(HSQUIRRELVM v); -SQInteger _stream_flush(HSQUIRRELVM v); - -#define _DECL_STREAM_FUNC(name,nparams,typecheck) {_SC(#name),_stream_##name,nparams,typecheck} -SQRESULT declare_stream(HSQUIRRELVM v,const SQChar* name,SQUserPointer typetag,const SQChar* reg_name,SQRegFunction *methods,SQRegFunction *globals); -#endif /*_SQSTD_STREAM_H_*/ +/* see copyright notice in squirrel.h */ +#ifndef _SQSTD_STREAM_H_ +#define _SQSTD_STREAM_H_ + +SQInteger _stream_readblob(HSQUIRRELVM v); +SQInteger _stream_readline(HSQUIRRELVM v); +SQInteger _stream_readn(HSQUIRRELVM v); +SQInteger _stream_writeblob(HSQUIRRELVM v); +SQInteger _stream_writen(HSQUIRRELVM v); +SQInteger _stream_seek(HSQUIRRELVM v); +SQInteger _stream_tell(HSQUIRRELVM v); +SQInteger _stream_len(HSQUIRRELVM v); +SQInteger _stream_eos(HSQUIRRELVM v); +SQInteger _stream_flush(HSQUIRRELVM v); + +#define _DECL_STREAM_FUNC(name,nparams,typecheck) {_SC(#name),_stream_##name,nparams,typecheck} +SQRESULT declare_stream(HSQUIRRELVM v,const SQChar* name,SQUserPointer typetag,const SQChar* reg_name,SQRegFunction *methods,SQRegFunction *globals); +#endif /*_SQSTD_STREAM_H_*/ diff --git a/squirrel_3_0_1_stable/sqstdlib/sqstdstring.cpp b/squirrel_3_0_1_stable/sqstdlib/sqstdstring.cpp index aaa37dfde..2a4e2a1fd 100644 --- a/squirrel_3_0_1_stable/sqstdlib/sqstdstring.cpp +++ b/squirrel_3_0_1_stable/sqstdlib/sqstdstring.cpp @@ -1,378 +1,378 @@ -/* see copyright notice in squirrel.h */ -#include -#include -#include -#include -#include -#include -#include - -#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 'o': case 'u': case 'x': case 'X': -#ifdef _SQ64 - { - size_t flen = scstrlen(fmt); - SQInteger fpos = flen - 1; - SQChar f = fmt[fpos]; - SQChar *prec = (SQChar *)_PRINT_INT_PREC; - while(*prec != _SC('\0')) { - fmt[fpos++] = *prec++; - } - fmt[fpos++] = f; - fmt[fpos++] = _SC('\0'); - } -#endif - case 'c': - 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} -}; -#undef _DECL_REX_FUNC - -#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} -}; -#undef _DECL_FUNC - - -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_newslot(v,-3,SQFalse); - i++; - } - sq_newslot(v,-3,SQFalse); - - 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_newslot(v,-3,SQFalse); - i++; - } - return 1; -} +/* see copyright notice in squirrel.h */ +#include +#include +#include +#include +#include +#include +#include + +#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 'o': case 'u': case 'x': case 'X': +#ifdef _SQ64 + { + size_t flen = scstrlen(fmt); + SQInteger fpos = flen - 1; + SQChar f = fmt[fpos]; + SQChar *prec = (SQChar *)_PRINT_INT_PREC; + while(*prec != _SC('\0')) { + fmt[fpos++] = *prec++; + } + fmt[fpos++] = f; + fmt[fpos++] = _SC('\0'); + } +#endif + case 'c': + 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} +}; +#undef _DECL_REX_FUNC + +#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} +}; +#undef _DECL_FUNC + + +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_newslot(v,-3,SQFalse); + i++; + } + sq_newslot(v,-3,SQFalse); + + 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_newslot(v,-3,SQFalse); + i++; + } + return 1; +} diff --git a/squirrel_3_0_1_stable/sqstdlib/sqstdsystem.cpp b/squirrel_3_0_1_stable/sqstdlib/sqstdsystem.cpp index 40f78d785..309139fec 100644 --- a/squirrel_3_0_1_stable/sqstdlib/sqstdsystem.cpp +++ b/squirrel_3_0_1_stable/sqstdlib/sqstdsystem.cpp @@ -1,147 +1,147 @@ -/* see copyright notice in squirrel.h */ -#include -#include -#include -#include -#include - -#ifdef SQUNICODE -#include -#define scgetenv _wgetenv -#define scsystem _wsystem -#define scasctime _wasctime -#define scremove _wremove -#define screname _wrename -#else -#define scgetenv getenv -#define scsystem system -#define scasctime asctime -#define scremove remove -#define screname rename -#endif - -static SQInteger _system_getenv(HSQUIRRELVM v) -{ - const SQChar *s; - if(SQ_SUCCEEDED(sq_getstring(v,2,&s))){ - sq_pushstring(v,scgetenv(s),-1); - return 1; - } - return 0; -} - - -static SQInteger _system_system(HSQUIRRELVM v) -{ - const SQChar *s; - if(SQ_SUCCEEDED(sq_getstring(v,2,&s))){ - sq_pushinteger(v,scsystem(s)); - return 1; - } - return sq_throwerror(v,_SC("wrong param")); -} - - -static SQInteger _system_clock(HSQUIRRELVM v) -{ - sq_pushfloat(v,((SQFloat)clock())/(SQFloat)CLOCKS_PER_SEC); - return 1; -} - -static SQInteger _system_time(HSQUIRRELVM v) -{ - time_t t; - time(&t); - sq_pushinteger(v,*((SQInteger *)&t)); - return 1; -} - -static SQInteger _system_remove(HSQUIRRELVM v) -{ - const SQChar *s; - sq_getstring(v,2,&s); - if(scremove(s)==-1) - return sq_throwerror(v,_SC("remove() failed")); - return 0; -} - -static SQInteger _system_rename(HSQUIRRELVM v) -{ - const SQChar *oldn,*newn; - sq_getstring(v,2,&oldn); - sq_getstring(v,3,&newn); - if(screname(oldn,newn)==-1) - return sq_throwerror(v,_SC("rename() failed")); - return 0; -} - -static void _set_integer_slot(HSQUIRRELVM v,const SQChar *name,SQInteger val) -{ - sq_pushstring(v,name,-1); - sq_pushinteger(v,val); - sq_rawset(v,-3); -} - -static SQInteger _system_date(HSQUIRRELVM v) -{ - time_t t; - SQInteger it; - SQInteger format = 'l'; - if(sq_gettop(v) > 1) { - sq_getinteger(v,2,&it); - t = it; - if(sq_gettop(v) > 2) { - sq_getinteger(v,3,(SQInteger*)&format); - } - } - else { - time(&t); - } - tm *date; - if(format == 'u') - date = gmtime(&t); - else - date = localtime(&t); - if(!date) - return sq_throwerror(v,_SC("crt api failure")); - sq_newtable(v); - _set_integer_slot(v, _SC("sec"), date->tm_sec); - _set_integer_slot(v, _SC("min"), date->tm_min); - _set_integer_slot(v, _SC("hour"), date->tm_hour); - _set_integer_slot(v, _SC("day"), date->tm_mday); - _set_integer_slot(v, _SC("month"), date->tm_mon); - _set_integer_slot(v, _SC("year"), date->tm_year+1900); - _set_integer_slot(v, _SC("wday"), date->tm_wday); - _set_integer_slot(v, _SC("yday"), date->tm_yday); - return 1; -} - - - -#define _DECL_FUNC(name,nparams,pmask) {_SC(#name),_system_##name,nparams,pmask} -static SQRegFunction systemlib_funcs[]={ - _DECL_FUNC(getenv,2,_SC(".s")), - _DECL_FUNC(system,2,_SC(".s")), - _DECL_FUNC(clock,0,NULL), - _DECL_FUNC(time,1,NULL), - _DECL_FUNC(date,-1,_SC(".nn")), - _DECL_FUNC(remove,2,_SC(".s")), - _DECL_FUNC(rename,3,_SC(".ss")), - {0,0} -}; -#undef _DECL_FUNC - -SQInteger sqstd_register_systemlib(HSQUIRRELVM v) -{ - SQInteger i=0; - while(systemlib_funcs[i].name!=0) - { - sq_pushstring(v,systemlib_funcs[i].name,-1); - sq_newclosure(v,systemlib_funcs[i].f,0); - sq_setparamscheck(v,systemlib_funcs[i].nparamscheck,systemlib_funcs[i].typemask); - sq_setnativeclosurename(v,-1,systemlib_funcs[i].name); - sq_newslot(v,-3,SQFalse); - i++; - } - return 1; -} +/* see copyright notice in squirrel.h */ +#include +#include +#include +#include +#include + +#ifdef SQUNICODE +#include +#define scgetenv _wgetenv +#define scsystem _wsystem +#define scasctime _wasctime +#define scremove _wremove +#define screname _wrename +#else +#define scgetenv getenv +#define scsystem system +#define scasctime asctime +#define scremove remove +#define screname rename +#endif + +static SQInteger _system_getenv(HSQUIRRELVM v) +{ + const SQChar *s; + if(SQ_SUCCEEDED(sq_getstring(v,2,&s))){ + sq_pushstring(v,scgetenv(s),-1); + return 1; + } + return 0; +} + + +static SQInteger _system_system(HSQUIRRELVM v) +{ + const SQChar *s; + if(SQ_SUCCEEDED(sq_getstring(v,2,&s))){ + sq_pushinteger(v,scsystem(s)); + return 1; + } + return sq_throwerror(v,_SC("wrong param")); +} + + +static SQInteger _system_clock(HSQUIRRELVM v) +{ + sq_pushfloat(v,((SQFloat)clock())/(SQFloat)CLOCKS_PER_SEC); + return 1; +} + +static SQInteger _system_time(HSQUIRRELVM v) +{ + time_t t; + time(&t); + sq_pushinteger(v,*((SQInteger *)&t)); + return 1; +} + +static SQInteger _system_remove(HSQUIRRELVM v) +{ + const SQChar *s; + sq_getstring(v,2,&s); + if(scremove(s)==-1) + return sq_throwerror(v,_SC("remove() failed")); + return 0; +} + +static SQInteger _system_rename(HSQUIRRELVM v) +{ + const SQChar *oldn,*newn; + sq_getstring(v,2,&oldn); + sq_getstring(v,3,&newn); + if(screname(oldn,newn)==-1) + return sq_throwerror(v,_SC("rename() failed")); + return 0; +} + +static void _set_integer_slot(HSQUIRRELVM v,const SQChar *name,SQInteger val) +{ + sq_pushstring(v,name,-1); + sq_pushinteger(v,val); + sq_rawset(v,-3); +} + +static SQInteger _system_date(HSQUIRRELVM v) +{ + time_t t; + SQInteger it; + SQInteger format = 'l'; + if(sq_gettop(v) > 1) { + sq_getinteger(v,2,&it); + t = it; + if(sq_gettop(v) > 2) { + sq_getinteger(v,3,(SQInteger*)&format); + } + } + else { + time(&t); + } + tm *date; + if(format == 'u') + date = gmtime(&t); + else + date = localtime(&t); + if(!date) + return sq_throwerror(v,_SC("crt api failure")); + sq_newtable(v); + _set_integer_slot(v, _SC("sec"), date->tm_sec); + _set_integer_slot(v, _SC("min"), date->tm_min); + _set_integer_slot(v, _SC("hour"), date->tm_hour); + _set_integer_slot(v, _SC("day"), date->tm_mday); + _set_integer_slot(v, _SC("month"), date->tm_mon); + _set_integer_slot(v, _SC("year"), date->tm_year+1900); + _set_integer_slot(v, _SC("wday"), date->tm_wday); + _set_integer_slot(v, _SC("yday"), date->tm_yday); + return 1; +} + + + +#define _DECL_FUNC(name,nparams,pmask) {_SC(#name),_system_##name,nparams,pmask} +static SQRegFunction systemlib_funcs[]={ + _DECL_FUNC(getenv,2,_SC(".s")), + _DECL_FUNC(system,2,_SC(".s")), + _DECL_FUNC(clock,0,NULL), + _DECL_FUNC(time,1,NULL), + _DECL_FUNC(date,-1,_SC(".nn")), + _DECL_FUNC(remove,2,_SC(".s")), + _DECL_FUNC(rename,3,_SC(".ss")), + {0,0} +}; +#undef _DECL_FUNC + +SQInteger sqstd_register_systemlib(HSQUIRRELVM v) +{ + SQInteger i=0; + while(systemlib_funcs[i].name!=0) + { + sq_pushstring(v,systemlib_funcs[i].name,-1); + sq_newclosure(v,systemlib_funcs[i].f,0); + sq_setparamscheck(v,systemlib_funcs[i].nparamscheck,systemlib_funcs[i].typemask); + sq_setnativeclosurename(v,-1,systemlib_funcs[i].name); + sq_newslot(v,-3,SQFalse); + i++; + } + return 1; +} -- cgit v1.2.3