diff --git a/aegisub/build/Aegisub/Aegisub.vcxproj b/aegisub/build/Aegisub/Aegisub.vcxproj index b40534193..69ec6704e 100644 --- a/aegisub/build/Aegisub/Aegisub.vcxproj +++ b/aegisub/build/Aegisub/Aegisub.vcxproj @@ -134,6 +134,7 @@ + diff --git a/aegisub/build/Aegisub/Aegisub.vcxproj.filters b/aegisub/build/Aegisub/Aegisub.vcxproj.filters index 3b718bcc5..e7b2dd773 100644 --- a/aegisub/build/Aegisub/Aegisub.vcxproj.filters +++ b/aegisub/build/Aegisub/Aegisub.vcxproj.filters @@ -687,6 +687,9 @@ ASS + + Automation\Lua + diff --git a/aegisub/src/auto4_lua.cpp b/aegisub/src/auto4_lua.cpp index c41287c4b..60633aa3f 100644 --- a/aegisub/src/auto4_lua.cpp +++ b/aegisub/src/auto4_lua.cpp @@ -38,6 +38,7 @@ #include "auto4_lua.h" +#include "auto4_lua_utils.h" #include "ass_dialogue.h" #include "ass_file.h" #include "ass_style.h" @@ -53,8 +54,6 @@ #include "utils.h" #include -#include -#include #include #include @@ -75,78 +74,7 @@ #include #include -// This must be below the headers above. -#ifdef __WINDOWS__ -#include "../../contrib/lua51/src/lualib.h" -#include "../../contrib/lua51/src/lauxlib.h" -#else -#include -#endif - namespace { - inline void push_value(lua_State *L, lua_CFunction fn) { - lua_pushcfunction(L, fn); - } - - inline void push_value(lua_State *L, int n) { - lua_pushinteger(L, n); - } - - inline void push_value(lua_State *L, void *p) { - lua_pushlightuserdata(L, p); - } - - inline void push_value(lua_State *L, agi::fs::path const& p) { - lua_pushstring(L, p.string().c_str()); - } - - inline void push_value(lua_State *L, wxString const& s) { - lua_pushstring(L, s.utf8_str()); - } - - inline void push_value(lua_State *L, std::string const& s) { - lua_pushstring(L, s.c_str()); - } - - inline void push_value(lua_State *L, const char *s) { - lua_pushstring(L, s); - } - - template - inline void set_field(lua_State *L, const char *name, T value) - { - push_value(L, value); - lua_setfield(L, -2, name); - } - - inline wxString get_wxstring(lua_State *L, int idx) - { - return wxString::FromUTF8(lua_tostring(L, idx)); - } - - inline wxString check_wxstring(lua_State *L, int idx) - { - return wxString::FromUTF8(luaL_checkstring(L, idx)); - } - - std::string get_string_or_default(lua_State *L, int idx) - { - const char *str = lua_tostring(L, idx); - if (!str) - str = ""; - return str; - } - - std::string get_global_string(lua_State *L, const char *name) - { - lua_getglobal(L, name); - std::string ret; - if (lua_isstring(L, -1)) - ret = lua_tostring(L, -1); - lua_pop(L, 1); - return ret; - } - void set_context(lua_State *L, const agi::Context *c) { // Explicit cast is needed to discard the const @@ -345,47 +273,6 @@ namespace { } } - // LuaStackcheck -#ifdef _DEBUG - struct LuaStackcheck { - lua_State *L; - int startstack; - void check_stack(int additional) - { - int top = lua_gettop(L); - if (top - additional != startstack) { - LOG_D("automation/lua") << "lua stack size mismatch."; - dump(); - assert(top - additional == startstack); - } - } - void dump() - { - int top = lua_gettop(L); - LOG_D("automation/lua/stackdump") << "--- dumping lua stack..."; - for (int i = top; i > 0; i--) { - lua_pushvalue(L, i); - std::string type(lua_typename(L, lua_type(L, -1))); - if (lua_isstring(L, i)) { - LOG_D("automation/lua/stackdump") << type << ": " << lua_tostring(L, -1); - } else { - LOG_D("automation/lua/stackdump") << type; - } - lua_pop(L, 1); - } - LOG_D("automation/lua") << "--- end dump"; - } - LuaStackcheck(lua_State *L) : L(L) { startstack = lua_gettop(L); } - ~LuaStackcheck() { check_stack(0); } - }; -#else - struct LuaStackcheck { - void check_stack(int) { } - void dump() { } - LuaStackcheck(lua_State*) { } - }; -#endif - namespace Automation4 { // LuaScript LuaScript::LuaScript(agi::fs::path const& filename) diff --git a/aegisub/src/auto4_lua_assfile.cpp b/aegisub/src/auto4_lua_assfile.cpp index 07e7b87af..9c8883009 100644 --- a/aegisub/src/auto4_lua_assfile.cpp +++ b/aegisub/src/auto4_lua_assfile.cpp @@ -37,6 +37,7 @@ #ifdef WITH_AUTO4_LUA #include "auto4_lua.h" +#include "auto4_lua_utils.h" #include "ass_dialogue.h" #include "ass_info.h" #include "ass_file.h" @@ -45,7 +46,6 @@ #include "utils.h" #include -#include #include #include @@ -54,48 +54,7 @@ #include #include -// This must be below the headers above. -#ifdef __WINDOWS__ -#include "../../contrib/lua51/src/lualib.h" -#include "../../contrib/lua51/src/lauxlib.h" -#else -#include -#endif - namespace { - void push_value(lua_State *L, std::string const& value) { - lua_pushstring(L, value.c_str()); - } - - void push_value(lua_State *L, const char *value) { - lua_pushstring(L, value); - } - - // Userdata object must be just above the target table - void push_value(lua_State *L, lua_CFunction value) { - assert(lua_type(L, -2) == LUA_TUSERDATA); - lua_pushvalue(L, -2); - lua_pushcclosure(L, value, 1); - } - - void push_value(lua_State *L, bool value) { - lua_pushboolean(L, value); - } - - void push_value(lua_State *L, double value) { - lua_pushnumber(L, value); - } - - void push_value(lua_State *L, int value) { - lua_pushinteger(L, value); - } - - template - void set_field(lua_State *L, const char *name, T value) { - push_value(L, value); - lua_setfield(L, -2, name); - } - DEFINE_SIMPLE_EXCEPTION_NOINNER(BadField, Automation4::MacroRunError, "automation/macro/bad_field") BadField bad_field(const char *expected_type, const char *name, const char *line_clasee) { diff --git a/aegisub/src/auto4_lua_progresssink.cpp b/aegisub/src/auto4_lua_progresssink.cpp index 76be20477..56191e2a8 100644 --- a/aegisub/src/auto4_lua_progresssink.cpp +++ b/aegisub/src/auto4_lua_progresssink.cpp @@ -35,17 +35,11 @@ #include "config.h" #ifdef WITH_AUTO4_LUA - #include "auto4_lua.h" -#include +#include "auto4_lua_utils.h" -#ifdef __WINDOWS__ -#include "../../contrib/lua51/src/lua.h" -#include "../../contrib/lua51/src/lauxlib.h" -#else -#include -#endif +#include namespace { void set_field_to_closure(lua_State *L, const char *name, lua_CFunction fn, int ps_idx = -3) @@ -60,11 +54,6 @@ namespace { lua_pushnil(L); lua_setfield(L, idx, name); } - - inline wxString check_wxstring(lua_State *L, int idx) - { - return wxString::FromUTF8(luaL_checkstring(L, idx)); - } } namespace Automation4 { diff --git a/aegisub/src/auto4_lua_utils.h b/aegisub/src/auto4_lua_utils.h new file mode 100644 index 000000000..607d3d32b --- /dev/null +++ b/aegisub/src/auto4_lua_utils.h @@ -0,0 +1,126 @@ +// Copyright (c) 2012, Thomas Goyne +// +// Permission to use, copy, modify, and distribute this software for any +// purpose with or without fee is hereby granted, provided that the above +// copyright notice and this permission notice appear in all copies. +// +// THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES +// WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF +// MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR +// ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES +// WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN +// ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF +// OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE. +// +// Aegisub Project http://www.aegisub.org/ + +#include + +#ifdef __WINDOWS__ +#include "../../contrib/lua51/src/lualib.h" +#include "../../contrib/lua51/src/lauxlib.h" +#else +#include +#endif + +#include + +#include +#include + +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); } +inline void push_value(lua_State *L, double value) { lua_pushnumber(L, value); } +inline void push_value(lua_State *L, int value) { lua_pushinteger(L, value); } +inline void push_value(lua_State *L, size_t value) { lua_pushinteger(L, value); } +inline void push_value(lua_State *L, void *p) { lua_pushlightuserdata(L, p); } + +inline void push_value(lua_State *L, wxString const& value) { + lua_pushstring(L, value.utf8_str()); +} + +inline void push_value(lua_State *L, agi::fs::path const& value) { + lua_pushstring(L, value.string().c_str()); +} + +inline void push_value(lua_State *L, std::string const& value) { + lua_pushstring(L, value.c_str()); +} + +inline void push_value(lua_State *L, lua_CFunction value) { + if (lua_type(L, -2) == LUA_TUSERDATA) { + lua_pushvalue(L, -2); + lua_pushcclosure(L, value, 1); + } + else + lua_pushcclosure(L, value, 0); +} + +template +inline void set_field(lua_State *L, const char *name, T value) { + push_value(L, value); + lua_setfield(L, -2, name); +} + +inline wxString get_wxstring(lua_State *L, int idx) { + return wxString::FromUTF8(lua_tostring(L, idx)); +} + +inline wxString check_wxstring(lua_State *L, int idx) { + return wxString::FromUTF8(luaL_checkstring(L, idx)); +} + +inline std::string get_string_or_default(lua_State *L, int idx) { + const char *str = lua_tostring(L, idx); + if (!str) + str = ""; + return str; +} + +inline std::string get_global_string(lua_State *L, const char *name) { + lua_getglobal(L, name); + std::string ret; + if (lua_isstring(L, -1)) + ret = lua_tostring(L, -1); + lua_pop(L, 1); + return ret; +} + +#ifdef _DEBUG +struct LuaStackcheck { + lua_State *L; + int startstack; + + void check_stack(int additional) { + int top = lua_gettop(L); + if (top - additional != startstack) { + LOG_D("automation/lua") << "lua stack size mismatch."; + dump(); + assert(top - additional == startstack); + } + } + + void dump() { + int top = lua_gettop(L); + LOG_D("automation/lua/stackdump") << "--- dumping lua stack..."; + for (int i = top; i > 0; i--) { + lua_pushvalue(L, i); + std::string type(lua_typename(L, lua_type(L, -1))); + if (lua_isstring(L, i)) + LOG_D("automation/lua/stackdump") << type << ": " << lua_tostring(L, -1); + else + LOG_D("automation/lua/stackdump") << type; + lua_pop(L, 1); + } + LOG_D("automation/lua") << "--- end dump"; + } + LuaStackcheck(lua_State *L) : L(L), startstack(lua_gettop(L)) { } + ~LuaStackcheck() { check_stack(0); } +}; +#else +struct LuaStackcheck { + void check_stack(int) { } + void dump() { } + LuaStackcheck(lua_State*) { } +}; +#endif