diff --git a/Makefile.inc.in b/Makefile.inc.in index fe1d825a3..536bbcdbe 100644 --- a/Makefile.inc.in +++ b/Makefile.inc.in @@ -86,7 +86,6 @@ CFLAGS_ICU = @ICU_I18N_CFLAGS@ CFLAGS_LIBASS = @LIBASS_CFLAGS@ CFLAGS_LIBCURL = @LIBCURL_CFLAGS@ CFLAGS_LIBPULSE = @LIBPULSE_CFLAGS@ -CFLAGS_LUA = -I../vendor/lua/src CFLAGS_OPENAL = @OPENAL_CFLAGS@ CFLAGS_OSS = @OSS_CFLAGS@ CFLAGS_PORTAUDIO = @PORTAUDIO_CFLAGS@ diff --git a/automation/Makefile b/automation/Makefile index d65ed375b..cd9199f26 100644 --- a/automation/Makefile +++ b/automation/Makefile @@ -4,7 +4,7 @@ PRECOMPILED_HEADER_NAME = ../libaegisub/lagi_pre.h PROGRAM = aegisub-lua -CXXFLAGS += -I../libaegisub/include -I../src -I ../vendor/lua/src $(CXXFLAGS_WX) +CXXFLAGS += -I../libaegisub/include -I../src -I.. -I../vendor/lua/src $(CXXFLAGS_WX) CPPFLAGS += $(CPPFLAGS_BOOST) LIBS := -L../libaegisub -laegisub -L../vendor/lua -llua-aegisub $(LIBS) diff --git a/automation/tests/aegisub.cpp b/automation/tests/aegisub.cpp index 7a1291122..ccec7db1b 100644 --- a/automation/tests/aegisub.cpp +++ b/automation/tests/aegisub.cpp @@ -20,9 +20,6 @@ #include #include -#include -#include -#include using namespace agi::lua; diff --git a/build/libaegisub/libaegisub.vcxproj b/build/libaegisub/libaegisub.vcxproj index 897402b57..26ec72c9b 100644 --- a/build/libaegisub/libaegisub.vcxproj +++ b/build/libaegisub/libaegisub.vcxproj @@ -122,7 +122,10 @@ - + + NotUsing + + diff --git a/build/libaegisub/libaegisub.vcxproj.filters b/build/libaegisub/libaegisub.vcxproj.filters index 12f04410b..4e1262339 100644 --- a/build/libaegisub/libaegisub.vcxproj.filters +++ b/build/libaegisub/libaegisub.vcxproj.filters @@ -310,7 +310,7 @@ Lua\Modules - + Lua\Modules diff --git a/build/lua51/lua51.vcxproj b/build/lua51/lua51.vcxproj index fac945ef6..3c7219286 100644 --- a/build/lua51/lua51.vcxproj +++ b/build/lua51/lua51.vcxproj @@ -23,35 +23,35 @@ - - - - - - - - - - - - - - - - - - - - - - - - - - - - - + + + + + + + + + + + + + + + + + + + + + + + + + + + + + @@ -81,7 +81,7 @@ diff --git a/build/lua51/lua51.vcxproj.filters b/build/lua51/lua51.vcxproj.filters index 9574231a7..997078b3e 100644 --- a/build/lua51/lua51.vcxproj.filters +++ b/build/lua51/lua51.vcxproj.filters @@ -15,91 +15,91 @@ - + Core - + Core - + Core - + Core - + Core - + Core - + Core - + Core - + Core - + Core - + Core - + Core - + Core - + Core - + Core - + Core - + Core - + Core - + Core - + Core - + Standard library - + Standard library - + Standard library - + Standard library - + Standard library - + Standard library - + Standard library - + Core - + Standard library diff --git a/build/luabins/luabins.vcxproj b/build/luabins/luabins.vcxproj index c0e7f4093..664b7721e 100644 --- a/build/luabins/luabins.vcxproj +++ b/build/luabins/luabins.vcxproj @@ -17,20 +17,20 @@ - LUABINS_LUABUILTASCPP;_CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) + _CRT_SECURE_NO_WARNINGS;%(PreprocessorDefinitions) $(SrcDir)..\..\lua51\src;%(AdditionalIncludeDirectories) - - - - - - - + + + + + + + diff --git a/build/luabins/luabins.vcxproj.filters b/build/luabins/luabins.vcxproj.filters index 7a9b51b8e..0db010b4e 100644 --- a/build/luabins/luabins.vcxproj.filters +++ b/build/luabins/luabins.vcxproj.filters @@ -9,25 +9,25 @@ - + Source - + Source - + Source - + Source - + Source - + Source - + Source diff --git a/libaegisub/Makefile b/libaegisub/Makefile index f7b1427c1..56c1d6000 100644 --- a/libaegisub/Makefile +++ b/libaegisub/Makefile @@ -11,6 +11,7 @@ lagi_pre.h.gch: CXXFLAGS := $(CXXFLAGS) common/charset_conv.o: CXXFLAGS += $(CFLAGS_ICONV) common/parser.o: CXXFLAGS += -ftemplate-depth=256 unix/path.o: CXXFLAGS += -DP_DATA=\"$(P_DATA)\" -DP_DOC=\"$(P_DOC)\" -DP_LOCALE=\"$(P_LOCALE)\" +lua/**/*.o: CPPFLAGS += -I../vendor/lua/src SRC += \ common/parser.cpp \ @@ -43,7 +44,7 @@ SRC += \ common/vfr.cpp \ lua/modules.cpp \ lua/modules/lfs.cpp \ - lua/modules/lpeg.cpp \ + lua/modules/lpeg.c \ lua/modules/re.cpp \ lua/script_reader.cpp \ lua/utils.cpp \ @@ -68,3 +69,5 @@ EXTRA_DIST += osx/util.mm include ../Makefile.target -include */*.d +-include lua/*/*.d +-include common/*/*.d diff --git a/libaegisub/include/libaegisub/lua/utils.h b/libaegisub/include/libaegisub/lua/utils.h index 8ea31374f..673041956 100644 --- a/libaegisub/include/libaegisub/lua/utils.h +++ b/libaegisub/include/libaegisub/lua/utils.h @@ -16,13 +16,22 @@ #include -#include -#include +#include +#include #include #include #include namespace agi { namespace lua { +// Exception type for errors where the error details are on the lua stack +struct error_tag {}; + +// Below are functionally equivalent to the luaL_ functions, but using a C++ +// exception for stack unwinding +int BOOST_ATTRIBUTE_NORETURN error(lua_State *L, const char *fmt, ...); +int BOOST_ATTRIBUTE_NORETURN argerror(lua_State *L, int narg, const char *extramsg); +int BOOST_ATTRIBUTE_NORETURN typerror(lua_State *L, int narg, const char *tname); +void argcheck(lua_State *L, bool cond, int narg, const char *msg); inline void push_value(lua_State *L, bool value) { lua_pushboolean(L, value); } inline void push_value(lua_State *L, const char *value) { lua_pushstring(L, value); } @@ -62,17 +71,51 @@ void push_value(lua_State *L, std::vector const& value) { } } +/// Wrap a function which may throw exceptions and make it trigger lua errors +/// whenever it throws +template +int exception_wrapper(lua_State *L) { + try { + return func(L); + } + catch (agi::Exception const& e) { + push_value(L, e.GetChainedMessage()); + return lua_error(L); + } + catch (std::exception const& e) { + push_value(L, e.what()); + return lua_error(L); + } + catch (error_tag) { + // Error message is already on the stack + return lua_error(L); + } + catch (...) { + std::terminate(); + } +} + template void set_field(lua_State *L, const char *name, T value) { push_value(L, value); lua_setfield(L, -2, name); } +template +void set_field(lua_State *L, const char *name) { + push_value(L, exception_wrapper); + lua_setfield(L, -2, name); +} + std::string get_string_or_default(lua_State *L, int idx); std::string get_string(lua_State *L, int idx); -std::string check_string(lua_State *L, int idx); std::string get_global_string(lua_State *L, const char *name); +std::string check_string(lua_State *L, int idx); +int check_int(lua_State *L, int idx); +size_t check_uint(lua_State *L, int idx); +void *check_udata(lua_State *L, int idx, const char *mt); + template T *make(lua_State *L, const char *mt, Args&&... args) { auto obj = static_cast(lua_newuserdata(L, sizeof(T))); @@ -84,7 +127,7 @@ T *make(lua_State *L, const char *mt, Args&&... args) { template T& get(lua_State *L, int idx, const char *mt) { - return *static_cast(luaL_checkudata(L, idx, mt)); + return *static_cast(check_udata(L, idx, mt)); } struct LuaForEachBreak {}; @@ -105,6 +148,8 @@ void lua_for_each(lua_State *L, Func&& func) { lua_pop(L, 1); // pop table } +/// Lua error handler which adds the stack trace to the error message, with +/// moonscript line rewriting support int add_stack_trace(lua_State *L); #ifdef _DEBUG diff --git a/libaegisub/lua/modules.cpp b/libaegisub/lua/modules.cpp index 852ca93bb..bd5646b52 100644 --- a/libaegisub/lua/modules.cpp +++ b/libaegisub/lua/modules.cpp @@ -18,12 +18,10 @@ #include "libaegisub/lua/utils.h" -#include - extern "C" int luaopen_luabins(lua_State *L); extern "C" int luaopen_re_impl(lua_State *L); -int luaopen_lfs(lua_State *L); -int luaopen_lpeg(lua_State *L); +extern "C" int luaopen_lfs(lua_State *L); +extern "C" int luaopen_lpeg(lua_State *L); namespace agi { namespace lua { int regex_init(lua_State *L); diff --git a/libaegisub/lua/modules/lfs.cpp b/libaegisub/lua/modules/lfs.cpp index 13bd22bbf..7b3153beb 100644 --- a/libaegisub/lua/modules/lfs.cpp +++ b/libaegisub/lua/modules/lfs.cpp @@ -24,32 +24,30 @@ using namespace agi::lua; using namespace agi::fs; namespace bfs = boost::filesystem; -template -int call(lua_State *L, Func&& f) { +template +int wrap(lua_State *L) { try { - f(); + func(L); return 1; } catch (bfs::filesystem_error const& e) { lua_pushnil(L); - lua_pushstring(L, e.what()); + push_value(L, e.what()); return 2; } catch (agi::Exception const& e) { lua_pushnil(L); - lua_pushstring(L, e.GetChainedMessage().c_str()); + push_value(L, e.GetChainedMessage()); return 2; } -} - -template -int wrap(lua_State *L) { - return call(L, [=] { func(L); }); + catch (error_tag) { + return lua_error(L); + } } void chdir(lua_State *L) { bfs::current_path(check_string(L, 1)); - lua_pushboolean(L, true); + push_value(L, true); } void currentdir(lua_State *L) { @@ -58,17 +56,17 @@ void currentdir(lua_State *L) { void mkdir(lua_State *L) { CreateDirectory(check_string(L, 1)); - lua_pushboolean(L, true); + push_value(L, true); } void rmdir(lua_State *L) { Remove(check_string(L, 1)); - lua_pushboolean(L, true); + push_value(L, true); } void touch(lua_State *L) { Touch(check_string(L, 1)); - lua_pushboolean(L, true); + push_value(L, true); } int dir_next(lua_State *L) { @@ -88,18 +86,13 @@ int dir_close(lua_State *L) { } int dir(lua_State *L) { - try { - const path p = check_string(L, 1); - push_value(L, dir_next); - make(L, "aegisub.lfs.dir", check_string(L, 1), ""); - return 2; - } - catch (agi::Exception const& e) { - return luaL_error(L, "%s", e.GetChainedMessage().c_str()); - } + const path p = check_string(L, 1); + push_value(L, dir_next); + make(L, "aegisub.lfs.dir", check_string(L, 1), ""); + return 2; } -int attributes(lua_State *L) { +void attributes(lua_State *L) { static std::pair fields[] = { {"mode", [](lua_State *L, path const& p) { switch (status(p).type()) { @@ -119,45 +112,43 @@ int attributes(lua_State *L) { {"size", [](lua_State *L, path const& p) { push_value(L, Size(p)); }} }; - return call(L, [=] { - const path p = check_string(L, 1); + const path p = check_string(L, 1); - const auto field = get_string(L, 2); - if (!field.empty()) { - for (const auto getter : fields) { - if (field == getter.first) { - getter.second(L, p); - return; - } - } - luaL_error(L, "Invalid attribute name: %s", field.c_str()); - } - - lua_createtable(L, 0, boost::size(fields)); + const auto field = get_string(L, 2); + if (!field.empty()) { for (const auto getter : fields) { - getter.second(L, p); - lua_setfield(L, -2, getter.first); + if (field == getter.first) { + getter.second(L, p); + return; + } } - }); + error(L, "Invalid attribute name: %s", field.c_str()); + } + + lua_createtable(L, 0, boost::size(fields)); + for (const auto getter : fields) { + getter.second(L, p); + lua_setfield(L, -2, getter.first); + } } } -int luaopen_lfs(lua_State *L) { +extern "C" int luaopen_lfs(lua_State *L) { if (luaL_newmetatable(L, "aegisub.lfs.dir")) { - set_field(L, "__gc", dir_close); + set_field(L, "__gc"); lua_createtable(L, 0, 2); - set_field(L, "next", dir_next); - set_field(L, "close", dir_close); + set_field(L, "next"); + set_field(L, "close"); lua_setfield(L, -2, "__index"); lua_pop(L, 1); } const struct luaL_Reg lib[] = { - {"attributes", attributes}, + {"attributes", wrap}, {"chdir", wrap}, {"currentdir", wrap}, - {"dir", dir}, + {"dir", exception_wrapper}, {"mkdir", wrap}, {"rmdir", wrap}, {"touch", wrap}, diff --git a/libaegisub/lua/modules/lpeg.cpp b/libaegisub/lua/modules/lpeg.c similarity index 100% rename from libaegisub/lua/modules/lpeg.cpp rename to libaegisub/lua/modules/lpeg.c diff --git a/libaegisub/lua/modules/re.cpp b/libaegisub/lua/modules/re.cpp index d5bdb4a55..efc42edd2 100644 --- a/libaegisub/lua/modules/re.cpp +++ b/libaegisub/lua/modules/re.cpp @@ -31,7 +31,7 @@ boost::smatch& get_smatch(lua_State *L) { } int regex_matches(lua_State *L) { - lua_pushboolean(L, u32regex_match(check_string(L, 2), get_regex(L))); + push_value(L, u32regex_match(check_string(L, 2), get_regex(L))); return 1; } @@ -52,9 +52,9 @@ int regex_match(lua_State *L) { } int regex_get_match(lua_State *L) { - auto match = get_smatch(L); - int idx = luaL_checkinteger(L, 2) - 1; - if (static_cast(idx) > match.size() || !match[idx].matched) { + auto& match = get_smatch(L); + auto idx = check_uint(L, 2) - 1; + if (idx > match.size() || !match[idx].matched) { lua_pushnil(L); return 1; } @@ -65,9 +65,10 @@ int regex_get_match(lua_State *L) { } int regex_search(lua_State *L) { - auto re = get_regex(L); - std::string str = check_string(L, 2); - int start = luaL_checkinteger(L, 3) - 1; + auto& re = get_regex(L); + auto str = check_string(L, 2); + auto start = check_uint(L, 3) - 1; + argcheck(L, start <= str.size(), 3, "out of bounds"); boost::smatch result; if (!u32regex_search(str.cbegin() + start, str.cend(), result, re, start > 0 ? boost::match_prev_avail | boost::match_not_bob : boost::match_default)) @@ -82,10 +83,10 @@ int regex_search(lua_State *L) { } int regex_replace(lua_State *L) { - auto re = get_regex(L); + auto& re = get_regex(L); const auto replacement = check_string(L, 2); - const std::string str = check_string(L, 3); - int max_count = luaL_checkinteger(L, 4); + const auto str = check_string(L, 3); + int max_count = check_int(L, 4); // Can't just use regex_replace here since it can only do one or infinite replacements auto match = boost::u32regex_iterator(begin(str), end(str), re); @@ -110,8 +111,8 @@ int regex_replace(lua_State *L) { } int regex_compile(lua_State *L) { - std::string pattern(check_string(L, 1)); - int flags = luaL_checkinteger(L, 2); + auto pattern(check_string(L, 1)); + int flags = check_int(L, 2); auto re = make(L, "aegisub.regex"); try { @@ -175,23 +176,23 @@ int regex_init_flags(lua_State *L) { extern "C" int luaopen_re_impl(lua_State *L) { if (luaL_newmetatable(L, "aegisub.regex")) { - set_field(L, "__gc", regex_gc); + set_field(L, "__gc"); lua_pop(L, 1); } if (luaL_newmetatable(L, "aegisub.smatch")) { - set_field(L, "__gc", smatch_gc); + set_field(L, "__gc"); lua_pop(L, 1); } lua_createtable(L, 0, 8); - set_field(L, "matches", regex_matches); - set_field(L, "search", regex_search); - set_field(L, "match", regex_match); - set_field(L, "get_match", regex_get_match); - set_field(L, "replace", regex_replace); - set_field(L, "compile", regex_compile); - set_field(L, "process_flags", regex_process_flags); - set_field(L, "init_flags", regex_init_flags); + set_field(L, "matches"); + set_field(L, "search"); + set_field(L, "match"); + set_field(L, "get_match"); + set_field(L, "replace"); + set_field(L, "compile"); + set_field(L, "process_flags"); + set_field(L, "init_flags"); return 1; } diff --git a/libaegisub/lua/script_reader.cpp b/libaegisub/lua/script_reader.cpp index 71f2752d6..53c4f13be 100644 --- a/libaegisub/lua/script_reader.cpp +++ b/libaegisub/lua/script_reader.cpp @@ -47,18 +47,19 @@ namespace agi { namespace lua { if (!agi::fs::HasExtension(filename, "moon")) return luaL_loadbuffer(L, 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 // It might be nice to have a dedicated lua state for compiling // MoonScript to Lua if (luaL_dostring(L, "return require('moonscript').loadstring")) return false; // Leaves error message on stack + + // Save the text we'll be loading for the line number rewriting in the + // error handling lua_pushlstring(L, buff, size); - lua_pushstring(L, filename.string().c_str()); + lua_pushvalue(L, -1); + lua_setfield(L, LUA_REGISTRYINDEX, ("raw moonscript: " + filename.string()).c_str()); + + push_value(L, filename); if (lua_pcall(L, 2, 2, 0)) return false; // Leaves error message on stack @@ -74,13 +75,13 @@ namespace agi { namespace lua { static int module_loader(lua_State *L) { int pretop = lua_gettop(L); - std::string module(luaL_checkstring(L, -1)); + std::string module(check_string(L, -1)); boost::replace_all(module, ".", LUA_DIRSEP); // Get the lua package include path (which the user may have modified) lua_getglobal(L, "package"); lua_getfield(L, -1, "path"); - std::string package_paths(luaL_checkstring(L, -1)); + std::string package_paths(check_string(L, -1)); lua_pop(L, 2); boost::char_separator sep(";"); @@ -99,7 +100,7 @@ namespace agi { namespace lua { try { if (!LoadFile(L, path)) - return luaL_error(L, "Error loading Lua module \"%s\":\n%s", path.string().c_str(), luaL_checkstring(L, 1)); + return error(L, "Error loading Lua module \"%s\":\n%s", path.string().c_str(), check_string(L, 1).c_str()); break; } catch (agi::fs::FileNotFound const&) { @@ -109,7 +110,7 @@ namespace agi { namespace lua { // Not an error so swallow and continue on } catch (agi::Exception const& e) { - return luaL_error(L, "Error loading Lua module \"%s\":\n%s", path.string().c_str(), e.GetChainedMessage().c_str()); + return error(L, "Error loading Lua module \"%s\":\n%s", path.string().c_str(), e.GetChainedMessage().c_str()); } } @@ -138,7 +139,7 @@ namespace agi { namespace lua { // Replace the default lua module loader with our unicode compatible one lua_getfield(L, -1, "loaders"); - push_value(L, module_loader); + push_value(L, exception_wrapper); lua_rawseti(L, -2, 2); lua_pop(L, 2); } diff --git a/libaegisub/lua/utils.cpp b/libaegisub/lua/utils.cpp index 84ed43b93..cab65aef8 100644 --- a/libaegisub/lua/utils.cpp +++ b/libaegisub/lua/utils.cpp @@ -24,6 +24,11 @@ #include #include +#ifdef _MSC_VER +// Disable warnings for noreturn functions having return types +#pragma warning(disable: 4645 4646) +#endif + namespace agi { namespace lua { std::string get_string_or_default(lua_State *L, int idx) { size_t len = 0; @@ -39,12 +44,6 @@ std::string get_string(lua_State *L, int idx) { return std::string(str ? str : "", len); } -std::string check_string(lua_State *L, int idx) { - size_t len = 0; - const char *str = luaL_checklstring(L, idx, &len); - return std::string(str ? str : "", len); -} - std::string get_global_string(lua_State *L, const char *name) { lua_getglobal(L, name); std::string ret; @@ -54,6 +53,41 @@ std::string get_global_string(lua_State *L, const char *name) { return ret; } +std::string check_string(lua_State *L, int idx) { + size_t len = 0; + const char *str = lua_tolstring(L, idx, &len); + if (!str) typerror(L, idx, "string"); + return std::string(str, len); +} + +int check_int(lua_State *L, int idx) { + auto v = lua_tointeger(L, idx); + if (v == 0 && !lua_isnumber(L, idx)) + typerror(L, idx, "number"); + return v; +} + +size_t check_uint(lua_State *L, int idx) { + auto v = lua_tointeger(L, idx); + if (v == 0 && !lua_isnumber(L, idx)) + typerror(L, idx, "number"); + if (v < 0) + argerror(L, idx, "must be >= 0"); + return static_cast(v); +} + +void *check_udata(lua_State *L, int idx, const char *mt) { + void *p = lua_touserdata(L, idx); + if (!p) typerror(L, idx, mt); + if (!lua_getmetatable(L, idx)) typerror(L, idx, mt); + + lua_getfield(L, LUA_REGISTRYINDEX, mt); + if (!lua_rawequal(L, -1, -2)) typerror(L, idx, mt); + + lua_pop(L, 2); + return p; +} + 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 @@ -147,6 +181,37 @@ int add_stack_trace(lua_State *L) { return 1; } +int BOOST_ATTRIBUTE_NORETURN error(lua_State *L, const char *fmt, ...) { + va_list argp; + va_start(argp, fmt); + luaL_where(L, 1); + lua_pushvfstring(L, fmt, argp); + va_end(argp); + lua_concat(L, 2); + throw error_tag(); +} + +int BOOST_ATTRIBUTE_NORETURN argerror(lua_State *L, int narg, const char *extramsg) { + lua_Debug ar; + if (!lua_getstack(L, 0, &ar)) + error(L, "bad argument #%d (%s)", narg, extramsg); + lua_getinfo(L, "n", &ar); + if (strcmp(ar.namewhat, "method") == 0 && --narg == 0) + error(L, "calling '%s' on bad self (%s)", ar.name, extramsg); + if (!ar.name) ar.name = "?"; + error(L, "bad argument #%d to '%s' (%s)", + narg, ar.name, extramsg); +} + +int BOOST_ATTRIBUTE_NORETURN typerror(lua_State *L, int narg, const char *tname) { + const char *msg = lua_pushfstring(L, "%s expected, got %s", + tname, luaL_typename(L, narg)); + argerror(L, narg, msg); +} + +void argcheck(lua_State *L, bool cond, int narg, const char *msg) { + if (!cond) argerror(L, narg, msg); +} #ifdef _DEBUG void LuaStackcheck::check_stack(int additional) { diff --git a/src/Makefile b/src/Makefile index 767dff4c6..dc40655bd 100644 --- a/src/Makefile +++ b/src/Makefile @@ -106,7 +106,7 @@ charset_detect.o: CXXFLAGS += -D_X86_ font_file_lister_fontconfig.o: CXXFLAGS += $(CFLAGS_FONTCONFIG) text_file_reader.o: CXXFLAGS += -D_X86_ video_provider_manager.o: CXXFLAGS += $(CFLAGS_FFMS2) -auto4_lua.o auto4_lua_assfile.o auto4_lua_dialog.o auto4_lua_progresssink.o: CXXFLAGS += $(CFLAGS_LUA) +auto4_lua.o auto4_lua_assfile.o auto4_lua_dialog.o auto4_lua_progresssink.o: CPPFLAGS += -I../vendor/lua/src SRC += \ MatroskaParser.c \ diff --git a/src/auto4_lua.cpp b/src/auto4_lua.cpp index 4aaa44c02..f49f0d12a 100644 --- a/src/auto4_lua.cpp +++ b/src/auto4_lua.cpp @@ -83,7 +83,7 @@ namespace { wxString check_wxstring(lua_State *L, int idx) { - return wxString::FromUTF8(luaL_checkstring(L, idx)); + return to_wx(check_string(L, idx)); } void set_context(lua_State *L, const agi::Context *c) @@ -134,7 +134,7 @@ namespace { int clipboard_set(lua_State *L) { - std::string str(luaL_checkstring(L, 1)); + std::string str(check_string(L, 1)); bool succeeded = false; @@ -158,8 +158,8 @@ namespace { int clipboard_init(lua_State *L) { lua_createtable(L, 0, 2); - set_field(L, "get", clipboard_get); - set_field(L, "set", clipboard_set); + set_field(L, "get"); + set_field(L, "set"); return 1; } @@ -189,7 +189,7 @@ namespace { }; template - int pairs(lua_State *L) { + int pairs(lua_State *L) BOOST_NOEXCEPT { // If the metamethod is defined, call it instead if (luaL_getmetafield(L, 1, TableIter::method())) { lua_pushvalue(L, 1); @@ -258,7 +258,7 @@ namespace { int decode_path(lua_State *L) { - std::string path = luaL_checkstring(L, 1); + std::string path = check_string(L, 1); lua_pop(L, 1); push_value(L, config::path->Decode(path)); return 1; @@ -267,13 +267,13 @@ namespace { int cancel_script(lua_State *L) { lua_pushnil(L); - return lua_error(L); + throw error_tag(); } int lua_text_textents(lua_State *L) { - luaL_argcheck(L, lua_istable(L, 1), 1, ""); - luaL_argcheck(L, lua_isstring(L, 2), 2, ""); + argcheck(L, !!lua_istable(L, 1), 1, ""); + argcheck(L, !!lua_isstring(L, 2), 2, ""); // have to check that it looks like a style table before actually converting // if it's a dialogue table then an active AssFile object is required @@ -282,7 +282,7 @@ namespace { std::string actual_class{lua_tostring(L, -1)}; boost::to_lower(actual_class); if (actual_class != "style") - return luaL_error(L, "Not a style entry"); + return error(L, "Not a style entry"); lua_pop(L, 1); } @@ -291,11 +291,11 @@ namespace { auto st = dynamic_cast(et.get()); lua_pop(L, 1); if (!st) - return luaL_error(L, "Not a style entry"); + return error(L, "Not a style entry"); double width, height, descent, extlead; - if (!Automation4::CalculateTextExtents(st, luaL_checkstring(L, 2), width, height, descent, extlead)) - return luaL_error(L, "Some internal error occurred calculating text_extents"); + if (!Automation4::CalculateTextExtents(st, check_string(L, 2), width, height, descent, extlead)) + return error(L, "Some internal error occurred calculating text_extents"); push_value(L, width); push_value(L, height); @@ -429,7 +429,7 @@ namespace { lua_setglobal(L, "dofile"); lua_pushnil(L); lua_setglobal(L, "loadfile"); - push_value(L, LuaInclude); + push_value(L, exception_wrapper); lua_setglobal(L, "include"); // replace pairs and ipairs with lua 5.2-style versions @@ -459,19 +459,19 @@ namespace { lua_pushstring(L, "aegisub"); lua_createtable(L, 0, 12); - set_field(L, "register_macro", LuaCommand::LuaRegister); - set_field(L, "register_filter", LuaExportFilter::LuaRegister); - set_field(L, "text_extents", lua_text_textents); - set_field(L, "frame_from_ms", frame_from_ms); - set_field(L, "ms_from_frame", ms_from_frame); - set_field(L, "video_size", video_size); - set_field(L, "keyframes", get_keyframes); - set_field(L, "decode_path", decode_path); - set_field(L, "cancel", cancel_script); + set_field(L, "register_macro"); + set_field(L, "register_filter"); + set_field(L, "text_extents"); + set_field(L, "frame_from_ms"); + set_field(L, "ms_from_frame"); + set_field(L, "video_size"); + set_field(L, "keyframes"); + set_field(L, "decode_path"); + set_field(L, "cancel"); set_field(L, "lua_automation_version", 4); - set_field(L, "__init_clipboard", clipboard_init); - set_field(L, "file_name", get_file_name); - set_field(L, "gettext", get_translation); + set_field(L, "__init_clipboard"); + set_field(L, "file_name"); + set_field(L, "gettext"); // store aegisub table to globals lua_settable(L, LUA_GLOBALSINDEX); @@ -550,8 +550,7 @@ namespace { { for (auto macro : macros) { if (macro->name() == command->name()) { - luaL_error(L, - "A macro named '%s' is already defined in script '%s'", + error(L, "A macro named '%s' is already defined in script '%s'", command->StrDisplay(nullptr).utf8_str().data(), name.c_str()); } } @@ -581,7 +580,7 @@ namespace { { const LuaScript *s = GetScriptObject(L); - const std::string filename(luaL_checkstring(L, 1)); + const std::string filename(check_string(L, 1)); agi::fs::path filepath; // Relative or absolute path @@ -596,10 +595,10 @@ namespace { } if (!agi::fs::FileExists(filepath)) - return luaL_error(L, "Lua include not found: %s", filename.c_str()); + return error(L, "Lua include not found: %s", filename.c_str()); if (!LoadFile(L, filepath)) - return luaL_error(L, "Error loading Lua include \"%s\":\n%s", filename.c_str(), luaL_checkstring(L, 1)); + return error(L, "Error loading Lua include \"%s\":\n%s", filename.c_str(), check_string(L, 1).c_str()); int pretop = lua_gettop(L) - 1; // don't count the function value itself lua_call(L, 0, LUA_MULTRET); @@ -677,10 +676,10 @@ namespace { , cmd_type(cmd::COMMAND_NORMAL) { lua_getfield(L, LUA_REGISTRYINDEX, "filename"); - cmd_name = str(boost::format("automation/lua/%s/%s") % luaL_checkstring(L, -1) % luaL_checkstring(L, 1)); + cmd_name = str(boost::format("automation/lua/%s/%s") % check_string(L, -1) % check_string(L, 1)); if (!lua_isfunction(L, 3)) - luaL_error(L, "The macro processing function must be a function"); + error(L, "The macro processing function must be a function"); if (lua_isfunction(L, 4)) cmd_type |= cmd::COMMAND_VALIDATE; @@ -899,11 +898,11 @@ namespace { // LuaFeatureFilter LuaExportFilter::LuaExportFilter(lua_State *L) - : ExportFilter(luaL_checkstring(L, 1), lua_tostring(L, 2), lua_tointeger(L, 3)) + : ExportFilter(check_string(L, 1), lua_tostring(L, 2), lua_tointeger(L, 3)) , LuaFeature(L) { if (!lua_isfunction(L, 4)) - luaL_error(L, "The filter processing function must be a function"); + error(L, "The filter processing function must be a function"); // new table for containing the functions for this feature lua_createtable(L, 0, 2); diff --git a/src/auto4_lua_assfile.cpp b/src/auto4_lua_assfile.cpp index a52aacbc9..9bf9a7336 100644 --- a/src/auto4_lua_assfile.cpp +++ b/src/auto4_lua_assfile.cpp @@ -131,13 +131,13 @@ namespace Automation4 { void LuaAssFile::CheckAllowModify() { if (!can_modify) - luaL_error(L, "Attempt to modify subtitles in read-only feature context."); + error(L, "Attempt to modify subtitles in read-only feature context."); } void LuaAssFile::CheckBounds(int idx) { if (idx <= 0 || idx > (int)lines.size()) - luaL_error(L, "Requested out-of-range line from subtitle file: %d", idx); + error(L, "Requested out-of-range line from subtitle file: %d", idx); } void LuaAssFile::AssEntryToLua(lua_State *L, size_t idx) @@ -239,89 +239,82 @@ namespace Automation4 { // convert it to a real AssEntry object, and pop the table from the stack if (!lua_istable(L, -1)) - luaL_error(L, "Can't convert a non-table value to AssEntry"); + error(L, "Can't convert a non-table value to AssEntry"); lua_getfield(L, -1, "class"); if (!lua_isstring(L, -1)) - luaL_error(L, "Table lacks 'class' field, can't convert to AssEntry"); + error(L, "Table lacks 'class' field, can't convert to AssEntry"); std::string lclass(lua_tostring(L, -1)); boost::to_lower(lclass); lua_pop(L, 1); std::unique_ptr result; - - try { - if (lclass == "info") - result = agi::make_unique(get_string_field(L, "key", "info"), get_string_field(L, "value", "info")); - else if (lclass == "style") { - auto sty = new AssStyle; - result.reset(sty); - sty->name = get_string_field(L, "name", "style"); - sty->font = get_string_field(L, "fontname", "style"); - sty->fontsize = get_double_field(L, "fontsize", "style"); - sty->primary = get_string_field(L, "color1", "style"); - sty->secondary = get_string_field(L, "color2", "style"); - sty->outline = get_string_field(L, "color3", "style"); - sty->shadow = get_string_field(L, "color4", "style"); - sty->bold = get_bool_field(L, "bold", "style"); - sty->italic = get_bool_field(L, "italic", "style"); - sty->underline = get_bool_field(L, "underline", "style"); - sty->strikeout = get_bool_field(L, "strikeout", "style"); - sty->scalex = get_double_field(L, "scale_x", "style"); - sty->scaley = get_double_field(L, "scale_y", "style"); - sty->spacing = get_double_field(L, "spacing", "style"); - sty->angle = get_double_field(L, "angle", "style"); - sty->borderstyle = get_int_field(L, "borderstyle", "style"); - sty->outline_w = get_double_field(L, "outline", "style"); - sty->shadow_w = get_double_field(L, "shadow", "style"); - sty->alignment = get_int_field(L, "align", "style"); - sty->Margin[0] = get_int_field(L, "margin_l", "style"); - sty->Margin[1] = get_int_field(L, "margin_r", "style"); - sty->Margin[2] = get_int_field(L, "margin_t", "style"); - sty->encoding = get_int_field(L, "encoding", "style"); - sty->UpdateData(); - } - else if (lclass == "dialogue") { - assert(ass != 0); // since we need AssFile::AddExtradata - auto dia = new AssDialogue; - result.reset(dia); - - dia->Comment = get_bool_field(L, "comment", "dialogue"); - dia->Layer = get_int_field(L, "layer", "dialogue"); - dia->Start = get_int_field(L, "start_time", "dialogue"); - dia->End = get_int_field(L, "end_time", "dialogue"); - dia->Style = get_string_field(L, "style", "dialogue"); - dia->Actor = get_string_field(L, "actor", "dialogue"); - dia->Margin[0] = get_int_field(L, "margin_l", "dialogue"); - dia->Margin[1] = get_int_field(L, "margin_r", "dialogue"); - dia->Margin[2] = get_int_field(L, "margin_t", "dialogue"); - dia->Effect = get_string_field(L, "effect", "dialogue"); - dia->Text = get_string_field(L, "text", "dialogue"); - - lua_getfield(L, -1, "extra"); - std::vector new_ids; - lua_pushnil(L); - while (lua_next(L, -2)) { - auto key = get_string_or_default(L, -2); - auto value = get_string_or_default(L, -1); - new_ids.push_back(ass->AddExtradata(key, value)); - lua_pop(L, 1); - } - lua_pop(L, 1); - dia->ExtradataIds = new_ids; - } - else { - luaL_error(L, "Found line with unknown class: %s", lclass.c_str()); - return nullptr; - } - - return result; + if (lclass == "info") + result = agi::make_unique(get_string_field(L, "key", "info"), get_string_field(L, "value", "info")); + else if (lclass == "style") { + auto sty = new AssStyle; + result.reset(sty); + sty->name = get_string_field(L, "name", "style"); + sty->font = get_string_field(L, "fontname", "style"); + sty->fontsize = get_double_field(L, "fontsize", "style"); + sty->primary = get_string_field(L, "color1", "style"); + sty->secondary = get_string_field(L, "color2", "style"); + sty->outline = get_string_field(L, "color3", "style"); + sty->shadow = get_string_field(L, "color4", "style"); + sty->bold = get_bool_field(L, "bold", "style"); + sty->italic = get_bool_field(L, "italic", "style"); + sty->underline = get_bool_field(L, "underline", "style"); + sty->strikeout = get_bool_field(L, "strikeout", "style"); + sty->scalex = get_double_field(L, "scale_x", "style"); + sty->scaley = get_double_field(L, "scale_y", "style"); + sty->spacing = get_double_field(L, "spacing", "style"); + sty->angle = get_double_field(L, "angle", "style"); + sty->borderstyle = get_int_field(L, "borderstyle", "style"); + sty->outline_w = get_double_field(L, "outline", "style"); + sty->shadow_w = get_double_field(L, "shadow", "style"); + sty->alignment = get_int_field(L, "align", "style"); + sty->Margin[0] = get_int_field(L, "margin_l", "style"); + sty->Margin[1] = get_int_field(L, "margin_r", "style"); + sty->Margin[2] = get_int_field(L, "margin_t", "style"); + sty->encoding = get_int_field(L, "encoding", "style"); + sty->UpdateData(); } - catch (agi::Exception const& e) { - luaL_error(L, e.GetMessage().c_str()); + else if (lclass == "dialogue") { + assert(ass != 0); // since we need AssFile::AddExtradata + auto dia = new AssDialogue; + result.reset(dia); + + dia->Comment = get_bool_field(L, "comment", "dialogue"); + dia->Layer = get_int_field(L, "layer", "dialogue"); + dia->Start = get_int_field(L, "start_time", "dialogue"); + dia->End = get_int_field(L, "end_time", "dialogue"); + dia->Style = get_string_field(L, "style", "dialogue"); + dia->Actor = get_string_field(L, "actor", "dialogue"); + dia->Margin[0] = get_int_field(L, "margin_l", "dialogue"); + dia->Margin[1] = get_int_field(L, "margin_r", "dialogue"); + dia->Margin[2] = get_int_field(L, "margin_t", "dialogue"); + dia->Effect = get_string_field(L, "effect", "dialogue"); + dia->Text = get_string_field(L, "text", "dialogue"); + + lua_getfield(L, -1, "extra"); + std::vector new_ids; + lua_pushnil(L); + while (lua_next(L, -2)) { + auto key = get_string_or_default(L, -2); + auto value = get_string_or_default(L, -1); + new_ids.push_back(ass->AddExtradata(key, value)); + lua_pop(L, 1); + } + lua_pop(L, 1); + dia->ExtradataIds = new_ids; + } + else { + error(L, "Found line with unknown class: %s", lclass.c_str()); return nullptr; } + + return result; } int LuaAssFile::ObjectIndexRead(lua_State *L) @@ -359,7 +352,7 @@ namespace Automation4 { else { // idiot lua_pop(L, 1); - return luaL_error(L, "Invalid indexing in Subtitle File object: '%s'", idx); + return error(L, "Invalid indexing in Subtitle File object: '%s'", idx); } return 1; @@ -367,7 +360,7 @@ namespace Automation4 { default: // crap, user is stupid! - return luaL_error(L, "Attempt to index a Subtitle File object with value of type '%s'.", lua_typename(L, lua_type(L, 2))); + return error(L, "Attempt to index a Subtitle File object with value of type '%s'.", lua_typename(L, lua_type(L, 2))); } assert(false); @@ -427,7 +420,7 @@ namespace Automation4 { CheckAllowModify(); - int n = luaL_checkint(L, 2); + int n = check_int(L, 2); if (n < 0) { // insert line so new index is n lua_remove(L, 1); @@ -475,20 +468,20 @@ namespace Automation4 { int itemcount = lua_gettop(L); if (itemcount == 0) return; - std::vector ids; + std::vector ids; if (itemcount == 1 && lua_istable(L, 1)) { lua_pushvalue(L, 1); lua_for_each(L, [&] { - int n = luaL_checkint(L, -1); - luaL_argcheck(L, n > 0 && n <= (int)lines.size(), 1, "Out of range line index"); + size_t n = check_uint(L, -1); + argcheck(L, n > 0 && n <= lines.size(), 1, "Out of range line index"); ids.push_back(n - 1); }); } else { ids.reserve(itemcount); while (itemcount > 0) { - int n = luaL_checkint(L, itemcount); - luaL_argcheck(L, n > 0 && n <= (int)lines.size(), itemcount, "Out of range line index"); + size_t n = check_uint(L, -1); + argcheck(L, n > 0 && n <= lines.size(), itemcount, "Out of range line index"); ids.push_back(n - 1); --itemcount; } @@ -515,8 +508,8 @@ namespace Automation4 { { CheckAllowModify(); - size_t a = std::max(luaL_checkinteger(L, 1), 1) - 1; - size_t b = std::min(luaL_checkinteger(L, 2), lines.size()); + size_t a = std::max(check_uint(L, 1), 1) - 1; + size_t b = std::min(check_uint(L, 2), lines.size()); if (a >= b) return; @@ -563,13 +556,13 @@ namespace Automation4 { { CheckAllowModify(); - int before = luaL_checkinteger(L, 1); + size_t before = check_uint(L, 1); // + 1 to allow appending at the end of the file - luaL_argcheck(L, before > 0 && before <= (int)lines.size() + 1, 1, + argcheck(L, before > 0 && before <= lines.size() + 1, 1, "Out of range line index"); - if (before == (int)lines.size() + 1) { + if (before == lines.size() + 1) { lua_remove(L, 1); ObjectAppend(L); return; @@ -606,8 +599,8 @@ namespace Automation4 { int LuaAssFile::IterNext(lua_State *L) { - int i = luaL_checkint(L, 2); - if (i >= (int)lines.size()) { + size_t i = check_uint(L, 2); + if (i >= lines.size()) { lua_pushnil(L); return 1; } @@ -621,7 +614,7 @@ namespace Automation4 { { auto e = LuaToAssEntry(L, ass); auto dia = dynamic_cast(e.get()); - luaL_argcheck(L, dia, 1, "Subtitle line must be a dialogue line"); + argcheck(L, !!dia, 1, "Subtitle line must be a dialogue line"); int idx = 0; @@ -655,14 +648,14 @@ namespace Automation4 { void LuaAssFile::LuaSetUndoPoint(lua_State *L) { if (!can_set_undo) - luaL_error(L, "Attempt to set an undo point in a context where it makes no sense to do so."); + error(L, "Attempt to set an undo point in a context where it makes no sense to do so."); if (modification_type) { pending_commits.emplace_back(); PendingCommit& back = pending_commits.back(); back.modification_type = modification_type; - back.mesage = wxString::FromUTF8(luaL_checkstring(L, 1)); + back.mesage = to_wx(check_string(L, 1)); back.lines = lines; modification_type = 0; } @@ -674,7 +667,7 @@ namespace Automation4 { auto ud = lua_touserdata(L, idx); auto laf = *static_cast(ud); if (!allow_expired && laf->references < 2) - luaL_error(L, "Subtitles object is no longer valid"); + error(L, "Subtitles object is no longer valid"); return laf; } @@ -741,19 +734,19 @@ namespace Automation4 { // make the metatable lua_createtable(L, 0, 5); - set_field(L, "__index", closure_wrapper<&LuaAssFile::ObjectIndexRead>); - set_field(L, "__newindex", closure_wrapper_v<&LuaAssFile::ObjectIndexWrite, false>); - set_field(L, "__len", closure_wrapper<&LuaAssFile::ObjectGetLen>); - set_field(L, "__gc", closure_wrapper_v<&LuaAssFile::ObjectGarbageCollect, true>); - set_field(L, "__ipairs", closure_wrapper<&LuaAssFile::ObjectIPairs>); + set_field>(L, "__index"); + set_field>(L, "__newindex"); + set_field>(L, "__len"); + set_field>(L, "__gc"); + set_field>(L, "__ipairs"); lua_setmetatable(L, -2); // register misc functions // assume the "aegisub" global table exists lua_getglobal(L, "aegisub"); - set_field(L, "parse_karaoke_data", closure_wrapper<&LuaAssFile::LuaParseKaraokeData>); - set_field(L, "set_undo_point", closure_wrapper_v<&LuaAssFile::LuaSetUndoPoint, false>); + set_field>(L, "parse_karaoke_data"); + set_field>(L, "set_undo_point"); lua_pop(L, 1); // pop "aegisub" table diff --git a/src/auto4_lua_dialog.cpp b/src/auto4_lua_dialog.cpp index 21d5086f6..b20230bef 100644 --- a/src/auto4_lua_dialog.cpp +++ b/src/auto4_lua_dialog.cpp @@ -413,13 +413,13 @@ namespace Automation4 { // assume top of stack now contains a dialog table if (!lua_istable(L, 1)) - luaL_error(L, "Cannot create config dialog from something non-table"); + error(L, "Cannot create config dialog from something non-table"); // Ok, so there is a table with controls lua_pushvalue(L, 1); lua_for_each(L, [&] { if (!lua_istable(L, -1)) - luaL_error(L, "bad control table entry"); + error(L, "bad control table entry"); std::string controlclass = get_field(L, "class"); boost::to_lower(controlclass); @@ -449,7 +449,7 @@ namespace Automation4 { // FIXME ctl = agi::make_unique(L); else - luaL_error(L, "bad control table entry"); + error(L, "bad control table entry"); controls.emplace_back(std::move(ctl)); }); @@ -457,19 +457,19 @@ namespace Automation4 { if (include_buttons && lua_istable(L, 2)) { lua_pushvalue(L, 2); lua_for_each(L, [&]{ - buttons.emplace_back(-1, luaL_checkstring(L, -1)); + buttons.emplace_back(-1, check_string(L, -1)); }); } if (include_buttons && lua_istable(L, 3)) { lua_pushvalue(L, 3); lua_for_each(L, [&]{ - int id = string_to_wx_id(luaL_checkstring(L, -2)); - std::string label = luaL_checkstring(L, -1); + int id = string_to_wx_id(check_string(L, -2)); + std::string label = check_string(L, -1); auto btn = boost::find_if(buttons, [&](std::pair& btn) { return btn.second == label; }); if (btn == end(buttons)) - luaL_error(L, "Invalid button for id %s", lua_tostring(L, -2)); + error(L, "Invalid button for id %s", lua_tostring(L, -2)); btn->first = id; }); } diff --git a/src/auto4_lua_progresssink.cpp b/src/auto4_lua_progresssink.cpp index 76fc8a1fa..c00d69ac0 100644 --- a/src/auto4_lua_progresssink.cpp +++ b/src/auto4_lua_progresssink.cpp @@ -38,11 +38,14 @@ #include +using namespace agi::lua; + namespace { - void set_field_to_closure(lua_State *L, const char *name, lua_CFunction fn, int ps_idx = -3) + template + void set_field_to_closure(lua_State *L, const char *name, int ps_idx = -3) { lua_pushvalue(L, ps_idx); - lua_pushcclosure(L, fn, 1); + lua_pushcclosure(L, exception_wrapper, 1); lua_setfield(L, -2, name); } @@ -54,15 +57,15 @@ namespace { wxString check_wxstring(lua_State *L, int idx) { - return wxString::FromUTF8(luaL_checkstring(L, idx)); + return to_wx(check_string(L, idx)); } } namespace Automation4 { LuaProgressSink::LuaProgressSink(lua_State *L, ProgressSink *ps, bool allow_config_dialog) - : L(L) + : L(L) { - ProgressSink **ud = (ProgressSink**)lua_newuserdata(L, sizeof(ProgressSink*)); + auto ud = (ProgressSink**)lua_newuserdata(L, sizeof(ProgressSink*)); *ud = ps; // register progress reporting stuff @@ -70,25 +73,25 @@ namespace Automation4 { // Create aegisub.progress table lua_createtable(L, 0, 5); - set_field_to_closure(L, "set", LuaSetProgress); - set_field_to_closure(L, "task", LuaSetTask); - set_field_to_closure(L, "title", LuaSetTitle); - set_field_to_closure(L, "is_cancelled", LuaGetCancelled); + set_field_to_closure(L, "set"); + set_field_to_closure(L, "task"); + set_field_to_closure(L, "title"); + set_field_to_closure(L, "is_cancelled"); lua_setfield(L, -2, "progress"); // Create aegisub.debug table lua_createtable(L, 0, 4); - set_field_to_closure(L, "out", LuaDebugOut); + set_field_to_closure(L, "out"); lua_setfield(L, -2, "debug"); // Set aegisub.log - set_field_to_closure(L, "log", LuaDebugOut, -2); + set_field_to_closure(L, "log", -2); if (allow_config_dialog) { lua_createtable(L, 0, 3); - set_field_to_closure(L, "display", LuaDisplayDialog); - set_field_to_closure(L, "open", LuaDisplayOpenDialog); - set_field_to_closure(L, "save", LuaDisplaySaveDialog); + set_field_to_closure(L, "display"); + set_field_to_closure(L, "open"); + set_field_to_closure(L, "save"); lua_setfield(L, -2, "dialog"); } @@ -124,13 +127,13 @@ namespace Automation4 { int LuaProgressSink::LuaSetTask(lua_State *L) { - GetObjPointer(L, lua_upvalueindex(1))->SetMessage(luaL_checkstring(L, 1)); + GetObjPointer(L, lua_upvalueindex(1))->SetMessage(check_string(L, 1)); return 0; } int LuaProgressSink::LuaSetTitle(lua_State *L) { - GetObjPointer(L, lua_upvalueindex(1))->SetTitle(luaL_checkstring(L, 1)); + GetObjPointer(L, lua_upvalueindex(1))->SetTitle(check_string(L, 1)); return 0; } @@ -170,12 +173,12 @@ namespace Automation4 { luaL_where(L, 1); lua_insert(L, 1); lua_concat(L, 2); - lua_error(L); + throw error_tag(); } } // Top of stack is now a string to output - ps->Log(luaL_checkstring(L, 1)); + ps->Log(check_string(L, 1)); return 0; } diff --git a/vendor/lua/Makefile b/vendor/lua/Makefile index cf559c8db..042e828d5 100644 --- a/vendor/lua/Makefile +++ b/vendor/lua/Makefile @@ -2,39 +2,39 @@ include ../../Makefile.inc LIB = liblua-aegisub.a -CXXFLAGS += -Wno-empty-body -Wno-deprecated-declarations -DLUA_USE_DLOPEN -DLUA_USE_POSIX +CFLAGS += -Wno-empty-body -Wno-deprecated-declarations -Wno-unused-const-variable -DLUA_USE_POSIX SRC = \ - src/lapi.cpp \ - src/lauxlib.cpp \ - src/lbaselib.cpp \ - src/lcode.cpp \ - src/ldblib.cpp \ - src/ldebug.cpp \ - src/ldo.cpp \ - src/ldump.cpp \ - src/lfunc.cpp \ - src/lgc.cpp \ - src/linit.cpp \ - src/liolib.cpp \ - src/llex.cpp \ - src/lmathlib.cpp \ - src/lmem.cpp \ - src/loadlib.cpp \ - src/lobject.cpp \ - src/lopcodes.cpp \ - src/loslib.cpp \ - src/lparser.cpp \ - src/lstate.cpp \ - src/lstring.cpp \ - src/lstrlib.cpp \ - src/ltable.cpp \ - src/ltablib.cpp \ - src/ltm.cpp \ - src/lundump.cpp \ - src/lvm.cpp \ - src/lzio.cpp \ - src/print.cpp + src/lapi.c \ + src/lauxlib.c \ + src/lbaselib.c \ + src/lcode.c \ + src/ldblib.c \ + src/ldebug.c \ + src/ldo.c \ + src/ldump.c \ + src/lfunc.c \ + src/lgc.c \ + src/linit.c \ + src/liolib.c \ + src/llex.c \ + src/lmathlib.c \ + src/lmem.c \ + src/loadlib.c \ + src/lobject.c \ + src/lopcodes.c \ + src/loslib.c \ + src/lparser.c \ + src/lstate.c \ + src/lstring.c \ + src/lstrlib.c \ + src/ltable.c \ + src/ltablib.c \ + src/ltm.c \ + src/lundump.c \ + src/lvm.c \ + src/lzio.c \ + src/print.c HEADER = src/*.h diff --git a/vendor/lua/src/lapi.cpp b/vendor/lua/src/lapi.c similarity index 100% rename from vendor/lua/src/lapi.cpp rename to vendor/lua/src/lapi.c diff --git a/vendor/lua/src/lauxlib.cpp b/vendor/lua/src/lauxlib.c similarity index 100% rename from vendor/lua/src/lauxlib.cpp rename to vendor/lua/src/lauxlib.c diff --git a/vendor/lua/src/lbaselib.cpp b/vendor/lua/src/lbaselib.c similarity index 100% rename from vendor/lua/src/lbaselib.cpp rename to vendor/lua/src/lbaselib.c diff --git a/vendor/lua/src/lcode.cpp b/vendor/lua/src/lcode.c similarity index 100% rename from vendor/lua/src/lcode.cpp rename to vendor/lua/src/lcode.c diff --git a/vendor/lua/src/ldblib.cpp b/vendor/lua/src/ldblib.c similarity index 100% rename from vendor/lua/src/ldblib.cpp rename to vendor/lua/src/ldblib.c diff --git a/vendor/lua/src/ldebug.cpp b/vendor/lua/src/ldebug.c similarity index 100% rename from vendor/lua/src/ldebug.cpp rename to vendor/lua/src/ldebug.c diff --git a/vendor/lua/src/ldo.cpp b/vendor/lua/src/ldo.c similarity index 100% rename from vendor/lua/src/ldo.cpp rename to vendor/lua/src/ldo.c diff --git a/vendor/lua/src/ldump.cpp b/vendor/lua/src/ldump.c similarity index 100% rename from vendor/lua/src/ldump.cpp rename to vendor/lua/src/ldump.c diff --git a/vendor/lua/src/lfunc.cpp b/vendor/lua/src/lfunc.c similarity index 100% rename from vendor/lua/src/lfunc.cpp rename to vendor/lua/src/lfunc.c diff --git a/vendor/lua/src/lgc.cpp b/vendor/lua/src/lgc.c similarity index 100% rename from vendor/lua/src/lgc.cpp rename to vendor/lua/src/lgc.c diff --git a/vendor/lua/src/linit.cpp b/vendor/lua/src/linit.c similarity index 100% rename from vendor/lua/src/linit.cpp rename to vendor/lua/src/linit.c diff --git a/vendor/lua/src/liolib.cpp b/vendor/lua/src/liolib.c similarity index 100% rename from vendor/lua/src/liolib.cpp rename to vendor/lua/src/liolib.c diff --git a/vendor/lua/src/llex.cpp b/vendor/lua/src/llex.c similarity index 100% rename from vendor/lua/src/llex.cpp rename to vendor/lua/src/llex.c diff --git a/vendor/lua/src/lmathlib.cpp b/vendor/lua/src/lmathlib.c similarity index 100% rename from vendor/lua/src/lmathlib.cpp rename to vendor/lua/src/lmathlib.c diff --git a/vendor/lua/src/lmem.cpp b/vendor/lua/src/lmem.c similarity index 100% rename from vendor/lua/src/lmem.cpp rename to vendor/lua/src/lmem.c diff --git a/vendor/lua/src/loadlib.cpp b/vendor/lua/src/loadlib.c similarity index 100% rename from vendor/lua/src/loadlib.cpp rename to vendor/lua/src/loadlib.c diff --git a/vendor/lua/src/lobject.cpp b/vendor/lua/src/lobject.c similarity index 100% rename from vendor/lua/src/lobject.cpp rename to vendor/lua/src/lobject.c diff --git a/vendor/lua/src/lopcodes.cpp b/vendor/lua/src/lopcodes.c similarity index 100% rename from vendor/lua/src/lopcodes.cpp rename to vendor/lua/src/lopcodes.c diff --git a/vendor/lua/src/loslib.cpp b/vendor/lua/src/loslib.c similarity index 100% rename from vendor/lua/src/loslib.cpp rename to vendor/lua/src/loslib.c diff --git a/vendor/lua/src/lparser.cpp b/vendor/lua/src/lparser.c similarity index 100% rename from vendor/lua/src/lparser.cpp rename to vendor/lua/src/lparser.c diff --git a/vendor/lua/src/lstate.cpp b/vendor/lua/src/lstate.c similarity index 100% rename from vendor/lua/src/lstate.cpp rename to vendor/lua/src/lstate.c diff --git a/vendor/lua/src/lstring.cpp b/vendor/lua/src/lstring.c similarity index 100% rename from vendor/lua/src/lstring.cpp rename to vendor/lua/src/lstring.c diff --git a/vendor/lua/src/lstrlib.cpp b/vendor/lua/src/lstrlib.c similarity index 100% rename from vendor/lua/src/lstrlib.cpp rename to vendor/lua/src/lstrlib.c diff --git a/vendor/lua/src/ltable.cpp b/vendor/lua/src/ltable.c similarity index 100% rename from vendor/lua/src/ltable.cpp rename to vendor/lua/src/ltable.c diff --git a/vendor/lua/src/ltablib.cpp b/vendor/lua/src/ltablib.c similarity index 100% rename from vendor/lua/src/ltablib.cpp rename to vendor/lua/src/ltablib.c diff --git a/vendor/lua/src/ltm.cpp b/vendor/lua/src/ltm.c similarity index 100% rename from vendor/lua/src/ltm.cpp rename to vendor/lua/src/ltm.c diff --git a/vendor/lua/src/lua.cpp b/vendor/lua/src/lua.c similarity index 100% rename from vendor/lua/src/lua.cpp rename to vendor/lua/src/lua.c diff --git a/vendor/lua/src/lua.hpp b/vendor/lua/src/lua.hpp new file mode 100644 index 000000000..cb5432043 --- /dev/null +++ b/vendor/lua/src/lua.hpp @@ -0,0 +1,10 @@ +// lua.hpp +// Lua header files for C++ +// <> not supplied automatically because Lua also compiles as C++ + +extern "C" { +#include "lua.h" +#include "lualib.h" +#include "lauxlib.h" +} + diff --git a/vendor/lua/src/luac.cpp b/vendor/lua/src/luac.c similarity index 100% rename from vendor/lua/src/luac.cpp rename to vendor/lua/src/luac.c diff --git a/vendor/lua/src/lundump.cpp b/vendor/lua/src/lundump.c similarity index 100% rename from vendor/lua/src/lundump.cpp rename to vendor/lua/src/lundump.c diff --git a/vendor/lua/src/lvm.cpp b/vendor/lua/src/lvm.c similarity index 100% rename from vendor/lua/src/lvm.cpp rename to vendor/lua/src/lvm.c diff --git a/vendor/lua/src/lzio.cpp b/vendor/lua/src/lzio.c similarity index 100% rename from vendor/lua/src/lzio.cpp rename to vendor/lua/src/lzio.c diff --git a/vendor/lua/src/print.cpp b/vendor/lua/src/print.c similarity index 100% rename from vendor/lua/src/print.cpp rename to vendor/lua/src/print.c diff --git a/vendor/luabins/Makefile b/vendor/luabins/Makefile index 6713d3759..4aaf493af 100644 --- a/vendor/luabins/Makefile +++ b/vendor/luabins/Makefile @@ -2,16 +2,16 @@ include ../../Makefile.inc LIB = libluabins.a -CXXFLAGS += -I../lua/src -DLUABINS_LUABUILTASCPP +CPPFLAGS += -I../lua/src SRC = \ - src/fwrite.cpp \ - src/load.cpp \ - src/luabins.cpp \ - src/luainternals.cpp \ - src/save.cpp \ - src/savebuffer.cpp \ - src/write.cpp + src/fwrite.c \ + src/load.c \ + src/luabins.c \ + src/luainternals.c \ + src/save.c \ + src/savebuffer.c \ + src/write.c HEADER = \ src/fwrite.h \ diff --git a/vendor/luabins/src/fwrite.cpp b/vendor/luabins/src/fwrite.c similarity index 100% rename from vendor/luabins/src/fwrite.cpp rename to vendor/luabins/src/fwrite.c diff --git a/vendor/luabins/src/load.cpp b/vendor/luabins/src/load.c similarity index 100% rename from vendor/luabins/src/load.cpp rename to vendor/luabins/src/load.c diff --git a/vendor/luabins/src/luabins.cpp b/vendor/luabins/src/luabins.c similarity index 100% rename from vendor/luabins/src/luabins.cpp rename to vendor/luabins/src/luabins.c diff --git a/vendor/luabins/src/luainternals.cpp b/vendor/luabins/src/luainternals.c similarity index 100% rename from vendor/luabins/src/luainternals.cpp rename to vendor/luabins/src/luainternals.c diff --git a/vendor/luabins/src/save.cpp b/vendor/luabins/src/save.c similarity index 100% rename from vendor/luabins/src/save.cpp rename to vendor/luabins/src/save.c diff --git a/vendor/luabins/src/savebuffer.cpp b/vendor/luabins/src/savebuffer.c similarity index 100% rename from vendor/luabins/src/savebuffer.cpp rename to vendor/luabins/src/savebuffer.c diff --git a/vendor/luabins/src/write.cpp b/vendor/luabins/src/write.c similarity index 100% rename from vendor/luabins/src/write.cpp rename to vendor/luabins/src/write.c