forked from mia/Aegisub
Fix line numbers for moonscript files in error messages
This commit is contained in:
parent
646e5deb52
commit
260b37ba8e
2 changed files with 53 additions and 3 deletions
|
@ -605,6 +605,43 @@ namespace Automation4 {
|
||||||
return lua_gettop(L) - pretop;
|
return lua_gettop(L) - pretop;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
static int moon_line(lua_State *L, int lua_line, std::string const& file)
|
||||||
|
{
|
||||||
|
if (luaL_dostring(L, "return require 'moonscript.line_tables'")) {
|
||||||
|
lua_pop(L, 1); // pop error message
|
||||||
|
return lua_line;
|
||||||
|
}
|
||||||
|
|
||||||
|
push_value(L, file);
|
||||||
|
lua_rawget(L, -2);
|
||||||
|
|
||||||
|
if (!lua_istable(L, -1)) {
|
||||||
|
lua_pop(L, 2);
|
||||||
|
return lua_line;
|
||||||
|
}
|
||||||
|
|
||||||
|
lua_rawgeti(L, -1, lua_line);
|
||||||
|
if (!lua_isnumber(L, -1)) {
|
||||||
|
lua_pop(L, 3);
|
||||||
|
return lua_line;
|
||||||
|
}
|
||||||
|
|
||||||
|
auto char_pos = static_cast<size_t>(lua_tonumber(L, -1));
|
||||||
|
lua_pop(L, 3);
|
||||||
|
|
||||||
|
// The moonscript line tables give us a character offset into the file,
|
||||||
|
// so now we need to map that to a line number
|
||||||
|
lua_getfield(L, LUA_REGISTRYINDEX, ("raw moonscript: " + file).c_str());
|
||||||
|
if (!lua_isstring(L, -1)) {
|
||||||
|
lua_pop(L, 1);
|
||||||
|
return lua_line;
|
||||||
|
}
|
||||||
|
|
||||||
|
size_t moon_len;
|
||||||
|
auto moon = lua_tolstring(L, -1, &moon_len);
|
||||||
|
return std::count(moon, moon + std::min(moon_len, char_pos), '\n') + 1;
|
||||||
|
}
|
||||||
|
|
||||||
static int add_stack_trace(lua_State *L)
|
static int add_stack_trace(lua_State *L)
|
||||||
{
|
{
|
||||||
int level = 1;
|
int level = 1;
|
||||||
|
@ -635,9 +672,16 @@ namespace Automation4 {
|
||||||
if (ar.what[0] == 't')
|
if (ar.what[0] == 't')
|
||||||
frames.emplace_back("(tail call)");
|
frames.emplace_back("(tail call)");
|
||||||
else {
|
else {
|
||||||
|
bool is_moon = false;
|
||||||
std::string file = ar.source;
|
std::string file = ar.source;
|
||||||
if (file == "=[C]")
|
if (file == "=[C]")
|
||||||
file = "<C function>";
|
file = "<C function>";
|
||||||
|
else if (boost::ends_with(file, ".moon"))
|
||||||
|
is_moon = true;
|
||||||
|
|
||||||
|
auto real_line = [&](int line) {
|
||||||
|
return is_moon ? moon_line(L, line, file) : line;
|
||||||
|
};
|
||||||
|
|
||||||
std::string function = ar.name ? ar.name : "";
|
std::string function = ar.name ? ar.name : "";
|
||||||
if (*ar.what == 'm')
|
if (*ar.what == 'm')
|
||||||
|
@ -645,9 +689,9 @@ namespace Automation4 {
|
||||||
else if (*ar.what == 'C')
|
else if (*ar.what == 'C')
|
||||||
function = '?';
|
function = '?';
|
||||||
else if (!*ar.namewhat)
|
else if (!*ar.namewhat)
|
||||||
function = str(boost::format("<anonymous function at lines %d-%d>") % ar.linedefined % ar.lastlinedefined);
|
function = str(boost::format("<anonymous function at lines %d-%d>") % real_line(ar.linedefined) % real_line(ar.lastlinedefined - 1));
|
||||||
|
|
||||||
frames.emplace_back(str(boost::format(" File \"%s\", line %d\n%s") % file % ar.currentline % function));
|
frames.emplace_back(str(boost::format(" File \"%s\", line %d\n%s") % file % real_line(ar.currentline) % function));
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
@ -21,8 +21,9 @@
|
||||||
|
|
||||||
#include "auto4_lua_scriptreader.h"
|
#include "auto4_lua_scriptreader.h"
|
||||||
|
|
||||||
|
#include "auto4_lua_utils.h"
|
||||||
|
|
||||||
#include <libaegisub/io.h>
|
#include <libaegisub/io.h>
|
||||||
#include <libaegisub/fs.h>
|
|
||||||
|
|
||||||
#include <fstream>
|
#include <fstream>
|
||||||
#include <lua.hpp>
|
#include <lua.hpp>
|
||||||
|
@ -53,6 +54,11 @@ namespace Automation4 {
|
||||||
if (!agi::fs::HasExtension(filename, "moon"))
|
if (!agi::fs::HasExtension(filename, "moon"))
|
||||||
return luaL_loadbuffer(L, &buff[0], buff.size(), filename.string().c_str()) == 0;
|
return luaL_loadbuffer(L, &buff[0], buff.size(), filename.string().c_str()) == 0;
|
||||||
|
|
||||||
|
// Save the text we'll be loading for the line number rewriting in the
|
||||||
|
// error handling
|
||||||
|
push_value(L, buff);
|
||||||
|
lua_setfield(L, LUA_REGISTRYINDEX, ("raw moonscript: " + filename.string()).c_str());
|
||||||
|
|
||||||
// We have a MoonScript file, so we need to load it with that
|
// We have a MoonScript file, so we need to load it with that
|
||||||
// It might be nice to have a dedicated lua state for compiling
|
// It might be nice to have a dedicated lua state for compiling
|
||||||
// MoonScript to Lua
|
// MoonScript to Lua
|
||||||
|
|
Loading…
Reference in a new issue