[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: Re: How to create Lua nested namespaces in C
- From: Malte Thiesen <malte.thiesen@...>
- Date: Sun, 28 Nov 2004 14:53:53 +0100
Hi,
I use the following code to create nested tables. The function takes a
Lua-state and a string like "very.deeply.nested" and then creates all
the subtables down to "nested" and leaves the "deepest" table on the stack.
It also makes sure that the tables aren't overwritten, so if you create
"very.deeply.nested" and "very.deeply" already exists only "nested" is
created. Unlike you I use std::string not C-strings so you may have to
adapt the code a little.
bool CreateNestedTable(lua_State * L, const std::string & TableName)
{
// The tablename is seperated at the periods and the subtables are
created if they don't exist.
// On success true is returned and the last subtable is on top of
the Lua-stack.
std::string::size_type PartBegin = 0;
while (PartBegin <= TableName.size())
{
std::string::size_type PartEnd;
PartEnd = TableName.find(".", PartBegin);
if (PartEnd == std::string::npos) PartEnd = TableName.size();
std::string SubTableName = TableName.substr(PartBegin, PartEnd -
PartBegin);
// Tables need to have a name (something like "a..b" occured)
if (SubTableName.size() == 0) return false;
// Check if a table already exists
// At the first pass the table is searched in the global
namespace. Later the parent-table on the stack is searched.
if (PartBegin == 0)
{
lua_pushstring(L, SubTableName.c_str());
lua_gettable(L, LUA_GLOBALSINDEX);
}
else
{
lua_pushstring(L, SubTableName.c_str());
lua_gettable(L, -2);
if (!lua_isnil(L, -1)) lua_remove(L, -2);
}
// If the table wasn't found, it has to be created
if (lua_isnil(L, -1))
{
// Pop nil from the stack
lua_pop(L, 1);
// Create new table
lua_newtable(L);
lua_pushstring(L, SubTableName.c_str());
lua_pushvalue(L, -2);
if (PartBegin == 0)
lua_settable(L, LUA_GLOBALSINDEX);
else
{
lua_settable(L, -4);
lua_remove(L, -2);
}
}
// Skip the period
PartBegin = PartEnd + 1;
}
return true;
}
Regards,
Malte