diff --git a/CMakeLists.txt b/CMakeLists.txt index 4e47a12d6..5672eaab7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -140,8 +140,8 @@ if (NOT EXISTS ${dfhack_SOURCE_DIR}/library/xml/codegen.pl OR NOT EXISTS ${dfhac endif() # set up versioning. -set(DF_VERSION "0.44.02") -SET(DFHACK_RELEASE "beta1") +set(DF_VERSION "0.44.03") +SET(DFHACK_RELEASE "alpha1") SET(DFHACK_PRERELEASE TRUE) set(DFHACK_VERSION "${DF_VERSION}-${DFHACK_RELEASE}") diff --git a/docs/NEWS-dev.rst b/docs/NEWS-dev.rst index e44bdf96c..6bed2e344 100644 --- a/docs/NEWS-dev.rst +++ b/docs/NEWS-dev.rst @@ -37,6 +37,15 @@ Development Changelog .. contents:: :depth: 2 +DFHack 0.44.03-alpha1 +===================== + +Other Changes +------------- +- Lua: Improved ``json`` I/O error messages +- Lua: Stopped a crash when trying to create instances of classes whose vtable + addresses are not available + DFHack 0.44.02-beta1 ==================== diff --git a/library/DataDefs.cpp b/library/DataDefs.cpp index c9586fcc0..ab50eb942 100644 --- a/library/DataDefs.cpp +++ b/library/DataDefs.cpp @@ -36,6 +36,7 @@ distribution. #include "DataDefs.h" #include "DataIdentity.h" #include "VTableInterpose.h" +#include "Error.h" #include "MiscUtils.h" @@ -310,7 +311,7 @@ void virtual_identity::adjust_vtable(virtual_ptr obj, virtual_identity *main) return; std::cerr << "Attempt to create class '" << getName() << "' without known vtable." << std::endl; - abort(); + throw DFHack::Error::VTableMissing(getName()); } virtual_ptr virtual_identity::clone(virtual_ptr obj) diff --git a/library/LuaTypes.cpp b/library/LuaTypes.cpp index 6e3c5d5cf..f30a1878e 100644 --- a/library/LuaTypes.cpp +++ b/library/LuaTypes.cpp @@ -1086,6 +1086,11 @@ int LuaWrapper::method_wrapper_core(lua_State *state, function_identity_base *id std::string tmp = stl_sprintf("Invalid argument; expected: %s", vn ? vn : "?"); field_error(state, UPVAL_METHOD_NAME, tmp.c_str(), "invoke"); } + catch (Error::VTableMissing &e) { + const char *cn = e.name(); + std::string tmp = stl_sprintf("Missing vtable address: %s", cn ? cn : "?"); + field_error(state, UPVAL_METHOD_NAME, tmp.c_str(), "invoke"); + } catch (std::exception &e) { std::string tmp = stl_sprintf("C++ exception: %s", e.what()); field_error(state, UPVAL_METHOD_NAME, tmp.c_str(), "invoke"); @@ -1110,6 +1115,10 @@ int Lua::CallWithCatch(lua_State *state, int (*fn)(lua_State*), const char *cont const char *vn = e.expr(); return luaL_error(state, "%s: Invalid argument; expected: %s", context, vn ? vn : "?"); } + catch (Error::VTableMissing &e) { + const char *cn = e.name(); + return luaL_error(state, "%s: Missing vtable address: %s", context, cn ? cn : "?"); + } catch (std::exception &e) { return luaL_error(state, "%s: C++ exception: %s", context, e.what()); } diff --git a/library/MiscUtils.cpp b/library/MiscUtils.cpp index a6bb4b412..bff7f07e1 100644 --- a/library/MiscUtils.cpp +++ b/library/MiscUtils.cpp @@ -49,6 +49,10 @@ const char *DFHack::Error::InvalidArgument::what() const throw() { return "DFHack::Error::InvalidArgument"; } +const char *DFHack::Error::VTableMissing::what() const throw() { + return "DFHack::Error::VTableMissing"; +} + std::string stl_sprintf(const char *fmt, ...) { va_list lst; va_start(lst, fmt); diff --git a/library/include/Error.h b/library/include/Error.h index 6b4781028..2d0baadfc 100644 --- a/library/include/Error.h +++ b/library/include/Error.h @@ -75,6 +75,14 @@ namespace DFHack #define CHECK_INVALID_ARGUMENT(expr) \ { if (!(expr)) throw DFHack::Error::InvalidArgument(#expr); } + class DFHACK_EXPORT VTableMissing : public All { + const char *name_; + public: + VTableMissing(const char *name_ = NULL) : name_(name_) {} + const char *name() const { return name_; } + virtual const char *what() const throw(); + }; + class DFHACK_EXPORT AllSymbols : public All{}; // Syntax errors and whatnot, the xml can't be read diff --git a/library/lua/json.lua b/library/lua/json.lua index ac7aa6327..2b4b3a66a 100644 --- a/library/lua/json.lua +++ b/library/lua/json.lua @@ -21,6 +21,9 @@ function encode_file(data, path, ...) end local contents = encode(data, ...) local f = io.open(path, 'w') + if not f then + error('Could not write to ' .. tostring(path)) + end f:write(contents) f:close() end @@ -32,7 +35,7 @@ end function decode_file(path, ...) local f = io.open(path) if not f then - error('Could not open ' .. path) + error('Could not read from ' .. tostring(path)) end local contents = f:read('*all') f:close() diff --git a/library/modules/Screen.cpp b/library/modules/Screen.cpp index 06faf610f..96f385d8d 100644 --- a/library/modules/Screen.cpp +++ b/library/modules/Screen.cpp @@ -372,12 +372,6 @@ bool Screen::hasActiveScreens(Plugin *plugin) } #ifdef _LINUX -// Link to the libgraphics class directly: -class DFHACK_EXPORT enabler_inputst { - public: - std::string GetKeyDisplay(int binding); -}; - class DFHACK_EXPORT renderer { unsigned char *screen; long *screentexpos; @@ -418,15 +412,6 @@ public: virtual bool get_mouse_coords(int &x, int &y) { return false; } virtual bool uses_opengl(); }; -#else -struct less_sz { - bool operator() (const string &a, const string &b) const { - if (a.size() < b.size()) return true; - if (a.size() > b.size()) return false; - return a < b; - } -}; -static std::map > *keydisplay = NULL; #endif void init_screen_module(Core *core) @@ -435,26 +420,13 @@ void init_screen_module(Core *core) renderer tmp; if (!strict_virtual_cast((virtual_ptr)&tmp)) cerr << "Could not fetch the renderer vtable." << std::endl; -#else - if (!core->vinfo->getAddress("keydisplay", keydisplay)) - keydisplay = NULL; #endif } string Screen::getKeyDisplay(df::interface_key key) { -#ifdef _LINUX - auto enabler = (enabler_inputst*)df::global::enabler; if (enabler) return enabler->GetKeyDisplay(key); -#else - if (keydisplay) - { - auto it = keydisplay->find(key); - if (it != keydisplay->end() && !it->second.empty()) - return *it->second.begin(); - } -#endif return "?"; }