summaryrefslogtreecommitdiff
path: root/src/predicate.cc
diff options
context:
space:
mode:
authorJohn Wiegley <johnw@newartisans.com>2009-02-07 00:04:33 -0400
committerJohn Wiegley <johnw@newartisans.com>2009-02-07 00:04:33 -0400
commit72b04f69e569eb9ba4c8c903e21dcd0ebfda23cb (patch)
tree11ca50b82ed24ffccd668ce4d3c114c19a3b8bd0 /src/predicate.cc
parente5befb01026d169d1a43bf7b3024d6391d5aee74 (diff)
downloadfork-ledger-72b04f69e569eb9ba4c8c903e21dcd0ebfda23cb.tar.gz
fork-ledger-72b04f69e569eb9ba4c8c903e21dcd0ebfda23cb.tar.bz2
fork-ledger-72b04f69e569eb9ba4c8c903e21dcd0ebfda23cb.zip
Corrected parsing of ) in command arg predicate expressions.
Diffstat (limited to 'src/predicate.cc')
-rw-r--r--src/predicate.cc49
1 files changed, 33 insertions, 16 deletions
diff --git a/src/predicate.cc b/src/predicate.cc
index 331e9211..26d9279d 100644
--- a/src/predicate.cc
+++ b/src/predicate.cc
@@ -41,29 +41,33 @@ string args_to_predicate_expr(value_t::sequence_t::const_iterator begin,
bool only_parenthesis;
while (begin != end) {
- string arg = (*begin).as_string();
- bool parse_argument = true;
+ string arg = (*begin).as_string();
+ string prefix;
+
+ bool parse_argument = true;
+ bool only_closed_parenthesis = false;;
if (arg == "not" || arg == "NOT") {
if (append_and)
- expr << " & ";
- expr << " ! ";
+ prefix = " & ! ";
+ else
+ prefix = " ! ";
parse_argument = false;
append_and = false;
}
else if (arg == "and" || arg == "AND") {
- expr << " & ";
+ prefix = " & ";
parse_argument = false;
append_and = false;
}
else if (arg == "or" || arg == "OR") {
- expr << " | ";
+ prefix = " | ";
parse_argument = false;
append_and = false;
}
else if (append_and) {
if (! only_parenthesis)
- expr << " & ";
+ prefix = " & ";
}
else {
append_and = true;
@@ -96,6 +100,8 @@ string args_to_predicate_expr(value_t::sequence_t::const_iterator begin,
only_parenthesis = true;
+ std::ostringstream buf;
+
for (const char * c = arg.c_str(); *c != '\0'; c++) {
bool consumed = false;
@@ -104,21 +110,25 @@ string args_to_predicate_expr(value_t::sequence_t::const_iterator begin,
if (in_prefix) {
switch (*c) {
+ case ')':
+ if (only_parenthesis)
+ only_closed_parenthesis = true;
+ break;
case '(':
break;
case '@':
- expr << "(payee =~ /";
+ buf << "(payee =~ /";
found_specifier = true;
consumed = true;
break;
case '=':
- expr << "(";
+ buf << "(";
found_specifier = true;
no_final_slash = true;
consumed = true;
break;
case '&':
- expr << "(note =~ /";
+ buf << "(note =~ /";
found_specifier = true;
consumed = true;
break;
@@ -126,14 +136,14 @@ string args_to_predicate_expr(value_t::sequence_t::const_iterator begin,
bool found_metadata = false;
for (const char *q = c; *q != '\0'; q++)
if (*q == '=') {
- expr << "has_tag(/"
+ buf << "has_tag(/"
<< string(c + 1, q - c - 1) << "/, /";
found_metadata = true;
c = q;
break;
}
if (! found_metadata) {
- expr << "has_tag(/";
+ buf << "has_tag(/";
}
found_specifier = true;
consumed = true;
@@ -143,7 +153,7 @@ string args_to_predicate_expr(value_t::sequence_t::const_iterator begin,
case '_':
default:
if (! found_specifier) {
- expr << "(account =~ /";
+ buf << "(account =~ /";
found_specifier = true;
}
in_prefix = false;
@@ -155,8 +165,8 @@ string args_to_predicate_expr(value_t::sequence_t::const_iterator begin,
if (! in_suffix) {
if (found_specifier) {
if (! no_final_slash)
- expr << "/";
- expr << ")";
+ buf << "/";
+ buf << ")";
}
in_suffix = true;
}
@@ -169,9 +179,14 @@ string args_to_predicate_expr(value_t::sequence_t::const_iterator begin,
}
if (! consumed)
- expr << *c;
+ buf << *c;
}
+ if (! prefix.empty() && ! only_closed_parenthesis)
+ expr << prefix;
+
+ expr << buf.str();
+
if (! in_suffix) {
if (found_specifier) {
if (! no_final_slash)
@@ -179,6 +194,8 @@ string args_to_predicate_expr(value_t::sequence_t::const_iterator begin,
expr << ")";
}
}
+ } else {
+ expr << prefix;
}
begin++;