void SQDbgServer::SerializeState() { sq_pushnull(_v); sq_setdebughook(_v); sq_pushnull(_v); sq_seterrorhandler(_v); const SQChar *sz; sq_pushobject(_v,_serializefunc); sq_pushobject(_v,_debugroot); sq_pushstring(_v,_SC("watches"),-1); sq_newtable(_v); for(WatchSetItor i=_watches.begin(); i!=_watches.end(); ++i) { sq_pushinteger(_v,i->_id); sq_pushstring(_v,i->_exp.c_str(),(int)i->_exp.length()); sq_createslot(_v,-3); } sq_rawset(_v,-3); if(SQ_SUCCEEDED(sq_call(_v,1,SQTrue,SQTrue))){ if(SQ_SUCCEEDED(sqstd_getblob(_v,-1,(SQUserPointer*)&sz))) SendChunk(sz); } sq_pop(_v,2); SetErrorHandlers(); }
int CEntityNatives::Create(SQVM* pVM) { CResource* pResource = g_pResourceManager->Get(pVM); assert( pResource ); const char* szName; sq_getstring(pVM,2,&szName); if(CEntity::GetType(szName) == ENTITY_TYPE_CUSTOM) { CEntity* pEntity = new CEntity(ENTITY_TYPE_CUSTOM, pResource, szName); if(pEntity->GetID() != INVALID_ENTITY_ID_LONG) { sq_pushentity(pVM,pEntity); } else { delete pEntity; sq_pushnull(pVM); } } else sq_pushnull(pVM); return 1; }
SQInteger Sq_GetLayerRects(HSQUIRRELVM v) { const SQChar *What; sq_getstring(v, 2, &What); int Layer = FindLayerByName(What); if(Layer < 0) { sq_pushnull(v); return 1; } sq_newarray(v, 0); for(LevelRect *Rect = LayerInfos[Layer].Rects; Rect; Rect=Rect->Next) { sq_newarray(v, 0); sq_pushstring(v, LayerInfos[Layer].TilesetLookup[Rect->Type].Name, -1); sq_arrayappend(v, -2); sq_pushinteger(v, Rect->X); sq_arrayappend(v, -2); sq_pushinteger(v, Rect->Y); sq_arrayappend(v, -2); sq_pushinteger(v, Rect->W); sq_arrayappend(v, -2); sq_pushinteger(v, Rect->H); sq_arrayappend(v, -2); sq_pushinteger(v, ((Rect->Flips&SDL_FLIP_HORIZONTAL)!=0)|(((Rect->Flips&SDL_FLIP_VERTICAL)!=0)<<1)); sq_arrayappend(v, -2); if(Rect->ExtraInfo) sq_pushstring(v, Rect->ExtraInfo, -1); else sq_pushnull(v); sq_arrayappend(v, -2); sq_arrayappend(v, -2); } return 1; }
SQRESULT at(HSQUIRRELVM vm) { SQObjectPtr self = vm->GetAt(vm->_top-2); if (type(self) == OT_STRING) { SQString *selfString = _string(self); SQInteger index = selfString->_len; sq_getinteger(vm, -1, &index); auto begin = selfString->_val; auto end = begin+selfString->_len; try { SQChar *from = NULL; if (index >= 0) { from = begin; utf8::advance(from, index, end); } else { from = end; for (auto i = index; i < 0; ++i) { utf8::prior(from, begin); } } auto to = from; utf8::advance(to, 1, end); SQInteger resultLen = to-from; assert((resultLen >= 0) && "Length of the resulting string should not be negative"); if (resultLen < 0) { sq_pushnull(vm); return 1; } SQChar *resultSequence = vm->_sharedstate->GetScratchPad(resultLen+1); memset(resultSequence, 0, (resultLen+1)*sizeof(SQChar)); memcpy(resultSequence, from, resultLen*sizeof(SQChar)); SQString *result = SQString::Create(vm->_sharedstate, resultSequence); vm->Push(result); } catch (...) { sq_pushnull(vm); } } else { vm->Raise_Error("string::at - Invalid receiver of type %s", GetTypeName(self)); return SQ_ERROR; } return 1; }
// variant fscan(handle file[, integer type = TEXT]) // Read data from file // For list of supported types look 'scan' function specification // If invalid file handle or unsupported type specified, read nothing and return 'null' value static SQInteger FScan (HSQUIRRELVM) { FILE* file = GetFile(); if (file) { SQInteger type = 't'; if (sq_gettop(sqvm) == 3) sq_getinteger(sqvm, 3, &type); SQInteger intVal; switch (type) { case 't': SQChar buf[4096]; fgets(buf, sizeof(buf), file); buf[sizeof(buf) - 1] = 0; for (SQChar* c = buf; *c; ++c) { if (*c == '\n') { *c = 0; break; } } sq_pushstring(sqvm, buf, -1); break; case 'c': sq_pushinteger(sqvm, fgetc(file)); break; case 'i': fscanf_s(file, FMT_INT, &intVal); sq_pushinteger(sqvm, intVal); break; case 'u': fscanf_s(file, FMT_UINT, &intVal); sq_pushinteger(sqvm, intVal); break; case 'f': SQFloat fltVal; fscanf_s(file, "%f", &fltVal); sq_pushfloat(sqvm, fltVal); break; default: sq_pushnull(sqvm); } } else sq_pushnull(sqvm); return 1; }
bool CSquirrelArgument::push(SQVM* pVM) { switch(type) { case OT_NULL: sq_pushnull(pVM); break; case OT_INTEGER: sq_pushinteger(pVM, data.i); break; case OT_BOOL: sq_pushbool(pVM, data.b); break; case OT_FLOAT: sq_pushfloat(pVM, data.f); break; case OT_STRING: sq_pushstring(pVM, data.str->Get(), data.str->GetLength()); break; case OT_ARRAY: { sq_newarray(pVM, 0); for(auto pArgument : *data.pArray->GetArguments()) { pArgument->push(pVM); sq_arrayappend(pVM, -2); } break; } case OT_TABLE: { sq_newtable(pVM); int i = 0; assert( data.pArray->GetArguments()->size() % 2 == 0 ); for(auto iter = data.pArray->GetArguments()->begin(); iter != data.pArray->GetArguments()->end(); ++ iter, ++ i ) { (*iter)->push(pVM); ++ iter; (*iter)->push(pVM); sq_createslot(pVM, -3); } break; } break; default: sq_pushnull(pVM); // table, whatsoever. do not even care. fix it if you dare. assert(0); return false; } return true; }
int CEntityNatives::GetParent(SQVM* pVM) { CEntity* pEntity = sq_toentity(pVM, 2); if(pEntity) { CEntity* pParent = pEntity->GetParent(); if(pParent) sq_pushentity(pVM,pParent); else sq_pushnull(pVM); } else sq_pushnull(pVM); return 1; }
int sq_whirlpool(HSQUIRRELVM pVM) { if(sq_gettop(pVM) == 2) { struct NESSIEstruct w; u8 digest[DIGESTBYTES]; const char* data; char out[DIGESTBYTES*2+1] = {0}; int i; sq_getstring(pVM, 2, &data); NESSIEinit(&w); NESSIEadd((const unsigned char*)data, strlen(data)*8, &w); NESSIEfinalize(&w, digest); for(i=0; i < DIGESTBYTES; ++i) { sprintf(out, "%s%02X", out, digest[i]); } sq_pushstring(pVM, out, -1); return 1; } sq_pushnull(pVM); return 1; }
/** * squirrel から吉里吉里オブジェクトを取得 */ bool TJSObject::getVariant(HSQUIRRELVM v, SQInteger idx, tTJSVariant *variant) { if (sq_gettype(v, idx) == OT_CLASS) { if (idx < 0) { idx = sq_gettop(v) + 1 + idx; } bool ret = false; // クラス属性からオブジェクト情報を引き出す sq_pushnull(v); if (SQ_SUCCEEDED(sq_getattributes(v, idx))) { sq_pushstring(v, tjsClassAttrName, -1); if (SQ_SUCCEEDED(sq_get(v,-2))) { if (SQ_SUCCEEDED(sq_getvariant(v,-1, variant))) { ret = true; } sq_pop(v,1); } sq_pop(v,1); } else { // XXX sq_pop(v,1); } return ret; } else if (sq_gettype(v, idx) == OT_INSTANCE) { TJSObject *obj = SQClassType<TJSObject>::getInstance(v, idx); if (obj && obj->instance.AsObjectClosureNoAddRef().IsValid(0, NULL, NULL, NULL) == TJS_S_TRUE) { *variant = obj->instance; return true; } } return false; }
SQRESULT sqext_register_MySQL(HSQUIRRELVM v) { sq_pushstring(v,MySQL_TAG,-1); sq_newclass(v,SQFalse); sq_settypetag(v,-1,(void*)MySQL_TAG); sq_insert_reg_funcs(v, sq_mysql_methods); sq_newslot(v,-3,SQTrue); sq_pushstring(v,MySQL_Statement_TAG,-1); sq_newclass(v,SQFalse); sq_settypetag(v,-1,(void*)MySQL_Statement_TAG); sq_insert_reg_funcs(v, sq_mysql_statement_methods); sq_newslot(v,-3,SQTrue); sq_pushstring(v,MySQL_Result_TAG,-1); sq_newclass(v,SQFalse); sq_settypetag(v,-1,(void*)MySQL_Result_TAG); sq_insert_reg_funcs(v, sq_mysql_result_methods); sq_pushstring(v, _curr_row_key, -1); sq_pushnull(v); sq_newslot(v, -3, SQFalse); sq_newslot(v,-3,SQTrue); return 0; }
SQInteger Sq_DecodeJSON(HSQUIRRELVM v) { const SQChar *Str; sq_getstring(v, 2, &Str); if(Str[0]!='{' && Str[0]!='[') { if(!strcmp(Str, "true")) sq_pushbool(v, SQTrue); else if(!strcmp(Str, "false")) sq_pushbool(v, SQFalse); else if(isdigit(Str[0]) || (Str[0]=='-' && isdigit(Str[1]))) sq_pushinteger(v, strtol(Str, NULL, 0)); else sq_pushstring(v, Str, -1); return 1; } cJSON *Root = cJSON_Parse(Str); if(!Root || !Root->child) { sq_pushnull(v); return 1; } sq_newtable(v); Sq_DecodeJSONTable(v, Root->child); cJSON_Delete(Root); return 1; }
//------------------------------------------------------------------------------ void SN_API getTable(HSQUIRRELVM vm, Variant & out_v, SQInteger index) { out_v.setDictionary(); Variant::Dictionary & d = out_v.getDictionary(); sq_push(vm, index); sq_pushnull(vm); while (SQ_SUCCEEDED(sq_next(vm, -2))) { if (sq_gettype(vm, -2) == OT_STRING) { const SQChar * key = nullptr; sq_getstring(vm, -2, &key); Variant & val = d[key]; getVariant(vm, val, -1); } else { SN_WARNING("non-string keys in tables are not supported by getVariant"); } sq_pop(vm, 2); } sq_pop(vm, 2); // Pop iterator and table }
std::vector<std::string> ConsoleImpl::get_roottable() { std::vector<std::string> roottable; HSQUIRRELVM v = script_manager->get_vm(); sq_pushroottable(v); //push your table/array here sq_pushnull(v); //null iterator while(SQ_SUCCEEDED(sq_next(v,-2))) { //here -1 is the value and -2 is the key const SQChar *s; if (SQ_SUCCEEDED(sq_getstring(v,-2, &s))) { roottable.push_back((char*)s); } else { console << "Unknown key type for element" << std::endl; } sq_pop(v,2); //pops key and val before the nex iteration } sq_pop(v, 1); return roottable; }
template <> inline Array *GetParam(ForceType<Array *>, HSQUIRRELVM vm, int index, SQAutoFreePointers *ptr) { SQObject obj; sq_getstackobj(vm, index, &obj); sq_pushobject(vm, obj); sq_pushnull(vm); SmallVector<int32, 2> data; while (SQ_SUCCEEDED(sq_next(vm, -2))) { SQInteger tmp; if (SQ_SUCCEEDED(sq_getinteger(vm, -1, &tmp))) { *data.Append() = (int32)tmp; } else { sq_pop(vm, 4); throw sq_throwerror(vm, _SC("a member of an array used as parameter to a function is not numeric")); } sq_pop(vm, 2); } sq_pop(vm, 2); Array *arr = (Array*)MallocT<byte>(sizeof(Array) + sizeof(int32) * data.Length()); arr->size = data.Length(); memcpy(arr->array, data.Begin(), sizeof(int32) * data.Length()); *ptr->Append() = arr; return arr; }
//------------------------------------------------------------------------------ void SN_API getArray(HSQUIRRELVM vm, Variant & out_v, SQInteger index) { out_v.setArray(); Variant::Array & a = out_v.getArray(); SQInteger len = sq_getsize(vm, index); SN_ASSERT(len >= 0, "Invalid array size"); if (len > 0) { a.resize(len); s32 i = 0; sq_push(vm, index); sq_pushnull(vm); while (SQ_SUCCEEDED(sq_next(vm, -2))) { // -1 is the value and -2 is the key sq_getinteger(vm, -2, &i); Variant & val = a[i]; getVariant(vm, val, -1); sq_pop(vm, 2); //pops key and val before the next iteration } sq_pop(vm, 2); // Pop the null iterator and array } }
BOOL SquirrelObject::BeginIteration() { if(!sq_istable(_o) && !sq_isarray(_o) && !sq_isclass(_o)) return FALSE; sq_pushobject(m_Vm.GetVMPtr(),_o); sq_pushnull(m_Vm.GetVMPtr()); return TRUE; }
static void sqlang_pushlstring(HSQUIRRELVM J, char *s, int l) { if(s==NULL) { sq_pushnull(J); return; } sq_pushstring(J, (const SQChar*)s, (SQInteger)l); }
// handle fopen(string path, string mode) // Open file // 'mode' may be either one of modes used by fopen() function in libc or one of these values: // READ_ONLY - open for reading only (the file must exist); // WRITE_ONLY - open for writing only; // READ_WRITE - open for both reading and writing (the file must exist); // APPEND - open for appending (writing data at the end of the file). static SQInteger FOpen (HSQUIRRELVM) { if (numFiles == MAX_OPENED_FILES) { PrintError("ERROR: Too many opened files.\n"); sq_pushnull(sqvm); return 1; } // Find first unopened file unsigned i; for (i = 0; i < MAX_OPENED_FILES; ++i) { if (!files[i]) break; } const SQChar *path, *mode; sq_getstring(sqvm, 2, &path); sq_getstring(sqvm, 3, &mode); // Binary file I/O isn't provided to scripts // FIXME: Wouldn't binary file I/O be useful? SQChar* c = (SQChar*)strchr(mode, 'b'); if (c) *c = 0; #if defined(_MSC_VER) && (_MSC_VER >= 1400) if (fopen_s(&files[i], ConvPath(path, SQTrue), mode)) files[i] = NULL; #else files[i] = fopen(ConvPath(path, SQTrue), mode); #endif FILE* res = files[i]; if (res) { sq_pushuserpointer(sqvm, res); ++numFiles; _RPT2(_CRT_WARN, "--- Opened file #%d. %d file(s) are opened.\n", i, numFiles); } else sq_pushnull(sqvm); 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_flush(HSQUIRRELVM v) { SETUP_STREAM(v); if(!self->Flush()) sq_pushinteger(v, 1); else sq_pushnull(v); return 1; }
int CEntityNatives::GetID(SQVM* pVM) { CEntity* pEntity = sq_toentity(pVM, 2); if(pEntity) sq_pushinteger(pVM,pEntity->GetID()); else sq_pushnull(pVM); return 1; }
int CEntityNatives::GetType(SQVM* pVM) { CEntity* pEntity = sq_toentity(pVM, 2); if(pEntity) sq_pushstring(pVM,pEntity->GetTag().Get(),pEntity->GetTag().GetLength()); else sq_pushnull(pVM); return 1; }
static SQRESULT sq_ssl_ctx_find(HSQUIRRELVM v){ SQ_FUNC_VARS_NO_TOP(v); GET_ssl_ctx_INSTANCE(); SQ_GET_INTEGER(v, 2, client_fd); SSL *ssl = ssl_find(self, client_fd); if(ssl) return ssl_constructor(v, ssl, 0); else sq_pushnull(v); return 1; }
/* static */ bool ScriptInstance::LoadObjects(HSQUIRRELVM vm) { SlObject(NULL, _script_byte); switch (_script_sl_byte) { case SQSL_INT: { int value; SlArray(&value, 1, SLE_INT32); if (vm != NULL) sq_pushinteger(vm, (SQInteger)value); return true; } case SQSL_STRING: { SlObject(NULL, _script_byte); static char buf[256]; SlArray(buf, _script_sl_byte, SLE_CHAR); if (vm != NULL) sq_pushstring(vm, OTTD2SQ(buf), -1); return true; } case SQSL_ARRAY: { if (vm != NULL) sq_newarray(vm, 0); while (LoadObjects(vm)) { if (vm != NULL) sq_arrayappend(vm, -2); /* The value is popped from the stack by squirrel. */ } return true; } case SQSL_TABLE: { if (vm != NULL) sq_newtable(vm); while (LoadObjects(vm)) { LoadObjects(vm); if (vm != NULL) sq_rawset(vm, -3); /* The key (-2) and value (-1) are popped from the stack by squirrel. */ } return true; } case SQSL_BOOL: { SlObject(NULL, _script_byte); if (vm != NULL) sq_pushinteger(vm, (SQBool)(_script_sl_byte != 0)); return true; } case SQSL_NULL: { if (vm != NULL) sq_pushnull(vm); return true; } case SQSL_ARRAY_TABLE_END: { return false; } default: NOT_REACHED(); } }
SQInteger Sq_SetLayerRects(HSQUIRRELVM v) { const SQChar *What; sq_getstring(v, 2, &What); int Layer = FindLayerByName(What); if(Layer < 0) { sq_pushnull(v); return 1; } return 0; }
int CVehicleNatives::GetId(SQVM * pVM) { CVehicle * pVehicle = sq_tovehicle(pVM, 2); if(pVehicle) sq_pushinteger(pVM, pVehicle->GetID()); else sq_pushnull(pVM); return 1; }
SQInteger Sq_Interpolate(HSQUIRRELVM v) { const SQChar *Str, *WordString; char Out[4096]; sq_getstring(v, 2, &Str); sq_getstring(v, 3, &WordString); char *Poke = Out; const char *Peek = Str; char WordBuff[strlen(Str)+1]; const char *Word[32]; const char *WordEol[32]; XChatTokenize(WordString, WordBuff, Word, WordEol, 32, TOKENIZE_MULTI_WORD); while(*Peek) { int Span = strcspn(Peek, "%&"); memcpy(Poke, Peek, Span); Poke += Span; Peek += Span; if(*Peek == '%' || *Peek == '&') { char Extra = Peek[1]; if(Extra == '%') *(Poke++) = '%'; else if(Extra == '&') *(Poke++) = '&'; else { if(isdigit(Extra)) { int WhichWord = Extra - '1'; strcpy(Poke, (*Peek=='%')?Word[WhichWord]:WordEol[WhichWord]); Poke = strrchr(Poke, 0); } else { // look in the list of extra words int top = sq_gettop(v);; sq_pushnull(v); //null iterator while(SQ_SUCCEEDED(sq_next(v,-2))) { const SQChar *ThisWord; sq_getstring(v, -1, &ThisWord); if(ThisWord[0]==Extra) { strcpy(Poke, ThisWord+1); Poke = strrchr(Poke, 0); break; } sq_pop(v,2); } sq_pop(v,1); //pops the null iterator sq_settop(v, top); } } Peek+= 2; } } *Poke = 0; sq_pushstring(v, Out, -1); return 1; }
int CPlayerNatives::GetVehicleSeatId(SQVM * pVM) { CPlayer * pPlayer = sq_toplayer(pVM, 2); if(pPlayer && pPlayer->GetVehicle()) sq_pushinteger(pVM, pPlayer->GetVehicleSeatId()); else sq_pushnull(pVM); return 1; }
int CPlayerNatives::GetVehicle(SQVM * pVM) { CPlayer * pPlayer = sq_toplayer(pVM, 2); if(pPlayer) sq_pushentity(pVM, pPlayer->GetVehicle()); else sq_pushnull(pVM); return 1; }
SQInteger ScriptEventAdminPort::GetObject(HSQUIRRELVM vm) { char *p = this->json; if (this->ReadTable(vm, p) == NULL) { sq_pushnull(vm); return 1; } return 1; }