Added a simple optimization to the way amount strings are parsed.

This commit is contained in:
John Wiegley 2008-07-26 23:55:06 -04:00
parent 7848dbd7f7
commit 9b7725ee18
3 changed files with 25 additions and 26 deletions

View file

@ -1062,7 +1062,7 @@ void parse_annotations(std::istream& in, amount_t& price,
<< " tag " << tag); << " tag " << tag);
} }
void amount_t::parse(std::istream& in, unsigned char flags) bool amount_t::parse(std::istream& in, unsigned char flags)
{ {
// The possible syntax for an amount is: // The possible syntax for an amount is:
// //
@ -1114,8 +1114,12 @@ void amount_t::parse(std::istream& in, unsigned char flags)
} }
} }
if (quant.empty()) if (quant.empty()) {
throw new amount_error("No quantity specified for amount"); if (flags & AMOUNT_PARSE_SOFT_FAIL)
return false;
else
throw new amount_error("No quantity specified for amount");
}
_init(); _init();
@ -1205,6 +1209,8 @@ void amount_t::parse(std::istream& in, unsigned char flags)
if (! (flags & AMOUNT_PARSE_NO_REDUCE)) if (! (flags & AMOUNT_PARSE_NO_REDUCE))
reduce(); reduce();
return true;
} }
void amount_t::reduce() void amount_t::reduce()
@ -1215,7 +1221,7 @@ void amount_t::reduce()
} }
} }
void amount_t::parse(const std::string& str, unsigned char flags) bool amount_t::parse(const std::string& str, unsigned char flags)
{ {
std::istringstream stream(str); std::istringstream stream(str);
parse(stream, flags); parse(stream, flags);

View file

@ -263,9 +263,10 @@ class amount_t
#define AMOUNT_PARSE_NO_MIGRATE 0x01 #define AMOUNT_PARSE_NO_MIGRATE 0x01
#define AMOUNT_PARSE_NO_REDUCE 0x02 #define AMOUNT_PARSE_NO_REDUCE 0x02
#define AMOUNT_PARSE_SOFT_FAIL 0x04
void parse(std::istream& in, unsigned char flags = 0); bool parse(std::istream& in, unsigned char flags = 0);
void parse(const std::string& str, unsigned char flags = 0); bool parse(const std::string& str, unsigned char flags = 0);
void reduce(); void reduce();
amount_t reduced() const { amount_t reduced() const {

View file

@ -772,29 +772,21 @@ value_expr_t * parse_value_term(std::istream& in, scope_t * scope,
// When in relaxed parsing mode, we do want to migrate commodity // When in relaxed parsing mode, we do want to migrate commodity
// flags, so that any precision specified by the user updates // flags, so that any precision specified by the user updates
// the current maximum precision displayed. // the current maximum precision displayed.
try { pos = (long)in.tellg();
pos = (long)in.tellg();
unsigned char parse_flags = 0; unsigned char parse_flags = 0;
if (flags & PARSE_VALEXPR_NO_MIGRATE) if (flags & PARSE_VALEXPR_NO_MIGRATE)
parse_flags |= AMOUNT_PARSE_NO_MIGRATE; parse_flags |= AMOUNT_PARSE_NO_MIGRATE;
if (flags & PARSE_VALEXPR_NO_REDUCE) if (flags & PARSE_VALEXPR_NO_REDUCE)
parse_flags |= AMOUNT_PARSE_NO_REDUCE; parse_flags |= AMOUNT_PARSE_NO_REDUCE;
temp.parse(in, parse_flags); if (! temp.parse(in, parse_flags | AMOUNT_PARSE_SOFT_FAIL)) {
} in.clear();
catch (amount_error * err) { in.seekg(pos, std::ios::beg);
// If the amount had no commodity, it must be an unambiguous c = prev_c;
// variable reference goto parse_ident;
if (std::strcmp(err->what(), "No quantity specified for amount") == 0) {
in.clear();
in.seekg(pos, std::ios::beg);
c = prev_c;
goto parse_ident;
} else {
throw err;
}
} }
node.reset(new value_expr_t(value_expr_t::CONSTANT)); node.reset(new value_expr_t(value_expr_t::CONSTANT));
node->value = new value_t(temp); node->value = new value_t(temp);
goto parsed; goto parsed;