summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Wiegley <johnw@newartisans.com>2008-07-26 23:55:06 -0400
committerJohn Wiegley <johnw@newartisans.com>2008-07-26 23:55:06 -0400
commit9b7725ee181617b2e0ea13189837b0724ab964b8 (patch)
treec69dd5865a7c6e32ff824984a914924450ca4947
parent7848dbd7f76e580760b585eba3f67cf3a4ebaed9 (diff)
downloadfork-ledger-9b7725ee181617b2e0ea13189837b0724ab964b8.tar.gz
fork-ledger-9b7725ee181617b2e0ea13189837b0724ab964b8.tar.bz2
fork-ledger-9b7725ee181617b2e0ea13189837b0724ab964b8.zip
Added a simple optimization to the way amount strings are parsed.
-rw-r--r--amount.cc14
-rw-r--r--amount.h5
-rw-r--r--valexpr.cc32
3 files changed, 25 insertions, 26 deletions
diff --git a/amount.cc b/amount.cc
index 1ac2f407..3a10828c 100644
--- a/amount.cc
+++ b/amount.cc
@@ -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);
diff --git a/amount.h b/amount.h
index 3df04c1d..ef1d2a3d 100644
--- a/amount.h
+++ b/amount.h
@@ -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 {
diff --git a/valexpr.cc b/valexpr.cc
index 5b5d29ba..4fed821e 100644
--- a/valexpr.cc
+++ b/valexpr.cc
@@ -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;