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