void read_object_properties(lua_State *L, int index, ObjectProperties *prop) { if(index < 0) index = lua_gettop(L) + 1 + index; if(!lua_istable(L, index)) return; prop->hp_max = getintfield_default(L, -1, "hp_max", 10); getboolfield(L, -1, "physical", prop->physical); getboolfield(L, -1, "collide_with_objects", prop->collideWithObjects); getfloatfield(L, -1, "weight", prop->weight); lua_getfield(L, -1, "collisionbox"); if(lua_istable(L, -1)) prop->collisionbox = read_aabb3f(L, -1, 1.0); lua_pop(L, 1); getstringfield(L, -1, "visual", prop->visual); getstringfield(L, -1, "mesh", prop->mesh); lua_getfield(L, -1, "visual_size"); if(lua_istable(L, -1)) prop->visual_size = read_v2f(L, -1); lua_pop(L, 1); lua_getfield(L, -1, "textures"); if(lua_istable(L, -1)){ prop->textures.clear(); int table = lua_gettop(L); lua_pushnil(L); while(lua_next(L, table) != 0){ // key at index -2 and value at index -1 if(lua_isstring(L, -1)) prop->textures.push_back(lua_tostring(L, -1)); else prop->textures.push_back(""); // removes value, keeps key for next iteration lua_pop(L, 1); } } lua_pop(L, 1); lua_getfield(L, -1, "colors"); if(lua_istable(L, -1)){ prop->colors.clear(); int table = lua_gettop(L); lua_pushnil(L); while(lua_next(L, table) != 0){ // key at index -2 and value at index -1 if(lua_isstring(L, -1)) prop->colors.push_back(readARGB8(L, -1)); else prop->colors.push_back(video::SColor(255, 255, 255, 255)); // removes value, keeps key for next iteration lua_pop(L, 1); } } lua_pop(L, 1); lua_getfield(L, -1, "spritediv"); if(lua_istable(L, -1)) prop->spritediv = read_v2s16(L, -1); lua_pop(L, 1); lua_getfield(L, -1, "initial_sprite_basepos"); if(lua_istable(L, -1)) prop->initial_sprite_basepos = read_v2s16(L, -1); lua_pop(L, 1); getboolfield(L, -1, "is_visible", prop->is_visible); getboolfield(L, -1, "makes_footstep_sound", prop->makes_footstep_sound); getfloatfield(L, -1, "automatic_rotate", prop->automatic_rotate); getfloatfield(L, -1, "stepheight", prop->stepheight); prop->stepheight*=BS; getboolfield(L, -1, "automatic_face_movement_dir", prop->automatic_face_movement_dir); }
int lua_Model_getMaterial(lua_State* state) { // Get the number of parameters. int paramCount = lua_gettop(state); // Attempt to match the parameters to a valid binding. switch (paramCount) { case 1: { if ((lua_type(state, 1) == LUA_TUSERDATA)) { Model* instance = getInstance(state); void* returnPtr = ((void*)instance->getMaterial()); if (returnPtr) { gameplay::ScriptUtil::LuaObject* object = (gameplay::ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(gameplay::ScriptUtil::LuaObject)); object->instance = returnPtr; object->owns = false; luaL_getmetatable(state, "Material"); lua_setmetatable(state, -2); } else { lua_pushnil(state); } return 1; } lua_pushstring(state, "lua_Model_getMaterial - Failed to match the given parameters to a valid function signature."); lua_error(state); break; } case 2: { if ((lua_type(state, 1) == LUA_TUSERDATA) && lua_type(state, 2) == LUA_TNUMBER) { // Get parameter 1 off the stack. int param1 = (int)luaL_checkint(state, 2); Model* instance = getInstance(state); void* returnPtr = ((void*)instance->getMaterial(param1)); if (returnPtr) { gameplay::ScriptUtil::LuaObject* object = (gameplay::ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(gameplay::ScriptUtil::LuaObject)); object->instance = returnPtr; object->owns = false; luaL_getmetatable(state, "Material"); lua_setmetatable(state, -2); } else { lua_pushnil(state); } return 1; } lua_pushstring(state, "lua_Model_getMaterial - Failed to match the given parameters to a valid function signature."); lua_error(state); break; } default: { lua_pushstring(state, "Invalid number of parameters (expected 1 or 2)."); lua_error(state); break; } } return 0; }
/* Object type */ static int tolua_bnd_type (lua_State* L) { tolua_typename(L,lua_gettop(L)); return 1; }
static int lgetopt_long_t(lua_State *l, func_t func) { const char *optstring = NULL; int result = 1; /* assume success */ int argc, ch, idx; char **argv = NULL; int error_func = 0; int numargs = lua_gettop(l); if ((numargs != 2 && numargs != 3 && numargs != 4) || lua_type(l,1) != LUA_TSTRING || lua_type(l,2) != LUA_TTABLE || (numargs >= 3 && (lua_type(l,3) != LUA_TTABLE && lua_type(l,3) != LUA_TNIL))) { ERROR("usage: getopt.long(optionstring, longopts[, resulttable[, errorfunc]])"); } if (numargs == 4 && lua_type(l,4) != LUA_TFUNCTION && lua_type(l,4) != LUA_TNIL) { ERROR("usage: getopt.long(optionstring, longopts[, resulttable[, errorfunc]])"); } if (numargs == 4 && lua_type(l,4) == LUA_TFUNCTION) { // We can't copy the error function - but we can make a // registry pointer. error_func = luaL_ref(l, LUA_REGISTRYINDEX); } optstring = lua_tostring(l, 1); /* Construct fake argc/argv from the magic lua 'arg' table. */ lua_getglobal(l, "arg"); construct_args(l, lua_gettop(l), &argc, &argv); lua_pop(l, 1); /* Construct a longopts struct from the one given. */ char **bound_variable_name = NULL; int *bound_variable_value = NULL; struct option *longopts = build_longopts(l, 2, &bound_variable_name, &bound_variable_value); /* Parse the options and store them in the Lua table. */ idx = -1; /* initialize idx to -1 so we can tell whether or not it's * updated by getopt_long (or whatever func() is) */ while ((ch=func(argc, argv, optstring, longopts, &idx)) > -1) { char buf[2] = { ch, 0 }; if (ch == '?' || ch == ':') { /* This is a special "got a bad option" character. Don't put it * in the table of results; just record that there's a failure. * The getopt call will have emitted an error to stderr. */ if (error_func) { lua_rawgeti(l, LUA_REGISTRYINDEX, error_func); lua_pushstring(l, buf); lua_call(l, 1, 0); // 1 argument, 0 results. Not protecting against errors. } result = 0; break; } if (idx == -1) { /* If idx == -1, then it wasn't updated by the library call; * that happens if it matches a short option. We'll have to dig * through and find it ourself. */ struct option *l = longopts; int i = 0; while (l[i].name) { if (l[i].val != 0 && l[i].val == ch) { idx = i; if (l[i].flag != NULL) { /* Fake the longopt "this is a bound variable thing" even * though it was called with a short variable? :/ */ ch = 0; *l[i].flag = l[i].val; } break; } i++; } } else { /* If we matched a long option with a val set, but the 'ch' is zero, * then we need to dig the character out of the option's "val" field * so we can set the captured value appropriately in the return opts. */ if (longopts[idx].val) { buf[0] = longopts[idx].val; if (longopts[idx].val <= 9) { /* Coerce to a character, rather than an integer */ buf[0] += '0'; } } } /* Call any available callbacks for this element, if we found the * element in the longopts struct list. */ if (idx != -1) { _call_callback(l, 2, &longopts[idx]); } /* Save the values in the user-specified return table. */ if (buf[0] && numargs >= 3 && lua_type(l,3) == LUA_TTABLE) { if (optarg) { lua_pushstring(l, optarg); } else { lua_pushboolean(l, 1); } lua_setfield(l, 3, buf); } if (ch == 0) { /* This is the special "bound a variable" return value. Perform * the bind. */ set_lua_variable(l, bound_variable_name[idx], bound_variable_value[idx]); } idx = -1; } /* Since the default behavior of many (but not all) getopt libraries is to * reorder argv so that non-arguments are all at the end (unless * POSIXLY_CORRECT is set or the options string begins with a '+'), we'll * go do that now. We do it by modifying the existing global table, which * will leave index [-1] in place if it's set (as it sometimes is). */ lua_getglobal(l, "arg"); int i; for (i=0; i<argc; i++) { lua_pushinteger(l, i); lua_pushstring(l, argv[i]); lua_rawset(l, -3); } free_longopts(longopts, bound_variable_name, bound_variable_value); free_args(argc, argv); if (error_func) { luaL_unref(l, LUA_REGISTRYINDEX, error_func); } /* Return 1 item on the stack (boolean) */ lua_pushboolean(l, result); return 1; /* # of arguments returned on stack */ }
static SoupCookie* cookie_new_from_table(lua_State *L, gint idx, gchar **error) { SoupCookie *cookie = NULL; SoupDate *date; const gchar *name, *value, *domain, *path; name = value = domain = path = NULL; gboolean secure, http_only; gint expires; /* correct relative index */ if (idx < 0) idx = lua_gettop(L) + idx + 1; /* check for cookie table */ if (!lua_istable(L, idx)) { *error = g_strdup_printf("invalid cookie table, got %s", lua_typename(L, lua_type(L, idx))); return NULL; } #define IS_STRING (lua_isstring(L, -1) || lua_isnumber(L, -1)) #define IS_BOOLEAN (lua_isboolean(L, -1) || lua_isnil(L, -1)) #define IS_NUMBER (lua_isnumber(L, -1)) #define GET_PROP(prop, typname, typexpr, typfunc) \ lua_pushliteral(L, #prop); \ lua_rawget(L, idx); \ if ((typexpr)) { \ prop = typfunc(L, -1); \ lua_pop(L, 1); \ } else { \ *error = g_strdup_printf("invalid cookie." #prop " type, expected " \ #typname ", got %s", lua_typename(L, lua_type(L, -1))); \ return NULL; \ } /* get cookie properties */ GET_PROP(name, string, IS_STRING, lua_tostring) GET_PROP(value, string, IS_STRING, lua_tostring) GET_PROP(domain, string, IS_STRING, lua_tostring) GET_PROP(path, string, IS_STRING, lua_tostring) GET_PROP(secure, boolean, IS_BOOLEAN, lua_toboolean) GET_PROP(http_only, boolean, IS_BOOLEAN, lua_toboolean) GET_PROP(expires, number, IS_NUMBER, lua_tonumber) #undef IS_STRING #undef IS_BOOLEAN #undef IS_NUMBER #undef GET_PROP /* create soup cookie */ if ((cookie = soup_cookie_new(name, value, domain, path, expires))) { soup_cookie_set_secure(cookie, secure); soup_cookie_set_http_only(cookie, http_only); /* set real expiry date from unixtime */ if (expires > 0) { date = soup_date_new_from_time_t((time_t) expires); soup_cookie_set_expires(cookie, date); soup_date_free(date); } return cookie; } /* soup cookie creation failed */ *error = g_strdup_printf("soup cookie creation failed"); return NULL; }
static void luayaml_push(LuaValue& value, lua_State *L, const char* name) { value.push(L); int tableind = lua_gettop(L); lua_getfield(L, tableind, name); lua_replace(L, tableind); }
/** * @brief Gets a planet. * * Possible values of param: * - nil : -OBSOLETE- Gets the current landed planet or nil if there is none. Use planet.cur() instead. * - bool : Gets a random planet. * - faction : Gets random planet belonging to faction matching the number. * - string : Gets the planet by name. * - table : Gets random planet belonging to any of the factions in the * table. * * @usage p,s = planet.get( "Anecu" ) -- Gets planet by name * @usage p,s = planet.get( faction.get( "Empire" ) ) -- Gets random Empire planet * @usage p,s = planet.get(true) -- Gets completely random planet * @usage p,s = planet.get( { faction.get("Empire"), faction.get("Dvaered") } ) -- Random planet belonging to Empire or Dvaered * @luaparam param See description. * @luareturn Returns the planet and the system it belongs to. * @luafunc get( param ) */ static int planetL_get( lua_State *L ) { int i; int *factions; int nfactions; char **planets; int nplanets; const char *rndplanet; LuaPlanet planet; LuaSystem luasys; LuaFaction *f; Planet *pnt; StarSystem *sys; char *sysname; rndplanet = NULL; planets = NULL; nplanets = 0; /* Get the landed planet */ if (lua_gettop(L) == 0) { if (land_planet != NULL) { planet.id = planet_index( land_planet ); lua_pushplanet(L,planet); luasys.id = system_index( system_get( planet_getSystem(land_planet->name) ) ); lua_pushsystem(L,luasys); return 2; } NLUA_ERROR(L,"Attempting to get landed planet when player not landed."); return 0; /* Not landed. */ } /* If boolean return random. */ else if (lua_isboolean(L,1)) { pnt = planet_get( space_getRndPlanet() ); planet.id = planet_index( pnt ); lua_pushplanet(L,planet); luasys.id = system_index( system_get( planet_getSystem(pnt->name) ) ); lua_pushsystem(L,luasys); return 2; } /* Get a planet by faction */ else if (lua_isfaction(L,1)) { f = lua_tofaction(L,1); planets = space_getFactionPlanet( &nplanets, &f->f, 1 ); } /* Get a planet by name */ else if (lua_isstring(L,1)) { rndplanet = lua_tostring(L,1); } /* Get a planet from faction list */ else if (lua_istable(L,1)) { /* Get table length and preallocate. */ nfactions = (int) lua_objlen(L,1); factions = malloc( sizeof(int) * nfactions ); /* Load up the table. */ lua_pushnil(L); i = 0; while (lua_next(L, -2) != 0) { f = lua_tofaction(L, -1); factions[i++] = f->f; lua_pop(L,1); } /* get the planets */ planets = space_getFactionPlanet( &nplanets, factions, nfactions ); free(factions); } else NLUA_INVALID_PARAMETER(L); /* Bad Parameter */ /* No suitable planet found */ if ((rndplanet == NULL) && ((planets == NULL) || nplanets == 0)) return 0; /* Pick random planet */ else if (rndplanet == NULL) { rndplanet = planets[RNG(0,nplanets-1)]; free(planets); } /* Push the planet */ pnt = planet_get(rndplanet); /* The real planet */ if (pnt == NULL) { NLUA_ERROR(L, "Planet '%s' not found in stack", rndplanet); return 0; } sysname = planet_getSystem(rndplanet); if (sysname == NULL) { NLUA_ERROR(L, "Planet '%s' is not placed in a system", rndplanet); return 0; } sys = system_get( sysname ); if (sys == NULL) { NLUA_ERROR(L, "Planet '%s' can't find system '%s'", rndplanet, sysname); return 0; } planet.id = planet_index( pnt ); lua_pushplanet(L,planet); luasys.id = system_index( sys ); lua_pushsystem(L,luasys); return 2; }
static int mc_eigen(lua_State *L) /* (-1,+2,e) */ { mMatComplex *m = qlua_checkMatComplex(L, 1); gsl_matrix_complex_view mx; gsl_eigen_hermv_workspace *w; gsl_vector *ev; mVecReal *lambda; mMatComplex *trans; mMatComplex *tmp; int n; int i; int lo, hi; switch (lua_gettop(L)) { case 1: if (m->l_size != m->r_size) return luaL_error(L, "matrix:eigen() expects square matrix"); lo = 0; hi = m->l_size; break; case 2: lo = 0; hi = luaL_checkint(L, 2); if ((hi > m->l_size) || (hi > m->r_size)) return slice_out(L); break; case 3: lo = luaL_checkint(L, 2); hi = luaL_checkint(L, 3); if ((lo >= hi) || (lo > m->l_size) || (lo > m->r_size) || (hi > m->l_size) || (hi > m->r_size)) return slice_out(L); break; default: return luaL_error(L, "matrix:eigen(): illegal arguments"); } n = hi - lo; mx = gsl_matrix_complex_submatrix(m->m, lo, lo, n, n); tmp = qlua_newMatComplex(L, n, n); gsl_matrix_complex_memcpy(tmp->m, &mx.matrix); lambda = qlua_newVecReal(L, n); trans = qlua_newMatComplex(L, n, n); ev = new_gsl_vector(L, n); w = gsl_eigen_hermv_alloc(n); if (w == 0) { lua_gc(L, LUA_GCCOLLECT, 0); w = gsl_eigen_hermv_alloc(n); if (w == 0) luaL_error(L, "not enough memory"); } if (gsl_eigen_hermv(tmp->m, ev, trans->m, w)) luaL_error(L, "matrix:eigen() failed"); if (gsl_eigen_hermv_sort(ev, trans->m, GSL_EIGEN_SORT_VAL_ASC)) luaL_error(L, "matrix:eigen() eigenvalue ordering failed"); for (i = 0; i < n; i++) lambda->val[i] = gsl_vector_get(ev, i); gsl_vector_free(ev); gsl_eigen_hermv_free(w); return 2; }
int LuaParser::_EventItem(std::string package_name, QuestEventID evt, Client *client, EQEmu::ItemInstance *item, Mob *mob, std::string data, uint32 extra_data, std::vector<EQEmu::Any> *extra_pointers, luabind::adl::object *l_func) { const char *sub_name = LuaEvents[evt]; int start = lua_gettop(L); try { int npop = 1; if(l_func != nullptr) { l_func->push(L); } else { lua_getfield(L, LUA_REGISTRYINDEX, package_name.c_str()); lua_getfield(L, -1, sub_name); } lua_createtable(L, 0, 0); //always push self Lua_ItemInst l_item(item); luabind::adl::object l_item_o = luabind::adl::object(L, l_item); l_item_o.push(L); lua_setfield(L, -2, "self"); Lua_Client l_client(client); luabind::adl::object l_client_o = luabind::adl::object(L, l_client); l_client_o.push(L); lua_setfield(L, -2, "owner"); //redo this arg function auto arg_function = ItemArgumentDispatch[evt]; arg_function(this, L, client, item, mob, data, extra_data, extra_pointers); quest_manager.StartQuest(client, client, item); if(lua_pcall(L, 1, 1, 0)) { std::string error = lua_tostring(L, -1); AddError(error); quest_manager.EndQuest(); return 0; } quest_manager.EndQuest(); if(lua_isnumber(L, -1)) { int ret = static_cast<int>(lua_tointeger(L, -1)); lua_pop(L, npop); return ret; } lua_pop(L, npop); } catch(std::exception &ex) { std::string error = "Lua Exception: "; error += std::string(ex.what()); AddError(error); //Restore our stack to the best of our ability int end = lua_gettop(L); int n = end - start; if(n > 0) { lua_pop(L, n); } } return 0; }
bool read_schematic(lua_State *L, int index, DecoSchematic *dschem, Server *server) { if (index < 0) index = lua_gettop(L) + 1 + index; INodeDefManager *ndef = server->getNodeDefManager(); if (lua_istable(L, index)) { lua_getfield(L, index, "size"); v3s16 size = read_v3s16(L, -1); lua_pop(L, 1); int numnodes = size.X * size.Y * size.Z; MapNode *schemdata = new MapNode[numnodes]; int i = 0; lua_getfield(L, index, "data"); luaL_checktype(L, -1, LUA_TTABLE); lua_pushnil(L); while (lua_next(L, -2)) { if (i < numnodes) { // same as readnode, except param1 default is MTSCHEM_PROB_CONST lua_getfield(L, -1, "name"); const char *name = luaL_checkstring(L, -1); lua_pop(L, 1); u8 param1; lua_getfield(L, -1, "param1"); param1 = !lua_isnil(L, -1) ? lua_tonumber(L, -1) : MTSCHEM_PROB_ALWAYS; lua_pop(L, 1); u8 param2; lua_getfield(L, -1, "param2"); param2 = !lua_isnil(L, -1) ? lua_tonumber(L, -1) : 0; lua_pop(L, 1); schemdata[i] = MapNode(ndef, name, param1, param2); } i++; lua_pop(L, 1); } dschem->size = size; dschem->schematic = schemdata; if (i != numnodes) { errorstream << "read_schematic: incorrect number of " "nodes provided in raw schematic data (got " << i << ", expected " << numnodes << ")." << std::endl; return false; } } else if (lua_isstring(L, index)) { dschem->filename = std::string(lua_tostring(L, index)); } else { errorstream << "read_schematic: missing schematic " "filename or raw schematic data" << std::endl; return false; } return true; }
bool luaW_toconfig(lua_State *L, int index, config &cfg) { if (!lua_checkstack(L, LUA_MINSTACK)) return false; // Get the absolute index of the table. index = lua_absindex(L, index); int initial_top = lua_gettop(L); switch (lua_type(L, index)) { case LUA_TTABLE: break; case LUA_TUSERDATA: { if (vconfig * ptr = static_cast<vconfig *> (luaL_testudata(L, index, vconfigKey))) { cfg = ptr->get_parsed_config(); return true; } else { return false; } } case LUA_TNONE: case LUA_TNIL: return true; default: return false; } // First convert the children (integer indices). for (int i = 1, i_end = lua_rawlen(L, index); i <= i_end; ++i) { lua_rawgeti(L, index, i); if (!lua_istable(L, -1)) return_misformed(); lua_rawgeti(L, -1, 1); char const *m = lua_tostring(L, -1); if (!m) return_misformed(); lua_rawgeti(L, -2, 2); if (!luaW_toconfig(L, -1, cfg.add_child(m))) return_misformed(); lua_pop(L, 3); } // Then convert the attributes (string indices). for (lua_pushnil(L); lua_next(L, index); lua_pop(L, 1)) { if (lua_isnumber(L, -2)) continue; if (!lua_isstring(L, -2)) return_misformed(); config::attribute_value &v = cfg[lua_tostring(L, -2)]; if (lua_istable(L, -1)) { int subindex = lua_absindex(L, -1); std::ostringstream str; for (int i = 1, i_end = lua_rawlen(L, subindex); i <= i_end; ++i, lua_pop(L, 1)) { lua_rawgeti(L, -1, i); config::attribute_value item; if (!luaW_toscalar(L, -1, item)) return_misformed(); if (i > 1) str << ','; str << item; } // If there are any string keys, it's misformed for (lua_pushnil(L); lua_next(L, subindex); lua_pop(L, 1)) { if (!lua_isnumber(L, -2)) return_misformed(); } v = str.str(); } else if (!luaW_toscalar(L, -1, v)) return_misformed(); } lua_settop(L, initial_top); return true; }
ToolCapabilities read_tool_capabilities( lua_State *L, int table) { ToolCapabilities toolcap; getfloatfield(L, table, "full_punch_interval", toolcap.full_punch_interval); getintfield(L, table, "max_drop_level", toolcap.max_drop_level); lua_getfield(L, table, "groupcaps"); if(lua_istable(L, -1)){ int table_groupcaps = lua_gettop(L); lua_pushnil(L); while(lua_next(L, table_groupcaps) != 0){ // key at index -2 and value at index -1 std::string groupname = luaL_checkstring(L, -2); if(lua_istable(L, -1)){ int table_groupcap = lua_gettop(L); // This will be created ToolGroupCap groupcap; // Read simple parameters getintfield(L, table_groupcap, "maxlevel", groupcap.maxlevel); getintfield(L, table_groupcap, "uses", groupcap.uses); // DEPRECATED: maxwear float maxwear = 0; if(getfloatfield(L, table_groupcap, "maxwear", maxwear)){ if(maxwear != 0) groupcap.uses = 1.0/maxwear; else groupcap.uses = 0; infostream<<script_get_backtrace(L)<<std::endl; infostream<<"WARNING: field \"maxwear\" is deprecated; " <<"should replace with uses=1/maxwear"<<std::endl; } // Read "times" table lua_getfield(L, table_groupcap, "times"); if(lua_istable(L, -1)){ int table_times = lua_gettop(L); lua_pushnil(L); while(lua_next(L, table_times) != 0){ // key at index -2 and value at index -1 int rating = luaL_checkinteger(L, -2); float time = luaL_checknumber(L, -1); groupcap.times[rating] = time; // removes value, keeps key for next iteration lua_pop(L, 1); } } lua_pop(L, 1); // Insert groupcap into toolcap toolcap.groupcaps[groupname] = groupcap; } // removes value, keeps key for next iteration lua_pop(L, 1); } } lua_pop(L, 1); lua_getfield(L, table, "damage_groups"); if(lua_istable(L, -1)){ int table_damage_groups = lua_gettop(L); lua_pushnil(L); while(lua_next(L, table_damage_groups) != 0){ // key at index -2 and value at index -1 std::string groupname = luaL_checkstring(L, -2); u16 value = luaL_checkinteger(L, -1); toolcap.damageGroups[groupname] = value; // removes value, keeps key for next iteration lua_pop(L, 1); } } lua_pop(L, 1); return toolcap; }
ItemDefinition read_item_definition(lua_State* L,int index, ItemDefinition default_def) { if(index < 0) index = lua_gettop(L) + 1 + index; // Read the item definition ItemDefinition def = default_def; def.type = (ItemType)getenumfield(L, index, "type", es_ItemType, ITEM_NONE); getstringfield(L, index, "name", def.name); getstringfield(L, index, "description", def.description); getstringfield(L, index, "inventory_image", def.inventory_image); getstringfield(L, index, "wield_image", def.wield_image); lua_getfield(L, index, "wield_scale"); if(lua_istable(L, -1)){ def.wield_scale = check_v3f(L, -1); } lua_pop(L, 1); def.stack_max = getintfield_default(L, index, "stack_max", def.stack_max); if(def.stack_max == 0) def.stack_max = 1; lua_getfield(L, index, "on_use"); def.usable = lua_isfunction(L, -1); lua_pop(L, 1); getboolfield(L, index, "liquids_pointable", def.liquids_pointable); warn_if_field_exists(L, index, "tool_digging_properties", "deprecated: use tool_capabilities"); lua_getfield(L, index, "tool_capabilities"); if(lua_istable(L, -1)){ def.tool_capabilities = new ToolCapabilities( read_tool_capabilities(L, -1)); } // If name is "" (hand), ensure there are ToolCapabilities // because it will be looked up there whenever any other item has // no ToolCapabilities if(def.name == "" && def.tool_capabilities == NULL){ def.tool_capabilities = new ToolCapabilities(); } lua_getfield(L, index, "groups"); read_groups(L, -1, def.groups); lua_pop(L, 1); lua_getfield(L, index, "sounds"); if(lua_istable(L, -1)){ lua_getfield(L, -1, "place"); read_soundspec(L, -1, def.sound_place); lua_pop(L, 1); } lua_pop(L, 1); def.range = getfloatfield_default(L, index, "range", def.range); // Client shall immediately place this node when player places the item. // Server will update the precise end result a moment later. // "" = no prediction getstringfield(L, index, "node_placement_prediction", def.node_placement_prediction); return def; }
ContentFeatures read_content_features(lua_State *L, int index) { if(index < 0) index = lua_gettop(L) + 1 + index; ContentFeatures f; /* Cache existence of some callbacks */ lua_getfield(L, index, "on_construct"); if(!lua_isnil(L, -1)) f.has_on_construct = true; lua_pop(L, 1); lua_getfield(L, index, "on_destruct"); if(!lua_isnil(L, -1)) f.has_on_destruct = true; lua_pop(L, 1); lua_getfield(L, index, "after_destruct"); if(!lua_isnil(L, -1)) f.has_after_destruct = true; lua_pop(L, 1); lua_getfield(L, index, "on_rightclick"); f.rightclickable = lua_isfunction(L, -1); lua_pop(L, 1); /* Name */ getstringfield(L, index, "name", f.name); /* Groups */ lua_getfield(L, index, "groups"); read_groups(L, -1, f.groups); lua_pop(L, 1); /* Visual definition */ f.drawtype = (NodeDrawType)getenumfield(L, index, "drawtype", ScriptApiNode::es_DrawType,NDT_NORMAL); getfloatfield(L, index, "visual_scale", f.visual_scale); // tiles = {} lua_getfield(L, index, "tiles"); // If nil, try the deprecated name "tile_images" instead if(lua_isnil(L, -1)){ lua_pop(L, 1); warn_if_field_exists(L, index, "tile_images", "Deprecated; new name is \"tiles\"."); lua_getfield(L, index, "tile_images"); } if(lua_istable(L, -1)){ int table = lua_gettop(L); lua_pushnil(L); int i = 0; while(lua_next(L, table) != 0){ // Read tiledef from value f.tiledef[i] = read_tiledef(L, -1); // removes value, keeps key for next iteration lua_pop(L, 1); i++; if(i==6){ lua_pop(L, 1); break; } } // Copy last value to all remaining textures if(i >= 1){ TileDef lasttile = f.tiledef[i-1]; while(i < 6){ f.tiledef[i] = lasttile; i++; } } } lua_pop(L, 1); // special_tiles = {} lua_getfield(L, index, "special_tiles"); // If nil, try the deprecated name "special_materials" instead if(lua_isnil(L, -1)){ lua_pop(L, 1); warn_if_field_exists(L, index, "special_materials", "Deprecated; new name is \"special_tiles\"."); lua_getfield(L, index, "special_materials"); } if(lua_istable(L, -1)){ int table = lua_gettop(L); lua_pushnil(L); int i = 0; while(lua_next(L, table) != 0){ // Read tiledef from value f.tiledef_special[i] = read_tiledef(L, -1); // removes value, keeps key for next iteration lua_pop(L, 1); i++; if(i==6){ lua_pop(L, 1); break; } } } lua_pop(L, 1); f.alpha = getintfield_default(L, index, "alpha", 255); bool usealpha = getboolfield_default(L, index, "use_texture_alpha", false); if (usealpha) f.alpha = 0; /* Other stuff */ lua_getfield(L, index, "post_effect_color"); if(!lua_isnil(L, -1)) f.post_effect_color = readARGB8(L, -1); lua_pop(L, 1); f.param_type = (ContentParamType)getenumfield(L, index, "paramtype", ScriptApiNode::es_ContentParamType, CPT_NONE); f.param_type_2 = (ContentParamType2)getenumfield(L, index, "paramtype2", ScriptApiNode::es_ContentParamType2, CPT2_NONE); // Warn about some deprecated fields warn_if_field_exists(L, index, "wall_mounted", "deprecated: use paramtype2 = 'wallmounted'"); warn_if_field_exists(L, index, "light_propagates", "deprecated: determined from paramtype"); warn_if_field_exists(L, index, "dug_item", "deprecated: use 'drop' field"); warn_if_field_exists(L, index, "extra_dug_item", "deprecated: use 'drop' field"); warn_if_field_exists(L, index, "extra_dug_item_rarity", "deprecated: use 'drop' field"); warn_if_field_exists(L, index, "metadata_name", "deprecated: use on_add and metadata callbacks"); // True for all ground-like things like stone and mud, false for eg. trees getboolfield(L, index, "is_ground_content", f.is_ground_content); f.light_propagates = (f.param_type == CPT_LIGHT); getboolfield(L, index, "sunlight_propagates", f.sunlight_propagates); // This is used for collision detection. // Also for general solidness queries. getboolfield(L, index, "walkable", f.walkable); // Player can point to these getboolfield(L, index, "pointable", f.pointable); // Player can dig these getboolfield(L, index, "diggable", f.diggable); // Player can climb these getboolfield(L, index, "climbable", f.climbable); // Player can build on these getboolfield(L, index, "buildable_to", f.buildable_to); // Whether the node is non-liquid, source liquid or flowing liquid f.liquid_type = (LiquidType)getenumfield(L, index, "liquidtype", ScriptApiNode::es_LiquidType, LIQUID_NONE); // If the content is liquid, this is the flowing version of the liquid. getstringfield(L, index, "liquid_alternative_flowing", f.liquid_alternative_flowing); // If the content is liquid, this is the source version of the liquid. getstringfield(L, index, "liquid_alternative_source", f.liquid_alternative_source); // Viscosity for fluid flow, ranging from 1 to 7, with // 1 giving almost instantaneous propagation and 7 being // the slowest possible f.liquid_viscosity = getintfield_default(L, index, "liquid_viscosity", f.liquid_viscosity); f.liquid_range = getintfield_default(L, index, "liquid_range", f.liquid_range); f.leveled = getintfield_default(L, index, "leveled", f.leveled); getboolfield(L, index, "liquid_renewable", f.liquid_renewable); getstringfield(L, index, "freezemelt", f.freezemelt); f.drowning = getintfield_default(L, index, "drowning", f.drowning); // Amount of light the node emits f.light_source = getintfield_default(L, index, "light_source", f.light_source); f.damage_per_second = getintfield_default(L, index, "damage_per_second", f.damage_per_second); lua_getfield(L, index, "node_box"); if(lua_istable(L, -1)) f.node_box = read_nodebox(L, -1); lua_pop(L, 1); lua_getfield(L, index, "selection_box"); if(lua_istable(L, -1)) f.selection_box = read_nodebox(L, -1); lua_pop(L, 1); // Set to true if paramtype used to be 'facedir_simple' getboolfield(L, index, "legacy_facedir_simple", f.legacy_facedir_simple); // Set to true if wall_mounted used to be set to true getboolfield(L, index, "legacy_wallmounted", f.legacy_wallmounted); // Sound table lua_getfield(L, index, "sounds"); if(lua_istable(L, -1)){ lua_getfield(L, -1, "footstep"); read_soundspec(L, -1, f.sound_footstep); lua_pop(L, 1); lua_getfield(L, -1, "dig"); read_soundspec(L, -1, f.sound_dig); lua_pop(L, 1); lua_getfield(L, -1, "dug"); read_soundspec(L, -1, f.sound_dug); lua_pop(L, 1); } lua_pop(L, 1); return f; }
static int lua_iso8583_pack(lua_State *L) { iso8583_userdata *iso8583u; char error[BUFSIZ]; int n = lua_gettop(L); unsigned int iso8583_maxsize = ISO8583_MAXSIZE; unsigned char iso8583_data[ISO8583_MAXSIZE]; if (n < 2) { lua_pushnil(L); lua_pushstring(L, "arguments error! too small!"); return 2; } iso8583u = (iso8583_userdata *)luaL_checkudata(L, 1, "iso8583"); if (!lua_istable(L, 2)) { lua_pushnil(L); lua_pushstring(L, "argument error! data must be table!"); return 2; } lua_pushnil(L); while(lua_next(L, 2) != 0) { if (lua_isnumber(L, -2)) { int i = lua_tointeger(L, -2); if (i >= 0 && i <= 128) { size_t size; const unsigned char *data; if (!lua_isstring(L, -1)) { lua_pushnil(L); snprintf(error, BUFSIZ, "data %d error! is not a string!", i); lua_pushstring(L, error); return 2; } data = (const unsigned char *)lua_tolstring(L, -1, &size); if (iso8583_set(iso8583u->handle, i, data, (unsigned int)size) != ISO8583_OK) { lua_pushnil(L); snprintf(error, BUFSIZ, "data %d error!", i); lua_pushstring(L, error); return 2; } } } lua_pop(L, 1); } lua_pop(L, 1); if (iso8583_pack(iso8583u->handle, iso8583_data, &iso8583_maxsize) != ISO8583_OK) { lua_pushnil(L); snprintf(error, BUFSIZ, "pack iso8583 error! %s", iso8583u->handle->error); lua_pushstring(L, error); return 2; } lua_pushlstring(L, (const char *)iso8583_data, iso8583_maxsize); return 1; }
int LuaParser::_EventSpell(std::string package_name, QuestEventID evt, NPC* npc, Client *client, uint32 spell_id, uint32 extra_data, std::vector<EQEmu::Any> *extra_pointers, luabind::adl::object *l_func) { const char *sub_name = LuaEvents[evt]; int start = lua_gettop(L); try { int npop = 1; if(l_func != nullptr) { l_func->push(L); } else { lua_getfield(L, LUA_REGISTRYINDEX, package_name.c_str()); lua_getfield(L, -1, sub_name); npop = 2; } lua_createtable(L, 0, 0); //always push self even if invalid if(IsValidSpell(spell_id)) { Lua_Spell l_spell(&spells[spell_id]); luabind::adl::object l_spell_o = luabind::adl::object(L, l_spell); l_spell_o.push(L); } else { Lua_Spell l_spell(nullptr); luabind::adl::object l_spell_o = luabind::adl::object(L, l_spell); l_spell_o.push(L); } lua_setfield(L, -2, "self"); auto arg_function = SpellArgumentDispatch[evt]; arg_function(this, L, npc, client, spell_id, extra_data, extra_pointers); quest_manager.StartQuest(npc, client, nullptr); if(lua_pcall(L, 1, 1, 0)) { std::string error = lua_tostring(L, -1); AddError(error); quest_manager.EndQuest(); return 0; } quest_manager.EndQuest(); if(lua_isnumber(L, -1)) { int ret = static_cast<int>(lua_tointeger(L, -1)); lua_pop(L, npop); return ret; } lua_pop(L, npop); } catch(std::exception &ex) { std::string error = "Lua Exception: "; error += std::string(ex.what()); AddError(error); //Restore our stack to the best of our ability int end = lua_gettop(L); int n = end - start; if(n > 0) { lua_pop(L, n); } } return 0; }
/// Returns the current Lua stack size inline int GetStackSize() const { return lua_gettop(this->L); }
void CLuaRules::Cob2Lua(const LuaHashString& name, const CUnit* unit, int& argsCount, int args[MAX_LUA_COB_ARGS]) { static int callDepth = 0; if (callDepth >= 16) { logOutput.Print("CLuaRules::Cob2Lua() call overflow: %s\n", name.GetString().c_str()); args[0] = 0; // failure return; } LUA_CALL_IN_CHECK(L); const int top = lua_gettop(L); if (!lua_checkstack(L, 1 + 3 + argsCount)) { logOutput.Print("CLuaRules::Cob2Lua() lua_checkstack() error: %s\n", name.GetString().c_str()); args[0] = 0; // failure lua_settop(L, top); return; } if (!name.GetGlobalFunc(L)) { logOutput.Print("CLuaRules::Cob2Lua() missing function: %s\n", name.GetString().c_str()); args[0] = 0; // failure lua_settop(L, top); return; } lua_pushnumber(L, unit->id); lua_pushnumber(L, unit->unitDef->id); lua_pushnumber(L, unit->team); for (int a = 0; a < argsCount; a++) { lua_pushnumber(L, args[a]); } // call the routine callDepth++; const int* oldArgs = currentCobArgs; currentCobArgs = args; const bool error = !RunCallIn(name, 3 + argsCount, LUA_MULTRET); currentCobArgs = oldArgs; callDepth--; // bail on error if (error) { args[0] = 0; // failure lua_settop(L, top); return; } // get the results const int retArgs = std::min(lua_gettop(L) - top, (MAX_LUA_COB_ARGS - 1)); for (int a = 1; a <= retArgs; a++) { const int index = (a + top); if (lua_isnumber(L, index)) { args[a] = lua_toint(L, index); } else if (lua_isboolean(L, index)) { args[a] = lua_toboolean(L, index) ? 1 : 0; } else if (lua_istable(L, index)) { lua_rawgeti(L, index, 1); lua_rawgeti(L, index, 2); if (lua_isnumber(L, -2) && lua_isnumber(L, -1)) { const int x = lua_toint(L, -2); const int z = lua_toint(L, -1); args[a] = PACKXZ(x, z); } else { args[a] = 0; } lua_pop(L, 2); } else { args[a] = 0; } } args[0] = 1; // success lua_settop(L, top); return; }
/* * Returns: processors_load_average (number), is_per_cpu (boolean) */ static int sys_loadavg (lua_State *L) { double loadavg; #ifndef _WIN32 const int res = 0; if (getloadavg(&loadavg, 1) == 1) { const int is_per_cpu = 1; #else const int res = getloadavg(&loadavg); if (!res) { const int is_per_cpu = 0; #endif lua_pushnumber(L, (lua_Number) loadavg); lua_pushboolean(L, is_per_cpu); return 2; } return sys_seterror(L, res); } /* * Arguments: [number_of_files (number)] * Returns: number_of_files (number) */ static int sys_limit_nfiles (lua_State *L) { #ifndef _WIN32 const int narg = lua_gettop(L); struct rlimit rlim; rlim.rlim_max = 0; getrlimit(RLIMIT_NOFILE, &rlim); lua_pushinteger(L, rlim.rlim_max); if (narg != 0) { const int n = lua_tointeger(L, 1); rlim.rlim_cur = rlim.rlim_max = n; if (setrlimit(RLIMIT_NOFILE, &rlim)) return sys_seterror(L, 0); } return 1; #else (void) L; lua_pushinteger(L, -1); return 1; #endif } /* * Arguments: string * Returns: number */ static int sys_toint (lua_State *L) { const char *s = lua_tostring(L, 1); int num = 0, sign = 1; if (s) { switch (*s) { case '-': sign = -1; case '+': ++s; } while (*s >= '0' && *s <= '9') num = (num << 3) + (num << 1) + (*s++ & ~'0'); } lua_pushinteger(L, sign * num); return 1; } /* * Arguments: error_handler (function), function, any ... * Returns: status (boolean), any ... */ static int sys_xpcall (lua_State *L) { const int status = lua_pcall(L, lua_gettop(L) - 2, LUA_MULTRET, 1); lua_pushboolean(L, !status); lua_insert(L, 2); return lua_gettop(L) - 1; } #include "isa/fcgi/sys_fcgi.c" #include "mem/sys_mem.c" #include "thread/sys_thread.c" #ifndef _WIN32 #include "sys_unix.c" #else #include "win32/sys_win32.c" #endif #include "sys_file.c" #include "sys_date.c" #include "sys_env.c" #include "sys_evq.c" #include "sys_fs.c" #include "sys_log.c" #include "sys_proc.c" #include "sys_rand.c" static luaL_Reg sys_lib[] = { {"strerror", sys_strerror}, {"nprocs", sys_nprocs}, {"loadavg", sys_loadavg}, {"limit_nfiles", sys_limit_nfiles}, {"toint", sys_toint}, {"xpcall", sys_xpcall}, DATE_METHODS, ENV_METHODS, EVQ_METHODS, FCGI_METHODS, FD_METHODS, FS_METHODS, LOG_METHODS, PROC_METHODS, RAND_METHODS, #ifndef _WIN32 UNIX_METHODS, #endif {NULL, NULL} }; /* * Arguments: ..., sys_lib (table) */ static void createmeta (lua_State *L) { const int top = lua_gettop(L); const struct meta_s { const char *tname; luaL_Reg *meth; int is_index; } meta[] = { {DIR_TYPENAME, dir_meth, 0}, {EVQ_TYPENAME, evq_meth, 1}, {FD_TYPENAME, fd_meth, 1}, {PERIOD_TYPENAME, period_meth, 1}, {PID_TYPENAME, pid_meth, 1}, {LOG_TYPENAME, log_meth, 0}, {RAND_TYPENAME, rand_meth, 0}, }; int i; for (i = 0; i < (int) (sizeof(meta) / sizeof(struct meta_s)); ++i) { luaL_newmetatable(L, meta[i].tname); if (meta[i].is_index) { lua_pushvalue(L, -1); /* push metatable */ lua_setfield(L, -2, "__index"); /* metatable.__index = metatable */ } luaL_setfuncs(L, meta[i].meth, 0); lua_pop(L, 1); } /* Predefined file handles */ luaL_getmetatable(L, FD_TYPENAME); { const char *std[] = {"stdin", "stdout", "stderr"}; for (i = 3; i--; ) { #ifndef _WIN32 const fd_t fd = i; #else const fd_t fd = GetStdHandle(i == 0 ? STD_INPUT_HANDLE : (i == 1 ? STD_OUTPUT_HANDLE : STD_ERROR_HANDLE)); #endif lua_pushstring(L, std[i]); lua_boxinteger(L, fd); lua_pushvalue(L, -3); /* metatable */ lua_pushboolean(L, 1); lua_rawseti(L, -2, (int) ((lua_Integer) fd)); /* don't close std. handles */ lua_setmetatable(L, -2); lua_rawset(L, top); } } lua_settop(L, top); } LUALIB_API int luaopen_sys (lua_State *L) { luaL_register(L, LUA_SYSLIBNAME, sys_lib); createmeta(L); signal_init(); #ifdef _WIN32 luaopen_sys_win32(L); #endif luaopen_sys_mem(L); luaopen_sys_thread(L); return 1; }
int end(luaState& L) { return lua_gettop(L); };
/* Call(). */ int32 Call( lua_State *_pState, const char *_pFunc, const char *_pSig, ... ) { ASSERT( _pState != NULL ); uint32 stackSizeIn = static_cast<uint32>(lua_gettop( _pState )); if( stackSizeIn != 0 ) { g_Log->Error( "Lua stack not empty..." ); return 0; } int delta = 0; va_list pArg; //try { // Number of arguments and results. int narg, nres; // Get function. lua_getglobal( _pState, _pFunc ); // Push arguments. narg = 0; char *pBinarySource = NULL; int32 binaryLen = 0; // Gimme args. va_start( pArg, _pSig ); while( *_pSig ) { // Push arguments. switch( *_pSig++ ) { case 'd': // Double argument. lua_pushnumber( _pState, va_arg( pArg, fp8 ) ); break; case 'i': // Int argument. lua_pushinteger( _pState, va_arg( pArg, int32 ) ); break; case 'b': // Bool argument. lua_pushboolean( _pState, va_arg( pArg, int32 ) != 0 ); break; case 'x': // Binary string argument. Next argument MUST be an integer. (which will be skipped) pBinarySource = va_arg( pArg, char * ); binaryLen = va_arg( pArg, int32 ); lua_pushlstring( _pState, pBinarySource, static_cast<size_t>(binaryLen) ); _pSig++; break; case 's': // String argument. lua_pushstring( _pState, va_arg( pArg, char * ) ); break; case '>': goto endwhileLabel; default: { g_Log->Error( "Invalid option (%c)", *(_pSig - 1) ); return 0; } } //printf( "stack: %d", lua_gettop( _pState ) ); narg++; luaL_checkstack( _pState, 1, "Too many arguments" ); } endwhileLabel: // Do the call. nres = (int)strlen( _pSig ); // Number of expected results. //LuaCall( _pState, narg, nres ); //int status = lua_pcall( _pState, narg, nres, 0 ); int status = docall( _pState, narg, 0 ); reportLua( _pState, status ); // Retrieve results. nres = -nres; // Stack index of first result. while( *_pSig ) // Get results. { switch( *_pSig++ ) { case 'd': // Double result. if( !lua_isnumber( _pState, nres ) ) g_Log->Error( "Wrong result type, expected double" ); else *va_arg( pArg, fp8 *) = lua_tonumber( _pState, nres ); break; case 'b': // Bool result. if( !lua_isboolean( _pState, nres ) ) g_Log->Error( "Wrong result type, expected bool" ); else *va_arg( pArg, bool *) = lua_toboolean( _pState, nres ) != 0; break; case 'i': // Int result. if( !lua_isnumber( _pState, nres ) ) g_Log->Error( "Wrong result type, expected integer" ); else *va_arg( pArg, int32 *) = (int32)lua_tonumber( _pState, nres ); break; case 's': // String result. if( !lua_isstring( _pState, nres ) ) g_Log->Error( "Wrong result type, expected string" ); else *va_arg( pArg, const char **) = lua_tostring( _pState, nres ); break; default: { g_Log->Error( "Invalid option (%c)", *(_pSig - 1) ); break; } } nres++; } /* HACK! Pop delta from stack, keeping this function from raceing away!. */ delta = lua_gettop( _pState ) - static_cast<int>(stackSizeIn); } /*catch( Base::CException &_e ) { va_end( pArg ); // Make sure to clean up stack in case of errors. delta = lua_gettop( _pState ) - stackSizeIn; if( delta != 0 ) lua_pop( _pState, delta ); g_Log->Warning( "%s", _e.Text().c_str() ); //_e.ReportCatch(); return 0; }*/ va_end( pArg ); return( delta ); }
static int co_yield (lua_State *L) { return lua_yield(L, lua_gettop(L)); }
static int lgetopt_std(lua_State *l) { const char *optstring = NULL; int result = 1; /* assume success */ int argc, ch; char **argv = NULL; int numargs = lua_gettop(l); if (numargs != 2 || lua_type(l,1) != LUA_TSTRING || lua_type(l,2) != LUA_TTABLE) { ERROR("usage: getopt.std(optionstring, resulttable)"); } optstring = lua_tostring(l, 1); /* Construct fake argc/argv from the magic lua 'arg' table. */ lua_getglobal(l, "arg"); construct_args(l, lua_gettop(l), &argc, &argv); lua_pop(l, 1); /* Parse the options and store them in the Lua table. */ while ((ch=getopt(argc, argv, optstring)) > -1) { char buf[2] = { ch, 0 }; if (ch == '?') { /* This is the special "got a bad option" character. Don't put it * in the table of results; just record that there's a failure. * The getopt call will have emitted an error to stderr. */ result = 0; continue; } if (optarg) { lua_pushstring(l, optarg); } else { lua_pushboolean(l, 1); } lua_setfield(l, 2, buf); } /* Since the default behavior of many (but not all) getopt libraries is to * reorder argv so that non-arguments are all at the end (unless * POSIXLY_CORRECT is set or the options string begins with a '+'), we'll * go do that now. We do it by modifying the existing global table, which * will leave index [-1] alone if it's set (as it sometimes is). */ lua_getglobal(l, "arg"); int i; for (i=0; i<argc; i++) { lua_pushinteger(l, i); lua_pushstring(l, argv[i]); lua_rawset(l, -3); } free_args(argc, argv); /* Return 1 item on the stack (boolean) */ lua_pushboolean(l, result); return 1; /* # of arguments returned on stack */ }
int function_dispatcher(lua_State* L) { function_rep* rep = static_cast<function_rep*>( lua_touserdata(L, lua_upvalueindex(1)) ); bool ambiguous = false; int min_match = std::numeric_limits<int>::max(); int match_index = -1; bool ret; #ifdef LUABIND_NO_ERROR_CHECKING if (rep->overloads().size() == 1) { match_index = 0; } else { #endif int num_params = lua_gettop(L); ret = find_best_match( L , &rep->overloads().front() , (int)rep->overloads().size() , sizeof(overload_rep) , ambiguous , min_match , match_index , num_params ); #ifdef LUABIND_NO_ERROR_CHECKING } #else if (!ret) { // this bock is needed to make sure the std::string is destructed { std::string msg = "no match for function call '"; msg += rep->name(); msg += "' with the parameters ("; msg += stack_content_by_name(L, 1); msg += ")\ncandidates are:\n"; msg += get_overload_signatures( L , rep->overloads().begin() , rep->overloads().end() , rep->name() ); lua_pushstring(L, msg.c_str()); } lua_error(L); } if (ambiguous) { // this bock is needed to make sure the std::string is destructed { std::string msg = "call of overloaded function '"; msg += rep->name(); msg += "("; msg += stack_content_by_name(L, 1); msg += ") is ambiguous\nnone of the overloads " "have a best conversion:"; std::vector<overload_rep_base const*> candidates; find_exact_match( L , &rep->overloads().front() , (int)rep->overloads().size() , sizeof(overload_rep) , min_match , num_params , candidates ); msg += get_overload_signatures_candidates( L , candidates.begin() , candidates.end() , rep->name() ); lua_pushstring(L, msg.c_str()); } lua_error(L); } #endif overload_rep const& ov_rep = rep->overloads()[match_index]; #ifndef LUABIND_NO_EXCEPTIONS try { #endif return ov_rep.call(L, ov_rep.fun); #ifndef LUABIND_NO_EXCEPTIONS } catch(const luabind::error&) { } catch(const std::exception& e) { lua_pushstring(L, e.what()); } catch (const char* s) { lua_pushstring(L, s); } catch(...) { std::string msg = rep->name(); msg += "() threw an exception"; lua_pushstring(L, msg.c_str()); } // we can only reach this line if an exception was thrown lua_error(L); return 0; // will never be reached #endif }
int LuaWrapper::gettop() { return lua_gettop(m_luaState); }
static int resource_set_add_resource(lua_State *L) { int narg; resource_set_lua_t *rset; resource_lua_t *resource; const char *resource_name; bool shared = FALSE; bool mandatory = TRUE; mrp_attr_t attribute_list[MAX_ATTRS], *attrs; mrp_debug("> add_resource"); narg = lua_gettop(L); if (narg != 2) return luaL_error(L, "expecting one argument"); rset = resource_set_lua_check(L, 1); if (!rset) goto error; /* the argument should be a table with at least "resource_name" index */ if (!lua_istable(L, -1)) return luaL_error(L, "argument error -- not a table"); lua_pushstring(L, "resource_name"); lua_gettable(L, -2); if (!lua_isstring(L, -1)) return luaL_error(L, "'resource_name' is a mandatory field"); resource_name = lua_tostring(L, -1); lua_pop(L, 1); lua_pushstring(L, "mandatory"); lua_gettable(L, -2); if (lua_isboolean(L, -1)) { mandatory = lua_toboolean(L, -1); } lua_pop(L, 1); lua_pushstring(L, "shared"); lua_gettable(L, -2); if (lua_isboolean(L, -1)) { shared = lua_toboolean(L, -1); } lua_pop(L, 1); /* create resource object and add it to the resource table in the resource * set object */ resource = (resource_lua_t *) mrp_lua_create_object(L, RESOURCE_LUA_CLASS, NULL, 0); if (!resource) goto error; resource->mandatory = mandatory; resource->shared = shared; resource->acquired = FALSE; resource->available = FALSE; resource->resource_name = mrp_strdup(resource_name); if (!resource->resource_name) goto error; resource->parent = rset; resource->L = L; resource->ctx = rset->ctx; resource->real_attributes = (attribute_lua_t *) mrp_lua_create_object(L, ATTRIBUTE_LUA_CLASS, NULL, 0); resource->real_attributes->L = L; resource->real_attributes->ctx = rset->ctx; resource->real_attributes->parent = resource; resource->real_attributes->resource_set = rset; resource->real_attributes->initialized = TRUE; attrs = mrp_resource_set_read_all_attributes(rset->resource_set, resource->resource_name, MAX_ATTRS-1, attribute_list); if (mrp_resource_set_add_resource(rset->resource_set, resource->resource_name, shared, attrs, mandatory) < 0) goto error; /* add to resource map */ mrp_htbl_insert(rset->resources, resource->resource_name, resource); return 1; error: /* TODO: clean up the already allocated objects */ return luaL_error(L, "internal resource library error"); }
int lua_Model_setMaterial(lua_State* state) { // Get the number of parameters. int paramCount = lua_gettop(state); // Attempt to match the parameters to a valid binding. switch (paramCount) { case 2: { do { if ((lua_type(state, 1) == LUA_TUSERDATA) && (lua_type(state, 2) == LUA_TUSERDATA || lua_type(state, 2) == LUA_TTABLE || lua_type(state, 2) == LUA_TNIL)) { // Get parameter 1 off the stack. bool param1Valid; gameplay::ScriptUtil::LuaArray<Material> param1 = gameplay::ScriptUtil::getObjectPointer<Material>(2, "Material", false, ¶m1Valid); if (!param1Valid) break; Model* instance = getInstance(state); instance->setMaterial(param1); return 0; } } while (0); do { if ((lua_type(state, 1) == LUA_TUSERDATA) && (lua_type(state, 2) == LUA_TSTRING || lua_type(state, 2) == LUA_TNIL)) { // Get parameter 1 off the stack. const char* param1 = gameplay::ScriptUtil::getString(2, false); Model* instance = getInstance(state); void* returnPtr = ((void*)instance->setMaterial(param1)); if (returnPtr) { gameplay::ScriptUtil::LuaObject* object = (gameplay::ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(gameplay::ScriptUtil::LuaObject)); object->instance = returnPtr; object->owns = false; luaL_getmetatable(state, "Material"); lua_setmetatable(state, -2); } else { lua_pushnil(state); } return 1; } } while (0); lua_pushstring(state, "lua_Model_setMaterial - Failed to match the given parameters to a valid function signature."); lua_error(state); break; } case 3: { do { if ((lua_type(state, 1) == LUA_TUSERDATA) && (lua_type(state, 2) == LUA_TUSERDATA || lua_type(state, 2) == LUA_TTABLE || lua_type(state, 2) == LUA_TNIL) && lua_type(state, 3) == LUA_TNUMBER) { // Get parameter 1 off the stack. bool param1Valid; gameplay::ScriptUtil::LuaArray<Material> param1 = gameplay::ScriptUtil::getObjectPointer<Material>(2, "Material", false, ¶m1Valid); if (!param1Valid) break; // Get parameter 2 off the stack. int param2 = (int)luaL_checkint(state, 3); Model* instance = getInstance(state); instance->setMaterial(param1, param2); return 0; } } while (0); do { if ((lua_type(state, 1) == LUA_TUSERDATA) && (lua_type(state, 2) == LUA_TSTRING || lua_type(state, 2) == LUA_TNIL) && (lua_type(state, 3) == LUA_TSTRING || lua_type(state, 3) == LUA_TNIL)) { // Get parameter 1 off the stack. const char* param1 = gameplay::ScriptUtil::getString(2, false); // Get parameter 2 off the stack. const char* param2 = gameplay::ScriptUtil::getString(3, false); Model* instance = getInstance(state); void* returnPtr = ((void*)instance->setMaterial(param1, param2)); if (returnPtr) { gameplay::ScriptUtil::LuaObject* object = (gameplay::ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(gameplay::ScriptUtil::LuaObject)); object->instance = returnPtr; object->owns = false; luaL_getmetatable(state, "Material"); lua_setmetatable(state, -2); } else { lua_pushnil(state); } return 1; } } while (0); do { if ((lua_type(state, 1) == LUA_TUSERDATA) && (lua_type(state, 2) == LUA_TSTRING || lua_type(state, 2) == LUA_TNIL) && lua_type(state, 3) == LUA_TNUMBER) { // Get parameter 1 off the stack. const char* param1 = gameplay::ScriptUtil::getString(2, false); // Get parameter 2 off the stack. int param2 = (int)luaL_checkint(state, 3); Model* instance = getInstance(state); void* returnPtr = ((void*)instance->setMaterial(param1, param2)); if (returnPtr) { gameplay::ScriptUtil::LuaObject* object = (gameplay::ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(gameplay::ScriptUtil::LuaObject)); object->instance = returnPtr; object->owns = false; luaL_getmetatable(state, "Material"); lua_setmetatable(state, -2); } else { lua_pushnil(state); } return 1; } } while (0); lua_pushstring(state, "lua_Model_setMaterial - Failed to match the given parameters to a valid function signature."); lua_error(state); break; } case 4: { do { if ((lua_type(state, 1) == LUA_TUSERDATA) && (lua_type(state, 2) == LUA_TSTRING || lua_type(state, 2) == LUA_TNIL) && (lua_type(state, 3) == LUA_TSTRING || lua_type(state, 3) == LUA_TNIL) && (lua_type(state, 4) == LUA_TSTRING || lua_type(state, 4) == LUA_TNIL)) { // Get parameter 1 off the stack. const char* param1 = gameplay::ScriptUtil::getString(2, false); // Get parameter 2 off the stack. const char* param2 = gameplay::ScriptUtil::getString(3, false); // Get parameter 3 off the stack. const char* param3 = gameplay::ScriptUtil::getString(4, false); Model* instance = getInstance(state); void* returnPtr = ((void*)instance->setMaterial(param1, param2, param3)); if (returnPtr) { gameplay::ScriptUtil::LuaObject* object = (gameplay::ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(gameplay::ScriptUtil::LuaObject)); object->instance = returnPtr; object->owns = false; luaL_getmetatable(state, "Material"); lua_setmetatable(state, -2); } else { lua_pushnil(state); } return 1; } } while (0); lua_pushstring(state, "lua_Model_setMaterial - Failed to match the given parameters to a valid function signature."); lua_error(state); break; } case 5: { do { if ((lua_type(state, 1) == LUA_TUSERDATA) && (lua_type(state, 2) == LUA_TSTRING || lua_type(state, 2) == LUA_TNIL) && (lua_type(state, 3) == LUA_TSTRING || lua_type(state, 3) == LUA_TNIL) && (lua_type(state, 4) == LUA_TSTRING || lua_type(state, 4) == LUA_TNIL) && lua_type(state, 5) == LUA_TNUMBER) { // Get parameter 1 off the stack. const char* param1 = gameplay::ScriptUtil::getString(2, false); // Get parameter 2 off the stack. const char* param2 = gameplay::ScriptUtil::getString(3, false); // Get parameter 3 off the stack. const char* param3 = gameplay::ScriptUtil::getString(4, false); // Get parameter 4 off the stack. int param4 = (int)luaL_checkint(state, 5); Model* instance = getInstance(state); void* returnPtr = ((void*)instance->setMaterial(param1, param2, param3, param4)); if (returnPtr) { gameplay::ScriptUtil::LuaObject* object = (gameplay::ScriptUtil::LuaObject*)lua_newuserdata(state, sizeof(gameplay::ScriptUtil::LuaObject)); object->instance = returnPtr; object->owns = false; luaL_getmetatable(state, "Material"); lua_setmetatable(state, -2); } else { lua_pushnil(state); } return 1; } } while (0); lua_pushstring(state, "lua_Model_setMaterial - Failed to match the given parameters to a valid function signature."); lua_error(state); break; } default: { lua_pushstring(state, "Invalid number of parameters (expected 2, 3, 4 or 5)."); lua_error(state); break; } } return 0; }
static int resource_set_lua_create(lua_State *L) { mrp_context_t *ctx = mrp_lua_get_murphy_context(); char e[128] = ""; resource_set_lua_t *rset; int narg; mrp_htbl_config_t conf; mrp_debug("> create"); if (ctx == NULL) luaL_error(L, "failed to get murphy context"); narg = lua_gettop(L); rset = (resource_set_lua_t *) mrp_lua_create_object(L, RESOURCE_SET_LUA_CLASS, NULL, 0); if (!rset) return luaL_error(L, "could not create Lua object"); rset->L = L; rset->ctx = ctx; /* user can affect these values */ rset->zone = mrp_strdup("default"); rset->application_class = NULL; rset->autorelease = FALSE; rset->dont_wait = FALSE; rset->priority = 0; switch (narg) { case 2: /* argument table */ if (mrp_lua_init_members(rset, L, -2, e, sizeof(e)) != 1) return luaL_error(L, "failed to initialize resource members (%s)", e); break; default: return luaL_error(L, "expecting a constructor argument, " "got %d", narg); } if (rset->application_class == NULL) return luaL_error(L, "application_class is a mandatory parameter"); if (rset->priority < 0) rset->priority = 0; /* initial state, these cannot be set by user */ rset->available = FALSE; rset->acquired = FALSE; /* initialize resource map */ conf.nbucket = 0; conf.nentry = 10; conf.comp = mrp_string_comp; conf.hash = mrp_string_hash; conf.free = htbl_free_resource; rset->resources = mrp_htbl_create(&conf); if (!rset->resources) goto error; /* do the actual resource work */ if (!client) { /* create the resource client */ client = mrp_resource_client_create("lua", NULL); if (!client) goto error; } rset->resource_set = mrp_resource_set_create(client, rset->autorelease, rset->dont_wait, rset->priority, event_cb, rset); if (rset->resource_set) n_sets++; else goto error; if (mrp_application_class_add_resource_set(rset->application_class, rset->zone, rset->resource_set, 0) < 0) goto error; mrp_lua_push_object(L, rset); return 1; error: return luaL_error(L, "internal resource library error"); }
void luaL_tofield(struct lua_State *L, struct luaL_serializer *cfg, int index, struct luaL_field *field) { if (index < 0) index = lua_gettop(L) + index + 1; double num; double intpart; size_t size; #define CHECK_NUMBER(x) ({\ if (!isfinite(x) && !cfg->encode_invalid_numbers) { \ if (!cfg->encode_invalid_as_nil) \ luaL_error(L, "number must not be NaN or Inf"); \ field->type = MP_NIL; \ }}) switch (lua_type(L, index)) { case LUA_TNUMBER: num = lua_tonumber(L, index); if (isfinite(num) && modf(num, &intpart) != 0.0) { field->type = MP_DOUBLE; field->dval = num; } else if (num >= 0 && num <= UINT64_MAX) { field->type = MP_UINT; field->ival = (uint64_t) num; } else if (num >= INT64_MIN && num <= INT64_MAX) { field->type = MP_INT; field->ival = (int64_t) num; } else { field->type = MP_DOUBLE; field->dval = num; CHECK_NUMBER(num); } return; case LUA_TCDATA: { uint32_t ctypeid = 0; void *cdata = luaL_checkcdata(L, index, &ctypeid); int64_t ival; switch (ctypeid) { case CTID_BOOL: field->type = MP_BOOL; field->bval = *(bool*) cdata; return; case CTID_CCHAR: case CTID_INT8: ival = *(int8_t *) cdata; field->type = (ival >= 0) ? MP_UINT : MP_INT; field->ival = ival; return; case CTID_INT16: ival = *(int16_t *) cdata; field->type = (ival >= 0) ? MP_UINT : MP_INT; field->ival = ival; return; case CTID_INT32: ival = *(int32_t *) cdata; field->type = (ival >= 0) ? MP_UINT : MP_INT; field->ival = ival; return; case CTID_INT64: ival = *(int64_t *) cdata; field->type = (ival >= 0) ? MP_UINT : MP_INT; field->ival = ival; return; case CTID_UINT8: field->type = MP_UINT; field->ival = *(uint8_t *) cdata; return; case CTID_UINT16: field->type = MP_UINT; field->ival = *(uint16_t *) cdata; return; case CTID_UINT32: field->type = MP_UINT; field->ival = *(uint32_t *) cdata; return; case CTID_UINT64: field->type = MP_UINT; field->ival = *(uint64_t *) cdata; return; case CTID_FLOAT: field->type = MP_FLOAT; field->fval = *(float *) cdata; CHECK_NUMBER(field->fval); return; case CTID_DOUBLE: field->type = MP_DOUBLE; field->dval = *(double *) cdata; CHECK_NUMBER(field->dval); return; case CTID_P_CVOID: case CTID_P_VOID: if (*(void **) cdata == NULL) { field->type = MP_NIL; return; } /* Fall through */ default: field->type = MP_EXT; return; } return; } case LUA_TBOOLEAN: field->type = MP_BOOL; field->bval = lua_toboolean(L, index); return; case LUA_TNIL: field->type = MP_NIL; return; case LUA_TSTRING: field->sval.data = lua_tolstring(L, index, &size); field->sval.len = (uint32_t) size; field->type = MP_STR; return; case LUA_TTABLE: { field->compact = false; lua_field_inspect_table(L, cfg, index, field); return; } case LUA_TLIGHTUSERDATA: case LUA_TUSERDATA: field->sval.data = NULL; field->sval.len = 0; if (lua_touserdata(L, index) == NULL) { field->type = MP_NIL; return; } /* Fall through */ default: field->type = MP_EXT; return; } #undef CHECK_NUMBER }
static int b_unpack (lua_State *L) { int native; const char *fmt = luaL_checkstring(L, 1); size_t ld; int pos, align, endian; const char *data; if(lua_isuserdata(L, 2)) { data = (const char*)lua_touserdata(L, 2); ld = (size_t)luaL_checkinteger(L, 3); pos = luaL_optint(L, 4, 1) - 1; } else { data = luaL_checklstring(L, 2, &ld); pos = luaL_optint(L, 3, 1) - 1; } endian = getendianess(&fmt, &native); align = getalign(&fmt); lua_settop(L, 2); while (*fmt) { int opt = *fmt++; int size = optsize(opt, &fmt); int toalign = gettoalign(L, align, opt, size); pos += toalign - 1; pos -= pos&(toalign-1); luaL_argcheck(L, pos+size <= (int)ld, 2, "data string too short"); switch (opt) { case ' ': break; /* ignore white spaces */ case 'b': case 'B': case 'h': case 'H': case 'l': case 'L': case 'i': case 'I': { /* integer types */ int withsign = islower(opt); getinteger(L, data+pos, endian, withsign, size); break; } case 'x': { break; } case 'f': { float f; memcpy(&f, data+pos, size); if (endian != native) invertbytes((char *)&f, sizeof(f)); lua_pushnumber(L, f); break; } case 'd': { double d; memcpy(&d, data+pos, size); if (endian != native) invertbytes((char *)&d, sizeof(d)); lua_pushnumber(L, d); break; } case 'c': { if (size == 0) { if (!lua_isnumber(L, -1)) luaL_error(L, "format `c0' needs a previous size"); size = lua_tonumber(L, -1); lua_pop(L, 1); luaL_argcheck(L, pos+size <= (int)ld, 2, "data string too short"); } lua_pushlstring(L, data+pos, size); break; } case 's': { const char *e = (const char *)memchr(data+pos, '\0', ld - pos); if (e == NULL) luaL_error(L, "unfinished string in data"); size = (e - (data+pos)) + 1; lua_pushlstring(L, data+pos, size - 1); break; } case 'p': { void* p; memcpy(&p, data+pos, size); lua_pushlightuserdata(L, p); break; } default: invalidformat(L, opt); } pos += size; } lua_pushnumber(L, pos + 1); return lua_gettop(L) - 2; }