/* see copyright notice in squirrel.h */ #include "sqpcheader.h" #include "sqvm.h" #include "sqstring.h" #include "sqtable.h" #include "sqarray.h" #include "sqfuncproto.h" #include "sqclosure.h" #include "squserdata.h" #include "sqcompiler.h" #include "sqfuncstate.h" #include "sqclass.h" #include #include #define _GETSAFE_OBJ(v,idx,type,o) { if(!sq_aux_gettypedarg(v,idx,type,&o)) return SQ_ERROR; } #define sq_aux_paramscheck(v,count) \ { \ if(sq_gettop(v) < count){ v->Raise_Error(_SC("not enough params in the stack")); return SQ_ERROR; }\ } static bool sq_aux_gettypedarg(HSQUIRRELVM v,SQInteger idx,SQObjectType type,SQObjectPtr **o) { *o = &stack_get(v,idx); if(sq_type(**o) != type){ SQObjectPtr oval = v->PrintObjVal(**o); v->Raise_Error(_SC("wrong argument type, expected '%s' got '%.50s'"),IdType2Name(type),_stringval(oval)); return false; } return true; } SQRESULT sq_throwerrorf(HSQUIRRELVM v,const SQChar *err,...) { SQInteger n=256; va_list args; begin: va_start(args,err); SQChar *b=sq_getscratchpad(v,n); SQInteger r=scvsprintf(b,n,err,args); va_end(args); if (r>=n) { n=r+1;//required+null goto begin; } else if (r<0) { v->_lasterror=SQString::Create(_ss(v),_SC("@failed to generate formatted error message")); } else { v->_lasterror=SQString::Create(_ss(v),b,r); } return SQ_ERROR; } SQRESULT sq_pushstringf(HSQUIRRELVM v,const SQChar *s,...) { SQInteger n=256; va_list args; begin: va_start(args,s); SQChar *b=sq_getscratchpad(v,n); SQInteger r=scvsprintf(b,n,s,args); va_end(args); if (r>=n) { n=r+1;//required+null goto begin; } else if (r<0) { v->PushNull(); return SQ_ERROR; } else { v->Push(SQObjectPtr(SQString::Create(_ss(v),b,r))); return SQ_OK; } } SQRESULT sq_vpushstringf(HSQUIRRELVM v,const SQChar *s,va_list l) { SQInteger n=256; va_list args; begin: va_copy(args,l); SQChar *b=sq_getscratchpad(v,n); SQInteger r=scvsprintf(b,n,s,args); va_end(args); if (r>=n) { n=r+1;//required+null goto begin; } else if (r<0) { v->PushNull(); return SQ_ERROR; } else { v->Push(SQObjectPtr(SQString::Create(_ss(v),b,r))); return SQ_OK; } } SQRESULT sq_getnativeclosurepointer(HSQUIRRELVM v,SQInteger idx,SQFUNCTION *f) { SQObject o = stack_get(v, idx); if(sq_type(o) == OT_NATIVECLOSURE) { SQNativeClosure *c = _nativeclosure(o); if (f) *f = c->_function; return SQ_OK; } return sq_throwerror(v,_SC("the object is not a native closure")); } SQRESULT sq_arrayreserve(HSQUIRRELVM v,SQInteger idx,SQInteger newcap) { sq_aux_paramscheck(v,1); SQObjectPtr *arr; _GETSAFE_OBJ(v, idx, OT_ARRAY,arr); if(newcap >= 0) { _array(*arr)->Reserve(newcap); return SQ_OK; } return sq_throwerror(v,_SC("negative capacity")); } void sq_newarrayex(HSQUIRRELVM v,SQInteger capacity) { SQArray* a = SQArray::Create(_ss(v), 0); a->Reserve(capacity); v->Push(a); } SQInteger sq_cmpr(HSQUIRRELVM v) { SQInteger res; v->ObjCmp(stack_get(v, -2), stack_get(v, -1),res); return res; }