sprinkled some exceptions over the memory reading

develop
mizipzor 2010-02-28 03:34:54 +01:00
parent 2b1940430f
commit 6be18fbf20
4 changed files with 149 additions and 212 deletions

@ -85,6 +85,7 @@ namespace DFHack
#include "DFMemInfoManager.h" #include "DFMemInfoManager.h"
#include "DFVector.h" #include "DFVector.h"
#include "DFMemInfo.h" #include "DFMemInfo.h"
#include "DFError.h"
#include <stdlib.h> #include <stdlib.h>
#include "tinyxml/tinyxml.h" #include "tinyxml/tinyxml.h"

@ -26,6 +26,7 @@ distribution.
#define ERROR_H_INCLUDED #define ERROR_H_INCLUDED
#include <string> #include <string>
#include <sstream>
#include <exception> #include <exception>
namespace DFHack namespace DFHack
@ -72,16 +73,39 @@ namespace DFHack
} }
}; };
// a call to DFHack::mem_info::getAdress() failed // a call to DFHack::mem_info::get* failed
class MissingAddress : public exception class MissingMemoryDefinition : public exception
{ {
public: public:
MissingAddress(const char* _address = "UNKNOWN") : address(_address) {} MissingMemoryDefinition(const char* _type, const char* _key) : type(_type), key(_key) {}
const std::string address; // Used by functios using integer keys, such as getTrait
MissingMemoryDefinition(const char* _type, uint32_t _key) : type(_type)
{
// FIXME fancy hex printer goes here
std::stringstream s;
s << _key;
key = s.str();
}
// (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
const std::string type;
std::string key;
virtual const char* what() const throw() virtual const char* what() const throw()
{ {
return "memory address missing"; return "memory definition missing";
} }
}; };
} }

@ -23,7 +23,6 @@ distribution.
*/ */
#include "DFCommonInternal.h" #include "DFCommonInternal.h"
#include "DFError.h"
using namespace DFHack; using namespace DFHack;
/* /*
@ -659,23 +658,6 @@ bool API::ReadGeology (vector < vector <uint16_t> >& assign)
uint32_t regionX, regionY, regionZ; uint32_t regionX, regionY, regionZ;
uint16_t worldSizeX, worldSizeY; uint16_t worldSizeX, worldSizeY;
// check if we have 'em all
if (
! (
region_x_offset && region_y_offset && region_z_offset && world_size_x && world_size_y
&& world_offset && world_regions_offset && world_geoblocks_offset && region_size
&& region_geo_index_offset && geolayer_geoblock_offset
)
)
{
// FIXME should probably be moved into getAdress or getOffset for easy storing of
// the missing definition
throw Error::MissingAddress();
// fail if we don't have them
//return false;
}
// read position of the region inside DF world // read position of the region inside DF world
g_pProcess->readDWord (region_x_offset, regionX); g_pProcess->readDWord (region_x_offset, regionX);
g_pProcess->readDWord (region_y_offset, regionY); g_pProcess->readDWord (region_y_offset, regionY);
@ -744,21 +726,10 @@ bool API::ReadGeology (vector < vector <uint16_t> >& assign)
bool API::InitReadBuildings ( uint32_t& numbuildings ) bool API::InitReadBuildings ( uint32_t& numbuildings )
{ {
int buildings = d->offset_descriptor->getAddress ("buildings"); int buildings = d->offset_descriptor->getAddress ("buildings");
if(buildings) d->buildingsInited = true;
{ d->p_bld = new DfVector (d->p->readVector (buildings, 4));
d->buildingsInited = true; numbuildings = d->p_bld->getSize();
d->p_bld = new DfVector (d->p->readVector (buildings, 4)); return true;
numbuildings = d->p_bld->getSize();
return true;
}
else
{
d->buildingsInited = false;
numbuildings = 0;
throw Error::MissingAddress("buildings");
//return false;
}
} }
@ -809,21 +780,10 @@ void API::FinishReadBuildings()
bool API::InitReadConstructions(uint32_t & numconstructions) bool API::InitReadConstructions(uint32_t & numconstructions)
{ {
int constructions = d->offset_descriptor->getAddress ("constructions"); int constructions = d->offset_descriptor->getAddress ("constructions");
if(constructions) d->p_cons = new DfVector (d->p->readVector (constructions, 4));
{ d->constructionsInited = true;
d->p_cons = new DfVector (d->p->readVector (constructions, 4)); numconstructions = d->p_cons->getSize();
d->constructionsInited = true; return true;
numconstructions = d->p_cons->getSize();
return true;
}
else
{
d->constructionsInited = false;
numconstructions = 0;
throw Error::MissingAddress("constructions");
//return false;
}
} }
@ -861,22 +821,21 @@ void API::FinishReadConstructions()
bool API::InitReadVegetation(uint32_t & numplants) bool API::InitReadVegetation(uint32_t & numplants)
{ {
int vegetation = d->offset_descriptor->getAddress ("vegetation"); try
d->tree_offset = d->offset_descriptor->getOffset ("tree_desc_offset");
if(vegetation && d->tree_offset)
{ {
int vegetation = d->offset_descriptor->getAddress ("vegetation");
d->tree_offset = d->offset_descriptor->getOffset ("tree_desc_offset");
d->vegetationInited = true; d->vegetationInited = true;
d->p_veg = new DfVector (d->p->readVector (vegetation, 4)); d->p_veg = new DfVector (d->p->readVector (vegetation, 4));
numplants = d->p_veg->getSize(); numplants = d->p_veg->getSize();
return true; return true;
} }
else catch (Error::MissingMemoryDefinition&)
{ {
d->vegetationInited = false; d->vegetationInited = false;
numplants = 0; numplants = 0;
throw;
throw Error::MissingAddress();
//return false;
} }
} }
@ -908,99 +867,69 @@ void API::FinishReadVegetation()
bool API::InitReadCreatures( uint32_t &numcreatures ) bool API::InitReadCreatures( uint32_t &numcreatures )
{ {
memory_info * minfo = d->offset_descriptor; try
int creatures = d->offset_descriptor->getAddress ("creatures"); {
d->creature_pos_offset = minfo->getOffset ("creature_position"); memory_info * minfo = d->offset_descriptor;
d->creature_type_offset = minfo->getOffset ("creature_race"); int creatures = d->offset_descriptor->getAddress ("creatures");
d->creature_flags1_offset = minfo->getOffset ("creature_flags1"); d->creature_pos_offset = minfo->getOffset ("creature_position");
d->creature_flags2_offset = minfo->getOffset ("creature_flags2"); d->creature_type_offset = minfo->getOffset ("creature_race");
d->creature_first_name_offset = minfo->getOffset ("creature_first_name"); d->creature_flags1_offset = minfo->getOffset ("creature_flags1");
d->creature_nick_name_offset = minfo->getOffset ("creature_nick_name"); d->creature_flags2_offset = minfo->getOffset ("creature_flags2");
d->creature_last_name_offset = minfo->getOffset ("creature_last_name"); d->creature_first_name_offset = minfo->getOffset ("creature_first_name");
d->creature_custom_profession_offset = minfo->getOffset ("creature_custom_profession"); d->creature_nick_name_offset = minfo->getOffset ("creature_nick_name");
d->creature_profession_offset = minfo->getOffset ("creature_profession"); d->creature_last_name_offset = minfo->getOffset ("creature_last_name");
d->creature_sex_offset = minfo->getOffset ("creature_sex"); d->creature_custom_profession_offset = minfo->getOffset ("creature_custom_profession");
d->creature_id_offset = minfo->getOffset ("creature_id"); d->creature_profession_offset = minfo->getOffset ("creature_profession");
d->creature_squad_name_offset = minfo->getOffset ("creature_squad_name"); d->creature_sex_offset = minfo->getOffset ("creature_sex");
d->creature_squad_leader_id_offset = minfo->getOffset ("creature_squad_leader_id"); d->creature_id_offset = minfo->getOffset ("creature_id");
d->creature_money_offset = minfo->getOffset ("creature_money"); d->creature_squad_name_offset = minfo->getOffset ("creature_squad_name");
d->creature_current_job_offset = minfo->getOffset ("creature_current_job"); d->creature_squad_leader_id_offset = minfo->getOffset ("creature_squad_leader_id");
d->creature_current_job_id_offset = minfo->getOffset ("current_job_id"); d->creature_money_offset = minfo->getOffset ("creature_money");
d->creature_strength_offset = minfo->getOffset ("creature_strength"); d->creature_current_job_offset = minfo->getOffset ("creature_current_job");
d->creature_agility_offset = minfo->getOffset ("creature_agility"); d->creature_current_job_id_offset = minfo->getOffset ("current_job_id");
d->creature_toughness_offset = minfo->getOffset ("creature_toughness"); d->creature_strength_offset = minfo->getOffset ("creature_strength");
d->creature_skills_offset = minfo->getOffset ("creature_skills"); d->creature_agility_offset = minfo->getOffset ("creature_agility");
d->creature_labors_offset = minfo->getOffset ("creature_labors"); d->creature_toughness_offset = minfo->getOffset ("creature_toughness");
d->creature_happiness_offset = minfo->getOffset ("creature_happiness"); d->creature_skills_offset = minfo->getOffset ("creature_skills");
d->creature_traits_offset = minfo->getOffset ("creature_traits"); d->creature_labors_offset = minfo->getOffset ("creature_labors");
d->creature_likes_offset = minfo->getOffset("creature_likes"); d->creature_happiness_offset = minfo->getOffset ("creature_happiness");
if (creatures d->creature_traits_offset = minfo->getOffset ("creature_traits");
&& d->creature_pos_offset d->creature_likes_offset = minfo->getOffset("creature_likes");
&& d->creature_type_offset
&& d->creature_flags1_offset
&& d->creature_flags2_offset
&& d->creature_nick_name_offset
&& d->creature_custom_profession_offset
&& d->creature_profession_offset
&& d->creature_sex_offset
&& d->creature_id_offset
&& d->creature_squad_name_offset
&& d->creature_squad_leader_id_offset
&& d->creature_money_offset
&& d->creature_current_job_offset
&& d->creature_strength_offset
&& d->creature_agility_offset
&& d->creature_toughness_offset
&& d->creature_skills_offset
&& d->creature_labors_offset
&& d->creature_happiness_offset
&& d->creature_traits_offset
// && d->creature_likes_offset
)
{
d->p_cre = new DfVector (d->p->readVector (creatures, 4)); d->p_cre = new DfVector (d->p->readVector (creatures, 4));
//InitReadNameTables(); //InitReadNameTables();
d->creaturesInited = true; d->creaturesInited = true;
numcreatures = d->p_cre->getSize(); numcreatures = d->p_cre->getSize();
return true; return true;
} }
else catch (Error::MissingMemoryDefinition&)
{ {
d->creaturesInited = false; d->creaturesInited = false;
numcreatures = 0; numcreatures = 0;
throw;
throw Error::MissingAddress();
//return false;
} }
} }
bool API::InitReadNotes( uint32_t &numnotes ) bool API::InitReadNotes( uint32_t &numnotes )
{ {
memory_info * minfo = d->offset_descriptor; try
int notes = minfo->getAddress ("notes");
d->note_foreground_offset = minfo->getOffset ("note_foreground");
d->note_background_offset = minfo->getOffset ("note_background");
d->note_name_offset = minfo->getOffset ("note_name");
d->note_xyz_offset = minfo->getOffset ("note_xyz");
if (notes
&& d->note_foreground_offset
&& d->note_background_offset
&& d->note_name_offset
&& d->note_xyz_offset
)
{ {
memory_info * minfo = d->offset_descriptor;
int notes = minfo->getAddress ("notes");
d->note_foreground_offset = minfo->getOffset ("note_foreground");
d->note_background_offset = minfo->getOffset ("note_background");
d->note_name_offset = minfo->getOffset ("note_name");
d->note_xyz_offset = minfo->getOffset ("note_xyz");
d->p_notes = new DfVector (d->p->readVector (notes, 4)); d->p_notes = new DfVector (d->p->readVector (notes, 4));
d->notesInited = true; d->notesInited = true;
numnotes = d->p_notes->getSize(); numnotes = d->p_notes->getSize();
return true; return true;
} }
else catch (Error::MissingMemoryDefinition&)
{ {
d->notesInited = false; d->notesInited = false;
numnotes = 0; numnotes = 0;
throw;
throw Error::MissingAddress();
//return false;
} }
} }
bool API::ReadNote (const int32_t index, t_note & note) bool API::ReadNote (const int32_t index, t_note & note)
@ -1017,32 +946,26 @@ bool API::ReadNote (const int32_t index, t_note & note)
} }
bool API::InitReadSettlements( uint32_t & numsettlements ) bool API::InitReadSettlements( uint32_t & numsettlements )
{ {
memory_info * minfo = d->offset_descriptor; try
int allSettlements = minfo->getAddress ("settlements");
int currentSettlement = minfo->getAddress("settlement_current");
d->settlement_name_offset = minfo->getOffset ("settlement_name");
d->settlement_world_xy_offset = minfo->getOffset ("settlement_world_xy");
d->settlement_local_xy_offset = minfo->getOffset ("settlement_local_xy");
if (allSettlements && currentSettlement
&& d->settlement_name_offset
&& d->settlement_world_xy_offset
&& d->settlement_local_xy_offset
)
{ {
memory_info * minfo = d->offset_descriptor;
int allSettlements = minfo->getAddress ("settlements");
int currentSettlement = minfo->getAddress("settlement_current");
d->settlement_name_offset = minfo->getOffset ("settlement_name");
d->settlement_world_xy_offset = minfo->getOffset ("settlement_world_xy");
d->settlement_local_xy_offset = minfo->getOffset ("settlement_local_xy");
d->p_settlements = new DfVector (d->p->readVector (allSettlements, 4)); d->p_settlements = new DfVector (d->p->readVector (allSettlements, 4));
d->p_current_settlement = new DfVector(d->p->readVector(currentSettlement,4)); d->p_current_settlement = new DfVector(d->p->readVector(currentSettlement,4));
d->settlementsInited = true; d->settlementsInited = true;
numsettlements = d->p_settlements->getSize(); numsettlements = d->p_settlements->getSize();
return true; return true;
} }
else catch (Error::MissingMemoryDefinition&)
{ {
d->settlementsInited = false; d->settlementsInited = false;
numsettlements = 0; numsettlements = 0;
throw;
throw Error::MissingAddress();
//return false;
} }
} }
bool API::ReadSettlement(const int32_t index, t_settlement & settlement) bool API::ReadSettlement(const int32_t index, t_settlement & settlement)
@ -1058,6 +981,7 @@ bool API::ReadSettlement(const int32_t index, t_settlement & settlement)
g_pProcess->read(temp + d->settlement_local_xy_offset, 4 * sizeof(int16_t), (uint8_t *) &settlement.local_x1); g_pProcess->read(temp + d->settlement_local_xy_offset, 4 * sizeof(int16_t), (uint8_t *) &settlement.local_x1);
return true; return true;
} }
bool API::ReadCurrentSettlement(t_settlement & settlement) bool API::ReadCurrentSettlement(t_settlement & settlement)
{ {
if(!d->settlementsInited) return false; if(!d->settlementsInited) return false;
@ -1089,23 +1013,21 @@ void API::FinishReadSettlements()
bool API::InitReadHotkeys( ) bool API::InitReadHotkeys( )
{ {
memory_info * minfo = d->offset_descriptor; try
d->hotkey_start = minfo->getAddress("hotkey_start");
d->hotkey_mode_offset = minfo->getOffset ("hotkey_mode");
d->hotkey_xyz_offset = minfo->getOffset("hotkey_xyz");
d->hotkey_size = minfo->getHexValue("hotkey_size");
if (d->hotkey_start && d->hotkey_mode_offset && d->hotkey_size)
{ {
memory_info * minfo = d->offset_descriptor;
d->hotkey_start = minfo->getAddress("hotkey_start");
d->hotkey_mode_offset = minfo->getOffset ("hotkey_mode");
d->hotkey_xyz_offset = minfo->getOffset("hotkey_xyz");
d->hotkey_size = minfo->getHexValue("hotkey_size");
d->hotkeyInited = true; d->hotkeyInited = true;
return true; return true;
} }
else catch (Error::MissingMemoryDefinition&)
{ {
d->hotkeyInited = false; d->hotkeyInited = false;
throw;
throw Error::MissingAddress();
//return false;
} }
} }
bool API::ReadHotkeys(t_hotkey hotkeys[]) bool API::ReadHotkeys(t_hotkey hotkeys[])
@ -1263,12 +1185,12 @@ void API::WriteLabors(const uint32_t index, uint8_t labors[NUM_CREATURE_LABORS])
bool API::InitReadNameTables (map< string, vector<string> > & nameTable) bool API::InitReadNameTables (map< string, vector<string> > & nameTable)
{ {
int genericAddress = d->offset_descriptor->getAddress ("language_vector"); try
int transAddress = d->offset_descriptor->getAddress ("translation_vector");
int word_table_offset = d->offset_descriptor->getOffset ("word_table");
if(genericAddress && transAddress && word_table_offset)
{ {
int genericAddress = d->offset_descriptor->getAddress ("language_vector");
int transAddress = d->offset_descriptor->getAddress ("translation_vector");
int word_table_offset = d->offset_descriptor->getOffset ("word_table");
DfVector genericVec (d->p->readVector (genericAddress, 4)); DfVector genericVec (d->p->readVector (genericAddress, 4));
DfVector transVec (d->p->readVector (transAddress, 4)); DfVector transVec (d->p->readVector (transAddress, 4));
@ -1294,12 +1216,10 @@ bool API::InitReadNameTables (map< string, vector<string> > & nameTable)
d->nameTablesInited = true; d->nameTablesInited = true;
return true; return true;
} }
else catch (Error::MissingMemoryDefinition&)
{ {
d->nameTablesInited = false; d->nameTablesInited = false;
throw;
throw Error::MissingAddress();
//return false;
} }
} }
@ -1482,42 +1402,39 @@ void API::WriteRaw (const uint32_t offset, const uint32_t size, uint8_t *source)
bool API::InitViewAndCursor() bool API::InitViewAndCursor()
{ {
d->window_x_offset = d->offset_descriptor->getAddress ("window_x"); try
d->window_y_offset = d->offset_descriptor->getAddress ("window_y");
d->window_z_offset = d->offset_descriptor->getAddress ("window_z");
d->cursor_xyz_offset = d->offset_descriptor->getAddress ("cursor_xyz");
d->current_cursor_creature_offset = d->offset_descriptor->getAddress ("current_cursor_creature");
d->current_menu_state_offset = d->offset_descriptor->getAddress("current_menu_state");
d->pause_state_offset = d->offset_descriptor->getAddress ("pause_state");
d->view_screen_offset = d->offset_descriptor->getAddress ("view_screen");
if (d->window_x_offset && d->window_y_offset && d->window_z_offset &&
d->current_cursor_creature_offset && d->current_menu_state_offset &&
d->pause_state_offset && d->view_screen_offset)
{ {
d->window_x_offset = d->offset_descriptor->getAddress ("window_x");
d->window_y_offset = d->offset_descriptor->getAddress ("window_y");
d->window_z_offset = d->offset_descriptor->getAddress ("window_z");
d->cursor_xyz_offset = d->offset_descriptor->getAddress ("cursor_xyz");
d->current_cursor_creature_offset = d->offset_descriptor->getAddress ("current_cursor_creature");
d->current_menu_state_offset = d->offset_descriptor->getAddress("current_menu_state");
d->pause_state_offset = d->offset_descriptor->getAddress ("pause_state");
d->view_screen_offset = d->offset_descriptor->getAddress ("view_screen");
d->cursorWindowInited = true; d->cursorWindowInited = true;
return true; return true;
} }
else catch (Error::MissingMemoryDefinition&)
{ {
throw Error::MissingAddress(); throw;
//return false;
} }
} }
bool API::InitViewSize() bool API::InitViewSize()
{ {
d->window_dims_offset = d->offset_descriptor->getAddress ("window_dims"); try
if (d->window_dims_offset)
{ {
d->window_dims_offset = d->offset_descriptor->getAddress ("window_dims");
d->viewSizeInited = true; d->viewSizeInited = true;
return true; return true;
} }
else catch (Error::MissingMemoryDefinition&)
{ {
throw Error::MissingAddress(); throw;
//return false;
} }
} }
@ -1595,23 +1512,21 @@ DFWindow * API::getWindow()
bool API::InitReadItems(uint32_t & numitems) bool API::InitReadItems(uint32_t & numitems)
{ {
int items = d->offset_descriptor->getAddress ("items"); try
d->item_material_offset = d->offset_descriptor->getOffset ("item_materials");
if(items && d->item_material_offset)
{ {
int items = d->offset_descriptor->getAddress ("items");
d->item_material_offset = d->offset_descriptor->getOffset ("item_materials");
d->p_itm = new DfVector (d->p->readVector (items, 4)); d->p_itm = new DfVector (d->p->readVector (items, 4));
d->itemsInited = true; d->itemsInited = true;
numitems = d->p_itm->getSize(); numitems = d->p_itm->getSize();
return true; return true;
} }
else catch (Error::MissingMemoryDefinition&)
{ {
d->itemsInited = false; d->itemsInited = false;
numitems = 0; numitems = 0;
throw;
throw Error::MissingAddress();
//return false;
} }
} }
bool API::ReadItem (const uint32_t index, t_item & item) bool API::ReadItem (const uint32_t index, t_item & item)

@ -450,7 +450,7 @@ uint32_t memory_info::getAddress (const char *key)
{ {
return (*iter).second; return (*iter).second;
} }
return 0; throw Error::MissingMemoryDefinition("address", key);
} }
@ -462,7 +462,7 @@ uint32_t memory_info::getOffset (const char *key)
{ {
return (*iter).second; return (*iter).second;
} }
return 0; throw Error::MissingMemoryDefinition("offset", key);
} }
// Get named numerical value // Get named numerical value
@ -473,7 +473,7 @@ uint32_t memory_info::getHexValue (const char *key)
{ {
return (*iter).second; return (*iter).second;
} }
return 0; throw Error::MissingMemoryDefinition("hexvalue", key);
} }
@ -486,7 +486,7 @@ uint32_t memory_info::getAddress (const string &key)
{ {
return (*iter).second; return (*iter).second;
} }
return 0; throw Error::MissingMemoryDefinition("address", key.c_str());
} }
@ -498,7 +498,7 @@ uint32_t memory_info::getOffset (const string &key)
{ {
return (*iter).second; return (*iter).second;
} }
return 0; throw Error::MissingMemoryDefinition("offset", key.c_str());
} }
// Get named numerical value // Get named numerical value
@ -509,7 +509,7 @@ uint32_t memory_info::getHexValue (const string &key)
{ {
return (*iter).second; return (*iter).second;
} }
return 0; throw Error::MissingMemoryDefinition("hexvalue", key.c_str());
} }
// Get named string // Get named string
@ -520,7 +520,7 @@ std::string memory_info::getString (const string &key)
{ {
return (*iter).second; return (*iter).second;
} }
return string(""); throw Error::MissingMemoryDefinition("string", key.c_str());
} }
// Get Profession // Get Profession
@ -530,10 +530,7 @@ string memory_info::getProfession (const uint32_t key) const
{ {
return d->professions[key]; return d->professions[key];
} }
else throw Error::MissingMemoryDefinition("profession", key);
{
return string("");
}
} }
// Get Job // Get Job
@ -543,7 +540,7 @@ string memory_info::getJob (const uint32_t key) const
{ {
return d->jobs[key]; return d->jobs[key];
} }
return string("Job Does Not Exist"); throw Error::MissingMemoryDefinition("job", key);
} }
string memory_info::getSkill (const uint32_t key) const string memory_info::getSkill (const uint32_t key) const
@ -552,7 +549,7 @@ string memory_info::getSkill (const uint32_t key) const
{ {
return d->skills[key]; return d->skills[key];
} }
return string("Skill is not Defined"); throw Error::MissingMemoryDefinition("skill", key);
} }
// FIXME: ugly hack that needs to die // FIXME: ugly hack that needs to die
@ -585,7 +582,7 @@ string memory_info::getTrait (const uint32_t traitIdx, const uint32_t traitValue
else else
return d->traits[traitIdx][0]; return d->traits[traitIdx][0];
} }
return string("Trait is not Defined"); throw Error::MissingMemoryDefinition("trait", traitIdx);
} }
string memory_info::getTraitName(const uint32_t traitIdx) const string memory_info::getTraitName(const uint32_t traitIdx) const
@ -594,7 +591,7 @@ string memory_info::getTraitName(const uint32_t traitIdx) const
{ {
return d->traits[traitIdx][d->traits[traitIdx].size()-1]; return d->traits[traitIdx][d->traits[traitIdx].size()-1];
} }
return string("Trait is not Defined"); throw Error::MissingMemoryDefinition("traitname", traitIdx);
} }
string memory_info::getLabor (const uint32_t laborIdx) string memory_info::getLabor (const uint32_t laborIdx)
@ -603,7 +600,7 @@ string memory_info::getLabor (const uint32_t laborIdx)
{ {
return d->labors[laborIdx]; return d->labors[laborIdx];
} }
return string(""); throw Error::MissingMemoryDefinition("labor", laborIdx);
} }
// Reset everything // Reset everything