[Date Prev][Date Next][Thread Prev][Thread Next]
[Date Index]
[Thread Index]
- Subject: RE: Using tables from the C API
- From: "Henderson, Michael D" <michael.d.henderson@...>
- Date: Wed, 17 Aug 2011 16:06:15 -0600
Thanks! That got me past the user data question. My next question is to see if I understand how to work with tables from within the C API.
Here's a C function that should take a string and a table.
1. Error if the first argument is not a string.
2. Error if the second argument is not a table.
3. Error if there is not a "name" field in the table.
4. Append the string to the "name" field in the table.
5. If there is not a "type" field in the table, add a "type" field with the value of "default".
When I run the script, I get the results that I'm expecting. Is my approach from the C side a sound approach?
------------------------------------------------------------
-- lua script. src is set to a class from the API
--
t = {name="foo"}
print("t.name", t.name)
print("t.type", t.type)
src:SillyFunc("x", t)
print("t.name", t.name)
print("t.type", t.type)
------------------------------------------------------------
-- output
--
t.name foo
t.type nil
silly: suffix is 'x'
silly: top of stack is 'foo'
silly: concat stack is 'foox'
silly: field stack is 'name'
silly: stack is 'foox'
silly: field stack is 'foox'
silly: stack is 'name'
silly: not of stack is 'foox'
t.name foox
t.type default
//----------------------------------------------------------
// C API
//----------------------------------------------------------
// SillyFunc(string, table)
//
int CSV_silly(lua_State *L) {
// stack: 1 -> table myCSV
// : 2 -> string "x"
// : 3 -> table {name="foo"}
// first argument must be self
myCSV *csv = (myCSV *)luaL_checkudata(L, 1, libName);
// second argument must be string
const char *suffix = luaL_checkstring(L, 2);
printf("silly: suffix is '%s'\n", suffix);
// third argument must be table
if (!lua_istable(L, 3)) {
error(L, "we demand table for 3rd parameter");
return 0;
}
const char *key = "name";
// get field value from the table
lua_pushstring(L, key);
// stack: 1 -> table myCSV
// : 2 -> string "x"
// : 3 -> table {name="foo"}
// : 4 -> string "name"
lua_gettable(L, 3);
// stack: 1 -> table myCSV
// : 2 -> string "x"
// : 3 -> table {name="foo"}
// : 4 -> table.foo which is string "foo"
// confirm that we have a value for that field
printf("silly: top of stack is '%s'\n", luaL_checkstring(L, -1));
// stack: 1 -> table myCSV
// : 2 -> string "x"
// : 3 -> table {name="foo"}
// : 4 -> string "foo"
// concatenate the suffix to the field
lua_pushstring(L, suffix);
// stack: 1 -> table myCSV
// : 2 -> string "x"
// : 3 -> table {name="foo"}
// : 4 -> string "foo"
// : 5 -> string "x"
lua_concat(L, 2);
// stack: 1 -> table myCSV
// : 2 -> string "x"
// : 3 -> table {name="foo"}
// : 4 -> string "foox"
// confirm that the concat worked
printf("silly: concat stack is '%s'\n", luaL_checkstring(L, -1));
// stack: 1 -> table myCSV
// : 2 -> string "x"
// : 3 -> table {name="foo"}
// : 4 -> string "foox"
// update the table with the concat'd value
// push the field name
lua_pushstring(L, key);
printf("silly: field stack is '%s'\n", luaL_checkstring(L, -1));
printf("silly: stack is '%s'\n", luaL_checkstring(L, -2));
// stack: 1 -> table myCSV
// : 2 -> string "x"
// : 3 -> table {name="foo"}
// : 4 -> string "foox"
// : 5 -> string "name"
// settable expects the top of the stack to have the value,
// then the field name. we're the other way around, so swap
// them
// stack: 1 -> table myCSV
// : 2 -> string "x"
// : 3 -> table {name="foo"}
// : 4 -> string "foox" -- field value
// : 5 -> string "name" -- field name
lua_insert(L, -2);
printf("silly: field stack is '%s'\n", luaL_checkstring(L, -1));
printf("silly: stack is '%s'\n", luaL_checkstring(L, -2));
// stack: 1 -> table myCSV
// : 2 -> string "x"
// : 3 -> table {name="foo"}
// : 4 -> string "name" -- field name
// : 5 -> string "foox" -- field value
// now call settable to update the table on the stack
lua_settable(L, 3);
// stack: 1 -> table myCSV
// : 2 -> string "x"
// : 3 -> table {name="foox"}
// get field value from the table
lua_pushstring(L, key);
// stack: 1 -> table myCSV
// : 2 -> string "x"
// : 3 -> table {name="foox"}
// : 4 -> string "name"
lua_gettable(L, 3);
// stack: 1 -> table myCSV
// : 2 -> string "x"
// : 3 -> table {name="foox"}
// : 4 -> table.foo which is string "foo"
// confirm that we have a value for that field
printf("silly: not of stack is '%s'\n", luaL_checkstring(L, -1));
// get rid of the value from the stack
// stack: 1 -> table myCSV
// : 2 -> string "x"
// : 3 -> table {name="foox"}
// : 4 -> string "foox"
lua_pop(L, 1);
// stack: 1 -> table myCSV
// : 2 -> string "x"
// : 3 -> table {name="foox"}
// check to see if the table has a field "type"
key = "type";
lua_pushstring(L, key);
// stack: 1 -> table myCSV
// : 2 -> string "x"
// : 3 -> table {name="foox"}
// : 4 -> string "type"
lua_gettable(L, 3);
// stack: 1 -> table myCSV
// : 2 -> string "x"
// : 3 -> table {name="foox"}
// : 4 -> table.type which is nil
if (lua_isnil(L, -1)) {
// no value, so provide a default value for the type field in the table
// stack: 1 -> table myCSV
// : 2 -> string "x"
// : 3 -> table {name="foox"}
// : 4 -> nil
// get rid of that value since we won't use it
lua_pop(L, 1);
// stack: 1 -> table myCSV
// : 2 -> string "x"
// : 3 -> table {name="foox"}
// push the field name to update
lua_pushstring(L, key);
// stack: 1 -> table myCSV
// : 2 -> string "x"
// : 3 -> table {name="foox"}
// : 4 -> string "type"
// push the default value
lua_pushstring(L, "default");
// stack: 1 -> table myCSV
// : 2 -> string "x"
// : 3 -> table {name="foox"}
// : 4 -> string "type"
// : 5 -> string "default"
// call settable to update the table on the stack
lua_settable(L, 3);
// stack: 1 -> table myCSV
// : 2 -> string "x"
// : 3 -> table {name="foox", type="default"}
}
return 0;
}