/** * Gets the parsed field of a vconfig object (_index metamethod). * Special fields __literal, __shallow_literal, __parsed, and * __shallow_parsed, return Lua tables. */ static int impl_vconfig_get(lua_State *L) { vconfig *v = static_cast<vconfig *>(lua_touserdata(L, 1)); if (lua_isnumber(L, 2)) { vconfig::all_children_iterator i = v->ordered_begin(); unsigned len = std::distance(i, v->ordered_end()); unsigned pos = lua_tointeger(L, 2) - 1; if (pos >= len) return 0; std::advance(i, pos); lua_createtable(L, 2, 0); lua_pushstring(L, i.get_key().c_str()); lua_rawseti(L, -2, 1); luaW_pushvconfig(L, vconfig(i.get_child())); lua_rawseti(L, -2, 2); return 1; } char const *m = luaL_checkstring(L, 2); if (strcmp(m, "__literal") == 0) { luaW_pushconfig(L, v->get_config()); return 1; } if (strcmp(m, "__parsed") == 0) { luaW_pushconfig(L, v->get_parsed_config()); return 1; } bool shallow_literal = strcmp(m, "__shallow_literal") == 0; if (shallow_literal || strcmp(m, "__shallow_parsed") == 0) { lua_newtable(L); BOOST_FOREACH(const config::attribute &a, v->get_config().attribute_range()) { if (shallow_literal) luaW_pushscalar(L, a.second); else luaW_pushscalar(L, v->expand(a.first)); lua_setfield(L, -2, a.first.c_str()); } vconfig::all_children_iterator i = v->ordered_begin(), i_end = v->ordered_end(); if (shallow_literal) { i.disable_insertion(); i_end.disable_insertion(); } for (int j = 1; i != i_end; ++i, ++j) { lua_createtable(L, 2, 0); lua_pushstring(L, i.get_key().c_str()); lua_rawseti(L, -2, 1); luaW_pushvconfig(L, i.get_child()); lua_rawseti(L, -2, 2); lua_rawseti(L, -2, j); } return 1; }
/** * Returns a clone (deep copy) of the passed config, which can be either a normal config or a vconfig * If it is a vconfig, the underlying config is also cloned. * - Arg 1: a config * - Ret: the cloned config */ static int intf_clone_wml(lua_State* L) { const vconfig* vcfg = nullptr; const config& cfg = luaW_checkconfig(L, 1, vcfg); if(vcfg) { config clone_underlying = vcfg->get_config(); vconfig clone(clone_underlying); luaW_pushvconfig(L, clone); } else { luaW_pushconfig(L, cfg); } return 1; }
/** * Iterate through the subtags of a vconfig */ static int impl_vconfig_ipairs_iter(lua_State *L) { luaW_checkvconfig(L, 1); int i = luaL_checkinteger(L, 2); void* p = luaL_checkudata(L, lua_upvalueindex(1), vconfigipairsKey); vconfig_child_range& range = *static_cast<vconfig_child_range*>(p); if (range.first == range.second) { return 0; } std::pair<std::string, vconfig> value = *range.first++; lua_pushinteger(L, i + 1); lua_createtable(L, 2, 0); lua_pushlstring(L, value.first.c_str(), value.first.length()); lua_rawseti(L, -2, 1); luaW_pushvconfig(L, value.second); lua_rawseti(L, -2, 2); return 2; }
/** * Creates a vconfig containing the WML table. * - Arg 1: WML table. * - Ret 1: vconfig userdata. */ int intf_tovconfig(lua_State *L) { vconfig vcfg = luaW_checkvconfig(L, 1); luaW_pushvconfig(L, vcfg); return 1; }