lua-users home
lua-l archive

[Date Prev][Date Next][Thread Prev][Thread Next] [Date Index] [Thread Index]


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