bool read_schematic_def(lua_State *L, int index, Schematic *schem, std::vector<std::string> *names) { if (!lua_istable(L, index)) return false; //// Get schematic size lua_getfield(L, index, "size"); v3s16 size = check_v3s16(L, -1); lua_pop(L, 1); schem->size = size; //// Get schematic data lua_getfield(L, index, "data"); luaL_checktype(L, -1, LUA_TTABLE); int numnodes = size.X * size.Y * size.Z; schem->schemdata = new MapNode[numnodes]; int i = 0; size_t names_base = names->size(); std::map<std::string, content_t> name_id_map; lua_pushnil(L); while (lua_next(L, -2)) { if (i >= numnodes) { i++; lua_pop(L, 1); continue; } // same as readnode, except param1 default is MTSCHEM_PROB_CONST lua_getfield(L, -1, "name"); std::string 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); std::map<std::string, content_t>::iterator it = name_id_map.find(name); content_t name_index; if (it != name_id_map.end()) { name_index = it->second; } else { name_index = names->size() - names_base; name_id_map[name] = name_index; names->push_back(name); } schem->schemdata[i] = MapNode(name_index, param1, param2); i++; lua_pop(L, 1); } if (i != numnodes) { errorstream << "read_schematic_def: incorrect number of " "nodes provided in raw schematic data (got " << i << ", expected " << numnodes << ")." << std::endl; return false; } //// Get Y-slice probability values (if present) schem->slice_probs = new u8[size.Y]; for (i = 0; i != size.Y; i++) schem->slice_probs[i] = MTSCHEM_PROB_ALWAYS; lua_getfield(L, index, "yslice_prob"); if (lua_istable(L, -1)) { lua_pushnil(L); while (lua_next(L, -2)) { if (getintfield(L, -1, "ypos", i) && i >= 0 && i < size.Y) { schem->slice_probs[i] = getintfield_default(L, -1, "prob", MTSCHEM_PROB_ALWAYS); } lua_pop(L, 1); } } return true; }
// register_decoration({lots of stuff}) int ModApiBasic::l_register_decoration(lua_State *L) { int index = 1; luaL_checktype(L, index, LUA_TTABLE); EmergeManager *emerge = getServer(L)->getEmergeManager(); BiomeDefManager *bdef = emerge->biomedef; enum DecorationType decotype = (DecorationType)getenumfield(L, index, "deco_type", es_DecorationType, -1); if (decotype == -1) { errorstream << "register_decoration: unrecognized " "decoration placement type"; return 0; } Decoration *deco = createDecoration(decotype); if (!deco) { errorstream << "register_decoration: decoration placement type " << decotype << " not implemented"; return 0; } deco->c_place_on = CONTENT_IGNORE; deco->place_on_name = getstringfield_default(L, index, "place_on", "ignore"); deco->fill_ratio = getfloatfield_default(L, index, "fill_ratio", 0.02); deco->sidelen = getintfield_default(L, index, "sidelen", 8); if (deco->sidelen <= 0) { errorstream << "register_decoration: sidelen must be " "greater than 0" << std::endl; delete deco; return 0; } lua_getfield(L, index, "noise_params"); deco->np = read_noiseparams(L, -1); lua_pop(L, 1); lua_getfield(L, index, "biomes"); if (lua_istable(L, -1)) { lua_pushnil(L); while (lua_next(L, -2)) { const char *s = lua_tostring(L, -1); u8 biomeid = bdef->getBiomeIdByName(s); if (biomeid) deco->biomes.insert(biomeid); lua_pop(L, 1); } lua_pop(L, 1); } switch (decotype) { case DECO_SIMPLE: { DecoSimple *dsimple = (DecoSimple *)deco; dsimple->c_deco = CONTENT_IGNORE; dsimple->c_spawnby = CONTENT_IGNORE; dsimple->spawnby_name = getstringfield_default(L, index, "spawn_by", "air"); dsimple->deco_height = getintfield_default(L, index, "height", 1); dsimple->deco_height_max = getintfield_default(L, index, "height_max", 0); dsimple->nspawnby = getintfield_default(L, index, "num_spawn_by", -1); lua_getfield(L, index, "decoration"); if (lua_istable(L, -1)) { lua_pushnil(L); while (lua_next(L, -2)) { const char *s = lua_tostring(L, -1); std::string str(s); dsimple->decolist_names.push_back(str); lua_pop(L, 1); } } else if (lua_isstring(L, -1)) { dsimple->deco_name = std::string(lua_tostring(L, -1)); } else { dsimple->deco_name = std::string("air"); } lua_pop(L, 1); if (dsimple->deco_height <= 0) { errorstream << "register_decoration: simple decoration height" " must be greater than 0" << std::endl; delete dsimple; return 0; } break; } case DECO_SCHEMATIC: { DecoSchematic *dschem = (DecoSchematic *)deco; dschem->flags = getflagsfield(L, index, "flags", flagdesc_deco_schematic); dschem->rotation = (Rotation)getenumfield(L, index, "rotation", es_Rotation, ROTATE_0); lua_getfield(L, index, "replacements"); if (lua_istable(L, -1)) { int i = lua_gettop(L); lua_pushnil(L); while (lua_next(L, i) != 0) { // key at index -2 and value at index -1 lua_rawgeti(L, -1, 1); std::string replace_from = lua_tostring(L, -1); lua_pop(L, 1); lua_rawgeti(L, -1, 2); std::string replace_to = lua_tostring(L, -1); lua_pop(L, 1); dschem->replacements[replace_from] = replace_to; // removes value, keeps key for next iteration lua_pop(L, 1); } } lua_pop(L, 1); lua_getfield(L, index, "schematic"); if (!read_schematic(L, -1, dschem, getServer(L))) { delete dschem; return 0; } lua_pop(L, -1); if (!dschem->filename.empty() && !dschem->loadSchematicFile()) { errorstream << "register_decoration: failed to load schematic file '" << dschem->filename << "'" << std::endl; delete dschem; return 0; } break; } case DECO_LSYSTEM: { //DecoLSystem *decolsystem = (DecoLSystem *)deco; break; } } emerge->decorations.push_back(deco); verbosestream << "register_decoration: decoration '" << deco->getName() << "' registered" << std::endl; return 0; }
int lbot_checkID(lua_State *L, int idx) { luaL_checktype(L, idx, LUA_TLIGHTUSERDATA); return reinterpret_cast<int>(lua_touserdata(L, idx)); }
static int ngx_http_lua_ngx_req_set_uri(lua_State *L) { ngx_http_request_t *r; size_t len; u_char *p; int n; int jump = 0; ngx_http_lua_ctx_t *ctx; n = lua_gettop(L); if (n != 1 && n != 2) { return luaL_error(L, "expecting 1 argument but seen %d", n); } lua_pushlightuserdata(L, &ngx_http_lua_request_key); lua_rawget(L, LUA_GLOBALSINDEX); r = lua_touserdata(L, -1); lua_pop(L, 1); if (n == 2) { luaL_checktype(L, 2, LUA_TBOOLEAN); jump = lua_toboolean(L, 2); if (jump) { ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module); if (ctx == NULL) { return luaL_error(L, "no ctx found"); } dd("rewrite: %d, access: %d, content: %d", (int) ctx->entered_rewrite_phase, (int) ctx->entered_access_phase, (int) ctx->entered_content_phase); ngx_http_lua_check_context(L, ctx, NGX_HTTP_LUA_CONTEXT_REWRITE); ngx_log_debug1(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "lua set uri jump to \"%V\"", &r->uri); ngx_http_lua_check_if_abortable(L, ctx); } } p = (u_char *) luaL_checklstring(L, 1, &len); if (len == 0) { return luaL_error(L, "attempt to use zero-length uri"); } r->uri.data = ngx_palloc(r->pool, len); if (r->uri.data == NULL) { return luaL_error(L, "out of memory"); } ngx_memcpy(r->uri.data, p, len); r->uri.len = len; r->internal = 1; r->valid_unparsed_uri = 0; ngx_http_set_exten(r); if (jump) { r->uri_changed = 1; return lua_yield(L, 0); } r->valid_location = 0; r->uri_changed = 0; 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; // Get schematic data 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); } if (i != numnodes) { errorstream << "read_schematic: incorrect number of " "nodes provided in raw schematic data (got " << i << ", expected " << numnodes << ")." << std::endl; return false; } u8 *sliceprobs = new u8[size.Y]; for (i = 0; i != size.Y; i++) sliceprobs[i] = MTSCHEM_PROB_ALWAYS; // Get Y-slice probability values (if present) lua_getfield(L, index, "yslice_prob"); if (lua_istable(L, -1)) { lua_pushnil(L); while (lua_next(L, -2)) { if (getintfield(L, -1, "ypos", i) && i >= 0 && i < size.Y) { sliceprobs[i] = getintfield_default(L, -1, "prob", MTSCHEM_PROB_ALWAYS); } lua_pop(L, 1); } } dschem->size = size; dschem->schematic = schemdata; dschem->slice_probs = sliceprobs; } 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; }
int EventDispatcherBinder::removeEventListener(lua_State* L) { StackChecker checker(L, "EventDispatcherBinder::removeEventListener", 0); Binder binder(L); EventDispatcher* eventDispatcher = static_cast<EventDispatcher*>(binder.getInstance("EventDispatcher")); luaL_checktype(L, 2, LUA_TSTRING); luaL_checktype(L, 3, LUA_TFUNCTION); bool hasData = lua_gettop(L) >= 4; createEventsTable(L, 1); // create __events table if it's not created EventBinderMap& map = getOrCreateEventBinderMap(eventDispatcher); const char* event = lua_tostring(L, 2); int eventid = StringId::instance().id(event); const std::vector<CppLuaBridge*>& bridges = map[eventid]; lua_getfield(L, 1, "__events"); // check if the event is already registered CppLuaBridge* bridge = 0; for (std::size_t i = 0; i < bridges.size(); ++i) { lua_pushlightuserdata(L, bridges[i]); lua_rawget(L, -2); // we get the event check closure if (hasData == false) { lua_pushvalue(L, 3); // function lua_call(L, 1, 1); } else { lua_pushvalue(L, 3); // function lua_pushvalue(L, 4); // data lua_call(L, 2, 1); } if (lua_toboolean(L, -1)) { bridge = bridges[i]; lua_pop(L, 1); break; } else lua_pop(L, 1); } if (bridge == 0) // event is not registered { lua_pop(L, 1); // pop __events return 0; } luaL_rawgetptr(L, LUA_REGISTRYINDEX, &key_eventClosures); lua_pushlightuserdata(L, bridge); // key=bridge lua_pushnil(L); // value=nil lua_rawset(L, -3); // envtable["eventClosures"][bridge] = nil lua_pop(L, 1); // pop envtable["eventClosures"] lua_pushlightuserdata(L, bridge); // key=bridge lua_pushnil(L); // value = nil lua_settable(L, -3); // __events[bridge] = nil eventDispatcher->removeEventListener(LuaEvent::Type(event), bridge, &CppLuaBridge::luaEvent); map.remove(eventid, bridge); lua_pop(L, 1); // pop __events return 0; }
// Push the list of callbacks (a lua table). // Then push nargs arguments. // Then call this function, which // - runs the callbacks // - removes the table and arguments from the lua stack // - pushes the return value, computed depending on mode void scriptapi_run_callbacks(lua_State *L, int nargs, RunCallbacksMode mode) { // Insert the return value into the lua stack, below the table assert(lua_gettop(L) >= nargs + 1); lua_pushnil(L); lua_insert(L, -(nargs + 1) - 1); // Stack now looks like this: // ... <return value = nil> <table> <arg#1> <arg#2> ... <arg#n> int rv = lua_gettop(L) - nargs - 1; int table = rv + 1; int arg = table + 1; luaL_checktype(L, table, LUA_TTABLE); // Foreach lua_pushnil(L); bool first_loop = true; while(lua_next(L, table) != 0){ // key at index -2 and value at index -1 luaL_checktype(L, -1, LUA_TFUNCTION); // Call function for(int i = 0; i < nargs; i++) lua_pushvalue(L, arg+i); if(lua_pcall(L, nargs, 1, 0)) script_error(L, "error: %s", lua_tostring(L, -1)); // Move return value to designated space in stack // Or pop it if(first_loop){ // Result of first callback is always moved lua_replace(L, rv); first_loop = false; } else { // Otherwise, what happens depends on the mode if(mode == RUN_CALLBACKS_MODE_FIRST) lua_pop(L, 1); else if(mode == RUN_CALLBACKS_MODE_LAST) lua_replace(L, rv); else if(mode == RUN_CALLBACKS_MODE_AND || mode == RUN_CALLBACKS_MODE_AND_SC){ if((bool)lua_toboolean(L, rv) == true && (bool)lua_toboolean(L, -1) == false) lua_replace(L, rv); else lua_pop(L, 1); } else if(mode == RUN_CALLBACKS_MODE_OR || mode == RUN_CALLBACKS_MODE_OR_SC){ if((bool)lua_toboolean(L, rv) == false && (bool)lua_toboolean(L, -1) == true) lua_replace(L, rv); else lua_pop(L, 1); } else assert(0); } // Handle short circuit modes if(mode == RUN_CALLBACKS_MODE_AND_SC && (bool)lua_toboolean(L, rv) == false) break; else if(mode == RUN_CALLBACKS_MODE_OR_SC && (bool)lua_toboolean(L, rv) == true) break; // value removed, keep key for next iteration } // Remove stuff from stack, leaving only the return value lua_settop(L, rv); // Fix return value in case no callbacks were called if(first_loop){ if(mode == RUN_CALLBACKS_MODE_AND || mode == RUN_CALLBACKS_MODE_AND_SC){ lua_pop(L, 1); lua_pushboolean(L, true); } else if(mode == RUN_CALLBACKS_MODE_OR || mode == RUN_CALLBACKS_MODE_OR_SC){ lua_pop(L, 1); lua_pushboolean(L, false); } } }
// register_ore({lots of stuff}) int ModApiMapgen::l_register_ore(lua_State *L) { NO_MAP_LOCK_REQUIRED; int index = 1; luaL_checktype(L, index, LUA_TTABLE); INodeDefManager *ndef = getServer(L)->getNodeDefManager(); BiomeManager *bmgr = getServer(L)->getEmergeManager()->biomemgr; OreManager *oremgr = getServer(L)->getEmergeManager()->oremgr; enum OreType oretype = (OreType)getenumfield(L, index, "ore_type", es_OreType, ORE_SCATTER); Ore *ore = oremgr->create(oretype); if (!ore) { errorstream << "register_ore: ore_type " << oretype << " not implemented\n"; return 0; } ore->name = getstringfield_default(L, index, "name", ""); ore->ore_param2 = (u8)getintfield_default(L, index, "ore_param2", 0); ore->clust_scarcity = getintfield_default(L, index, "clust_scarcity", 1); ore->clust_num_ores = getintfield_default(L, index, "clust_num_ores", 1); ore->clust_size = getintfield_default(L, index, "clust_size", 0); ore->noise = NULL; ore->flags = 0; //// Get noise_threshold warn_if_field_exists(L, index, "noise_threshhold", "Deprecated: new name is \"noise_threshold\"."); float nthresh; if (!getfloatfield(L, index, "noise_threshold", nthresh) && !getfloatfield(L, index, "noise_threshhold", nthresh)) nthresh = 0; ore->nthresh = nthresh; //// Get y_min/y_max warn_if_field_exists(L, index, "height_min", "Deprecated: new name is \"y_min\"."); warn_if_field_exists(L, index, "height_max", "Deprecated: new name is \"y_max\"."); int ymin, ymax; if (!getintfield(L, index, "y_min", ymin) && !getintfield(L, index, "height_min", ymin)) ymin = -31000; if (!getintfield(L, index, "y_max", ymax) && !getintfield(L, index, "height_max", ymax)) ymax = 31000; ore->y_min = ymin; ore->y_max = ymax; if (ore->clust_scarcity <= 0 || ore->clust_num_ores <= 0) { errorstream << "register_ore: clust_scarcity and clust_num_ores" "must be greater than 0" << std::endl; delete ore; return 0; } //// Get flags getflagsfield(L, index, "flags", flagdesc_ore, &ore->flags, NULL); //// Get biomes associated with this decoration (if any) lua_getfield(L, index, "biomes"); if (get_biome_list(L, -1, bmgr, &ore->biomes)) infostream << "register_ore: couldn't get all biomes " << std::endl; lua_pop(L, 1); //// Get noise parameters if needed lua_getfield(L, index, "noise_params"); if (read_noiseparams(L, -1, &ore->np)) { ore->flags |= OREFLAG_USE_NOISE; } else if (ore->NEEDS_NOISE) { errorstream << "register_ore: specified ore type requires valid " "'noise_params' parameter" << std::endl; delete ore; return 0; } lua_pop(L, 1); //// Get type-specific parameters switch (oretype) { case ORE_SHEET: { OreSheet *oresheet = (OreSheet *)ore; oresheet->column_height_min = getintfield_default(L, index, "column_height_min", 1); oresheet->column_height_max = getintfield_default(L, index, "column_height_max", ore->clust_size); oresheet->column_midpoint_factor = getfloatfield_default(L, index, "column_midpoint_factor", 0.5f); break; } case ORE_PUFF: { OrePuff *orepuff = (OrePuff *)ore; lua_getfield(L, index, "np_puff_top"); read_noiseparams(L, -1, &orepuff->np_puff_top); lua_pop(L, 1); lua_getfield(L, index, "np_puff_bottom"); read_noiseparams(L, -1, &orepuff->np_puff_bottom); lua_pop(L, 1); break; } case ORE_VEIN: { OreVein *orevein = (OreVein *)ore; orevein->random_factor = getfloatfield_default(L, index, "random_factor", 1.f); break; } case ORE_STRATUM: { OreStratum *orestratum = (OreStratum *)ore; lua_getfield(L, index, "np_stratum_thickness"); if (read_noiseparams(L, -1, &orestratum->np_stratum_thickness)) ore->flags |= OREFLAG_USE_NOISE2; lua_pop(L, 1); orestratum->stratum_thickness = getintfield_default(L, index, "stratum_thickness", 8); break; } default: break; } ObjDefHandle handle = oremgr->add(ore); if (handle == OBJDEF_INVALID_HANDLE) { delete ore; return 0; } ore->m_nodenames.push_back(getstringfield_default(L, index, "ore", "")); size_t nnames = getstringlistfield(L, index, "wherein", &ore->m_nodenames); ore->m_nnlistsizes.push_back(nnames); ndef->pendNodeResolve(ore); lua_pushinteger(L, handle); return 1; }
bool read_schematic_def(lua_State *L, int index, Schematic *schem, std::vector<std::string> *names) { if (!lua_istable(L, index)) return false; //// Get schematic size lua_getfield(L, index, "size"); v3s16 size = check_v3s16(L, -1); lua_pop(L, 1); schem->size = size; //// Get schematic data lua_getfield(L, index, "data"); luaL_checktype(L, -1, LUA_TTABLE); u32 numnodes = size.X * size.Y * size.Z; schem->schemdata = new MapNode[numnodes]; size_t names_base = names->size(); std::unordered_map<std::string, content_t> name_id_map; u32 i = 0; for (lua_pushnil(L); lua_next(L, -2); i++, lua_pop(L, 1)) { if (i >= numnodes) continue; //// Read name std::string name; if (!getstringfield(L, -1, "name", name)) throw LuaError("Schematic data definition with missing name field"); //// Read param1/prob u8 param1; if (!getintfield(L, -1, "param1", param1) && !getintfield(L, -1, "prob", param1)) param1 = MTSCHEM_PROB_ALWAYS_OLD; //// Read param2 u8 param2 = getintfield_default(L, -1, "param2", 0); //// Find or add new nodename-to-ID mapping std::unordered_map<std::string, content_t>::iterator it = name_id_map.find(name); content_t name_index; if (it != name_id_map.end()) { name_index = it->second; } else { name_index = names->size() - names_base; name_id_map[name] = name_index; names->push_back(name); } //// Perform probability/force_place fixup on param1 param1 >>= 1; if (getboolfield_default(L, -1, "force_place", false)) param1 |= MTSCHEM_FORCE_PLACE; //// Actually set the node in the schematic schem->schemdata[i] = MapNode(name_index, param1, param2); } if (i != numnodes) { errorstream << "read_schematic_def: incorrect number of " "nodes provided in raw schematic data (got " << i << ", expected " << numnodes << ")." << std::endl; return false; } //// Get Y-slice probability values (if present) schem->slice_probs = new u8[size.Y]; for (i = 0; i != (u32) size.Y; i++) schem->slice_probs[i] = MTSCHEM_PROB_ALWAYS; lua_getfield(L, index, "yslice_prob"); if (lua_istable(L, -1)) { for (lua_pushnil(L); lua_next(L, -2); lua_pop(L, 1)) { u16 ypos; if (!getintfield(L, -1, "ypos", ypos) || (ypos >= size.Y) || !getintfield(L, -1, "prob", schem->slice_probs[ypos])) continue; schem->slice_probs[ypos] >>= 1; } } return true; }
inline int __call(lua_State *L) { luaL_checktype(L, lua_upvalueindex(1), LUA_TLIGHTUSERDATA); callsite * site = reinterpret_cast<callsite*>(lua_touserdata(L, lua_upvalueindex(1))); return site->call(L); }
// register_decoration({lots of stuff}) int ModApiMapgen::l_register_decoration(lua_State *L) { NO_MAP_LOCK_REQUIRED; int index = 1; luaL_checktype(L, index, LUA_TTABLE); INodeDefManager *ndef = getServer(L)->getNodeDefManager(); DecorationManager *decomgr = getServer(L)->getEmergeManager()->decomgr; BiomeManager *biomemgr = getServer(L)->getEmergeManager()->biomemgr; SchematicManager *schemmgr = getServer(L)->getEmergeManager()->schemmgr; enum DecorationType decotype = (DecorationType)getenumfield(L, index, "deco_type", es_DecorationType, -1); Decoration *deco = decomgr->create(decotype); if (!deco) { errorstream << "register_decoration: decoration placement type " << decotype << " not implemented" << std::endl; return 0; } deco->name = getstringfield_default(L, index, "name", ""); deco->fill_ratio = getfloatfield_default(L, index, "fill_ratio", 0.02); deco->y_min = getintfield_default(L, index, "y_min", -31000); deco->y_max = getintfield_default(L, index, "y_max", 31000); deco->nspawnby = getintfield_default(L, index, "num_spawn_by", -1); deco->place_offset_y = getintfield_default(L, index, "place_offset_y", 0); deco->sidelen = getintfield_default(L, index, "sidelen", 8); if (deco->sidelen <= 0) { errorstream << "register_decoration: sidelen must be " "greater than 0" << std::endl; delete deco; return 0; } //// Get node name(s) to place decoration on size_t nread = getstringlistfield(L, index, "place_on", &deco->m_nodenames); deco->m_nnlistsizes.push_back(nread); //// Get decoration flags getflagsfield(L, index, "flags", flagdesc_deco, &deco->flags, NULL); //// Get NoiseParams to define how decoration is placed lua_getfield(L, index, "noise_params"); if (read_noiseparams(L, -1, &deco->np)) deco->flags |= DECO_USE_NOISE; lua_pop(L, 1); //// Get biomes associated with this decoration (if any) lua_getfield(L, index, "biomes"); if (get_biome_list(L, -1, biomemgr, &deco->biomes)) infostream << "register_decoration: couldn't get all biomes " << std::endl; lua_pop(L, 1); //// Get node name(s) to 'spawn by' size_t nnames = getstringlistfield(L, index, "spawn_by", &deco->m_nodenames); deco->m_nnlistsizes.push_back(nnames); if (nnames == 0 && deco->nspawnby != -1) { errorstream << "register_decoration: no spawn_by nodes defined," " but num_spawn_by specified" << std::endl; } //// Handle decoration type-specific parameters bool success = false; switch (decotype) { case DECO_SIMPLE: success = read_deco_simple(L, (DecoSimple *)deco); break; case DECO_SCHEMATIC: success = read_deco_schematic(L, schemmgr, (DecoSchematic *)deco); break; case DECO_LSYSTEM: break; } if (!success) { delete deco; return 0; } ndef->pendNodeResolve(deco); ObjDefHandle handle = decomgr->add(deco); if (handle == OBJDEF_INVALID_HANDLE) { delete deco; return 0; } lua_pushinteger(L, handle); return 1; }
/** * Allocate a structure, initialize with zero and return it. * * This is NOT intended for objects or structures that have specialized * creator functions, like gtk_window_new and such. Use it for simple * structures like GtkTreeIter. * * The object is, as usual, a Lua wrapper in the form of a userdata, * containing a pointer to the actual object. * * @param L Lua State * @param mi Module that handles the type * @param is_array If true, Stack[2] is the count, else allocate a single * object. * * @luaparam typename Type of the structure to allocate * @luaparam ... array size, or optional additional arguments to the allocator * function. * @luareturn The new structure */ static int lg_generic_new_array(lua_State *L, cmi mi, int is_array) { typespec_t ts; void *p; char tmp_name[80]; const char *type_name; int flags; const char *name_in = luaL_checkstring(L, 1); int count = 0; if (is_array) { count = luaL_checknumber(L, 2); if (count <= 0) return luaL_error(L, "%s Invalid array size %d", msgprefix, count); } // add the prefix if available. if (mi->prefix_type) { strcpy(tmp_name, mi->prefix_type); strcat(tmp_name, name_in); type_name = tmp_name; } else type_name = name_in; // look for the type; if not found, try again without the prefix. for (;;) { ts = lg_find_struct(L, type_name, 1); if (ts.value) break; ts = lg_find_struct(L, type_name, 0); if (ts.value) break; if (type_name == name_in) return luaL_error(L, "%s type %s* not found\n", msgprefix, type_name); type_name = name_in; } /* There may be an allocator function; if so, use it (but only for single * objects, not for arrays); use the optional additional arguments */ if (count == 0) { char func_name[80]; struct func_info fi; lg_make_func_name(mi, func_name, sizeof(func_name), type_name, "new"); if (lg_find_func(L, mi, func_name, &fi)) return lg_call(L, &fi, 2); } /* no additional arguments must be given - they won't be used. */ luaL_checktype(L, 3, LUA_TNONE); if (mi->allocate_object) p = mi->allocate_object(mi, L, ts, count, &flags); else p = default_allocate_object(mi, L, ts, count, &flags); /* Allocate and initialize the object. I used to allocate just one * userdata big enough for both the wrapper and the object, but many free * functions exist, like gtk_tree_iter_free, and they expect a memory block * allocated by g_slice_alloc0. Therefore this optimization is not * possible. */ /* Make a Lua wrapper for it, push it on the stack. FLAG_ALLOCATED causes * the _malloc_handler be used, and FLAG_NEW_OBJECT makes it not complain * about increasing the (non existant) refcounter. */ lg_get_object(L, p, ts, flags); if (count) { struct object *w = (struct object*) lua_touserdata(L, -1); w->array_size = count; } return 1; }
/* * file:lock() method */ static void file_lock_work(struct lem_async *a) { struct file *f = (struct file *)a; struct flock fl = { .l_type = f->lock.type, .l_whence = SEEK_SET, .l_start = f->lock.start, .l_len = f->lock.len, }; if (fcntl(f->fd, F_SETLK, &fl) == -1) f->ret = errno; else f->ret = 0; } static void file_lock_reap(struct lem_async *a) { struct file *f = (struct file *)a; lua_State *T = f->T; f->T = NULL; if (f->ret) { lem_queue(T, io_strerror(T, f->ret)); return; } lua_pushboolean(T, 1); lem_queue(T, 1); } static int file_lock(lua_State *T) { static const short mode[] = { F_RDLCK, F_WRLCK, F_UNLCK }; static const char *const modenames[] = { "r", "w", "u", NULL }; struct file *f; int op; lua_Number start; lua_Number len; luaL_checktype(T, 1, LUA_TUSERDATA); op = luaL_checkoption(T, 2, NULL, modenames); start = luaL_optnumber(T, 3, 0); len = luaL_optnumber(T, 4, 0); f = lua_touserdata(T, 1); f->lock.start = (off_t)start; luaL_argcheck(T, (lua_Number)f->lock.start == start, 3, "not an integer in proper range"); f->lock.len = (off_t)len; luaL_argcheck(T, (lua_Number)f->lock.len == len, 4, "not an integer in proper range"); if (f->fd < 0) return io_closed(T); if (f->T != NULL) return io_busy(T); f->T = T; f->lock.type = mode[op]; lem_async_do(&f->a, file_lock_work, file_lock_reap); lua_settop(T, 1); return lua_yield(T, 1); }
// register_ore({lots of stuff}) int ModApiMapgen::l_register_ore(lua_State *L) { int index = 1; luaL_checktype(L, index, LUA_TTABLE); INodeDefManager *ndef = getServer(L)->getNodeDefManager(); BiomeManager *bmgr = getServer(L)->getEmergeManager()->biomemgr; OreManager *oremgr = getServer(L)->getEmergeManager()->oremgr; enum OreType oretype = (OreType)getenumfield(L, index, "ore_type", es_OreType, ORE_SCATTER); Ore *ore = oremgr->create(oretype); if (!ore) { errorstream << "register_ore: ore_type " << oretype << " not implemented"; return 0; } ore->name = getstringfield_default(L, index, "name", ""); ore->ore_param2 = (u8)getintfield_default(L, index, "ore_param2", 0); ore->clust_scarcity = getintfield_default(L, index, "clust_scarcity", 1); ore->clust_num_ores = getintfield_default(L, index, "clust_num_ores", 1); ore->clust_size = getintfield_default(L, index, "clust_size", 0); ore->nthresh = getfloatfield_default(L, index, "noise_threshhold", 0); ore->noise = NULL; ore->flags = 0; //// Get y_min/y_max warn_if_field_exists(L, index, "height_min", "Deprecated: new name is \"y_min\"."); warn_if_field_exists(L, index, "height_max", "Deprecated: new name is \"y_max\"."); int ymin, ymax; if (!getintfield(L, index, "y_min", ymin) && !getintfield(L, index, "height_min", ymin)) ymin = -31000; if (!getintfield(L, index, "y_max", ymax) && !getintfield(L, index, "height_max", ymax)) ymax = 31000; ore->y_min = ymin; ore->y_max = ymax; if (ore->clust_scarcity <= 0 || ore->clust_num_ores <= 0) { errorstream << "register_ore: clust_scarcity and clust_num_ores" "must be greater than 0" << std::endl; delete ore; return 0; } //// Get flags getflagsfield(L, index, "flags", flagdesc_ore, &ore->flags, NULL); //// Get biomes associated with this decoration (if any) lua_getfield(L, index, "biomes"); if (get_biome_list(L, -1, bmgr, &ore->biomes)) errorstream << "register_ore: couldn't get all biomes " << std::endl; lua_pop(L, 1); //// Get noise parameters if needed lua_getfield(L, index, "noise_params"); if (read_noiseparams(L, -1, &ore->np)) { ore->flags |= OREFLAG_USE_NOISE; } else if (ore->NEEDS_NOISE) { errorstream << "register_ore: specified ore type requires valid " "noise parameters" << std::endl; delete ore; return 0; } lua_pop(L, 1); if (oretype == ORE_VEIN) { OreVein *orevein = (OreVein *)ore; orevein->random_factor = getfloatfield_default(L, index, "random_factor", 1.f); } ObjDefHandle handle = oremgr->add(ore); if (handle == OBJDEF_INVALID_HANDLE) { delete ore; return 0; } ore->m_nodenames.push_back(getstringfield_default(L, index, "ore", "")); size_t nnames = getstringlistfield(L, index, "wherein", &ore->m_nodenames); ore->m_nnlistsizes.push_back(nnames); ndef->pendNodeResolve(ore, NODE_RESOLVE_DEFERRED); lua_pushinteger(L, handle); return 1; }
static int lload(lua_State *L) { int top = lua_gettop(L); FILE *fp; struct png_source source; if (top == 1) { const char *filename = luaL_checkstring(L,1); fp = fopen(filename, "rb"); if (fp == NULL) { return luaL_error(L, strerror(errno)); } unsigned char header[PNGSIGSIZE]; if (fread(header, 1, PNGSIGSIZE, fp) != PNGSIGSIZE) { return luaL_error(L, "png invalid"); } if (png_sig_cmp(header, 0, PNGSIGSIZE)) { return luaL_error(L, "png sig invalid"); } fseek(fp, 0, SEEK_SET); } else if (top == 2) { luaL_checktype(L,1,LUA_TLIGHTUSERDATA); void *data = lua_touserdata(L,1); size_t size = luaL_checkinteger(L,2); if (size < PNGSIGSIZE) { return luaL_error(L, "png invalid"); } if (png_sig_cmp(data, 0, PNGSIGSIZE)) { return luaL_error(L, "png sig invalid"); } source.data = data; source.size = size; source.offset = 0; } else { return luaL_error(L, "invalid argument number"); } png_structp png_ptr; png_infop info_ptr; png_uint_32 width, height; int bit_depth, color_type, interlace_type; int step;//, type; png_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING, NULL, NULL, NULL); if (png_ptr == NULL) { return 0; } info_ptr = png_create_info_struct(png_ptr); if (info_ptr == NULL) { png_destroy_read_struct(&png_ptr, NULL, NULL); return 0; } if (setjmp(png_jmpbuf(png_ptr))) { png_destroy_read_struct(&png_ptr, &info_ptr, NULL); return 0; } if (top == 1) png_init_io(png_ptr, fp); else png_set_read_fn(png_ptr, (void *)&source, png_read_cb); //png_set_sig_bytes(png_ptr, PNGSIGSIZE); png_read_info(png_ptr, info_ptr); png_get_IHDR(png_ptr, info_ptr, &width, &height, &bit_depth, &color_type, &interlace_type, NULL, NULL); if (color_type == PNG_COLOR_TYPE_PALETTE) png_set_palette_to_rgb(png_ptr); if (color_type == PNG_COLOR_TYPE_GRAY && bit_depth < 8) { bit_depth = 8; png_set_expand_gray_1_2_4_to_8(png_ptr); } if (png_get_valid(png_ptr, info_ptr, PNG_INFO_tRNS) != 0) png_set_tRNS_to_alpha(png_ptr); if (bit_depth == 16) png_set_strip_16(png_ptr); if (bit_depth < 8) png_set_packing(png_ptr); png_read_update_info(png_ptr, info_ptr); bit_depth = png_get_bit_depth(png_ptr, info_ptr); color_type = png_get_color_type(png_ptr, info_ptr); switch (color_type) { case PNG_COLOR_TYPE_GRAY: // type = TEXTURE_DEPTH; step = 1; break; case PNG_COLOR_TYPE_RGB: //type = TEXTURE_RGB; step = 3; break; case PNG_COLOR_TYPE_RGB_ALPHA: //type = TEXTURE_RGBA; step = 4; break; default: return luaL_error(L, "png color type %d not support", color_type); } png_bytep *row_pointers = (png_bytep *)malloc(height * sizeof(png_bytep)); png_size_t rowbytes = png_get_rowbytes(png_ptr,info_ptr); size_t bytes = rowbytes * height; uint8_t *buffer = (uint8_t *)malloc(bytes); int i; for (i=0; i<height; ++i) { row_pointers[i] = buffer + i*rowbytes; } png_read_image(png_ptr, row_pointers); png_read_end(png_ptr, info_ptr); png_destroy_read_struct(&png_ptr, &info_ptr, NULL); free(row_pointers); switch (color_type) { case PNG_COLOR_TYPE_GRAY: lua_pushliteral(L,"GRAY"); break; case PNG_COLOR_TYPE_RGB: lua_pushliteral(L,"RGB8"); break; case PNG_COLOR_TYPE_RGBA: lua_pushliteral(L,"RGBA8"); break; } lua_pushinteger(L,width); lua_pushinteger(L,height); int n = width * height * step; lua_createtable(L,n,0); for (i=0; i<n; ++i) { lua_pushinteger(L, buffer[i]); lua_rawseti(L, -2, i+1); } free(buffer); return 4; }
// satisfies wrapper tb_int_t xm_semver_select(lua_State* lua) { semver_t semver = {0}; semvers_t matches = {0}; semver_range_t range = {0}; lua_Integer i; size_t range_len = 0, source_len; tb_char_t const* source_str; tb_char_t const* source; tb_bool_t is_range; lua_settop(lua, 4); // check tb_assert_and_check_return_val(lua, 0); // get the version string tb_char_t const* range_str = luaL_checkstring(lua, 1); tb_check_return_val(range_str, 0); range_len = tb_strlen(range_str); is_range = semver_rangen(&range, range_str, range_len) == 0; if (is_range) { source = "versions"; luaL_checktype(lua, 2, LUA_TTABLE); for (i = lua_objlen(lua, 2); i > 0; --i) { lua_pushinteger(lua, i); lua_gettable(lua, 2); source_str = luaL_checkstring(lua, -1); tb_check_return_val(source_str, 0); if (semver_tryn(&semver, source_str, tb_strlen(source_str)) == 0) { if (semver_range_match(semver, range)) { semvers_push(matches, semver); } else { semver_dtor(&semver); } } } if (matches.length) { goto match; } semvers_clear(matches); source = "tags"; luaL_checktype(lua, 3, LUA_TTABLE); for (i = lua_objlen(lua, 3); i > 0; --i) { lua_pushinteger(lua, i); lua_gettable(lua, 3); source_str = luaL_checkstring(lua, -1); tb_check_return_val(source_str, 0); if (semver_tryn(&semver, source_str, tb_strlen(source_str)) == 0) { if (semver_range_match(semver, range)) { semvers_push(matches, semver); } else { semver_dtor(&semver); } } } if (matches.length) { goto match; } semvers_dtor(matches); semver_range_dtor(&range); } source = "branches"; luaL_checktype(lua, 4, LUA_TTABLE); for (i = lua_objlen(lua, 4); i > 0; --i) { lua_pushinteger(lua, i); lua_gettable(lua, 4); source_str = luaL_checkstring(lua, -1); tb_check_return_val(source_str, 0); source_len = tb_strlen(source_str); if (source_len == range_len && tb_memcmp(source_str, range_str, source_len) == 0) { lua_createtable(lua, 0, 2); lua_pushlstring(lua, source_str, source_len); lua_setfield(lua, -2, "version"); lua_pushstring(lua, source); lua_setfield(lua, -2, "source"); return 1; } } if (!is_range) { lua_pushnil(lua); lua_pushfstring(lua, "Unable to parse semver range '%s'", range_str); return 2; } lua_pushnil(lua); lua_pushfstring(lua, "Unable to select version for range '%s'", range_str); return 2; match: semvers_sort(matches); semver = semvers_pop(matches); lua_createtable(lua, 0, 2); lua_pushstring(lua, semver.raw); lua_setfield(lua, -2, "version"); lua_pushstring(lua, source); lua_setfield(lua, -2, "source"); semvers_dtor(matches); semver_dtor(&semver); semver_range_dtor(&range); return 1; }
static int luaModelInsertMix(lua_State *L) { unsigned int chn = luaL_checkunsigned(L, 1); unsigned int idx = luaL_checkunsigned(L, 2); unsigned int first = getFirstMix(chn); unsigned int count = getMixesCountFromFirst(chn, first); if (chn<NUM_CHNOUT && getExpoMixCount(0)<MAX_MIXERS && idx<=count) { idx += first; s_currCh = chn+1; insertExpoMix(0, idx); MixData *mix = mixAddress(idx); luaL_checktype(L, -1, LUA_TTABLE); for (lua_pushnil(L); lua_next(L, -2); lua_pop(L, 1)) { luaL_checktype(L, -2, LUA_TSTRING); // key is string const char * key = luaL_checkstring(L, -2); if (!strcmp(key, "name")) { const char * name = luaL_checkstring(L, -1); str2zchar(mix->name, name, sizeof(mix->name)); } else if (!strcmp(key, "source")) { mix->srcRaw = luaL_checkinteger(L, -1); } else if (!strcmp(key, "weight")) { mix->weight = luaL_checkinteger(L, -1); } else if (!strcmp(key, "offset")) { mix->offset = luaL_checkinteger(L, -1); } else if (!strcmp(key, "switch")) { mix->swtch = luaL_checkinteger(L, -1); } else if (!strcmp(key, "curveType")) { mix->curve.type = luaL_checkinteger(L, -1); } else if (!strcmp(key, "curveValue")) { mix->curve.value = luaL_checkinteger(L, -1); } else if (!strcmp(key, "multiplex")) { mix->mltpx = luaL_checkinteger(L, -1); } else if (!strcmp(key, "flightModes")) { mix->flightModes = luaL_checkinteger(L, -1); } else if (!strcmp(key, "carryTrim")) { mix->carryTrim = lua_toboolean(L, -1); } else if (!strcmp(key, "mixWarn")) { mix->mixWarn = luaL_checkinteger(L, -1); } else if (!strcmp(key, "delayUp")) { mix->delayUp = luaL_checkinteger(L, -1); } else if (!strcmp(key, "delayDown")) { mix->delayDown = luaL_checkinteger(L, -1); } else if (!strcmp(key, "speedUp")) { mix->speedUp = luaL_checkinteger(L, -1); } else if (!strcmp(key, "speedDown")) { mix->speedDown = luaL_checkinteger(L, -1); } } } return 0; }
// register_ore({lots of stuff}) int ModApiMapgen::l_register_ore(lua_State *L) { int index = 1; luaL_checktype(L, index, LUA_TTABLE); EmergeManager *emerge = getServer(L)->getEmergeManager(); enum OreType oretype = (OreType)getenumfield(L, index, "ore_type", es_OreType, ORE_SCATTER); Ore *ore = createOre(oretype); if (!ore) { errorstream << "register_ore: ore_type " << oretype << " not implemented"; return 0; } ore->ore_name = getstringfield_default(L, index, "ore", ""); ore->ore_param2 = (u8)getintfield_default(L, index, "ore_param2", 0); ore->clust_scarcity = getintfield_default(L, index, "clust_scarcity", 1); ore->clust_num_ores = getintfield_default(L, index, "clust_num_ores", 1); ore->clust_size = getintfield_default(L, index, "clust_size", 0); ore->height_min = getintfield_default(L, index, "height_min", 0); ore->height_max = getintfield_default(L, index, "height_max", 0); ore->nthresh = getfloatfield_default(L, index, "noise_threshhold", 0.); ore->flags = 0; getflagsfield(L, index, "flags", flagdesc_ore, &ore->flags, NULL); lua_getfield(L, index, "wherein"); if (lua_istable(L, -1)) { int i = lua_gettop(L); lua_pushnil(L); while(lua_next(L, i) != 0) { ore->wherein_names.push_back(lua_tostring(L, -1)); lua_pop(L, 1); } } else if (lua_isstring(L, -1)) { ore->wherein_names.push_back(lua_tostring(L, -1)); } else { ore->wherein_names.push_back(""); } lua_pop(L, 1); lua_getfield(L, index, "noise_params"); ore->np = read_noiseparams(L, -1); lua_pop(L, 1); ore->noise = NULL; if (ore->clust_scarcity <= 0 || ore->clust_num_ores <= 0) { errorstream << "register_ore: clust_scarcity and clust_num_ores" "must be greater than 0" << std::endl; delete ore; return 0; } emerge->ores.push_back(ore); verbosestream << "register_ore: ore '" << ore->ore_name << "' registered" << std::endl; return 0; }
int EventDispatcherBinder::addEventListener(lua_State* L) { StackChecker checker(L, "EventDispatcherBinder::addEventListener", 0); Binder binder(L); EventDispatcher* eventDispatcher = static_cast<EventDispatcher*>(binder.getInstance("EventDispatcher", 1)); luaL_checktype(L, 2, LUA_TSTRING); luaL_checktype(L, 3, LUA_TFUNCTION); bool hasData = !lua_isnoneornil(L, 4); createEventsTable(L, 1); // create self.__events table if it's not created EventBinderMap& map = getOrCreateEventBinderMap(eventDispatcher); const char* event = lua_tostring(L, 2); int eventid = StringId::instance().id(event); const std::vector<CppLuaBridge*>& bridges = map[eventid]; lua_getfield(L, 1, "__events"); // key is CppLuaBridge*, value is 'event check closure' // check if the event is already registered bool isFound = false; for (std::size_t i = 0; i < bridges.size(); ++i) { lua_pushlightuserdata(L, bridges[i]); lua_rawget(L, -2); // we get the event check closure if (hasData == false) { lua_pushvalue(L, 3); // function lua_call(L, 1, 1); } else { lua_pushvalue(L, 3); // function lua_pushvalue(L, 4); // data lua_call(L, 2, 1); } if (lua_toboolean(L, -1)) { lua_pop(L, 1); isFound = true; break; } else lua_pop(L, 1); } if (isFound == true) { lua_pop(L, 1); // pop __events, leave stack as it is return 0; } LuaApplication *application = (LuaApplication*)luaL_getdata(L); lua_State *mainL = application->getLuaState(); CppLuaBridge* bridge = new CppLuaBridge(mainL); // create event closure luaL_rawgetptr(L, LUA_REGISTRYINDEX, &key_eventClosures); lua_pushlightuserdata(L, bridge); // key=bridge if (hasData == false) // value=closure { // self ve function'in eventClosure'in icine upvalue olarak koyulmasi garbage collect edilmesini engelliyor // bu yuzden {self, function} seklinde bi weak table yaratip ilk upvalue olarak onu set ediyoruz luaL_newweaktable(L); lua_pushvalue(L, 1); // self lua_rawseti(L, -2, 1); lua_pushvalue(L, 3); // function lua_rawseti(L, -2, 2); lua_pushcclosure(L, &eventClosure, 1); } else { // self, function ve data'nin eventClosure'in icine upvalue olarak koyulmasi garbage collect edilmesini engelliyor // bu yuzden {self, function, data} seklinde bi weak table yaratip ilk upvalue olarak onu set ediyoruz luaL_newweaktable(L); lua_pushvalue(L, 1); // self lua_rawseti(L, -2, 1); lua_pushvalue(L, 3); // function lua_rawseti(L, -2, 2); lua_pushvalue(L, 4); // data lua_rawseti(L, -2, 3); lua_pushcclosure(L, &eventClosureWithData, 1); } lua_rawset(L, -3); // envtable["eventClosures"][bridge] = closure lua_pop(L, 1); // pop envtable["eventClosures"] // create event check closure lua_pushlightuserdata(L, bridge); if (hasData == false) { lua_pushvalue(L, 3); // function lua_pushcclosure(L, &eventCheckClosure, 1); } else { lua_pushvalue(L, 3); // function lua_pushvalue(L, 4); // data lua_pushcclosure(L, &eventCheckClosureWithData, 2); } lua_rawset(L, -3); map.push_back(eventid, bridge); bridge->unref(); eventDispatcher->addEventListener(LuaEvent::Type(event), bridge, &CppLuaBridge::luaEvent); lua_pop(L, 1); // pop __events, leave stack as it is return 0; }
static int lp_foldcapture (lua_State *L) { luaL_checktype(L, 2, LUA_TFUNCTION); return capture_aux(L, Cfold, 2); }
/*---------------------------------------------------------------------*/ static int pkteng_link(lua_State *L) { TRACE_LUA_FUNC_START(); PktEngine_Intf *pe = check_pkteng(L, 1); Linker_Intf *linker; Brick *first_brick; int nargs = lua_gettop(L); int i; /* check if args2 is user-data */ luaL_checktype(L, 2, LUA_TUSERDATA); /* Retrieve linker data */ linker = (Linker_Intf *)luaL_optudata(L, 2); /* set values as default */ pe->batch = DEFAULT_BATCH_SIZE; pe->qid = -1; /* if 3rd arg is passed, fill it with batch size */ if (nargs >= 3) pe->batch = luaL_checkint(L, 3); /* if 4th arg is passed, fill it with qid */ if (nargs >= 4) pe->qid = luaL_checkint(L, 4); lua_settop(L, 1); TRACE_DEBUG_LOG("Engine info so far...:\n" "\tName: %s\n" "\tCpu: %d\n" "\tBatch: %d\n" "\tQid: %d\n", pe->eng_name, pe->cpu, pe->batch, pe->qid); for (i = 0; i < linker->input_count; i++) { /* link the source(s) with the packet engine */ pktengine_link_iface((uint8_t *)pe->eng_name, (uint8_t *)linker->input_link[i], pe->batch, pe->qid); TRACE_LOG("Linking %s with link %s with batch size: %d and qid: %d\n", pe->eng_name, linker->input_link[i], pe->batch, pe->qid); } first_brick = createBrick(linker->type); if (first_brick == NULL) { TRACE_LUA_FUNC_END(); return 1; } first_brick->eng = engine_find((unsigned char *)pe->eng_name); first_brick->elib->init(first_brick, linker); if (first_brick->eng == NULL) { TRACE_LOG("Could not find engine with name: %s\n", pe->eng_name); TRACE_LUA_FUNC_END(); free(first_brick); return 1; } first_brick->elib->link(first_brick, linker); /* if there are pipelines, link them as well */ while (linker->next_linker != NULL) { linker = linker->next_linker; first_brick->elib->link(first_brick, linker); } TRACE_LUA_FUNC_END(); return 1; }
LUA_EXPORT(int openldap_uv_lua_search(lua_State *L)) { openldap_uv_lua_handle_t *ldap = luaL_checkudata(L, 1, META_TABLE); if(!ldap->ldap) { luaL_error(L, "Handle is not connected"); } const char *dn = openldap_uv_lua__string_or_null(L, 2); const char *scope = luaL_checkstring(L, 3); int _scope; if(strcmp(scope, "LDAP_SCOPE_BASE") == 0 || strcmp(scope, "LDAP_SCOPE_BASEOBJECT") == 0) _scope = LDAP_SCOPE_BASEOBJECT; else if(strcmp(scope, "LDAP_SCOPE_ONE") == 0 || strcasecmp(scope, "LDAP_SCOPE_ONELEVEL") == 0) _scope = LDAP_SCOPE_ONELEVEL; else if(strcmp(scope, "LDAP_SCOPE_SUB") == 0 || strcasecmp(scope, "LDAP_SCOPE_SUBTREE") == 0) _scope = LDAP_SCOPE_SUBTREE; else if(strcmp(scope, "LDAP_SCOPE_CHILDREN") == 0 || strcasecmp(scope, "LDAP_SCOPE_SUBORDINATE") == 0) _scope = LDAP_SCOPE_CHILDREN; else luaL_error(L, "Unsupported scope %s", scope); const char *filter = openldap_uv_lua__string_or_null(L, 4); char **fieldSelector = NULL; if(!lua_isnil(L, 5)) { luaL_checktype(L, 5, LUA_TTABLE); int size = lua_objlen(L, 5); fieldSelector = malloc(sizeof(*fieldSelector) * (size + 1)); lua_pushnil(L); for(int i = 0; lua_next(L, 5); i++) { fieldSelector[i] = (char *)lua_tostring(L, -1); fieldSelector[i+1] = 0; lua_pop(L, 1); } lua_pop(L, 1); } int onlyFieldNames = lua_toboolean(L, 6) ? 1 : 0; LDAPMessage *message = 0; int err = ldap_search_ext_s(ldap->ldap, dn, _scope, filter, fieldSelector, onlyFieldNames, 0, 0, 0, LDAP_NO_LIMIT, &message); if(err != 0) { ldap_msgfree(message); openldap_uv_lua__check_error(L, ldap, err); } LDAPMessage *entry = ldap_first_entry(ldap->ldap, message); lua_newtable(L); while(entry) { char *dn = ldap_get_dn(ldap->ldap, entry); lua_pushstring(L, dn); free(dn); lua_newtable(L); BerElement *ber; char *attr = ldap_first_attribute(ldap->ldap, entry, &ber); int j = 0; while(attr) { struct berval **vals = ldap_get_values_len(ldap->ldap, entry, attr ); if(vals) { for(int i = 0; vals[i]; i++) { lua_pushnumber(L, ++j); lua_newtable(L); lua_pushnumber(L, 1); lua_pushstring(L, attr); lua_rawset(L, -3); lua_pushnumber(L, 2); lua_pushlstring(L, vals[i]->bv_val, vals[i]->bv_len); lua_rawset(L, -3); lua_rawset(L, -3); } ldap_value_free_len( vals ); } ldap_memfree( attr ); attr = ldap_next_attribute( ldap->ldap, entry, ber); } lua_rawset(L, -3); entry = ldap_next_entry(ldap->ldap, entry); } ldap_msgfree(message); return 1; }
static int l_mainloop(lua_State *L) { luaL_checktype(L, 1, LUA_TTHREAD); lua_State *dispatcher = lua_tothread(L, 1); fps_ctrl *fps_control = (fps_ctrl*)lua_touserdata(L, luaT_upvalueindex(1)); SDL_TimerID timer = SDL_AddTimer(30, timer_frame_callback, NULL); SDL_Event e; while(SDL_WaitEvent(&e) != 0) { bool do_frame = false; bool do_timer = false; do { int nargs; switch(e.type) { case SDL_QUIT: goto leave_loop; case SDL_KEYDOWN: lua_pushliteral(dispatcher, "keydown"); lua_pushstring(dispatcher, SDL_GetKeyName(e.key.keysym.sym)); l_push_modifiers_table(dispatcher, e.key.keysym.mod); lua_pushboolean(dispatcher, e.key.repeat != 0); nargs = 4; break; case SDL_KEYUP: lua_pushliteral(dispatcher, "keyup"); lua_pushstring(dispatcher, SDL_GetKeyName(e.key.keysym.sym)); nargs = 2; break; case SDL_TEXTINPUT: lua_pushliteral(dispatcher, "textinput"); lua_pushstring(dispatcher, e.text.text); nargs = 2; break; case SDL_TEXTEDITING: lua_pushliteral(dispatcher, "textediting"); lua_pushstring(dispatcher, e.edit.text); lua_pushinteger(dispatcher, e.edit.start); lua_pushinteger(dispatcher, e.edit.length); nargs = 4; break; case SDL_MOUSEBUTTONDOWN: lua_pushliteral(dispatcher, "buttondown"); lua_pushinteger(dispatcher, e.button.button); lua_pushinteger(dispatcher, e.button.x); lua_pushinteger(dispatcher, e.button.y); nargs = 4; break; case SDL_MOUSEBUTTONUP: lua_pushliteral(dispatcher, "buttonup"); lua_pushinteger(dispatcher, e.button.button); lua_pushinteger(dispatcher, e.button.x); lua_pushinteger(dispatcher, e.button.y); nargs = 4; break; case SDL_MOUSEWHEEL: lua_pushliteral(dispatcher, "mousewheel"); lua_pushinteger(dispatcher, e.wheel.x); lua_pushinteger(dispatcher, e.wheel.y); nargs = 3; break; case SDL_MOUSEMOTION: lua_pushliteral(dispatcher, "motion"); lua_pushinteger(dispatcher, e.motion.x); lua_pushinteger(dispatcher, e.motion.y); lua_pushinteger(dispatcher, e.motion.xrel); lua_pushinteger(dispatcher, e.motion.yrel); nargs = 5; break; case SDL_WINDOWEVENT: switch (e.window.event) { case SDL_WINDOWEVENT_FOCUS_GAINED: lua_pushliteral(dispatcher, "active"); lua_pushinteger(dispatcher, 1); nargs = 2; break; case SDL_WINDOWEVENT_FOCUS_LOST: lua_pushliteral(dispatcher, "active"); lua_pushinteger(dispatcher, 0); nargs = 2; break; default: nargs = 0; break; } break; case SDL_USEREVENT_MUSIC_OVER: lua_pushliteral(dispatcher, "music_over"); nargs = 1; break; case SDL_USEREVENT_CPCALL: if(luaT_cpcall(L, (lua_CFunction)e.user.data1, e.user.data2)) { SDL_RemoveTimer(timer); lua_pushliteral(L, "callback"); return 2; } nargs = 0; break; case SDL_USEREVENT_TICK: do_timer = true; nargs = 0; break; case SDL_USEREVENT_MOVIE_OVER: lua_pushliteral(dispatcher, "movie_over"); nargs = 1; break; case SDL_USEREVENT_SOUND_OVER: lua_pushliteral(dispatcher, "sound_over"); lua_pushinteger(dispatcher, *(static_cast<int*>(e.user.data1))); nargs = 2; break; default: nargs = 0; break; } if(nargs != 0) { if(luaT_resume(dispatcher, dispatcher, nargs) != LUA_YIELD) { goto leave_loop; } do_frame = do_frame || (lua_toboolean(dispatcher, 1) != 0); lua_settop(dispatcher, 0); } } while(SDL_PollEvent(&e) != 0); if(do_timer) { lua_pushliteral(dispatcher, "timer"); if(luaT_resume(dispatcher, dispatcher, 1) != LUA_YIELD) { break; } do_frame = do_frame || (lua_toboolean(dispatcher, 1) != 0); lua_settop(dispatcher, 0); } if(do_frame || !fps_control->limit_fps) { do { if(fps_control->track_fps) { fps_control->count_frame(); } lua_pushliteral(dispatcher, "frame"); if(luaT_resume(dispatcher, dispatcher, 1) != LUA_YIELD) { goto leave_loop; } lua_settop(dispatcher, 0); } while(fps_control->limit_fps == false && SDL_PollEvent(NULL) == 0); } // No events pending - a good time to do a bit of garbage collection lua_gc(L, LUA_GCSTEP, 2); } leave_loop: SDL_RemoveTimer(timer); int n = lua_gettop(dispatcher); if(lua_status(dispatcher) >= LUA_ERRRUN) { n = 1; } lua_checkstack(L, n); lua_xmove(dispatcher, L, n); return n; }
/* Request internal information from the curl session */ static int lcurl_easy_getinfo(lua_State* L) { curlT* c=tocurl(L, 1); CURLINFO nInfo; CURLcode code=-1; luaL_checktype(L, 2, LUA_TNUMBER); /* accept info code number only */ nInfo=lua_tonumber(L, 2); if (nInfo>CURLINFO_SLIST) { /* string list */ struct curl_slist *slist=0; if (CURLE_OK == (code=curl_easy_getinfo(c->curl, nInfo, &slist))) { if (slist) { int i; lua_newtable(L); for (i=1; slist; i++, slist=slist->next) { lua_pushnumber(L, i); lua_pushstring(L, slist->data); lua_settable(L, -3); } curl_slist_free_all(slist); } else { lua_pushnil(L); } return 1; } else { /* curl_easy_getinfo returns error */ } } else if (nInfo>CURLINFO_DOUBLE) { /* double */ double value; if (CURLE_OK == (code=curl_easy_getinfo(c->curl, nInfo, &value))) { lua_pushnumber(L, value); return 1; } else { /* curl_easy_getinfo returns error */ } } else if (nInfo>CURLINFO_LONG) { /* long */ long value; if (CURLE_OK == (code=curl_easy_getinfo(c->curl, nInfo, &value))) { lua_pushinteger(L, (lua_Integer)value); return 1; } else { /* curl_easy_getinfo returns error */ } } else if (nInfo>CURLINFO_STRING) { /* string */ char* value; if (CURLE_OK == (code=curl_easy_getinfo(c->curl, nInfo, &value))) { lua_pushstring(L, value); return 1; } else { /* curl_easy_getinfo returns error */ } } /* on error */ /* return nil, error message, error code */ lua_pushnil(L); if (code>CURLE_OK) { #if CURL_NEWER(7,11,2) lua_pushstring(L, curl_easy_strerror(code)); #else lua_pushfstring(L, "Curl error: #%d", (code)); #endif lua_pushnumber(L, code); return 3; } else { lua_pushfstring(L, "Invalid CURLINFO number: %d", nInfo); return 2; } }
static int ngx_http_lua_ngx_location_capture_multi(lua_State *L) { ngx_http_request_t *r; ngx_http_request_t *sr; /* subrequest object */ ngx_http_post_subrequest_t *psr; ngx_http_lua_ctx_t *sr_ctx; ngx_http_lua_ctx_t *ctx; ngx_array_t *extra_vars; ngx_str_t uri; ngx_str_t args; ngx_str_t extra_args; ngx_uint_t flags; u_char *p; u_char *q; size_t len; size_t nargs; int rc; int n; ngx_uint_t method; ngx_http_request_body_t *body; int type; ngx_buf_t *b; unsigned vars_action; ngx_uint_t nsubreqs; ngx_uint_t index; size_t sr_statuses_len; size_t sr_headers_len; size_t sr_bodies_len; unsigned custom_ctx; ngx_http_lua_co_ctx_t *coctx; ngx_http_lua_post_subrequest_data_t *psr_data; n = lua_gettop(L); if (n != 1) { return luaL_error(L, "only one argument is expected, but got %d", n); } luaL_checktype(L, 1, LUA_TTABLE); nsubreqs = lua_objlen(L, 1); if (nsubreqs == 0) { return luaL_error(L, "at least one subrequest should be specified"); } lua_pushlightuserdata(L, &ngx_http_lua_request_key); lua_rawget(L, LUA_GLOBALSINDEX); r = lua_touserdata(L, -1); lua_pop(L, 1); if (r == NULL) { return luaL_error(L, "no request object found"); } ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module); if (ctx == NULL) { return luaL_error(L, "no ctx found"); } ngx_http_lua_check_context(L, ctx, NGX_HTTP_LUA_CONTEXT_REWRITE | NGX_HTTP_LUA_CONTEXT_ACCESS | NGX_HTTP_LUA_CONTEXT_CONTENT); coctx = ctx->cur_co_ctx; if (coctx == NULL) { return luaL_error(L, "no co ctx found"); } sr_statuses_len = nsubreqs * sizeof(ngx_int_t); sr_headers_len = nsubreqs * sizeof(ngx_http_headers_out_t *); sr_bodies_len = nsubreqs * sizeof(ngx_str_t); p = ngx_pcalloc(r->pool, sr_statuses_len + sr_headers_len + sr_bodies_len); if (p == NULL) { return luaL_error(L, "out of memory"); } coctx->sr_statuses = (void *) p; p += sr_statuses_len; coctx->sr_headers = (void *) p; p += sr_headers_len; coctx->sr_bodies = (void *) p; coctx->nsubreqs = nsubreqs; coctx->pending_subreqs = 0; extra_vars = NULL; for (index = 0; index < nsubreqs; index++) { coctx->pending_subreqs++; lua_rawgeti(L, 1, index + 1); if (lua_isnil(L, -1)) { return luaL_error(L, "only array-like tables are allowed"); } dd("queries query: top %d", lua_gettop(L)); if (lua_type(L, -1) != LUA_TTABLE) { return luaL_error(L, "the query argument %d is not a table, " "but a %s", index, lua_typename(L, lua_type(L, -1))); } nargs = lua_objlen(L, -1); if (nargs != 1 && nargs != 2) { return luaL_error(L, "query argument %d expecting one or " "two arguments", index); } lua_rawgeti(L, 2, 1); /* queries query uri */ dd("queries query uri: %d", lua_gettop(L)); dd("first arg in first query: %s", lua_typename(L, lua_type(L, -1))); body = NULL; extra_args.data = NULL; extra_args.len = 0; if (extra_vars != NULL) { /* flush out existing elements in the array */ extra_vars->nelts = 0; } vars_action = 0; custom_ctx = 0; if (nargs == 2) { /* check out the options table */ lua_rawgeti(L, 2, 2); /* queries query uri opts */ dd("queries query uri opts: %d", lua_gettop(L)); if (lua_type(L, 4) != LUA_TTABLE) { return luaL_error(L, "expecting table as the 2nd argument for " "subrequest %d, but got %s", index, luaL_typename(L, 4)); } dd("queries query uri opts: %d", lua_gettop(L)); /* check the args option */ lua_getfield(L, 4, "args"); type = lua_type(L, -1); switch (type) { case LUA_TTABLE: ngx_http_lua_process_args_option(r, L, -1, &extra_args); break; case LUA_TNIL: /* do nothing */ break; case LUA_TNUMBER: case LUA_TSTRING: extra_args.data = (u_char *) lua_tolstring(L, -1, &len); extra_args.len = len; break; default: return luaL_error(L, "Bad args option value"); } lua_pop(L, 1); dd("queries query uri opts: %d", lua_gettop(L)); /* check the vars option */ lua_getfield(L, 4, "vars"); switch (lua_type(L, -1)) { case LUA_TTABLE: ngx_http_lua_process_vars_option(r, L, -1, &extra_vars); dd("post process vars top: %d", lua_gettop(L)); break; case LUA_TNIL: /* do nothing */ break; default: return luaL_error(L, "Bad vars option value"); } lua_pop(L, 1); dd("queries query uri opts: %d", lua_gettop(L)); /* check the share_all_vars option */ lua_getfield(L, 4, "share_all_vars"); switch (lua_type(L, -1)) { case LUA_TNIL: /* do nothing */ break; case LUA_TBOOLEAN: if (lua_toboolean(L, -1)) { vars_action |= NGX_HTTP_LUA_SHARE_ALL_VARS; } break; default: return luaL_error(L, "Bad share_all_vars option value"); } lua_pop(L, 1); dd("queries query uri opts: %d", lua_gettop(L)); /* check the copy_all_vars option */ lua_getfield(L, 4, "copy_all_vars"); switch (lua_type(L, -1)) { case LUA_TNIL: /* do nothing */ break; case LUA_TBOOLEAN: if (lua_toboolean(L, -1)) { vars_action |= NGX_HTTP_LUA_COPY_ALL_VARS; } break; default: return luaL_error(L, "Bad copy_all_vars option value"); } lua_pop(L, 1); dd("queries query uri opts: %d", lua_gettop(L)); /* check the "method" option */ lua_getfield(L, 4, "method"); type = lua_type(L, -1); if (type == LUA_TNIL) { method = NGX_HTTP_GET; } else { if (type != LUA_TNUMBER) { return luaL_error(L, "Bad http request method"); } method = (ngx_uint_t) lua_tonumber(L, -1); } lua_pop(L, 1); dd("queries query uri opts: %d", lua_gettop(L)); /* check the "ctx" option */ lua_getfield(L, 4, "ctx"); type = lua_type(L, -1); if (type != LUA_TNIL) { if (type != LUA_TTABLE) { return luaL_error(L, "Bad ctx option value type %s, " "expected a Lua table", lua_typename(L, type)); } custom_ctx = 1; } else { lua_pop(L, 1); } dd("queries query uri opts ctx?: %d", lua_gettop(L)); /* check the "body" option */ lua_getfield(L, 4, "body"); type = lua_type(L, -1); if (type != LUA_TNIL) { if (type != LUA_TSTRING && type != LUA_TNUMBER) { return luaL_error(L, "Bad http request body"); } body = ngx_pcalloc(r->pool, sizeof(ngx_http_request_body_t)); if (body == NULL) { return luaL_error(L, "out of memory"); } q = (u_char *) lua_tolstring(L, -1, &len); dd("request body: [%.*s]", (int) len, q); if (len) { b = ngx_create_temp_buf(r->pool, len); if (b == NULL) { return luaL_error(L, "out of memory"); } b->last = ngx_copy(b->last, q, len); body->bufs = ngx_alloc_chain_link(r->pool); if (body->bufs == NULL) { return luaL_error(L, "out of memory"); } body->bufs->buf = b; body->bufs->next = NULL; body->buf = b; } } lua_pop(L, 1); /* pop the body */ /* stack: queries query uri opts ctx? */ lua_remove(L, 4); /* stack: queries query uri ctx? */ dd("queries query uri ctx?: %d", lua_gettop(L)); } else { method = NGX_HTTP_GET; } /* stack: queries query uri ctx? */ p = (u_char *) luaL_checklstring(L, 3, &len); uri.data = ngx_palloc(r->pool, len); if (uri.data == NULL) { return luaL_error(L, "memory allocation error"); } ngx_memcpy(uri.data, p, len); uri.len = len; args.data = NULL; args.len = 0; flags = 0; rc = ngx_http_parse_unsafe_uri(r, &uri, &args, &flags); if (rc != NGX_OK) { dd("rc = %d", (int) rc); return luaL_error(L, "unsafe uri in argument #1: %s", p); } if (args.len == 0) { args = extra_args; } else if (extra_args.len) { /* concatenate the two parts of args together */ len = args.len + (sizeof("&") - 1) + extra_args.len; p = ngx_palloc(r->pool, len); if (p == NULL) { return luaL_error(L, "out of memory"); } q = ngx_copy(p, args.data, args.len); *q++ = '&'; ngx_memcpy(q, extra_args.data, extra_args.len); args.data = p; args.len = len; } p = ngx_pnalloc(r->pool, sizeof(ngx_http_post_subrequest_t) + sizeof(ngx_http_lua_ctx_t) + sizeof(ngx_http_lua_post_subrequest_data_t)); if (p == NULL) { return luaL_error(L, "out of memory"); } psr = (ngx_http_post_subrequest_t *) p; p += sizeof(ngx_http_post_subrequest_t); sr_ctx = (ngx_http_lua_ctx_t *) p; p += sizeof(ngx_http_lua_ctx_t); psr_data = (ngx_http_lua_post_subrequest_data_t *) p; ngx_memzero(sr_ctx, sizeof(ngx_http_lua_ctx_t)); /* set by ngx_memzero: * sr_ctx->run_post_subrequest = 0 * sr_ctx->free = NULL */ ngx_http_lua_init_ctx(sr_ctx); sr_ctx->capture = 1; sr_ctx->index = index; psr_data->ctx = sr_ctx; psr_data->pr_co_ctx = coctx; psr->handler = ngx_http_lua_post_subrequest; psr->data = psr_data; rc = ngx_http_lua_subrequest(r, &uri, &args, &sr, psr, 0); if (rc != NGX_OK) { return luaL_error(L, "failed to issue subrequest: %d", (int) rc); } ngx_http_set_ctx(sr, sr_ctx, ngx_http_lua_module); rc = ngx_http_lua_adjust_subrequest(sr, method, body, vars_action, extra_vars); if (rc != NGX_OK) { ngx_http_lua_cancel_subreq(sr); return luaL_error(L, "failed to adjust the subrequest: %d", (int) rc); } dd("queries query uri opts ctx? %d", lua_gettop(L)); /* stack: queries query uri ctx? */ if (custom_ctx) { ngx_http_lua_ngx_set_ctx_helper(L, sr, sr_ctx, -1); lua_pop(L, 3); } else { lua_pop(L, 2); } /* stack: queries */ } if (extra_vars) { ngx_array_destroy(extra_vars); } ctx->no_abort = 1; return lua_yield(L, 0); }
/* set any supported curl option (see also ALL_CURL_OPT) */ static int lcurl_easy_setopt(lua_State* L) { union luaValueT v; /* the result option value */ int curlOpt; /* the provided option code */ CURLcode code; /* return error code from curl */ curlT* c = tocurl(L, 1); /* get self object */ luaL_checktype(L, 2, LUA_TNUMBER); /* accept only number option codes */ if (lua_gettop(L)<3) /* option value is always required */ { luaL_error(L, "Invalid number of arguments %d to `setopt' method", lua_gettop(L)); } curlOpt=(int)lua_tonumber(L, 2); /* get the curl option code */ v.nval=0; switch (curlOpt) { case CURLOPT_PROGRESSFUNCTION: case CURLOPT_READFUNCTION: case CURLOPT_WRITEFUNCTION: case CURLOPT_HEADERFUNCTION: case CURLOPT_IOCTLFUNCTION: luaL_checktype(L, 3, LUA_TFUNCTION); /* callback options require Lua function value */ case CURLOPT_READDATA: case CURLOPT_WRITEDATA: case CURLOPT_PROGRESSDATA: case CURLOPT_HEADERDATA: #if CURL_NEWER(7,12,3) case CURLOPT_IOCTLDATA: #endif switch (lua_type(L, 3)) /* handle table, userdata and funtion callback params specially */ { case LUA_TTABLE: case LUA_TUSERDATA: case LUA_TTHREAD: case LUA_TFUNCTION: { int ref; lua_pushvalue(L, 3); ref=luaL_ref(L, LUA_REGISTRYINDEX); /* get reference to the lua object in registry */ if (curlOpt == CURLOPT_READFUNCTION) { luaL_unref(L, LUA_REGISTRYINDEX, c->freaderRef); /* unregister previous reference to reader if any */ c->freaderRef=ref; /* keep the reader function reference in self */ v.rcb=(curl_read_callback)readerCallback; /* redirect the option value to readerCallback */ if (CURLE_OK != (code=curl_easy_setopt(c->curl, CURLOPT_READDATA, c))) goto on_error; } else if (curlOpt == CURLOPT_WRITEFUNCTION) { luaL_unref(L, LUA_REGISTRYINDEX, c->fwriterRef); c->fwriterRef=ref; v.wcb=(curl_write_callback)writerCallback; if (CURLE_OK != (code=curl_easy_setopt(c->curl, CURLOPT_WRITEDATA, c))) goto on_error; } else if (curlOpt == CURLOPT_PROGRESSFUNCTION) { luaL_unref(L, LUA_REGISTRYINDEX, c->fprogressRef); c->fprogressRef=ref; v.pcb=(curl_progress_callback)progressCallback; if (CURLE_OK != (code=curl_easy_setopt(c->curl, CURLOPT_PROGRESSDATA, c))) goto on_error; } else if (curlOpt == CURLOPT_HEADERFUNCTION) { luaL_unref(L, LUA_REGISTRYINDEX, c->fheaderRef); c->fheaderRef=ref; v.wcb=(curl_write_callback)headerCallback; if (CURLE_OK != (code=curl_easy_setopt(c->curl, CURLOPT_HEADERDATA, c))) goto on_error; } #if CURL_NEWER(7,12,3) else if (curlOpt == CURLOPT_IOCTLFUNCTION) { luaL_unref(L, LUA_REGISTRYINDEX, c->fioctlRef); c->fioctlRef=ref; v.icb=ioctlCallback; if (CURLE_OK != (code=curl_easy_setopt(c->curl, CURLOPT_IOCTLDATA, c))) goto on_error; } #endif else { /* When the option code is any of CURLOPT_xxxDATA and the argument is table, userdata or function set the curl option value to the lua object reference */ v.nval=ref; } }break; }break; /* Handle all supported curl options differently according the specific option argument type */ #undef C_OPT #define C_OPT(n, t) \ case CURLOPT_##n: \ v=get_##t(L, 3); \ break; #undef C_OPT_SL #define C_OPT_SL(n) \ case CURLOPT_##n: \ { \ v=get_slist(L, 3, &KEY_##n); \ }break; /* Expands all the list of switch-case's here */ ALL_CURL_OPT default: luaL_error(L, "Not supported curl option %d", curlOpt); } /* additional check if the option value has compatible type with the option code */ switch (lua_type(L, 3)) { case LUA_TFUNCTION: /* allow function argument only for the special option codes */ if (curlOpt == CURLOPT_READFUNCTION || curlOpt == CURLOPT_WRITEFUNCTION || curlOpt == CURLOPT_PROGRESSFUNCTION || curlOpt == CURLOPT_HEADERFUNCTION || curlOpt == CURLOPT_IOCTLFUNCTION ) break; case LUA_TTABLE: /* allow table or userdata only for the callback parameter option */ case LUA_TUSERDATA: if (curlOpt != CURLOPT_READDATA && curlOpt != CURLOPT_WRITEDATA && curlOpt != CURLOPT_PROGRESSDATA && curlOpt != CURLOPT_HEADERDATA #if CURL_NEWER(7,12,3) && curlOpt != CURLOPT_IOCTLDATA #endif ) luaL_error(L, "argument #2 type %s is not compatible with this option", lua_typename(L, 3)); break; } /* handle curl option for setting callback parameter */ switch (curlOpt) { case CURLOPT_READDATA: if (c->rudtype == LUA_TFUNCTION || c->rudtype == LUA_TUSERDATA || c->rudtype == LUA_TTABLE || c->rudtype == LUA_TTHREAD) luaL_unref(L, LUA_REGISTRYINDEX, c->rud.nval); /* unref previously referenced read data */ c->rudtype=lua_type(L, 3); /* set the read data type */ c->rud=v; /* set the read data value (it can be reference) */ v.ptr=c; /* set the real read data to curl as our self object */ break; case CURLOPT_WRITEDATA: if (c->wudtype == LUA_TFUNCTION || c->wudtype == LUA_TUSERDATA || c->wudtype == LUA_TTABLE || c->wudtype == LUA_TTHREAD) luaL_unref(L, LUA_REGISTRYINDEX, c->wud.nval); c->wudtype=lua_type(L, 3); c->wud=v; v.ptr=c; break; case CURLOPT_PROGRESSDATA: if (c->pudtype == LUA_TFUNCTION || c->pudtype == LUA_TUSERDATA || c->pudtype == LUA_TTABLE || c->pudtype == LUA_TTHREAD) luaL_unref(L, LUA_REGISTRYINDEX, c->pud.nval); c->pudtype=lua_type(L, 3); c->pud=v; v.ptr=c; break; case CURLOPT_HEADERDATA: if (c->hudtype == LUA_TFUNCTION || c->hudtype == LUA_TUSERDATA || c->hudtype == LUA_TTABLE || c->hudtype == LUA_TTHREAD) luaL_unref(L, LUA_REGISTRYINDEX, c->hud.nval); c->hudtype=lua_type(L, 3); c->hud=v; v.ptr=c; break; #if CURL_NEWER(7,12,3) case CURLOPT_IOCTLDATA: if (c->iudtype == LUA_TFUNCTION || c->iudtype == LUA_TUSERDATA || c->iudtype == LUA_TTABLE || c->iudtype == LUA_TTHREAD) luaL_unref(L, LUA_REGISTRYINDEX, c->iud.nval); c->iudtype=lua_type(L, 3); c->iud=v; v.ptr=c; break; #endif } /* set easy the curl option with the processed value */ if (CURLE_OK == (code=curl_easy_setopt(c->curl, (int)lua_tonumber(L, 2), v.nval))) { /* on success return true */ lua_pushboolean(L, 1); return 1; } on_error: /* on fail return nil, error message, error code */ lua_pushnil(L); #if CURL_NEWER(7,11,2) lua_pushstring(L, curl_easy_strerror(code)); #else lua_pushfstring(L, "Curl error: #%d", (code)); #endif lua_pushnumber(L, code); return 3; }
////////////////////////////////////////////////////////////////////// // Constructor: static int ar_read(lua_State *L) { struct archive** self_ref; static named_setter format_names[] = { /* Copied from archive.h */ { "all", archive_read_support_format_all }, { "ar", archive_read_support_format_ar }, { "cpio", archive_read_support_format_cpio }, { "empty", archive_read_support_format_empty }, { "gnutar", archive_read_support_format_gnutar }, { "iso9660", archive_read_support_format_iso9660 }, { "mtree", archive_read_support_format_mtree }, { "tar", archive_read_support_format_tar }, { "zip", archive_read_support_format_zip }, { NULL, NULL } }; static named_setter compression_names[] = { { "all", archive_read_support_compression_all }, { "bzip2", archive_read_support_compression_bzip2 }, { "compress", archive_read_support_compression_compress }, { "gzip", archive_read_support_compression_gzip }, { "lzma", archive_read_support_compression_lzma }, { "none", archive_read_support_compression_none }, { "xz", archive_read_support_compression_xz }, { NULL, NULL } }; luaL_checktype(L, 1, LUA_TTABLE); self_ref = (struct archive**) lua_newuserdata(L, sizeof(struct archive*)); // {ud} *self_ref = NULL; luaL_getmetatable(L, AR_READ); // {ud}, [read] lua_setmetatable(L, -2); // {ud} __ref_count++; *self_ref = archive_read_new(); // Register it in the weak metatable: ar_registry_set(L, *self_ref); // Create an environment to store a reference to the callbacks: lua_createtable(L, 1, 0); // {ud}, {fenv} lua_getfield(L, 1, "reader"); // {ud}, {fenv}, fn if ( ! lua_isfunction(L, -1) ) err("MissingArgument: required parameter 'reader' must be a function"); lua_setfield(L, -2, "reader"); // {ud}, {fenv} lua_setfenv(L, -2); // {ud} // Do it the easy way for now... perhaps in the future we will // have a parameter to support toggling which algorithms are // supported: if ( ARCHIVE_OK != archive_read_support_compression_all(*self_ref) ) { err("archive_read_support_compression_all: %s", archive_error_string(*self_ref)); } if ( ARCHIVE_OK != archive_read_support_format_all(*self_ref) ) { err("archive_read_support_format_all: %s", archive_error_string(*self_ref)); } // Extract various fields and prepare the archive: lua_getfield(L, 1, "format"); if ( NULL == lua_tostring(L, -1) ) { lua_pop(L, 1); lua_pushliteral(L, "all"); } if ( 0 == call_setters(L, *self_ref, "archive_read_support_format_", format_names, lua_tostring(L, -1)) ) { // We will be strict for now... perhaps in the future we will // default to "all"? err("empty format='%s' is not allowed, you must specify at least one format", lua_tostring(L, -1)); } lua_pop(L, 1); lua_getfield(L, 1, "compression"); if ( NULL == lua_tostring(L, -1) ) { lua_pop(L, 1); lua_pushliteral(L, "none"); } call_setters(L, *self_ref, "archive_read_support_compression_", compression_names, lua_tostring(L, -1)); lua_pop(L, 1); lua_getfield(L, 1, "options"); if ( ! lua_isnil(L, -1) && ARCHIVE_OK != archive_read_set_options(*self_ref, lua_tostring(L, -1)) ) { err("archive_read_set_options: %s", archive_error_string(*self_ref)); } lua_pop(L, 1); if ( ARCHIVE_OK != archive_read_open(*self_ref, L, NULL, &ar_read_cb, NULL) ) { err("archive_read_open: %s", archive_error_string(*self_ref)); } return 1; }
static int lsave(lua_State *L) { int color_type; int step; int bit_depth = 8; const char *filename = luaL_checkstring(L,1); const char *type = luaL_checkstring(L,2); if (!strcmp(type, "RGBA8")) { color_type = PNG_COLOR_TYPE_RGB_ALPHA; step = 4; } else if (!strcmp(type, "RGB8")) { color_type = PNG_COLOR_TYPE_RGB; step = 3; } else if (!strcmp(type, "GRAY")) { color_type = PNG_COLOR_TYPE_GRAY; step = 1; } else { return luaL_error(L, "png type %s not support", type); } int width = luaL_checkinteger(L,3); int height = luaL_checkinteger(L,4); luaL_checktype(L,5, LUA_TTABLE); int n = lua_rawlen(L,5); if (n != width * height * step) { return luaL_error(L, "Data number %d invalid, should be %d*%d*%d = %d", n, width, height, step, width * height * step); } FILE *fp = fopen(filename, "wb"); if (fp == NULL) { return luaL_error(L, strerror(errno)); } png_structp png_ptr; png_infop info_ptr; png_colorp palette; png_bytep *row_pointers; png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,NULL,NULL,NULL); if (png_ptr == NULL) { return luaL_error(L, "png_create_write_struct fail"); } info_ptr = png_create_info_struct(png_ptr); if (info_ptr == NULL) { png_destroy_write_struct(&png_ptr, NULL); return luaL_error(L, "png_destroy_write_struct fail"); } if (setjmp(png_jmpbuf(png_ptr))) { png_destroy_write_struct(&png_ptr, &info_ptr); return 0; } uint8_t *buffer = (uint8_t *)malloc(width * height *step); int i; for (i=0; i<height *width; ++i) { lua_rawgeti(L,5,i*step+1); lua_rawgeti(L,5,i*step+2); lua_rawgeti(L,5,i*step+3); lua_rawgeti(L,5,i*step+4); buffer[i*step+0] = (uint8_t)lua_tointeger(L,-4); buffer[i*step+1] = (uint8_t)lua_tointeger(L,-3); buffer[i*step+2] = (uint8_t)lua_tointeger(L,-2); buffer[i*step+3] = (uint8_t)lua_tointeger(L,-1); lua_pop(L,4); } png_init_io(png_ptr, fp); png_set_IHDR(png_ptr, info_ptr, width, height, bit_depth, color_type, PNG_INTERLACE_NONE, PNG_COMPRESSION_TYPE_BASE, PNG_FILTER_TYPE_BASE); palette = (png_colorp)png_malloc(png_ptr, PNG_MAX_PALETTE_LENGTH * (sizeof (png_color))); png_set_PLTE(png_ptr, info_ptr, palette, PNG_MAX_PALETTE_LENGTH); png_write_info(png_ptr, info_ptr); png_set_packing(png_ptr); row_pointers = (png_bytep*)malloc(height * sizeof(png_bytep)); for (i = 0; i<height; i++) row_pointers[i] = buffer + i* width* step; png_write_image(png_ptr, row_pointers); png_write_end(png_ptr, info_ptr); png_free(png_ptr, palette); png_destroy_write_struct(&png_ptr, &info_ptr); free(row_pointers); free(buffer); fclose(fp); return 0; }
static int ngx_http_lua_socket_udp_setpeername(lua_State *L) { ngx_http_request_t *r; ngx_http_lua_ctx_t *ctx; ngx_str_t host; int port; ngx_resolver_ctx_t *rctx, temp; ngx_http_core_loc_conf_t *clcf; int saved_top; int n; u_char *p; size_t len; ngx_url_t url; ngx_int_t rc; ngx_http_lua_loc_conf_t *llcf; int timeout; ngx_http_lua_co_ctx_t *coctx; ngx_http_lua_udp_connection_t *uc; ngx_http_lua_socket_udp_upstream_t *u; /* * TODO: we should probably accept an extra argument to setpeername() * to allow the user bind the datagram unix domain socket himself, * which is necessary for systems without autobind support. */ n = lua_gettop(L); if (n != 2 && n != 3) { return luaL_error(L, "ngx.socket.udp setpeername: expecting 2 or 3 " "arguments (including the object), but seen %d", n); } r = ngx_http_lua_get_req(L); if (r == NULL) { return luaL_error(L, "no request found"); } ctx = ngx_http_get_module_ctx(r, ngx_http_lua_module); if (ctx == NULL) { return luaL_error(L, "no ctx found"); } ngx_http_lua_check_context(L, ctx, NGX_HTTP_LUA_CONTEXT_REWRITE | NGX_HTTP_LUA_CONTEXT_ACCESS | NGX_HTTP_LUA_CONTEXT_CONTENT | NGX_HTTP_LUA_CONTEXT_TIMER | NGX_HTTP_LUA_CONTEXT_SSL_CERT); luaL_checktype(L, 1, LUA_TTABLE); p = (u_char *) luaL_checklstring(L, 2, &len); host.data = ngx_palloc(r->pool, len + 1); if (host.data == NULL) { return luaL_error(L, "no memory"); } host.len = len; ngx_memcpy(host.data, p, len); host.data[len] = '\0'; if (n == 3) { port = luaL_checkinteger(L, 3); if (port < 0 || port > 65535) { lua_pushnil(L); lua_pushfstring(L, "bad port number: %d", port); return 2; } } else { /* n == 2 */ port = 0; } lua_rawgeti(L, 1, SOCKET_CTX_INDEX); u = lua_touserdata(L, -1); lua_pop(L, 1); if (u) { if (u->request && u->request != r) { return luaL_error(L, "bad request"); } if (u->waiting) { lua_pushnil(L); lua_pushliteral(L, "socket busy"); return 2; } if (u->udp_connection.connection) { ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "lua udp socket reconnect without shutting down"); ngx_http_lua_socket_udp_finalize(r, u); } ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "lua reuse socket upstream ctx"); } else { u = lua_newuserdata(L, sizeof(ngx_http_lua_socket_udp_upstream_t)); if (u == NULL) { return luaL_error(L, "no memory"); } #if 1 lua_pushlightuserdata(L, &ngx_http_lua_udp_udata_metatable_key); lua_rawget(L, LUA_REGISTRYINDEX); lua_setmetatable(L, -2); #endif lua_rawseti(L, 1, SOCKET_CTX_INDEX); } ngx_memzero(u, sizeof(ngx_http_lua_socket_udp_upstream_t)); u->request = r; /* set the controlling request */ llcf = ngx_http_get_module_loc_conf(r, ngx_http_lua_module); u->conf = llcf; uc = &u->udp_connection; uc->log = *r->connection->log; dd("lua peer connection log: %p", &uc->log); lua_rawgeti(L, 1, SOCKET_TIMEOUT_INDEX); timeout = (ngx_int_t) lua_tointeger(L, -1); lua_pop(L, 1); if (timeout > 0) { u->read_timeout = (ngx_msec_t) timeout; } else { u->read_timeout = u->conf->read_timeout; } ngx_memzero(&url, sizeof(ngx_url_t)); url.url.len = host.len; url.url.data = host.data; url.default_port = (in_port_t) port; url.no_resolve = 1; if (ngx_parse_url(r->pool, &url) != NGX_OK) { lua_pushnil(L); if (url.err) { lua_pushfstring(L, "failed to parse host name \"%s\": %s", host.data, url.err); } else { lua_pushfstring(L, "failed to parse host name \"%s\"", host.data); } return 2; } u->resolved = ngx_pcalloc(r->pool, sizeof(ngx_http_upstream_resolved_t)); if (u->resolved == NULL) { return luaL_error(L, "no memory"); } if (url.addrs && url.addrs[0].sockaddr) { ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "lua udp socket network address given directly"); u->resolved->sockaddr = url.addrs[0].sockaddr; u->resolved->socklen = url.addrs[0].socklen; u->resolved->naddrs = 1; u->resolved->host = url.addrs[0].name; } else { u->resolved->host = host; u->resolved->port = (in_port_t) port; } if (u->resolved->sockaddr) { rc = ngx_http_lua_socket_resolve_retval_handler(r, u, L); if (rc == NGX_AGAIN) { return lua_yield(L, 0); } return rc; } clcf = ngx_http_get_module_loc_conf(r, ngx_http_core_module); temp.name = host; rctx = ngx_resolve_start(clcf->resolver, &temp); if (rctx == NULL) { u->ft_type |= NGX_HTTP_LUA_SOCKET_FT_RESOLVER; lua_pushnil(L); lua_pushliteral(L, "failed to start the resolver"); return 2; } if (rctx == NGX_NO_RESOLVER) { u->ft_type |= NGX_HTTP_LUA_SOCKET_FT_RESOLVER; lua_pushnil(L); lua_pushfstring(L, "no resolver defined to resolve \"%s\"", host.data); return 2; } rctx->name = host; #if !defined(nginx_version) || nginx_version < 1005008 rctx->type = NGX_RESOLVE_A; #endif rctx->handler = ngx_http_lua_socket_resolve_handler; rctx->data = u; rctx->timeout = clcf->resolver_timeout; u->co_ctx = ctx->cur_co_ctx; u->resolved->ctx = rctx; saved_top = lua_gettop(L); coctx = ctx->cur_co_ctx; ngx_http_lua_cleanup_pending_operation(coctx); coctx->cleanup = ngx_http_lua_udp_resolve_cleanup; if (ngx_resolve_name(rctx) != NGX_OK) { ngx_log_debug0(NGX_LOG_DEBUG_HTTP, r->connection->log, 0, "lua udp socket fail to run resolver immediately"); u->ft_type |= NGX_HTTP_LUA_SOCKET_FT_RESOLVER; u->resolved->ctx = NULL; lua_pushnil(L); lua_pushfstring(L, "%s could not be resolved", host.data); return 2; } if (u->waiting == 1) { /* resolved and already connecting */ return lua_yield(L, 0); } n = lua_gettop(L) - saved_top; if (n) { /* errors occurred during resolving or connecting * or already connected */ return n; } /* still resolving */ u->waiting = 1; u->prepare_retvals = ngx_http_lua_socket_resolve_retval_handler; coctx->data = u; if (ctx->entered_content_phase) { r->write_event_handler = ngx_http_lua_content_wev_handler; } else { r->write_event_handler = ngx_http_core_run_phases; } return lua_yield(L, 0); }
static int luaB_rawget (lua_State *L) { luaL_checktype(L, 1, LUA_TTABLE); luaL_checkany(L, 2); lua_rawget(L, 1); return 1; }