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);
}
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:
//
@ -1114,8 +1114,12 @@ void amount_t::parse(std::istream& in, unsigned char flags)
}
}
if (quant.empty())
throw new amount_error("No quantity specified for amount");
if (quant.empty()) {
if (flags & AMOUNT_PARSE_SOFT_FAIL)
return false;
else
throw new amount_error("No quantity specified for amount");
}
_init();
@ -1205,6 +1209,8 @@ void amount_t::parse(std::istream& in, unsigned char flags)
if (! (flags & AMOUNT_PARSE_NO_REDUCE))
reduce();
return true;
}
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);
parse(stream, flags);

View file

@ -263,9 +263,10 @@ class amount_t
#define AMOUNT_PARSE_NO_MIGRATE 0x01
#define AMOUNT_PARSE_NO_REDUCE 0x02
#define AMOUNT_PARSE_SOFT_FAIL 0x04
void parse(std::istream& in, unsigned char flags = 0);
void parse(const std::string& str, unsigned char flags = 0);
bool parse(std::istream& in, unsigned char flags = 0);
bool parse(const std::string& str, unsigned char flags = 0);
void reduce();
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
// flags, so that any precision specified by the user updates
// the current maximum precision displayed.
try {
pos = (long)in.tellg();
pos = (long)in.tellg();
unsigned char parse_flags = 0;
if (flags & PARSE_VALEXPR_NO_MIGRATE)
parse_flags |= AMOUNT_PARSE_NO_MIGRATE;
if (flags & PARSE_VALEXPR_NO_REDUCE)
parse_flags |= AMOUNT_PARSE_NO_REDUCE;
unsigned char parse_flags = 0;
if (flags & PARSE_VALEXPR_NO_MIGRATE)
parse_flags |= AMOUNT_PARSE_NO_MIGRATE;
if (flags & PARSE_VALEXPR_NO_REDUCE)
parse_flags |= AMOUNT_PARSE_NO_REDUCE;
temp.parse(in, parse_flags);
}
catch (amount_error * err) {
// If the amount had no commodity, it must be an unambiguous
// variable reference
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;
}
if (! temp.parse(in, parse_flags | AMOUNT_PARSE_SOFT_FAIL)) {
in.clear();
in.seekg(pos, std::ios::beg);
c = prev_c;
goto parse_ident;
}
node.reset(new value_expr_t(value_expr_t::CONSTANT));
node->value = new value_t(temp);
goto parsed;