Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Lua C API: setting error source information

Tags:

c

lua

c-api

I'm implementing a simple LUA online interpreter which takes multiple LUA scripts from plain text (i.e. C strings) and runs them. Everything is working OK but now I'm testing my program's response when syntax or runtime errors occur from those scripts.

So far, when an error occurs, after calling lua_pcall I'm getting from the stack message errors like this:

[string "..."]:7: attempt to call field 'push' (a nil value)

Now, what I want is LUA's runtime to replace the token [string "..."] by a virtual file name (remember that the interpreter takes LUA code from strings), so that if the user submits a virtual script using the name "my.lua", then error messages raised from LUA's runtime for that script would be formatted as:

my.lua:7: attempt to call field 'push' (a nil value)

I've tried to analyze LUA's source code to find out how the LUA interpreter succeeds in this purpose. So far all I have found is that lua_loadstring() and lua_loadfile() differ in that the latter pushes into the stack the name of the file prepended with "@". From LUA's source code (lauxlib.c):

LUALIB_API int luaL_loadfilex (lua_State *L, const char *filename,
                                         const char *mode) {
  LoadF lf;
  int status, readstatus;
  int c;
  int fnameindex = lua_gettop(L) + 1; /* index of filename on the stack */
  if (filename == NULL) {
    lua_pushliteral(L, "=stdin");
    lf.f = stdin;
  }
  else {
    lua_pushfstring(L, "@%s", filename);
    lf.f = fopen(filename, "r");
    if (lf.f == NULL) return errfile(L, "open", fnameindex);
  }
  //...
  status = lua_load(L, getF, &lf, lua_tostring(L, -1), mode);
  //...

}

LUALIB_API int luaL_loadstring (lua_State *L, const char *s) {
  return luaL_loadbuffer(L, s, strlen(s), s); //eventually calls lua_load
}

Both functions, luaL_loadfilex() and luaL_loadstring() end up calling lua_load(), so the difference between both is that the former pushes either "=stdin" or the filename into the stack before calling lua_load(). My code just calls luaL_loadstring(), so I thought that pushing the virtual filename before calling it would have the same effect, but it doesn't.

Am I missing some point? Thank you.

like image 468
Claudix Avatar asked Dec 03 '25 07:12

Claudix


1 Answers

This should be possible with luaL_loadbuffer():

int luaL_loadbuffer (lua_State *L,
                 const char *buff,
                 size_t sz,
                 const char *name);

Example:

luaL_loadbuffer(L, code, code_length, "@my.lua");

EDIT The '@' before the name is required to tell LUA the chunk's name is actually the name of a script, not the script code itself.

It should load the buffer as a lua-chunk and use the name in the fourth argument for debug information and error messages.

like image 72
Ctx Avatar answered Dec 05 '25 00:12

Ctx



Donate For Us

If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!