1

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.

2
  • 1
    Could you consider editing it to MCVE? Commented Sep 30, 2015 at 18:57
  • @cubuspl42 Apologies, I'm modifying the question to include only the issue at hand. Commented Sep 30, 2015 at 19:03

1 Answer 1

3

luaL_loadfile loads a Lua script but does not execute it and so does not define the global program. Use luaL_dofile instead.

luaL_loadfile compiles a Lua script and leaves the code as a Lua function on the stack.

luaL_dofile calls luaL_loadfile and then calls that function.

See the manual entries for luaL_loadfile and luaL_dofile.

Sign up to request clarification or add additional context in comments.

2 Comments

Thanks for your answer. Can you help me with why there's a function on the stack after the luaL_loadfile()?
@Doddy: Because that's how it's defined to work. luaL_loadfile is equivalent to luaL_loadfilex with mode equal to NULL. luaL_loadfilex returns the same results as lua_load. lua_load "pushes the compiled chunk as a Lua function on top of the stack" (or pushes an error message). Start at lua.org/manual/5.3/manual.html#luaL_loadfile and follow the links.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.