Corrected parsing of ) in command arg predicate expressions.

This commit is contained in:
John Wiegley 2009-02-07 00:04:33 -04:00
parent e5befb0102
commit 72b04f69e5

View file

@ -41,29 +41,33 @@ string args_to_predicate_expr(value_t::sequence_t::const_iterator begin,
bool only_parenthesis; bool only_parenthesis;
while (begin != end) { while (begin != end) {
string arg = (*begin).as_string(); string arg = (*begin).as_string();
bool parse_argument = true; string prefix;
bool parse_argument = true;
bool only_closed_parenthesis = false;;
if (arg == "not" || arg == "NOT") { if (arg == "not" || arg == "NOT") {
if (append_and) if (append_and)
expr << " & "; prefix = " & ! ";
expr << " ! "; else
prefix = " ! ";
parse_argument = false; parse_argument = false;
append_and = false; append_and = false;
} }
else if (arg == "and" || arg == "AND") { else if (arg == "and" || arg == "AND") {
expr << " & "; prefix = " & ";
parse_argument = false; parse_argument = false;
append_and = false; append_and = false;
} }
else if (arg == "or" || arg == "OR") { else if (arg == "or" || arg == "OR") {
expr << " | "; prefix = " | ";
parse_argument = false; parse_argument = false;
append_and = false; append_and = false;
} }
else if (append_and) { else if (append_and) {
if (! only_parenthesis) if (! only_parenthesis)
expr << " & "; prefix = " & ";
} }
else { else {
append_and = true; append_and = true;
@ -96,6 +100,8 @@ string args_to_predicate_expr(value_t::sequence_t::const_iterator begin,
only_parenthesis = true; only_parenthesis = true;
std::ostringstream buf;
for (const char * c = arg.c_str(); *c != '\0'; c++) { for (const char * c = arg.c_str(); *c != '\0'; c++) {
bool consumed = false; bool consumed = false;
@ -104,21 +110,25 @@ string args_to_predicate_expr(value_t::sequence_t::const_iterator begin,
if (in_prefix) { if (in_prefix) {
switch (*c) { switch (*c) {
case ')':
if (only_parenthesis)
only_closed_parenthesis = true;
break;
case '(': case '(':
break; break;
case '@': case '@':
expr << "(payee =~ /"; buf << "(payee =~ /";
found_specifier = true; found_specifier = true;
consumed = true; consumed = true;
break; break;
case '=': case '=':
expr << "("; buf << "(";
found_specifier = true; found_specifier = true;
no_final_slash = true; no_final_slash = true;
consumed = true; consumed = true;
break; break;
case '&': case '&':
expr << "(note =~ /"; buf << "(note =~ /";
found_specifier = true; found_specifier = true;
consumed = true; consumed = true;
break; break;
@ -126,14 +136,14 @@ string args_to_predicate_expr(value_t::sequence_t::const_iterator begin,
bool found_metadata = false; bool found_metadata = false;
for (const char *q = c; *q != '\0'; q++) for (const char *q = c; *q != '\0'; q++)
if (*q == '=') { if (*q == '=') {
expr << "has_tag(/" buf << "has_tag(/"
<< string(c + 1, q - c - 1) << "/, /"; << string(c + 1, q - c - 1) << "/, /";
found_metadata = true; found_metadata = true;
c = q; c = q;
break; break;
} }
if (! found_metadata) { if (! found_metadata) {
expr << "has_tag(/"; buf << "has_tag(/";
} }
found_specifier = true; found_specifier = true;
consumed = true; consumed = true;
@ -143,7 +153,7 @@ string args_to_predicate_expr(value_t::sequence_t::const_iterator begin,
case '_': case '_':
default: default:
if (! found_specifier) { if (! found_specifier) {
expr << "(account =~ /"; buf << "(account =~ /";
found_specifier = true; found_specifier = true;
} }
in_prefix = false; in_prefix = false;
@ -155,8 +165,8 @@ string args_to_predicate_expr(value_t::sequence_t::const_iterator begin,
if (! in_suffix) { if (! in_suffix) {
if (found_specifier) { if (found_specifier) {
if (! no_final_slash) if (! no_final_slash)
expr << "/"; buf << "/";
expr << ")"; buf << ")";
} }
in_suffix = true; in_suffix = true;
} }
@ -169,9 +179,14 @@ string args_to_predicate_expr(value_t::sequence_t::const_iterator begin,
} }
if (! consumed) if (! consumed)
expr << *c; buf << *c;
} }
if (! prefix.empty() && ! only_closed_parenthesis)
expr << prefix;
expr << buf.str();
if (! in_suffix) { if (! in_suffix) {
if (found_specifier) { if (found_specifier) {
if (! no_final_slash) if (! no_final_slash)
@ -179,6 +194,8 @@ string args_to_predicate_expr(value_t::sequence_t::const_iterator begin,
expr << ")"; expr << ")";
} }
} }
} else {
expr << prefix;
} }
begin++; begin++;