テーブルのデータを読み込む方法

luaで定義されたテーブルをCで利用する方法。

テーブルの変数personを定義するファイルが用意されているとする。

-- data2.lua
person= {
   name="YAMADA Taro",
   age=25,
   height=171.0,
   checked=false,
}

これをCで読み込んで処理するコードの一例を示す。

#include <string.h>
#include <assert.h>
#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>

#define NAME_LENGTH 256
#define MAX(a,b) ( (a)>(b) ? (a):(b) )

struct Person {
  char		name[NAME_LENGTH];
  int		age;
  double	height;
  int		checked;
};


int loadPersonFromFile(struct Person *config, const char *fname);

int main(int argc, char* argv[])
{
  struct Person config;

  if ( loadPersonFromFile(&config, argv[1])<0 )
    {
      return 0;
    }

  printf("name    : %s\n",  config.name );
  printf("age     : %d\n",  config.age );
  printf("height  : %lf\n", config.height );
  printf("checked : %s\n",  (config.checked)? "checked": "unchecked" );

  return 0;
}

int loadPersonFromFile(struct Person	*config,
		       const char	*fname)
{
  int		 retval = 0;
  const char	*s;
  size_t	 l;

  lua_State	*L	= luaL_newstate();

  if ( luaL_loadfile(L, fname) || lua_pcall(L, 0,0,0) )
    {
      fprintf(stderr, "cannnot load config file : %s\n", lua_tostring(L, -1));
      retval = -1;
      goto done;
    }

  lua_getglobal(L, "person");

  assert ( lua_istable (L, -1) );

  // name
  {
    lua_pushstring(L, "name");
    lua_gettable(L, -2);
    assert ( lua_isstring (L, -1) );

    s		  = lua_tolstring(L, -1, &l);
    assert(s[l]=='\0');
    assert(strlen(s) <= l);
    strncpy(config->name, s, MAX(NAME_LENGTH, l));

    lua_pop(L, 1);
  }

  // age
  {
    lua_pushstring(L, "age");
    lua_gettable(L, -2);
    assert ( lua_isnumber (L, -1) );

    config->age     = lua_tointeger(L, -1);

    lua_pop(L, 1);
  }

  // height
  {
    lua_pushstring(L, "height");
    lua_gettable(L, -2);
    assert ( lua_isnumber (L, -1) );

    config->height  = lua_tonumber (L, -1);

    lua_pop(L, 1);
  }

  // checked
  {
    lua_pushstring(L, "checked");
    lua_gettable(L, -2);
    assert ( lua_isboolean(L, -1) );

    config->checked = lua_toboolean(L, -1);

    lua_pop(L, 1);
  }

 done:
  lua_close(L);
  return retval;
}

Cのコードが長いけど、各メンバ毎にほとんど同じ処理を呼び出しているだけで内容は多くない。