I'm trying to learn Lua and how to interface to and from C with it. My first attempt follows but has been simplified to include only the issue I'm seeing.
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <linux/limits.h> /* For PATH_MAX */
#include <unistd.h>
#include <getopt.h>
#include <lua.h>
#include <lualib.h>
#include <lauxlib.h>
#define EXITF exit(EXIT_FAILURE)
lua_State* lua;
void stackDump(lua_State* lua)
{
int i, t;
int top = lua_gettop(lua);
for (i = 1; i <= top; i++)
{
t = lua_type(lua, i);
switch (t)
{
case LUA_TSTRING:
printf("\"%s\"", lua_tostring(lua, i));
break;
case LUA_TBOOLEAN:
printf(lua_toboolean(lua, i) ? "true" : "false");
case LUA_TNUMBER:
printf("%g", lua_tonumber(lua, i));
break;
default:
printf("%s", lua_typename(lua, t));
break;
}
if (i < top)
printf(", ");
}
printf("\n");
}
int main(int argc, char** argv)
{
int opt;
char cfgFile[PATH_MAX];
cfgFile[0] = 0;
lua = luaL_newstate();
luaL_openlibs(lua);
stackDump(lua);
while ((opt = getopt(argc, argv, "c:")) != -1)
{
switch (opt)
{
case 'c':
strncpy(cfgFile, optarg, PATH_MAX);
cfgFile[PATH_MAX - 1] = 0;
break;
}
}
if (cfgFile[0] == 0)
{
fprintf(stderr, "No cfg file specified\n");
return EXIT_FAILURE;
}
printf("cfgFile = \"%s\"\n", cfgFile);
if (luaL_loadfile(lua, cfgFile) != LUA_OK)
{
fprintf(stderr, "%s\n", lua_tostring(lua, -1));
lua_pop(lua, 1);
lua_close(lua);
return EXIT_FAILURE;
}
stackDump(lua);
lua_getglobal(lua, "program");
stackDump(lua);
if (lua_isstring(lua, -1) == 0)
{
fprintf(stderr, "`program` should be a string\n");
lua_close(lua);
return EXIT_FAILURE;
}
char execArg0[256];
strncpy(execArg0, lua_tostring(lua, -1), 256);
lua_pop(lua, 1);
lua_close(lua);
return EXIT_SUCCESS;
}
Lua script:
#!/usr/bin/env lua
program = "echo"
What I'm seeing when running this is:
$ ./wrapper2 -c wrapper2.lua
cfgFile = "wrapper2.lua"
function
function, nil
`program` should be a string
Note that the empty line is intentional; stackDump() tells us that the stack is empty at that point. It seems that the call to lua_getglobal(lua, "program") is pushing nil on the stack instead of the string "echo". Please could you help me work out why I'm seeing this?
As a side question: why is there a function pushed on the stack (presumably by luaL_loadfile())? I don't remember reading that functions are pushed on the stack automatically.