diff --git a/library/Core.cpp b/library/Core.cpp index 56c400e878..c406fb6c01 100644 --- a/library/Core.cpp +++ b/library/Core.cpp @@ -42,6 +42,7 @@ using namespace std; #include "Core.h" #include "DataDefs.h" #include "Console.h" +#include "MiscUtils.h" #include "Module.h" #include "VersionInfoFactory.h" #include "VersionInfo.h" @@ -1522,7 +1523,7 @@ Core::~Core() } Core::Core() : - d{new Private}, + d(dts::make_unique()), script_path_mutex{}, HotkeyMutex{}, HotkeyCond{}, @@ -1535,10 +1536,7 @@ Core::Core() : { // init the console. This must be always the first step! plug_mgr = 0; - vif = 0; - p = 0; errorstate = false; - vinfo = 0; started = false; memset(&(s_mods), 0, sizeof(s_mods)); @@ -1617,27 +1615,27 @@ bool Core::Init() #else const char * path = "hack\\symbols.xml"; #endif - vif = new DFHack::VersionInfoFactory(); + auto local_vif = dts::make_unique(); cerr << "Identifying DF version.\n"; try { - vif->loadFile(path); + local_vif->loadFile(path); } catch(Error::All & err) { std::stringstream out; out << "Error while reading symbols.xml:\n"; out << err.what() << std::endl; - delete vif; - vif = NULL; errorstate = true; fatal(out.str()); return false; } - p = new DFHack::Process(vif); - vinfo = p->getDescriptor(); + vif = std::move(local_vif); + auto local_p = dts::make_unique(*vif); + local_p->ValidateDescriptionOS(); + vinfo = local_p->getDescriptor(); - if(!vinfo || !p->isIdentified()) + if(!vinfo || !local_p->isIdentified()) { if (!Version::git_xml_match()) { @@ -1668,23 +1666,10 @@ bool Core::Init() fatal("Not a known DF version.\n"); } errorstate = true; - delete p; - p = NULL; return false; } cerr << "Version: " << vinfo->getVersion() << endl; - -#if defined(_WIN32) - const OSType expected = OS_WINDOWS; -#elif defined(_DARWIN) - const OSType expected = OS_APPLE; -#else - const OSType expected = OS_LINUX; -#endif - if (expected != vinfo->getOS()) { - cerr << "OS mismatch; resetting to " << int(expected) << endl; - vinfo->setOS(expected); - } + p = std::move(local_p); // Init global object pointers df::global::InitGlobals(); @@ -2319,14 +2304,9 @@ int Core::Shutdown ( void ) plug_mgr = 0; } // invalidate all modules - for(size_t i = 0 ; i < allModules.size(); i++) - { - delete allModules[i]; - } allModules.clear(); memset(&(s_mods), 0, sizeof(s_mods)); - delete d; - d = nullptr; + d.reset(); return -1; } @@ -2755,7 +2735,7 @@ void ClassNameCheck::getKnownClassNames(std::vector &names) MemoryPatcher::MemoryPatcher(Process *p_) : p(p_) { if (!p) - p = Core::getInstance().p; + p = Core::getInstance().p.get(); } MemoryPatcher::~MemoryPatcher() @@ -2846,9 +2826,9 @@ TYPE * Core::get##TYPE() \ if(errorstate) return NULL;\ if(!s_mods.p##TYPE)\ {\ - Module * mod = create##TYPE();\ - s_mods.p##TYPE = (TYPE *) mod;\ - allModules.push_back(mod);\ + std::unique_ptr mod = create##TYPE();\ + s_mods.p##TYPE = (TYPE *) mod.get();\ + allModules.push_back(std::move(mod));\ }\ return s_mods.p##TYPE;\ } diff --git a/library/DataStatics.cpp b/library/DataStatics.cpp index 1e4b21be9a..31c8c02002 100644 --- a/library/DataStatics.cpp +++ b/library/DataStatics.cpp @@ -17,7 +17,7 @@ namespace { } #define INIT_GLOBAL_FUNCTION_PREFIX \ - DFHack::VersionInfo *global_table_ = DFHack::Core::getInstance().vinfo; \ + DFHack::VersionInfo *global_table_ = DFHack::Core::getInstance().vinfo.get(); \ void * tmp_; #define INIT_GLOBAL_FUNCTION_ITEM(type,name) \ diff --git a/library/LuaApi.cpp b/library/LuaApi.cpp index a435c7a8ef..2840aa5b9f 100644 --- a/library/LuaApi.cpp +++ b/library/LuaApi.cpp @@ -2521,7 +2521,7 @@ static const LuaWrapper::FunctionReg dfhack_internal_module[] = { static int internal_getmd5(lua_State *L) { - auto p = Core::getInstance().p; + auto& p = Core::getInstance().p; if (p->getDescriptor()->getOS() == OS_WINDOWS) luaL_error(L, "process MD5 not available on Windows"); lua_pushstring(L, p->getMD5().c_str()); @@ -2530,7 +2530,7 @@ static int internal_getmd5(lua_State *L) static int internal_getPE(lua_State *L) { - auto p = Core::getInstance().p; + auto& p = Core::getInstance().p; if (p->getDescriptor()->getOS() != OS_WINDOWS) luaL_error(L, "process PE timestamp not available on non-Windows"); lua_pushinteger(L, p->getPE()); diff --git a/library/Process-darwin.cpp b/library/Process-darwin.cpp index 2091d9a966..4e1abc1086 100644 --- a/library/Process-darwin.cpp +++ b/library/Process-darwin.cpp @@ -48,7 +48,7 @@ using namespace std; #include using namespace DFHack; -Process::Process(VersionInfoFactory * known_versions) +Process::Process(const VersionInfoFactory& known_versions) : identified(false), my_pe(0) { int target_result; @@ -59,10 +59,6 @@ Process::Process(VersionInfoFactory * known_versions) real_path = realpath(path, NULL); } - identified = false; - my_descriptor = 0; - my_pe = 0; - md5wrapper md5; uint32_t length; uint8_t first_kb [1024]; @@ -70,10 +66,10 @@ Process::Process(VersionInfoFactory * known_versions) // get hash of the running DF process my_md5 = md5.getHashFromFile(real_path, length, (char *) first_kb); // create linux process, add it to the vector - VersionInfo * vinfo = known_versions->getVersionInfoByMD5(my_md5); + auto vinfo = known_versions.getVersionInfoByMD5(my_md5); if(vinfo) { - my_descriptor = new VersionInfo(*vinfo); + my_descriptor = std::make_shared(*vinfo); identified = true; } else @@ -112,8 +108,7 @@ Process::Process(VersionInfoFactory * known_versions) Process::~Process() { - // destroy our copy of the memory descriptor - delete my_descriptor; + // Nothing to do here } string Process::doReadClassName (void * vptr) diff --git a/library/Process-linux.cpp b/library/Process-linux.cpp index fa06d28e47..a7f09a7f64 100644 --- a/library/Process-linux.cpp +++ b/library/Process-linux.cpp @@ -46,7 +46,7 @@ using namespace std; #include using namespace DFHack; -Process::Process(VersionInfoFactory * known_versions) +Process::Process(const VersionInfoFactory& known_versions) : identified(false), my_pe(0) { const char * dir_name = "/proc/self/"; const char * exe_link_name = "/proc/self/exe"; @@ -54,10 +54,6 @@ Process::Process(VersionInfoFactory * known_versions) const char * cmdline_name = "/proc/self/cmdline"; int target_result; - identified = false; - my_descriptor = 0; - my_pe = 0; - // valgrind replaces readlink for /proc/self/exe, but not open. char self_exe[1024]; memset(self_exe, 0, sizeof(self_exe)); @@ -74,10 +70,10 @@ Process::Process(VersionInfoFactory * known_versions) // get hash of the running DF process my_md5 = md5.getHashFromFile(self_exe_name, length, (char *) first_kb); // create linux process, add it to the vector - VersionInfo * vinfo = known_versions->getVersionInfoByMD5(my_md5); + auto vinfo = known_versions.getVersionInfoByMD5(my_md5); if(vinfo) { - my_descriptor = new VersionInfo(*vinfo); + my_descriptor = std::make_shared(*vinfo); identified = true; } else @@ -116,8 +112,7 @@ Process::Process(VersionInfoFactory * known_versions) Process::~Process() { - // destroy our copy of the memory descriptor - delete my_descriptor; + // Nothing to do here } string Process::doReadClassName (void * vptr) diff --git a/library/Process-windows.cpp b/library/Process-windows.cpp index 3a1da0ac49..9e3b7d1fbc 100644 --- a/library/Process-windows.cpp +++ b/library/Process-windows.cpp @@ -62,13 +62,11 @@ namespace DFHack char * base; }; } -Process::Process(VersionInfoFactory * factory) +Process::Process(const VersionInfoFactory& factory) : identified(false) { HMODULE hmod = NULL; DWORD needed; bool found = false; - identified = false; - my_descriptor = NULL; d = new PlatformSpecific(); // open process @@ -97,12 +95,12 @@ Process::Process(VersionInfoFactory * factory) return; } my_pe = d->pe_header.FileHeader.TimeDateStamp; - VersionInfo* vinfo = factory->getVersionInfoByPETimestamp(my_pe); + auto vinfo = factory.getVersionInfoByPETimestamp(my_pe); if(vinfo) { identified = true; // give the process a data model and memory layout fixed for the base of first module - my_descriptor = new VersionInfo(*vinfo); + my_descriptor = std::make_shared(*vinfo); my_descriptor->rebaseTo(getBase()); } else @@ -115,7 +113,6 @@ Process::Process(VersionInfoFactory * factory) Process::~Process() { // destroy our rebased copy of the memory descriptor - delete my_descriptor; if(d->sections != NULL) free(d->sections); } diff --git a/library/VersionInfoFactory.cpp b/library/VersionInfoFactory.cpp index c895a1510d..4202df5bb7 100644 --- a/library/VersionInfoFactory.cpp +++ b/library/VersionInfoFactory.cpp @@ -52,33 +52,28 @@ VersionInfoFactory::~VersionInfoFactory() void VersionInfoFactory::clear() { - // for each stored version, delete - for(size_t i = 0; i < versions.size();i++) - { - delete versions[i]; - } versions.clear(); error = false; } -VersionInfo * VersionInfoFactory::getVersionInfoByMD5(string hash) +std::shared_ptr VersionInfoFactory::getVersionInfoByMD5(string hash) const { - for(size_t i = 0; i < versions.size();i++) + for (const auto& version : versions) { - if(versions[i]->hasMD5(hash)) - return versions[i]; + if(version->hasMD5(hash)) + return version; } - return 0; + return nullptr; } -VersionInfo * VersionInfoFactory::getVersionInfoByPETimestamp(uintptr_t timestamp) +std::shared_ptr VersionInfoFactory::getVersionInfoByPETimestamp(uintptr_t timestamp) const { - for(size_t i = 0; i < versions.size();i++) + for (const auto& version : versions) { - if(versions[i]->hasPE(timestamp)) - return versions[i]; + if(version->hasPE(timestamp)) + return version; } - return 0; + return nullptr; } void VersionInfoFactory::ParseVersion (TiXmlElement* entry, VersionInfo* mem) @@ -230,8 +225,8 @@ bool VersionInfoFactory::loadFile(string path_to_xml) const char *name = pMemInfo->Attribute("name"); if(name) { - VersionInfo *version = new VersionInfo(); - ParseVersion( pMemInfo , version ); + auto version = std::make_shared(); + ParseVersion( pMemInfo , version.get() ); versions.push_back(version); } } diff --git a/library/include/Core.h b/library/include/Core.h index 529633ff21..0fec2774d4 100644 --- a/library/include/Core.h +++ b/library/include/Core.h @@ -30,6 +30,7 @@ distribution. #include #include #include +#include #include #include "Console.h" #include "modules/Graphic.h" @@ -135,7 +136,6 @@ namespace DFHack /// Get the single Core instance or make one. static Core& getInstance() { - // FIXME: add critical section for thread safety here. static Core instance; return instance; } @@ -191,8 +191,8 @@ namespace DFHack DFHack::Console &getConsole() { return con; } - DFHack::Process * p; - DFHack::VersionInfo * vinfo; + std::unique_ptr p; + std::shared_ptr vinfo; DFHack::Windows::df_window * screen_window; static void print(const char *format, ...) Wformat(printf,1,2); @@ -209,7 +209,7 @@ namespace DFHack ~Core(); struct Private; - Private *d; + std::unique_ptr d; bool Init(); int Update (void); @@ -235,7 +235,7 @@ namespace DFHack struct Cond; // FIXME: shouldn't be kept around like this - DFHack::VersionInfoFactory * vif; + std::unique_ptr vif; // Module storage struct { @@ -243,7 +243,7 @@ namespace DFHack Notes * pNotes; Graphic * pGraphic; } s_mods; - std::vector allModules; + std::vector> allModules; DFHack::PluginManager * plug_mgr; std::vector script_paths[2]; diff --git a/library/include/MemAccess.h b/library/include/MemAccess.h index 3022688f92..7f3be74dff 100644 --- a/library/include/MemAccess.h +++ b/library/include/MemAccess.h @@ -33,10 +33,12 @@ distribution. #include #include #include +#include + +#include "VersionInfo.h" namespace DFHack { - struct VersionInfo; class Process; //class Window; class DFVector; @@ -78,7 +80,7 @@ namespace DFHack { public: /// this is the single most important destructor ever. ~px - Process(VersionInfoFactory * known_versions); + Process(const VersionInfoFactory& known_versions); ~Process(); /// read a 8-byte integer uint64_t readQuad(const void * address) @@ -246,10 +248,15 @@ namespace DFHack void getMemRanges(std::vector & ranges ); /// get the symbol table extension of this process - VersionInfo *getDescriptor() + std::shared_ptr getDescriptor() { return my_descriptor; }; + + void ValidateDescriptionOS() { + my_descriptor->ValidateOS(); + }; + uintptr_t getBase(); /// get the DF Process ID int getPID(); @@ -291,7 +298,7 @@ namespace DFHack std::string getMD5() { return my_md5; } private: - VersionInfo * my_descriptor; + std::shared_ptr my_descriptor; PlatformSpecific *d; bool identified; uint32_t my_pid; diff --git a/library/include/ModuleFactory.h b/library/include/ModuleFactory.h index 87c9a726f4..5c3c149a2c 100644 --- a/library/include/ModuleFactory.h +++ b/library/include/ModuleFactory.h @@ -27,13 +27,13 @@ distribution. #ifndef MODULE_FACTORY_H_INCLUDED #define MODULE_FACTORY_H_INCLUDED +#include + namespace DFHack { class Module; - Module* createGui(); - Module* createWorld(); - Module* createMaterials(); - Module* createNotes(); - Module* createGraphic(); + std::unique_ptr createMaterials(); + std::unique_ptr createNotes(); + std::unique_ptr createGraphic(); } #endif diff --git a/library/include/VersionInfo.h b/library/include/VersionInfo.h index dc959f1db0..0d069c00cd 100644 --- a/library/include/VersionInfo.h +++ b/library/include/VersionInfo.h @@ -26,6 +26,7 @@ distribution. #pragma once #include +#include #include #include #include @@ -169,5 +170,19 @@ namespace DFHack { return OS; }; + + void ValidateOS() { +#if defined(_WIN32) + const OSType expected = OS_WINDOWS; +#elif defined(_DARWIN) + const OSType expected = OS_APPLE; +#else + const OSType expected = OS_LINUX; +#endif + if (expected != getOS()) { + std::cerr << "OS mismatch; resetting to " << int(expected) << std::endl; + setOS(expected); + } + } }; } diff --git a/library/include/VersionInfoFactory.h b/library/include/VersionInfoFactory.h index 8a2cabdc36..a6b1a17d5d 100644 --- a/library/include/VersionInfoFactory.h +++ b/library/include/VersionInfoFactory.h @@ -25,6 +25,8 @@ distribution. #pragma once +#include + #include "Pragma.h" #include "Export.h" @@ -39,12 +41,12 @@ namespace DFHack ~VersionInfoFactory(); bool loadFile( std::string path_to_xml); bool isInErrorState() const {return error;}; - VersionInfo * getVersionInfoByMD5(std::string md5string); - VersionInfo * getVersionInfoByPETimestamp(uintptr_t timestamp); - std::vector versions; + std::shared_ptr getVersionInfoByMD5(std::string md5string) const; + std::shared_ptr getVersionInfoByPETimestamp(uintptr_t timestamp) const; // trash existing list void clear(); private: + std::vector> versions; void ParseVersion (TiXmlElement* version, VersionInfo* mem); bool error; }; diff --git a/library/modules/Graphic.cpp b/library/modules/Graphic.cpp index e965bc7e17..1d84926e34 100644 --- a/library/modules/Graphic.cpp +++ b/library/modules/Graphic.cpp @@ -36,14 +36,15 @@ using namespace std; #include "Error.h" #include "VersionInfo.h" #include "MemAccess.h" +#include "MiscUtils.h" #include "ModuleFactory.h" #include "Core.h" using namespace DFHack; -Module* DFHack::createGraphic() +std::unique_ptr DFHack::createGraphic() { - return new Graphic(); + return dts::make_unique(); } struct Graphic::Private diff --git a/library/modules/Materials.cpp b/library/modules/Materials.cpp index a8f10d7d23..51d717d05c 100644 --- a/library/modules/Materials.cpp +++ b/library/modules/Materials.cpp @@ -592,12 +592,11 @@ bool DFHack::isStoneInorganic(int material) return true; } -Module* DFHack::createMaterials() +std::unique_ptr DFHack::createMaterials() { - return new Materials(); + return dts::make_unique(); } - Materials::Materials() { } diff --git a/library/modules/Notes.cpp b/library/modules/Notes.cpp index b5215102fd..04fb59e4dc 100644 --- a/library/modules/Notes.cpp +++ b/library/modules/Notes.cpp @@ -33,6 +33,7 @@ using namespace std; #include "Types.h" #include "Error.h" #include "MemAccess.h" +#include "MiscUtils.h" #include "ModuleFactory.h" #include "Core.h" #include "modules/Notes.h" @@ -40,9 +41,9 @@ using namespace std; #include "df/ui.h" using namespace DFHack; -Module* DFHack::createNotes() +std::unique_ptr DFHack::createNotes() { - return new Notes(); + return dts::make_unique(); } // FIXME: not even a wrapper now