From f2dea86819253a5b86a4eb4c82101462b903e62d Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?Petr=20Mr=C3=A1zek?= Date: Sat, 28 Aug 2010 03:57:56 +0200 Subject: [PATCH] Seemingly working VersionInfo loading parts. The offset names are now all wrong in the modules. DO NOT USE --- data/Memory-ng.xml | 29 ++- library/CMakeLists.txt | 2 +- library/DFContextManager.cpp | 2 +- library/DFProcess-linux.cpp | 1 + library/DFProcessEnumerator.cpp | 2 +- library/VersionInfo.cpp | 214 ++++++++++++------ library/VersionInfoFactory.cpp | 208 ++++++++++++++--- library/include/dfhack/DFError.h | 52 +++-- library/include/dfhack/VersionInfo.h | 56 ++--- .../dfhack}/VersionInfoFactory.h | 5 +- tools/supported/dumpoffsets.cpp | 23 +- 11 files changed, 412 insertions(+), 182 deletions(-) rename library/{private => include/dfhack}/VersionInfoFactory.h (92%) diff --git a/data/Memory-ng.xml b/data/Memory-ng.xml index 294886988..100a2657b 100644 --- a/data/Memory-ng.xml +++ b/data/Memory-ng.xml @@ -813,6 +813,9 @@ +
+ @@ -1407,7 +1410,7 @@ - +
@@ -1603,7 +1606,7 @@ - +
@@ -1618,18 +1621,18 @@ 0x92d7a10 - + - + - + - + @@ -1647,17 +1650,19 @@ - + -
VERIFIED -
VERIFIED -
VERIFIED -
VERIFIED + +
VERIFIED +
VERIFIED +
VERIFIED +
VERIFIED + - + diff --git a/library/CMakeLists.txt b/library/CMakeLists.txt index de869ddbc..6bd4815a6 100644 --- a/library/CMakeLists.txt +++ b/library/CMakeLists.txt @@ -27,10 +27,10 @@ include_directories (${CMAKE_SOURCE_DIR}/library/depends/argstream/) include_directories (${CMAKE_SOURCE_DIR}/library/private/) SET(PROJECT_HDRS -private/VersionInfoFactory.h private/ContextShared.h private/Internal.h include/dfhack/DFError.h +include/dfhack/VersionInfoFactory.h include/dfhack/VersionInfo.h include/dfhack/DFProcessEnumerator.h include/dfhack/DFProcess.h diff --git a/library/DFContextManager.cpp b/library/DFContextManager.cpp index 62f6ec351..f338ce6ee 100644 --- a/library/DFContextManager.cpp +++ b/library/DFContextManager.cpp @@ -23,8 +23,8 @@ distribution. */ #include "Internal.h" -#include "VersionInfoFactory.h" +#include "dfhack/VersionInfoFactory.h" #include "dfhack/DFProcess.h" #include "dfhack/DFProcessEnumerator.h" #include "dfhack/DFError.h" diff --git a/library/DFProcess-linux.cpp b/library/DFProcess-linux.cpp index 9339685cb..164834543 100644 --- a/library/DFProcess-linux.cpp +++ b/library/DFProcess-linux.cpp @@ -120,6 +120,7 @@ bool NormalProcess::Private::validate(char * exe_file,uint32_t pid, char * memFi { try { + //cout << hash << " ?= " << (*it)->getMD5() << endl; if(hash == (*it)->getMD5()) // are the md5 hashes the same? { VersionInfo * m = *it; diff --git a/library/DFProcessEnumerator.cpp b/library/DFProcessEnumerator.cpp index 19164be88..b790cb0dd 100644 --- a/library/DFProcessEnumerator.cpp +++ b/library/DFProcessEnumerator.cpp @@ -23,8 +23,8 @@ distribution. */ #include "Internal.h" -#include "VersionInfoFactory.h" +#include "dfhack/VersionInfoFactory.h" #include "dfhack/DFProcessEnumerator.h" #include "dfhack/DFProcess.h" #include "dfhack/VersionInfo.h" diff --git a/library/VersionInfo.cpp b/library/VersionInfo.cpp index 57cd54c7b..e5c6873f9 100644 --- a/library/VersionInfo.cpp +++ b/library/VersionInfo.cpp @@ -87,132 +87,195 @@ namespace DFHack */ namespace DFHack { + typedef pair nullableUint32; + typedef map ::iterator uint32_Iter; + typedef pair nullableInt32; + typedef map ::iterator int32_Iter; + typedef pair nullableString; + typedef map ::iterator strings_Iter; + typedef map ::iterator groups_Iter; class OffsetGroupPrivate { public: - map addresses; - map offsets; - map hexvals; - map strings; - map groups; + map addresses; + map hexvals; + map offsets; + map strings; + map groups; }; } +void OffsetGroup::createOffset(const string & key) +{ + OGd->offsets[key] = nullableInt32(false, 0); +} + +void OffsetGroup::createAddress(const string & key) +{ + OGd->addresses[key] = nullableUint32(false, 0); +} + +void OffsetGroup::createHexValue(const string & key) +{ + OGd->hexvals[key] = nullableUint32(false, 0); +} + +void OffsetGroup::createString(const string & key) +{ + OGd->strings[key] = nullableString(false, std::string()); +} void OffsetGroup::setOffset (const string & key, const string & value) { - int32_t offset = strtol(value.c_str(), NULL, 16); - d->offsets[key] = offset; + int32_Iter it; + if((it = OGd->offsets.find(key)) != OGd->offsets.end()) + { + int32_t offset = strtol(value.c_str(), NULL, 16); + (*it).second.second = offset; + (*it).second.first = true; + } + else throw Error::MissingMemoryDefinition("offset", key); } void OffsetGroup::setAddress (const string & key, const string & value) { - uint32_t address = strtol(value.c_str(), NULL, 16); - d->addresses[key] = address; + uint32_Iter it; + if((it = OGd->addresses.find(key)) != OGd->addresses.end()) + { + int32_t address = strtol(value.c_str(), NULL, 16); + (*it).second.second = address; + (*it).second.first = true; + } + else throw Error::MissingMemoryDefinition("address", key); } void OffsetGroup::setHexValue (const string & key, const string & value) { - uint32_t hexval = strtol(value.c_str(), NULL, 16); - d->hexvals[key] = hexval; + uint32_Iter it; + if((it = OGd->hexvals.find(key)) != OGd->hexvals.end()) + { + (*it).second.second = strtol(value.c_str(), NULL, 16); + (*it).second.first = true; + } + else throw Error::MissingMemoryDefinition("hexvalue", key); } void OffsetGroup::setString (const string & key, const string & value) { - d->strings[key] = value; + strings_Iter it; + if((it = OGd->strings.find(key)) != OGd->strings.end()) + { + (*it).second.second = value; + (*it).second.first = true; + } + else throw Error::MissingMemoryDefinition("string", key); } // Get named address -uint32_t OffsetGroup::getAddress (const char *key) +uint32_t OffsetGroup::getAddress (const string & key) { - map ::iterator iter = d->addresses.find(key); + uint32_Iter iter = OGd->addresses.find(key); - if(iter != d->addresses.end()) + if(iter != OGd->addresses.end()) { - return (*iter).second; + if((*iter).second.first) + return (*iter).second.second; + throw Error::UnsetMemoryDefinition("address", key); } throw Error::MissingMemoryDefinition("address", key); } // Get named offset -int32_t OffsetGroup::getOffset (const char *key) +int32_t OffsetGroup::getOffset (const string & key) { - map ::iterator iter = d->offsets.find(key); - if(iter != d->offsets.end()) + int32_Iter iter = OGd->offsets.find(key); + if(iter != OGd->offsets.end()) { - return (*iter).second; + if((*iter).second.first) + return (*iter).second.second; + throw Error::UnsetMemoryDefinition("offset", key); } throw Error::MissingMemoryDefinition("offset", key); } // Get named numerical value -uint32_t OffsetGroup::getHexValue (const char *key) +uint32_t OffsetGroup::getHexValue (const string & key) { - map ::iterator iter = d->hexvals.find(key); - if(iter != d->hexvals.end()) + uint32_Iter iter = OGd->hexvals.find(key); + if(iter != OGd->hexvals.end()) { - return (*iter).second; + if((*iter).second.first) + return (*iter).second.second; + throw Error::UnsetMemoryDefinition("hexvalue", key); } throw Error::MissingMemoryDefinition("hexvalue", key); } - -// Get named address -uint32_t OffsetGroup::getAddress (const string &key) +// Get named string +std::string OffsetGroup::getString (const string &key) { - map ::iterator iter = d->addresses.find(key); - - if(iter != d->addresses.end()) + strings_Iter iter = OGd->strings.find(key); + if(iter != OGd->strings.end()) { - return (*iter).second; + if((*iter).second.first) + return (*iter).second.second; + throw Error::UnsetMemoryDefinition("string", key); } - throw Error::MissingMemoryDefinition("address", key.c_str()); + throw Error::MissingMemoryDefinition("string", key); } - -// Get named offset -int32_t OffsetGroup::getOffset (const string &key) +OffsetGroup * OffsetGroup::getGroup(const std::string &name) { - map ::iterator iter = d->offsets.find(key); - if(iter != d->offsets.end()) - { - return (*iter).second; - } - throw Error::MissingMemoryDefinition("offset", key.c_str()); + groups_Iter iter = OGd->groups.find(name); + if(iter != OGd->groups.end()) + return ((*iter).second); + return 0; } +OffsetGroup * OffsetGroup::createGroup(const std::string &name) +{ + OffsetGroup * ret = getGroup(name); + if(ret) + return ret; + ret = new OffsetGroup(); + OGd->groups[name] = ret; + return ret; +} -// Get named numerical value -uint32_t OffsetGroup::getHexValue (const string &key) +void OffsetGroup::RebaseAddresses(int32_t offset) { - map ::iterator iter = d->hexvals.find(key); - if(iter != d->hexvals.end()) + for(uint32_Iter iter = OGd->addresses.begin(); iter != OGd->addresses.end(); iter++) + { + if(iter->second.first) + OGd->addresses[iter->first].second = iter->second.second + offset; + } + for(groups_Iter iter = OGd->groups.begin(); iter != OGd->groups.end(); iter++) { - return (*iter).second; + (*iter).second->RebaseAddresses(offset); } - throw Error::MissingMemoryDefinition("hexvalue", key.c_str()); } +OffsetGroup::OffsetGroup() +{ + OGd = new OffsetGroupPrivate(); +} -// Get named string -std::string OffsetGroup::getString (const string &key) +OffsetGroup::~OffsetGroup() { - map ::iterator iter = d->strings.find(key); - if(iter != d->strings.end()) + for(groups_Iter it = OGd->groups.begin();it != OGd->groups.end();it++) { - return (*iter).second; + delete (*it).second; } - throw Error::MissingMemoryDefinition("string", key.c_str()); + OGd->groups.clear(); + delete OGd; } - - /* * Private data */ @@ -221,11 +284,6 @@ namespace DFHack class VersionInfoPrivate { public: - map addresses; - map offsets; - map hexvals; - map strings; - vector professions; vector jobs; vector skills; @@ -277,16 +335,26 @@ VersionInfo::VersionInfo(const VersionInfo &old) copy(&old); } +void OffsetGroup::copy(const OffsetGroup * old) +{ + OGd->addresses = old->OGd->addresses; + OGd->offsets = old->OGd->offsets; + OGd->hexvals = old->OGd->hexvals; + OGd->strings = old->OGd->strings; + for(groups_Iter it = old->OGd->groups.begin(); it != old->OGd->groups.end(); it++) + { + OffsetGroup * ogn = new OffsetGroup(); + ogn->copy((*it).second); + OGd->groups[(*it).first] = ogn; + } +} + void VersionInfo::copy(const VersionInfo * old) { d->version = old->d->version; d->OS = old->d->OS; d->md5 = old->d->md5; d->PE_timestamp = old->d->PE_timestamp; - d->addresses = old->d->addresses; - d->offsets = old->d->offsets; - d->hexvals = old->d->hexvals; - d->strings = old->d->strings; d->base = old->d->base; //d->classes = old.d->classes; for(uint32_t i = 0; i < old->d->classes.size(); i++) @@ -303,6 +371,7 @@ void VersionInfo::copy(const VersionInfo * old) d->labors = old->d->labors; d->levels = old->d->levels; d->moods = old->d->moods; + OffsetGroup::copy(reinterpret_cast(old)); } void VersionInfo::setParentProcess(Process * _p) @@ -677,12 +746,7 @@ const vector * VersionInfo::getClassIDMapping() // change base of all addresses void VersionInfo::RebaseAddresses(const int32_t new_base) { - map::iterator iter; - int32_t rebase = - (int32_t)d->base + new_base; - for(iter = d->addresses.begin(); iter != d->addresses.end(); iter++) - { - d->addresses[iter->first] = iter->second + rebase; - } + OffsetGroup::RebaseAddresses(- (int32_t)d->base + new_base); } @@ -841,25 +905,27 @@ std::string VersionInfo::PrintOffsets() ss << " UNKNOWN" << endl; } ss << "" << endl; + /* map::const_iterator iter; - for(iter = d->addresses.begin(); iter != d->addresses.end(); iter++) + for(iter = OGd->addresses.begin(); iter != OGd->addresses.end(); iter++) { ss << "
" << endl; } map::const_iterator iter2; - for(iter2 = d->offsets.begin(); iter2 != d->offsets.end(); iter2++) + for(iter2 = OGd->offsets.begin(); iter2 != OGd->offsets.end(); iter2++) { ss << " " << endl; } - for(iter = d->hexvals.begin(); iter != d->hexvals.end(); iter++) + for(iter = OGd->hexvals.begin(); iter != OGd->hexvals.end(); iter++) { ss << " " << endl; } map::const_iterator iter3; - for(iter3 = d->strings.begin(); iter3 != d->strings.end(); iter3++) + for(iter3 = OGd->strings.begin(); iter3 != OGd->strings.end(); iter3++) { ss << " " << endl; } + */ ss << "" << endl; ss << "" << endl; return ss.str(); diff --git a/library/VersionInfoFactory.cpp b/library/VersionInfoFactory.cpp index 002b9ae4f..14076426b 100644 --- a/library/VersionInfoFactory.cpp +++ b/library/VersionInfoFactory.cpp @@ -23,10 +23,11 @@ distribution. */ #include "Internal.h" -#include "VersionInfoFactory.h" +#include "dfhack/VersionInfoFactory.h" #include "dfhack/VersionInfo.h" #include "dfhack/DFError.h" +#include using namespace DFHack; @@ -94,6 +95,167 @@ void VersionInfoFactory::ParseVTable(TiXmlElement* vtable, VersionInfo* mem) } } +// FIXME: this is ripe for replacement with a more generic approach +void VersionInfoFactory::ParseOffsets(TiXmlElement * parent, VersionInfo* target, bool initial) +{ + // we parse the groups iteratively instead of recursively + // breadcrubs acts like a makeshift stack + // first pair entry stores the current element of that level + // second pair entry the group object from OffsetGroup + typedef pair < TiXmlElement *, OffsetGroup * > groupPair; + vector< groupPair > breadcrumbs; + { + TiXmlElement* pEntry; + // we get the , look at the children + pEntry = parent->FirstChildElement(); + if(!pEntry) + return; + + OffsetGroup * currentGroup = reinterpret_cast (target); + breadcrumbs.push_back(groupPair(pEntry,currentGroup)); + } + + // work variables + OffsetGroup * currentGroup = 0; + TiXmlElement * currentElem = 0; + cerr << ""<< endl; + while(1) + { + // get current work variables + currentElem = breadcrumbs.back().first; + currentGroup = breadcrumbs.back().second; + + // we reached the end of the current group? + if(!currentElem) + { + // go one level up + breadcrumbs.pop_back(); + // exit if no more work + if(breadcrumbs.empty()) + { + break; + } + else + { + cerr << "" << endl; + continue; + } + } + + if(!currentGroup) + { + groupPair & gp = breadcrumbs.back(); + gp.first = gp.first->NextSiblingElement(); + continue; + } + + // skip non-elements + if (currentElem->Type() != TiXmlNode::ELEMENT) + { + groupPair & gp = breadcrumbs.back(); + gp.first = gp.first->NextSiblingElement(); + continue; + } + + // we have a valid current element and current group + // get properties + string type = currentElem->Value(); + std::transform(type.begin(), type.end(), type.begin(), ::tolower); + const char *cstr_name = currentElem->Attribute("name"); + if(!cstr_name) + { + // ERROR, missing attribute + } + + // evaluate elements + const char *cstr_value = currentElem->Attribute("value"); + if(type == "group") + { + // FIXME: possibly use setGroup always, with the initial flag as parameter? + // create or get group + OffsetGroup * og; + if(initial) + og = currentGroup->createGroup(cstr_name); + else + og = currentGroup->getGroup(cstr_name); + cerr << "" << endl; + // advance this level to the next element + groupPair & gp = breadcrumbs.back(); + gp.first = gp.first->NextSiblingElement(); + + // add a new level that will be processed next + breadcrumbs.push_back(groupPair(currentElem->FirstChildElement(), og)); + continue; + } + else if(type == "address") + { + if(initial) + { + currentGroup->createAddress(cstr_name); + } + else if(cstr_value) + { + currentGroup->setAddress(cstr_name, cstr_value); + } + else + { + // ERROR, missing attribute + } + } + else if(type == "offset") + { + if(initial) + { + currentGroup->createOffset(cstr_name); + } + else if(cstr_value) + { + currentGroup->setOffset(cstr_name, cstr_value); + } + else + { + // ERROR, missing attribute + } + } + else if(type == "string") + { + if(initial) + { + currentGroup->createString(cstr_name); + } + else if(cstr_value) + { + currentGroup->setString(cstr_name, cstr_value); + } + else + { + // ERROR, missing attribute + } + } + else if(type == "hexvalue") + { + if(initial) + { + currentGroup->createHexValue(cstr_name); + } + else if(cstr_value) + { + currentGroup->setHexValue(cstr_name, cstr_value); + } + else + { + // ERROR, missing attribute + } + } + + // advance to next element + groupPair & gp = breadcrumbs.back(); + gp.first = gp.first->NextSiblingElement(); + continue; + } + cerr << ""<< endl; +} + void VersionInfoFactory::ParseBase (TiXmlElement* entry, VersionInfo* mem) { TiXmlElement* pElement; @@ -121,12 +283,12 @@ void VersionInfoFactory::ParseBase (TiXmlElement* entry, VersionInfo* mem) else if(type == "Offsets") { // we don't care about the descriptions here, do nothing - //ParseBaseOffsets(pMemEntry, mem); + ParseOffsets(pElement, mem, true); continue; } else if (type == "Professions") { - pElement2nd = entry->FirstChildElement("Profession")->ToElement(); + pElement2nd = entry->FirstChildElement("Profession"); for(;pElement2nd;pElement2nd=pElement2nd->NextSiblingElement("Profession")) { const char * id = pElement2nd->Attribute("id"); @@ -145,7 +307,7 @@ void VersionInfoFactory::ParseBase (TiXmlElement* entry, VersionInfo* mem) } else if (type == "Jobs") { - pElement2nd = entry->FirstChildElement("Job")->ToElement(); + pElement2nd = entry->FirstChildElement("Job"); for(;pElement2nd;pElement2nd=pElement2nd->NextSiblingElement("Job")) { const char * id = pElement2nd->Attribute("id"); @@ -163,7 +325,7 @@ void VersionInfoFactory::ParseBase (TiXmlElement* entry, VersionInfo* mem) } else if (type == "Skills") { - pElement2nd = entry->FirstChildElement("Skill")->ToElement(); + pElement2nd = entry->FirstChildElement("Skill"); for(;pElement2nd;pElement2nd=pElement2nd->NextSiblingElement("Skill")) { const char * id = pElement2nd->Attribute("id"); @@ -181,7 +343,7 @@ void VersionInfoFactory::ParseBase (TiXmlElement* entry, VersionInfo* mem) } else if (type == "Traits") { - pElement2nd = entry->FirstChildElement("Trait")->ToElement(); + pElement2nd = entry->FirstChildElement("Trait"); for(;pElement2nd;pElement2nd=pElement2nd->NextSiblingElement("Trait")) { const char * id = pElement2nd->Attribute("id"); @@ -205,7 +367,7 @@ void VersionInfoFactory::ParseBase (TiXmlElement* entry, VersionInfo* mem) } else if (type == "Labors") { - pElement2nd = entry->FirstChildElement("Labor")->ToElement(); + pElement2nd = entry->FirstChildElement("Labor"); for(;pElement2nd;pElement2nd=pElement2nd->NextSiblingElement("Labor")) { const char * id = pElement2nd->Attribute("id"); @@ -223,7 +385,7 @@ void VersionInfoFactory::ParseBase (TiXmlElement* entry, VersionInfo* mem) } else if (type == "Levels") { - pElement2nd = entry->FirstChildElement("Level")->ToElement(); + pElement2nd = entry->FirstChildElement("Level"); for(;pElement2nd;pElement2nd=pElement2nd->NextSiblingElement("Level")) { const char * id = pElement2nd->Attribute("id"); @@ -242,7 +404,7 @@ void VersionInfoFactory::ParseBase (TiXmlElement* entry, VersionInfo* mem) } else if (type == "Moods") { - pElement2nd = entry->FirstChildElement("Mood")->ToElement(); + pElement2nd = entry->FirstChildElement("Mood"); for(;pElement2nd;pElement2nd=pElement2nd->NextSiblingElement("Mood")) { const char * id = pElement2nd->Attribute("id"); @@ -276,7 +438,6 @@ void VersionInfoFactory::EvalVersion(string base, VersionInfo * mem) VersionInfo * newmem = new VersionInfo(); ParseVersion(desc.first, newmem); desc.second = newmem; - versions.push_back(newmem); } mem->copy(desc.second); } @@ -345,29 +506,7 @@ void VersionInfoFactory::ParseVersion (TiXmlElement* entry, VersionInfo* mem) } else if(type == "Offsets") { - /* - if (type == "HexValue") - { - mem->setHexValue(name, value); - } - else if (type == "Address") - { - mem->setAddress(name, value); - } - else if (type == "Offset") - { - mem->setOffset(name, value); - } - else if (type == "String") - { - mem->setString(name, value); - } - else - { - throw Error::MemoryXmlUnknownType(type.c_str()); - } - */ - //ParseOffsets(pMemEntry, mem); + ParseOffsets(pMemEntry, mem); continue; } else if (type == "MD5") @@ -382,7 +521,7 @@ void VersionInfoFactory::ParseVersion (TiXmlElement* entry, VersionInfo* mem) const char *cstr_value = pMemEntry->Attribute("value"); if(!cstr_value) throw Error::MemoryXmlUnderspecifiedEntry(cstr_name); - mem->setPE(atol(cstr_value)); + mem->setPE(strtol(cstr_value, 0, 16)); } } // for } // method @@ -446,6 +585,7 @@ bool VersionInfoFactory::loadFile(string path_to_xml) { string str_name = name; VersionInfo *base = new VersionInfo(); + mem = new VersionInfo(); ParseBase( pMemInfo , mem ); knownVersions[str_name] = v_descr (pMemInfo, mem); } diff --git a/library/include/dfhack/DFError.h b/library/include/dfhack/DFError.h index 79823a9fa..6e967218f 100644 --- a/library/include/dfhack/DFError.h +++ b/library/include/dfhack/DFError.h @@ -78,10 +78,10 @@ namespace DFHack class DFHACK_EXPORT MissingMemoryDefinition : public std::exception { public: - MissingMemoryDefinition(const char* _type, const char* _key) : type(_type), key(_key) + MissingMemoryDefinition(const char* _type, const std::string _key) : type(_type), key(_key) { std::stringstream s; - s << "memory definition missing: type " << type << " key " << key; + s << "memory object not declared: type " << type << " key " << key; full = s.str(); } // Used by functios using integer keys, such as getTrait @@ -92,24 +92,44 @@ namespace DFHack key = s1.str(); std::stringstream s; - s << "memory definition missing: type " << type << " key " << key; + s << "memory object not declared: type " << type << " key " << key; full = s.str(); } virtual ~MissingMemoryDefinition() throw(){}; - // (perhaps it should be an enum, but this is intended for easy printing/logging) - // type can be any of the following: - // - // address - // offset - // hexvalue - // string - // profession - // job - // skill - // trait - // traitname - // labor + std::string full; + const std::string type; + std::string key; + + virtual const char* what() const throw() + { + return full.c_str(); + } + }; + + // a call to DFHack::mem_info::get* failed + class DFHACK_EXPORT UnsetMemoryDefinition : public std::exception + { + public: + UnsetMemoryDefinition(const char* _type, const std::string _key) : type(_type), key(_key) + { + std::stringstream s; + s << "memory object not set: type " << type << " key " << key; + full = s.str(); + } + // Used by functios using integer keys, such as getTrait + UnsetMemoryDefinition(const char* _type, uint32_t _key) : type(_type) + { + std::stringstream s1; + s1 << _key; + key = s1.str(); + + std::stringstream s; + s << "memory object not set: type " << type << " key " << key; + full = s.str(); + } + virtual ~UnsetMemoryDefinition() throw(){}; + std::string full; const std::string type; std::string key; diff --git a/library/include/dfhack/VersionInfo.h b/library/include/dfhack/VersionInfo.h index 7bc4f0c2e..e76fe65d1 100644 --- a/library/include/dfhack/VersionInfo.h +++ b/library/include/dfhack/VersionInfo.h @@ -39,38 +39,42 @@ namespace DFHack struct t_class; class VersionInfoPrivate; class OffsetGroupPrivate; + + /* + * Offset Group + */ class DFHACK_EXPORT OffsetGroup { protected: - OffsetGroupPrivate * d; + OffsetGroupPrivate * OGd; public: - int32_t getOffset (const std::string&); - uint32_t getAddress (const std::string&); - uint32_t getHexValue (const std::string&); - std::string getString (const std::string&); - - int32_t getOffset (const char *); - uint32_t getAddress (const char *); - uint32_t getHexValue (const char *); - std::string getString (const char *); - - void setOffset (const std::string &, const int32_t); - void setAddress (const std::string &, const uint32_t); - void setHexValue (const std::string &, const uint32_t); - - void setOffset (const std::string &, const char *); - void setAddress (const std::string &, const char *); - void setHexValue (const std::string &, const char *); - void setString (const std::string &, const char *); - - void setOffset (const std::string &, const std::string &); - void setAddress (const std::string &, const std::string &); - void setHexValue (const std::string &, const std::string &); - void setString (const std::string &, const std::string &); - - OffsetGroup & getGroup (const std::string name); + OffsetGroup(); + ~OffsetGroup(); + + void copy(const OffsetGroup * old); // recursive + void RebaseAddresses( int32_t offset ); // recursive + + void createOffset (const std::string & key); + void createAddress (const std::string & key); + void createHexValue (const std::string & key); + void createString (const std::string & key); + OffsetGroup * createGroup ( const std::string & name ); + + int32_t getOffset (const std::string & key); + uint32_t getAddress (const std::string & key); + uint32_t getHexValue (const std::string & key); + std::string getString (const std::string & key); + OffsetGroup * getGroup ( const std::string & name ); + + void setOffset (const std::string & key, const std::string & value); + void setAddress (const std::string & key, const std::string & value); + void setHexValue (const std::string & key, const std::string & value); + void setString (const std::string & key, const std::string & value); }; + /* + * Version Info + */ class DFHACK_EXPORT VersionInfo : public OffsetGroup { private: diff --git a/library/private/VersionInfoFactory.h b/library/include/dfhack/VersionInfoFactory.h similarity index 92% rename from library/private/VersionInfoFactory.h rename to library/include/dfhack/VersionInfoFactory.h index 36c1cbd78..7f811f588 100644 --- a/library/private/VersionInfoFactory.h +++ b/library/include/dfhack/VersionInfoFactory.h @@ -26,12 +26,13 @@ distribution. #define MEMINFO_MANAGER_H_INCLUDED #include "dfhack/DFPragma.h" +#include "dfhack/DFExport.h" class TiXmlElement; namespace DFHack { class VersionInfo; - class VersionInfoFactory + class DFHACK_EXPORT VersionInfoFactory { friend class ProcessEnumerator; public: @@ -47,6 +48,8 @@ namespace DFHack void ParseVersion (TiXmlElement* version, VersionInfo* mem); // copy version 'base' to 'target' or throw void EvalVersion(std::string base, VersionInfo* target); + void ParseOffsets(TiXmlElement* elem, VersionInfo* target, bool initial = false); + bool error; typedef std::pair < TiXmlElement *, VersionInfo *> v_descr; std::map knownVersions; diff --git a/tools/supported/dumpoffsets.cpp b/tools/supported/dumpoffsets.cpp index f2d8d12b7..963cffcbb 100644 --- a/tools/supported/dumpoffsets.cpp +++ b/tools/supported/dumpoffsets.cpp @@ -8,31 +8,22 @@ using namespace std; #include +#include using namespace DFHack; int main (int numargs, const char ** args) { - DFHack::ContextManager DFMgr("Memory.xml"); - DFHack::Context * DF; - try - { - DF = DFMgr.getSingleContext(); - DF->Attach(); - } - catch (exception& e) + + DFHack::VersionInfoFactory * VIF = new DFHack::VersionInfoFactory("Memory.xml"); + for(int i = 0; i < VIF->versions.size(); i++) { - cerr << e.what() << endl; - #ifndef LINUX_BUILD - cin.ignore(); - #endif - return 1; + cout << VIF->versions[i]->PrintOffsets(); } - VersionInfo * minfo = DF->getMemoryInfo(); - if(minfo) - cout << minfo->PrintOffsets(); + #ifndef LINUX_BUILD cout << "Done. Press any key to continue" << endl; cin.ignore(); #endif + delete VIF; return 0; }