Merge branch 'errorhandling' of git://github.com/mizipzor/dfhack

develop
Petr Mrázek 2010-03-01 01:13:07 +01:00
commit 0a23757797
3 changed files with 150 additions and 69 deletions

@ -108,7 +108,96 @@ namespace DFHack
virtual const char* what() const throw()
{
return "memory definition missing";
std::stringstream s;
s << "memory definition missing: type " << type << " key " << key;
return s.str().c_str();
}
};
// Syntax errors and whatnot, the xml cant be read
class DFHACK_EXPORT MemoryXmlParse : public std::exception
{
public:
MemoryXmlParse(const char* _desc, int _id, int _row, int _col) :
desc(_desc), id(_id), row(_row), col(_col) {}
const std::string desc;
const int id;
const int row;
const int col;
virtual const char* what() const throw()
{
std::stringstream s;
s << "error " << id << ": " << desc << ", at row " << row << " col " << col;
return s.str().c_str();
}
};
class DFHACK_EXPORT MemoryXmlBadAttribute : public std::exception
{
public:
MemoryXmlBadAttribute(const char* _attr) : attr(_attr) {}
std::string attr;
virtual const char* what() const throw()
{
std::stringstream s;
s << "attribute is either missing or invalid: " << attr;
return s.str().c_str();
}
};
class DFHACK_EXPORT MemoryXmlNoRoot : public std::exception
{
public:
MemoryXmlNoRoot() {}
virtual const char* what() const throw()
{
return "no pElem found";
}
};
class DFHACK_EXPORT MemoryXmlNoDFExtractor : public std::exception
{
public:
MemoryXmlNoDFExtractor(const char* _name) : name(_name) {}
std::string name;
virtual const char* what() const throw()
{
std::stringstream s;
s << "DFExtractor != " << name;
return s.str().c_str();
}
};
class DFHACK_EXPORT MemoryXmlUnderspecifiedEntry : public std::exception
{
public:
MemoryXmlUnderspecifiedEntry() {}
virtual const char* what() const throw()
{
return "underspecified MemInfo entry, each entry needs to set both the name attribute and have a value";
}
};
class DFHACK_EXPORT MemoryXmlUnknownType : public std::exception
{
public:
MemoryXmlUnknownType(const char* _type) : type(_type) {}
std::string type;
virtual const char* what() const throw()
{
std::stringstream s;
s << "unknown MemInfo type: " << type;
return s.str().c_str();
}
};
}

@ -1419,6 +1419,7 @@ bool API::InitViewAndCursor()
}
catch (Error::MissingMemoryDefinition&)
{
d->cursorWindowInited = false;
throw;
}
}
@ -1434,6 +1435,7 @@ bool API::InitViewSize()
}
catch (Error::MissingMemoryDefinition&)
{
d->viewSizeInited = false;
throw;
}
}

@ -101,14 +101,12 @@ void MemInfoManager::ParseEntry (TiXmlElement* entry, memory_info* mem, map <str
string base = cstr_base;
ParseEntry(knownEntries[base], mem, knownEntries);
}
if (!cstr_version)
throw Error::MemoryXmlBadAttribute("version");
if (!cstr_os)
throw Error::MemoryXmlBadAttribute("os");
// mandatory attributes missing?
if(!(cstr_version && cstr_os))
{
cerr << "Bad entry in memory.xml detected, version or os attribute is missing.";
// skip if we don't have valid attributes
return;
}
string os = cstr_os;
mem->setVersion(cstr_version);
mem->setOS(cstr_os);
@ -139,8 +137,7 @@ void MemInfoManager::ParseEntry (TiXmlElement* entry, memory_info* mem, map <str
}
else
{
cerr << "unknown operating system " << os << endl;
return;
throw Error::MemoryXmlBadAttribute("os");
}
// process additional entries
@ -160,10 +157,9 @@ void MemInfoManager::ParseEntry (TiXmlElement* entry, memory_info* mem, map <str
ParseVTable(pMemEntry, mem);
continue;
}
if( !(cstr_name && cstr_value))
if(!(cstr_name && cstr_value))
{
cerr << "underspecified MemInfo entry" << endl;
continue;
throw Error::MemoryXmlUnderspecifiedEntry();
}
name = cstr_name;
value = cstr_value;
@ -205,7 +201,7 @@ void MemInfoManager::ParseEntry (TiXmlElement* entry, memory_info* mem, map <str
}
else
{
cerr << "Unknown MemInfo type: " << type << endl;
throw Error::MemoryXmlUnknownType(type.c_str());
}
} // for
} // method
@ -220,71 +216,65 @@ MemInfoManager::MemInfoManager(string path_to_xml)
bool MemInfoManager::loadFile(string path_to_xml)
{
TiXmlDocument doc( path_to_xml.c_str() );
bool loadOkay = doc.LoadFile();
//bool loadOkay = doc.LoadFile();
if (!doc.LoadFile())
{
error = true;
throw Error::MemoryXmlParse(doc.ErrorDesc(), doc.ErrorId(), doc.ErrorRow(), doc.ErrorCol());
}
TiXmlHandle hDoc(&doc);
TiXmlElement* pElem;
TiXmlHandle hRoot(0);
memory_info mem;
if ( loadOkay )
// block: name
{
// block: name
pElem=hDoc.FirstChildElement().Element();
// should always have a valid root but handle gracefully if it does
if (!pElem)
{
pElem=hDoc.FirstChildElement().Element();
// should always have a valid root but handle gracefully if it does
if (!pElem)
{
cerr << "no pElem found" << endl;
return false;
}
string m_name=pElem->Value();
if(m_name != "DFExtractor")
{
cerr << "DFExtractor != " << m_name << endl;
return false;
}
//cout << "got DFExtractor XML!" << endl;
// save this for later
hRoot=TiXmlHandle(pElem);
error = true;
throw Error::MemoryXmlNoRoot();
}
// transform elements
string m_name=pElem->Value();
if(m_name != "DFExtractor")
{
// trash existing list
for(int i = 0; i < meminfo.size(); i++)
{
delete meminfo[i];
}
meminfo.clear();
TiXmlElement* pMemInfo=hRoot.FirstChild( "MemoryDescriptors" ).FirstChild( "Entry" ).Element();
map <string ,TiXmlElement *> map_pNamedEntries;
vector <TiXmlElement *> v_pEntries;
for( ; pMemInfo; pMemInfo=pMemInfo->NextSiblingElement("Entry"))
{
v_pEntries.push_back(pMemInfo);
const char *id = pMemInfo->Attribute("id");
if(id)
{
string str_id = id;
map_pNamedEntries[str_id] = pMemInfo;
}
}
for(uint32_t i = 0; i< v_pEntries.size();i++)
{
memory_info *mem = new memory_info();
//FIXME: add a set of entries processed in a step of this cycle, use it to check for infinite loops
/* recursive */ParseEntry( v_pEntries[i] , mem , map_pNamedEntries);
meminfo.push_back(mem);
}
// process found things here
error = true;
throw Error::MemoryXmlNoDFExtractor(m_name.c_str());
}
error = false;
return true;
// save this for later
hRoot=TiXmlHandle(pElem);
}
else
// transform elements
{
// load failed
cerr << "Can't load memory offsets from memory.xml" << endl;
error = true;
return false;
// trash existing list
for(int i = 0; i < meminfo.size(); i++)
{
delete meminfo[i];
}
meminfo.clear();
TiXmlElement* pMemInfo=hRoot.FirstChild( "MemoryDescriptors" ).FirstChild( "Entry" ).Element();
map <string ,TiXmlElement *> map_pNamedEntries;
vector <TiXmlElement *> v_pEntries;
for( ; pMemInfo; pMemInfo=pMemInfo->NextSiblingElement("Entry"))
{
v_pEntries.push_back(pMemInfo);
const char *id = pMemInfo->Attribute("id");
if(id)
{
string str_id = id;
map_pNamedEntries[str_id] = pMemInfo;
}
}
for(uint32_t i = 0; i< v_pEntries.size();i++)
{
memory_info *mem = new memory_info();
//FIXME: add a set of entries processed in a step of this cycle, use it to check for infinite loops
/* recursive */ParseEntry( v_pEntries[i] , mem , map_pNamedEntries);
meminfo.push_back(mem);
}
// process found things here
}
error = false;
return true;
}