lua-users home
lua-l archive

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


It was thus said that the Great Henderson, Michael D once stated:
> 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?

  Yes, but it helps to know the Lua API.  I'm using a stack notation popular
from Forth to mark the stack effects of each line.  Top of stack is always
on the right, and the stack before and after the call is separated by a
"--".

int CSV_silly(lua_State *L)
{
  myCSV *csv;

  /*------------------------------------------------------------------------
  ; In C89/C99, you don't need to cast the result from luaL_checkudata(), as
  ; it returns a void * which requires no cast.
  ;------------------------------------------------------------------------*/

  csv = luaL_checkudata(L,1,libName);
  
  /*--------------------------------------------------------------------
  ; you can use luaL_checktype() to check the types of a stack entry
  ;-------------------------------------------------------------------*/
  
  luaL_checktype(L,3,LUA_TTABLE);	/* self s t -- self s t */
  
  /*------------------------------------------------------------------
  ; append the suffix (parameter 2) to the "name" field of the table.
  ;------------------------------------------------------------------*/
  
  lua_getfield(L,3,"name");	    /* self s t      -- self s t s2 */
  luaL_checktype(L,-1,LUA_TSTRING); /* self s t s2   -- self s t s2 */
  lua_pushvalue(L,2);               /* self s t s2   -- self s t s2 s */
  lua_concat(L,2);                  /* self s t s2 s -- self s t s3 */
  lua_setfield(L,-2,"name");        /* self s t s3   -- self s t */
  
  /*---------------------------------------------------
  ; for adding a prefix, the order would be:
  ;
  ; lua_pushvalue(L,2);
  ; lua_getfield(L,3,"name");
  ; luaL_checktype(L,-1,LUA_TSTRING);
  ; lua_concat(L,2);
  ; lua_setfield(L,-2,"name");
  ;
  ; Now check for the "type" field, and if not there, provide a default
  ;---------------------------------------------------------------------*/
  
  lua_getfield(L,3,"type");
  if (lua_isnil(L,-1))
  {
    lua_pushliteral(L,"default"); /* self s t nil           -- self s t nil "default" */
    lua_setfield(L,3,"type");     /* self s t nil "default" -- self s t nil */
  }
  
  return 0;
}

  There was no real need to call lua_pop() in this routine.  Sometimes you
do need it, othertimes, no.  It really depends upon the code and the stack
gyrations.

  -spc (also, "//" comments are allowed in C99, but not in C89)