简体   繁体   English

Lua C API:设置错误源信息

[英]Lua C API: setting error source information

I'm implementing a simple LUA online interpreter which takes multiple LUA scripts from plain text (ie C strings) and runs them. 我正在实现一个简单的LUA在线解释器,它从纯文本(即C字符串)中获取多个LUA脚本并运行它们。 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: 到目前为止,当发生错误时,在调用lua_pcall我从堆栈消息中得到如下错误:

[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: 现在,我想要的是LUA的运行时用虚拟文件名替换令牌[string "..."] (记住解释器从字符串中获取LUA代码),这样如果用户使用名称提交虚拟脚本“ my.lua“,然后从LUA的运行时为该脚本引发的错误消息将格式化为:

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. 我试图分析LUA的源代码,以了解LUA解释器如何成功实现此目的。 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 "@". 到目前为止,我发现lua_loadstring()lua_loadfile()不同之处在于,后者将“@”前面的文件名称压入堆栈。 From LUA's source code ( lauxlib.c ): 来自LUA的源代码( 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() . 两个函数luaL_loadfilex()luaL_loadstring()最终调用lua_load() ,因此两者之间的区别在于前者在调用lua_load()之前将“= stdin”或文件名压入堆栈。 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. 我的代码只调用luaL_loadstring() ,所以我认为在调用之前推送虚拟文件名会产生相同的效果,但事实并非如此。

Am I missing some point? 我错过了一些观点吗? Thank you. 谢谢。

This should be possible with luaL_loadbuffer() : 这应该可以使用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. 编辑名称前面的'@'告诉LUA块的名称实际上是脚本的名称,而不是脚本代码本身。

It should load the buffer as a lua-chunk and use the name in the fourth argument for debug information and error messages. 它应该将缓冲区加载为lua-chunk,并使用第四个参数中的名称来获取调试信息和错误消息。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM