/** * 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; }
bool luaW_pushvariable(lua_State *L, variable_access_const& v) { try { if(v.exists_as_attribute()) { luaW_pushscalar(L, v.as_scalar()); return true; } else if(v.exists_as_container()) { lua_newtable(L); if (luaW_toboolean(L, 2)) luaW_filltable(L, v.as_container()); return true; } else { lua_pushnil(L); return true; } } catch (const invalid_variablename_exception&) { WRN_LUA << v.get_error_message(); return false; } }
/** * Iterate through the attributes of a vconfig */ static int impl_vconfig_pairs_iter(lua_State *L) { vconfig vcfg = luaW_checkvconfig(L, 1); void* p = luaL_checkudata(L, lua_upvalueindex(1), vconfigpairsKey); config::const_attr_itors& range = *static_cast<config::const_attr_itors*>(p); if (range.first == range.second) { return 0; } config::attribute value = *range.first++; lua_pushlstring(L, value.first.c_str(), value.first.length()); luaW_pushscalar(L, vcfg[value.first]); return 2; }
void luaW_filltable(lua_State *L, config const &cfg) { if (!lua_checkstack(L, LUA_MINSTACK)) return; int k = 1; for (const config::any_child &ch : cfg.all_children_range()) { lua_createtable(L, 2, 0); lua_pushstring(L, ch.key.c_str()); lua_rawseti(L, -2, 1); lua_newtable(L); luaW_filltable(L, ch.cfg); lua_rawseti(L, -2, 2); lua_rawseti(L, -2, k++); } for (const config::attribute &attr : cfg.attribute_range()) { luaW_pushscalar(L, attr.second); lua_setfield(L, -2, attr.first.c_str()); } }
/** * The __index metamethod. * Parameter 1: the preference table. * Parameter 2: preference name, must be a string. * Returns: preference value. If there isn't such a preference, returns nil. */ static int impl_preferences_get(lua_State* L) { std::string preference_name = luaL_checkstring(L, 2); luaW_pushscalar(L, preferences::get_as_attribute(preference_name)); return 1; }