On 19-Jan-07, at 9:44 PM, Raymond Jacobs wrote:
> Thanks for adding that Chris,
>
> We're a bit closer, I get through one element in the sub-table
>
> however when it goes through and pops off an element and goes to
> lua_next,
>
> it crashes =/
Have you:
-- made sure that you're running inside of a protected call?
-- enabled Lua's API check feature?
You're making the assumption that all keys are strings; that's
certainly not the case. If a key is a number, then the lua_tostring(l,
-2) will turn it into a string representation of that number, and
lua_next will throw an error since it won't find the resulting string
as a key in the table; if you're not running inside of a protected call
(which you always should be), then Lua will terminate the application
"with extreme prejudice", as it were.
Remember that a table key can be *anything* (except nil and NaN),
including another table.
>
>
> here is the actual code:
>
>
> void OutputArchive::writeLuaTable(lua_State* l,int idx)
> {
> lua_pushnil(l);
> while(lua_next(l,idx)!=0)
> {
> const char* key=lua_tostring(l,-2);
> int type=lua_type(l,-1);
> switch(type)
> {
> case LUA_TNUMBER:
> writeByte(1);
> writeString(key);
> writeInt(type);
> writeDouble(lua_tonumber(l,-1));
> break;
> case LUA_TSTRING:
> writeByte(1);
> writeString(key);
> writeInt(type);
> writeString(lua_tostring(l,-1));
> break;
> case LUA_TBOOLEAN:
> writeByte(1);
> writeString(key);
> writeInt(type);
> writeBool(lua_toboolean(l,-1)!=0);
> break;
> case LUA_TNIL:
> writeByte(1);
> writeString(key);
> writeInt(type);
> break;
> case LUA_TTABLE:
> {
> writeByte(1);
> writeString(key);
> writeInt(type);
> writeLuaTable(l,lua_gettop(l));
> }
> break;
> }
> lua_pop(l,1);
> }
> }
>
>
> void OutputArchive::writeLuaState(lua_State* l)
> {
> writeLuaTable(l,LUA_GLOBALSINDEX);
> }
>
> On 1/19/07, Raymond Jacobs <raymondj@gmail.com> wrote:
>> Thanks for a quick reply =)
>>
>> I noticed I wasn't pushing the nil,
>>
>> my code now looks exactly like yours, but it's still error-ing;
>>
>> correct me if I'm wrong but,
>>
>>
>> when you go to recurse, you pass in an index of -1 for lua_next to
>> use, which is the top of the stack, yet in the function you then push
>> a nil, which is then at the top of the stack, thus using -1 to
>> reference the table would be wrong?
>>
>> -Raymond
>>
>> On 1/19/07, Jérôme VUARAND <jerome.vuarand@gmail.com> wrote:
>> > 2007/1/19, Raymond Jacobs <raymondj@gmail.com>:
>> > > int idx=LUA_GLOBALSINDEX;
>> > > lua_getfenv(l,idx);
>> > >
>> > > while(lua_next(l,idx)!=0)
>> > > {
>> > > const char* key=lua_tostring(l,-2);
>> > >
>> > > //get value at -1 index and check type of it
>> > >
>> > > //do somthing with key and value based on type of
>> value
>> > > //if value is a table call this function again to
>> traverse it, then
>> > > continue here
>> > >
>> > >
>> > > lua_pop(l,1);
>> > > }
>> > >
>> > > it seems in theory it should be as simple as doing another
>> lua_next,
>> > > however I've not been able to get it to work, and I end up
>> crashing,
>> > > likely due to corupting the stack; either my logic or how I'm
>> going
>> > > about it is wrong, an example of how to do this in the C API
>> would be
>> > > really helpful.
>> >
>> > You forget to push an initial nil on the stack before entering you
>> > while loop (see lua_next documentation example). Here is what your
>> > code could look like :
>> >
>> > int dosomestuff(lua_State* L, int index)
>> > {
>> > // Do something with value at index (which is not a table)
>> > return 1;
>> > }
>> >
>> > int parsetable(lua_State* L, int index)
>> > {
>> > // Push an initial nil to init lua_next
>> > lua_pushnil(L);
>> > // Parse the table at index
>> > while (lua_next(index)!=0)
>> > {
>> > if (lua_istable(L, -1)
>> > {
>> > parsetable(L, -1);
>> > }
>> > else
>> > {
>> > dosomestuff(L, -1);
>> > }
>> > // Pop value, keep key
>> > lua_pop(L, 1);
>> > }
>> > return 1;
>> > }
>> >
>> > int parseglobals(lua_State* L)
>> > {
>> > parsetable(L, LUA_GLOBALSINDEX);
>> > return 0;
>> > }
>> >
>>