Commit 2b28977f authored by twanvl's avatar twanvl

rewritten retrying part of reader, it is now implemented how it should have been from the start.

parent 610a52e6
full name: English full name: English
############################################################## Menu items ############################################################## Menu items
menu menu:
file: &File file: &File
new set: &New... Ctrl+N new set: &New... Ctrl+N
open set: &Open... Ctrl+O open set: &Open... Ctrl+O
......
...@@ -31,7 +31,7 @@ void deserialize_from_clipboard(T& object, Package& package, const String& data) ...@@ -31,7 +31,7 @@ void deserialize_from_clipboard(T& object, Package& package, const String& data)
shared_ptr<wxStringInputStream> stream( new wxStringInputStream(data) ); shared_ptr<wxStringInputStream> stream( new wxStringInputStream(data) );
Reader reader(stream, _("clipboard")); Reader reader(stream, _("clipboard"));
WITH_DYNAMIC_ARG(clipboard_package, &package); WITH_DYNAMIC_ARG(clipboard_package, &package);
reader.handle(object); reader.handle_greedy(object);
} }
// ----------------------------------------------------------------------------- : CardDataObject // ----------------------------------------------------------------------------- : CardDataObject
......
...@@ -76,7 +76,7 @@ void addStatsDimensionsForFields(); ...@@ -76,7 +76,7 @@ void addStatsDimensionsForFields();
// special behaviour of reading/writing GamePs: only read/write the name // special behaviour of reading/writing GamePs: only read/write the name
void Reader::handle(GameP& game) { void Reader::handle(GameP& game) {
game = Game::byName(value); game = Game::byName(getValue());
} }
void Writer::handle(const GameP& game) { void Writer::handle(const GameP& game) {
if (game) handle(game->name()); if (game) handle(game->name());
......
...@@ -223,7 +223,7 @@ IndexMap<FieldP, ValueP>& Set::stylingDataFor(const StyleSheet& stylesheet) { ...@@ -223,7 +223,7 @@ IndexMap<FieldP, ValueP>& Set::stylingDataFor(const StyleSheet& stylesheet) {
// we delayed the reading of the data, read it now // we delayed the reading of the data, read it now
styling->data.init(stylesheet.styling_fields); styling->data.init(stylesheet.styling_fields);
Reader reader(new_shared1<wxStringInputStream>(styling->unread_data), _("styling data of ") + stylesheet.stylesheetName()); Reader reader(new_shared1<wxStringInputStream>(styling->unread_data), _("styling data of ") + stylesheet.stylesheetName());
reader.handle(styling->data); reader.handle_greedy(styling->data);
styling->unread_data.clear(); styling->unread_data.clear();
} }
return styling->data; return styling->data;
......
...@@ -170,7 +170,7 @@ void Settings::read() { ...@@ -170,7 +170,7 @@ void Settings::read() {
shared_ptr<wxFileInputStream> file = new_shared1<wxFileInputStream>(filename); shared_ptr<wxFileInputStream> file = new_shared1<wxFileInputStream>(filename);
if (!file->Ok()) return; // failure is not an error if (!file->Ok()) return; // failure is not an error
Reader reader(file, filename); Reader reader(file, filename);
reader.handle(*this); reader.handle_greedy(*this);
} }
} }
......
...@@ -87,7 +87,7 @@ void Reader::handle(StyleSheetP& stylesheet) { ...@@ -87,7 +87,7 @@ void Reader::handle(StyleSheetP& stylesheet) {
if (!game_for_reading()) { if (!game_for_reading()) {
throw InternalError(_("game_for_reading not set")); throw InternalError(_("game_for_reading not set"));
} }
stylesheet = StyleSheet::byGameAndName(*game_for_reading(), value); stylesheet = StyleSheet::byGameAndName(*game_for_reading(), getValue());
} }
void Writer::handle(const StyleSheetP& stylesheet) { void Writer::handle(const StyleSheetP& stylesheet) {
if (stylesheet) handle(stylesheet->stylesheetName()); if (stylesheet) handle(stylesheet->stylesheetName());
......
...@@ -29,7 +29,7 @@ SymbolWindow::SymbolWindow(Window* parent, const String& filename) { ...@@ -29,7 +29,7 @@ SymbolWindow::SymbolWindow(Window* parent, const String& filename) {
// open file // open file
Reader reader(filename); Reader reader(filename);
SymbolP symbol; SymbolP symbol;
reader.handle(symbol); reader.handle_greedy(symbol);
init(parent, symbol); init(parent, symbol);
} }
...@@ -151,7 +151,7 @@ void SymbolWindow::onFileOpen(wxCommandEvent& ev) { ...@@ -151,7 +151,7 @@ void SymbolWindow::onFileOpen(wxCommandEvent& ev) {
//% symbol = importSymbol(wxImage(name)); //% symbol = importSymbol(wxImage(name));
} else { } else {
Reader reader(new_shared1<wxFileInputStream>(name), name); Reader reader(new_shared1<wxFileInputStream>(name), name);
reader.handle(symbol); reader.handle_greedy(symbol);
} }
// show... // show...
parts->setSymbol(symbol); parts->setSymbol(symbol);
......
...@@ -174,6 +174,7 @@ struct CompareTop { ...@@ -174,6 +174,7 @@ struct CompareTop {
}; };
size_t TextViewer::indexAt(const RealPoint& pos) const { size_t TextViewer::indexAt(const RealPoint& pos) const {
// 1. find the line // 1. find the line
if (lines.empty()) return 0;
vector<Line>::const_iterator l = lower_bound(lines.begin(), lines.end(), pos.y, CompareTop()); vector<Line>::const_iterator l = lower_bound(lines.begin(), lines.end(), pos.y, CompareTop());
if (l != lines.begin()) l--; if (l != lines.begin()) l--;
assert(l != lines.end()); assert(l != lines.end());
......
...@@ -14,6 +14,7 @@ ...@@ -14,6 +14,7 @@
void ChoiceValueViewer::draw(RotatedDC& dc) { void ChoiceValueViewer::draw(RotatedDC& dc) {
drawFieldBorder(dc); drawFieldBorder(dc);
if (style().render_style & RENDER_HIDDEN) return;
if (value().value().empty()) return; if (value().value().empty()) return;
double margin = 0; double margin = 0;
if (style().render_style & RENDER_IMAGE) { if (style().render_style & RENDER_IMAGE) {
......
...@@ -495,7 +495,7 @@ SCRIPT_FUNCTION_DEP(combined_editor) { ...@@ -495,7 +495,7 @@ SCRIPT_FUNCTION_DEP(combined_editor) {
pos = value.find(_("<sep")); pos = value.find(_("<sep"));
} }
value_parts.push_back(value); value_parts.push_back(value);
if (value_parts.size() < values.size()) value_parts.resize(values.size()); value_parts.resize(values.size()); // TODO: what if there are more value_parts than values?
// update the values if our input value is newer? // update the values if our input value is newer?
Age new_value_update = last_update_age(); Age new_value_update = last_update_age();
FOR_EACH_2(v, values, nv, value_parts) { FOR_EACH_2(v, values, nv, value_parts) {
......
...@@ -71,7 +71,7 @@ String to_string(Alignment align) { ...@@ -71,7 +71,7 @@ String to_string(Alignment align) {
// we need custom io, because there can be both a horizontal and a vertical component // we need custom io, because there can be both a horizontal and a vertical component
template <> void Reader::handle(Alignment& align) { template <> void Reader::handle(Alignment& align) {
align = from_string(value); align = from_string(getValue());
} }
template <> void Writer::handle(const Alignment& align) { template <> void Writer::handle(const Alignment& align) {
handle(to_string(align)); handle(to_string(align));
......
...@@ -424,7 +424,7 @@ void Packaged::open(const String& package) { ...@@ -424,7 +424,7 @@ void Packaged::open(const String& package) {
Package::open(package); Package::open(package);
Reader reader(openIn(typeName()), absoluteFilename() + _("/") + typeName()); Reader reader(openIn(typeName()), absoluteFilename() + _("/") + typeName());
try { try {
reader.handle(*this); reader.handle_greedy(*this);
validate(reader.file_app_version); validate(reader.file_app_version);
} catch (const ParseError& err) { } catch (const ParseError& err) {
throw FileParseError(err.what(), absoluteFilename() + _("/") + typeName()); // more detailed message throw FileParseError(err.what(), absoluteFilename() + _("/") + typeName()); // more detailed message
......
...@@ -117,7 +117,7 @@ class Package { ...@@ -117,7 +117,7 @@ class Package {
void readFile(const String& file, T& obj) { void readFile(const String& file, T& obj) {
Reader reader(openIn(file), absoluteFilename() + _("/") + file); Reader reader(openIn(file), absoluteFilename() + _("/") + file);
try { try {
reader.handle(obj); reader.handle_greedy(obj);
} catch (const ParseError& err) { } catch (const ParseError& err) {
throw FileParseError(err.what(), absoluteFilename() + _("/") + file); // more detailed message throw FileParseError(err.what(), absoluteFilename() + _("/") + file); // more detailed message
} }
......
...@@ -81,6 +81,7 @@ void Reader::exitBlock() { ...@@ -81,6 +81,7 @@ void Reader::exitBlock() {
while (indent > expected_indent) { while (indent > expected_indent) {
moveNext(); moveNext();
} }
handled = true;
} }
void Reader::moveNext() { void Reader::moveNext() {
...@@ -110,12 +111,12 @@ void Reader::readLine() { ...@@ -110,12 +111,12 @@ void Reader::readLine() {
} }
// read key / value // read key / value
size_t pos = line.find_first_of(_(':'), indent); size_t pos = line.find_first_of(_(':'), indent);
if (!pos || line.GetChar(indent) == _('#')) { if (trim(line).empty() || line.GetChar(indent) == _('#')) {
// empty line or comment // empty line or comment
key.clear(); key.clear();
return; return;
} }
if (key.empty() && input->Eof()) { if (input->Eof()) {
// end of file // end of file
indent = -1; indent = -1;
return; return;
...@@ -147,9 +148,10 @@ void Reader::unknownKey() { ...@@ -147,9 +148,10 @@ void Reader::unknownKey() {
// ----------------------------------------------------------------------------- : Handling basic types // ----------------------------------------------------------------------------- : Handling basic types
template <> void Reader::handle(String& s) { const String& Reader::getValue() {
handled = true;
if (!multi_line_str.empty()) { if (!multi_line_str.empty()) {
s = multi_line_str; return multi_line_str;
} else if (value.empty()) { } else if (value.empty()) {
// a multiline string // a multiline string
bool first = true; bool first = true;
...@@ -161,50 +163,54 @@ template <> void Reader::handle(String& s) { ...@@ -161,50 +163,54 @@ template <> void Reader::handle(String& s) {
multi_line_str += line.substr(expected_indent); // strip expected indent multi_line_str += line.substr(expected_indent); // strip expected indent
readLine(); readLine();
} }
// moveNext(), but without emptying multiLineStr // moveNext(), but without emptying multi_line_str
just_opened = false; just_opened = false;
while (key.empty() && !input->Eof()) { while (key.empty() && !input->Eof()) {
readLine(); readLine();
} }
s = multi_line_str; return multi_line_str;
} else { } else {
s = value; return value;
} }
} }
template <> void Reader::handle(String& s) {
s = getValue();
}
template <> void Reader::handle(int& i) { template <> void Reader::handle(int& i) {
long l = 0; long l = 0;
value.ToLong(&l); getValue().ToLong(&l);
i = l; i = l;
} }
template <> void Reader::handle(unsigned int& i) { template <> void Reader::handle(unsigned int& i) {
long l = 0; long l = 0;
value.ToLong(&l); getValue().ToLong(&l);
i = abs(l); // abs, because it will seem strange if -1 comes out as MAX_INT i = abs(l); // abs, because it will seem strange if -1 comes out as MAX_INT
} }
template <> void Reader::handle(double& d) { template <> void Reader::handle(double& d) {
value.ToDouble(&d); getValue().ToDouble(&d);
} }
template <> void Reader::handle(bool& b) { template <> void Reader::handle(bool& b) {
b = (value==_("true") || value==_("1") || value==_("yes")); b = (getValue()==_("true") || getValue()==_("1") || getValue()==_("yes"));
} }
// ----------------------------------------------------------------------------- : Handling less basic util types // ----------------------------------------------------------------------------- : Handling less basic util types
template <> void Reader::handle(Vector2D& vec) { template <> void Reader::handle(Vector2D& vec) {
if (!wxSscanf(value.c_str(), _("(%lf,%lf)"), &vec.x, &vec.y)) { if (!wxSscanf(getValue().c_str(), _("(%lf,%lf)"), &vec.x, &vec.y)) {
throw ParseError(_("Expected (x,y)")); throw ParseError(_("Expected (x,y)"));
} }
} }
template <> void Reader::handle(Color& col) { template <> void Reader::handle(Color& col) {
UInt r,g,b; UInt r,g,b;
if (wxSscanf(value.c_str(),_("rgb(%u,%u,%u)"),&r,&g,&b)) { if (wxSscanf(getValue().c_str(),_("rgb(%u,%u,%u)"),&r,&g,&b)) {
col.Set(r, g, b); col.Set(r, g, b);
} }
} }
template <> void Reader::handle(FileName& f) { template <> void Reader::handle(FileName& f) {
if (clipboard_package()) { if (clipboard_package()) {
String str; handle(str); String str = getValue();
if (!str.empty()) { if (!str.empty()) {
// copy file into current package // copy file into current package
try { try {
......
...@@ -62,11 +62,23 @@ class Reader { ...@@ -62,11 +62,23 @@ class Reader {
void showWarnings(); void showWarnings();
// --------------------------------------------------- : Handling objects // --------------------------------------------------- : Handling objects
/// Handle an object that can read as much as it can eat
template <typename T>
void handle_greedy(T& object) {
do {
// UInt l = line_number;
handled = false;
handle(object);
// if (l == line_number && !handled) unknownKey(object);
if (!handled) unknownKey(object);
} while (indent >= expected_indent);
}
/// Handle an object: read it if it's name matches /// Handle an object: read it if it's name matches
template <typename T> template <typename T>
void handle(const Char* name, T& object) { void handle(const Char* name, T& object) {
if (enterBlock(name)) { if (enterBlock(name)) {
handle(object); handle_greedy(object);
exitBlock(); exitBlock();
} }
} }
...@@ -100,6 +112,8 @@ class Reader { ...@@ -100,6 +112,8 @@ class Reader {
String key, value; String key, value;
/// A string spanning multiple lines /// A string spanning multiple lines
String multi_line_str; String multi_line_str;
/// Has the current line been handled?
bool handled;
/// Indentation of the last line we read /// Indentation of the last line we read
int indent; int indent;
/// Indentation of the block we are in /// Indentation of the block we are in
...@@ -132,13 +146,16 @@ class Reader { ...@@ -132,13 +146,16 @@ class Reader {
/// Reads the next line from the input, and stores it in line/key/value/indent /// Reads the next line from the input, and stores it in line/key/value/indent
void readLine(); void readLine();
/// Return the value on the current line
const String& getValue();
/// No line was read, because nothing mathes the current key /// No line was read, because nothing mathes the current key
/** Maybe the key is "include file" */ /** Maybe the key is "include file" */
template <typename T> template <typename T>
void unknownKey(T& v) { void unknownKey(T& v) {
if (key == _("include file")) { if (key == _("include file")) {
Reader reader(value); Reader reader(value);
reader.handle(v); reader.handle_greedy(v);
moveNext(); moveNext();
} else { } else {
unknownKey(); unknownKey();
...@@ -166,7 +183,7 @@ void Reader::handle(const Char* name, vector<T>& vector) { ...@@ -166,7 +183,7 @@ void Reader::handle(const Char* name, vector<T>& vector) {
String vectorKey = singular_form(name); String vectorKey = singular_form(name);
while (enterBlock(vectorKey)) { while (enterBlock(vectorKey)) {
vector.resize(vector.size() + 1); vector.resize(vector.size() + 1);
handle(vector.back()); handle_greedy(vector.back());
update_index(vector.back(), vector.size() - 1); // update index for IndexMap update_index(vector.back(), vector.size() - 1); // update index for IndexMap
exitBlock(); exitBlock();
} }
...@@ -187,20 +204,16 @@ void Reader::handle(map<String, V>& m) { ...@@ -187,20 +204,16 @@ void Reader::handle(map<String, V>& m) {
just_opened = true; just_opened = true;
expected_indent += 1; expected_indent += 1;
// now read the value // now read the value
handle(m[key]); handle_greedy(m[key]);
exitBlock(); exitBlock();
} }
} }
template <typename K, typename V> template <typename K, typename V>
void Reader::handle(IndexMap<K,V>& m) { void Reader::handle(IndexMap<K,V>& m) {
//do { for (typename IndexMap<K,V>::iterator it = m.begin() ; it != m.end() ; ++it) {
// UInt l = line_number; handle(get_key_name(*it).c_str(), *it);
for (typename IndexMap<K,V>::iterator it = m.begin() ; it != m.end() ; ++it) { }
handle(get_key_name(*it).c_str(), *it);
}
// if (l == line_number) unknownKey(m);
//} while (indent >= expected_indent);
} }
// ----------------------------------------------------------------------------- : Reflection // ----------------------------------------------------------------------------- : Reflection
...@@ -208,11 +221,7 @@ void Reader::handle(IndexMap<K,V>& m) { ...@@ -208,11 +221,7 @@ void Reader::handle(IndexMap<K,V>& m) {
/// Implement reflection as used by Reader /// Implement reflection as used by Reader
#define REFLECT_OBJECT_READER(Cls) \ #define REFLECT_OBJECT_READER(Cls) \
template<> void Reader::handle<Cls>(Cls& object) { \ template<> void Reader::handle<Cls>(Cls& object) { \
do { \ object.reflect(*this); \
UInt l = line_number; \
object.reflect(*this); \
if (l == line_number) unknownKey(object); \
} while (indent >= expected_indent); \
} \ } \
void Cls::reflect(Reader& reader) { \ void Cls::reflect(Reader& reader) { \
reflect_impl(reader); \ reflect_impl(reader); \
...@@ -223,7 +232,7 @@ void Reader::handle(IndexMap<K,V>& m) { ...@@ -223,7 +232,7 @@ void Reader::handle(IndexMap<K,V>& m) {
/// Implement enum reflection as used by Reader /// Implement enum reflection as used by Reader
#define REFLECT_ENUM_READER(Enum) \ #define REFLECT_ENUM_READER(Enum) \
template<> void Reader::handle<Enum>(Enum& enum_) { \ template<> void Reader::handle<Enum>(Enum& enum_) { \
EnumReader reader(value); \ EnumReader reader(getValue()); \
reflect_ ## Enum(enum_, reader); \ reflect_ ## Enum(enum_, reader); \
if (!reader.isDone()) { \ if (!reader.isDone()) { \
/* warning: unknown value */ \ /* warning: unknown value */ \
......
...@@ -29,7 +29,7 @@ Version Version::fromString(const String& version) { ...@@ -29,7 +29,7 @@ Version Version::fromString(const String& version) {
template <> void Reader::handle(Version& v) { template <> void Reader::handle(Version& v) {
v = Version::fromString(value); v = Version::fromString(getValue());
} }
template <> void Writer::handle(const Version& v) { template <> void Writer::handle(const Version& v) {
handle(v.toString()); handle(v.toString());
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment