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;
}