From c8d9a2a268724d39f1f15541a2decfe6f0bb7358 Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Sun, 12 Jun 2011 09:17:50 -0400 Subject: [PATCH] Expressions - Support and documentation for rc.patterns, which enables/disables support for /pattern/ command line arguments. - Support and documentation for rc.expressions, which enables/disables support for command line expressions. - Now canonicalizes attribute names. - Now canonicalizes modifier names. - New colorization (temporary) that colors all Arguments::dump output green when processed. - New distinction between 'old' and 'new' style command lines. Old style is "pro:A +foo pri.not:M" with implicit "and" operators. New style includes operators but does not include "+foo" and "/foo/". - Many tokens are converted directly to primitive types (int, number, string) when no further processing is required. - Restored CmdShow to functionality, and linearized the list of supported configuration variables, for easier insertion. - Modified arguments.t.cpp unit tests. --- doc/man/taskrc.5.in | 10 ++ src/Arguments.cpp | 191 +++++++++++++++++++++++++++++---------- src/Arguments.h | 3 + src/Config.cpp | 2 + src/Expression.cpp | 189 +++++++++++++++++++++++++++++--------- src/Expression.h | 3 + src/commands/CmdShow.cpp | 189 ++++++++++++++++++++++++++++++-------- test/arguments.t.cpp | 32 +------ 8 files changed, 462 insertions(+), 157 deletions(-) diff --git a/doc/man/taskrc.5.in b/doc/man/taskrc.5.in index 084c40bb0..cd6b42ab5 100644 --- a/doc/man/taskrc.5.in +++ b/doc/man/taskrc.5.in @@ -299,6 +299,16 @@ among users that are not comfortable with regular expressions. .B xterm.title=no Sets the xterm window title when reports are run. Defaults to off. +.TP +.B patterns=on +Enables or disables pattern support on the command line, such as /foo/. +Defaults to on. + +.TP +.B expressions=on +Enables or disables algebraic expression support on the command line, such as +"due=", 10, 'b', 'l' }, // Greater than or equal - { "ge", 10, 'b', 'l' }, // Greater than or equal - { ">", 10, 'b', 'l' }, // Greater than - { "gt", 10, 'b', 'l' }, // Greater than + { "<", 10, 'b', 1, 'l' }, // Less than + { "lt", 10, 'b', 0, 'l' }, // Less than + { "<=", 10, 'b', 1, 'l' }, // Less than or equal + { "le", 10, 'b', 0, 'l' }, // Less than or equal + { ">=", 10, 'b', 1, 'l' }, // Greater than or equal + { "ge", 10, 'b', 0, 'l' }, // Greater than or equal + { ">", 10, 'b', 1, 'l' }, // Greater than + { "gt", 10, 'b', 0, 'l' }, // Greater than - { "~", 9, 'b', 'l' }, // Regex match - { "!~", 9, 'b', 'l' }, // Regex non-match - { "=", 9, 'b', 'l' }, // Equal - { "eq", 9, 'b', 'l' }, // Equal - { "!=", 9, 'b', 'l' }, // Inequal - { "ne", 9, 'b', 'l' }, // Inequal + { "~", 9, 'b', 1, 'l' }, // Regex match + { "!~", 9, 'b', 1, 'l' }, // Regex non-match + { "=", 9, 'b', 1, 'l' }, // Equal + { "eq", 9, 'b', 0, 'l' }, // Equal + { "!=", 9, 'b', 1, 'l' }, // Inequal + { "ne", 9, 'b', 0, 'l' }, // Inequal - { "and", 5, 'b', 'l' }, // Conjunction + { "and", 5, 'b', 0, 'l' }, // Conjunction - { "or", 4, 'b', 'l' }, // Disjunction + { "or", 4, 'b', 0, 'l' }, // Disjunction - { "(", 0, 'b', 'l' }, // Precedence start - { ")", 0, 'b', 'l' }, // Precedence end + { "(", 0, 'b', 1, 'l' }, // Precedence start + { ")", 0, 'b', 1, 'l' }, // Precedence end }; -#define NUM_MODIFIER_NAMES (sizeof (modifierNames) / sizeof (modifierNames[0])) -#define NUM_OPERATORS (sizeof (operators) / sizeof (operators[0])) +#define NUM_ATT_NAMES (sizeof (attributeNames) / sizeof (attributeNames[0])) +#define NUM_MODIFIABLE_ATT_NAMES (sizeof (modifiableAttributeNames) / sizeof (modifiableAttributeNames[0])) +#define NUM_MODIFIER_NAMES (sizeof (modifierNames) / sizeof (modifierNames[0])) +#define NUM_OPERATORS (sizeof (operators) / sizeof (operators[0])) static const char* non_word_chars = " +-*/%()=<>!~"; @@ -181,6 +214,10 @@ void Arguments::categorize () bool found_something_after_sequence = false; bool found_non_sequence = false; + // Configurable support. + bool enable_expressions = context.config.getBoolean ("expressions"); + bool enable_patterns = context.config.getBoolean ("patterns"); + // Generate a vector of command keywords against which autoComplete can run. std::vector keywords; std::map ::iterator k; @@ -312,7 +349,7 @@ void Arguments::categorize () } // /pattern/ - else if (is_pattern (arg->first)) + else if (enable_patterns && is_pattern (arg->first)) { found_non_sequence = true; if (found_sequence) @@ -332,7 +369,7 @@ void Arguments::categorize () } // - else if (is_expression (arg->first)) + else if (enable_expressions && is_expression (arg->first)) { found_non_sequence = true; if (found_sequence) @@ -636,8 +673,9 @@ bool Arguments::is_attr (const std::string& input) n.getUntilEOS (value) || n.depleted ()) { - // TODO Validate and expand attribute name - return true; + // Validate and canonicalize attribute name. + if (is_attribute (name, name)) + return true; } } } @@ -688,9 +726,10 @@ bool Arguments::is_attmod (const std::string& input) { return ! is_expression (value); - // TODO Validate and expand attribute name - // TODO Validate and expand modifier name - return true; + // Validate and canonicalize attribute and modifier names. + if (is_attribute (name, name) && + is_modifier (modifier)) + return true; } } } @@ -844,6 +883,57 @@ bool Arguments::is_operator ( return false; } +//////////////////////////////////////////////////////////////////////////////// +bool Arguments::is_symbol_operator (const std::string& input) +{ + for (unsigned int i = 0; i < NUM_OPERATORS; ++i) + if (operators[i].symbol && + operators[i].op == input) + return true; + + return false; +} + +//////////////////////////////////////////////////////////////////////////////// +bool Arguments::is_attribute (const std::string& input, std::string& canonical) +{ + // Guess at the full attribute name. + std::vector candidates; + for (unsigned i = 0; i < NUM_ATT_NAMES; ++i) + candidates.push_back (attributeNames[i]); + + for (unsigned i = 0; i < NUM_MODIFIABLE_ATT_NAMES; ++i) + candidates.push_back (modifiableAttributeNames[i]); + + std::vector matches; + autoComplete (input, candidates, matches); + + if (matches.size () == 1) + { + canonical = matches[0]; + return true; + } + + return false; +} + +//////////////////////////////////////////////////////////////////////////////// +bool Arguments::is_modifier (const std::string& input) +{ + // Guess at the full attribute name. + std::vector candidates; + for (unsigned i = 0; i < NUM_MODIFIER_NAMES; ++i) + candidates.push_back (modifierNames[i]); + + std::vector matches; + autoComplete (input, candidates, matches); + + if (matches.size () == 1) + return true; + + return false; +} + //////////////////////////////////////////////////////////////////////////////// bool Arguments::is_expression (const std::string& input) { @@ -1322,16 +1412,23 @@ void Arguments::dump (const std::string& label) color_map["command"] = Color ("black on cyan"); color_map["rc"] = Color ("bold white on red"); color_map["override"] = Color ("white on red"); - color_map["tag"] = Color ("green on gray3"); - color_map["pattern"] = Color ("cyan on gray3"); - color_map["attr"] = Color ("bold red on gray3"); - color_map["attmod"] = Color ("bold red on gray3"); - color_map["id"] = Color ("yellow on gray3"); - color_map["uuid"] = Color ("yellow on gray3"); - color_map["subst"] = Color ("bold cyan on gray3"); - color_map["op"] = Color ("bold blue on gray3"); - color_map["exp"] = Color ("bold green on gray5"); - color_map["none"] = Color ("white on gray3"); + color_map["tag"] = Color ("green on gray2"); + color_map["pattern"] = Color ("cyan on gray2"); + color_map["attr"] = Color ("bold red on gray2"); + color_map["attmod"] = Color ("bold red on gray2"); + color_map["id"] = Color ("yellow on gray2"); + color_map["uuid"] = Color ("yellow on gray2"); + color_map["subst"] = Color ("bold cyan on gray2"); + color_map["exp"] = Color ("bold green on gray2"); + color_map["none"] = Color ("white on gray2"); + + // Fundamentals. + color_map["lvalue"] = Color ("bold green on rgb010"); + color_map["op"] = Color ("white on rgb010"); + color_map["int"] = Color ("bold yellow on rgb010"); + color_map["number"] = Color ("bold yellow on rgb010"); + color_map["string"] = Color ("bold yellow on rgb010"); + color_map["rx"] = Color ("bold red on rgb010"); Color color_debug (context.config.get ("color.debug")); std::stringstream out; diff --git a/src/Arguments.h b/src/Arguments.h index c08f12e8f..e0e042328 100644 --- a/src/Arguments.h +++ b/src/Arguments.h @@ -66,6 +66,9 @@ public: static bool is_tag (const std::string&); static bool is_operator (const std::string&); static bool is_operator (const std::string&, char&, int&, char&); + static bool is_symbol_operator (const std::string&); + static bool is_attribute (const std::string&, std::string&); + static bool is_modifier (const std::string&); static bool is_expression (const std::string&); // TODO Decide if these are really useful. diff --git a/src/Config.cpp b/src/Config.cpp index f8a9d4fc4..531736aa0 100644 --- a/src/Config.cpp +++ b/src/Config.cpp @@ -95,6 +95,8 @@ std::string Config::defaults = "burndown.bias=0.666 # Weighted mean bias toward recent data\n" "regex=no # Assume all search/filter strings are regexes\n" "xterm.title=no # Sets xterm title for some commands\n" + "expressions=on # Support for algebraic expressions\n" + "patterns=on # Support for regex patterns\n" "\n" "# Dates\n" "dateformat=m/d/Y # Preferred input and display date format\n" diff --git a/src/Expression.cpp b/src/Expression.cpp index eab4b187b..10be61f77 100644 --- a/src/Expression.cpp +++ b/src/Expression.cpp @@ -25,12 +25,12 @@ // //////////////////////////////////////////////////////////////////////////////// -#include // TODO Remove. #include #include #include #include #include +#include #include #include #include @@ -44,15 +44,26 @@ Expression::Expression (Arguments& arguments) { _args.dump ("Expression::Expression"); - expand_sequence (); - implicit_and (); - expand_tag (); - expand_pattern (); // Configurable - expand_attr (); - expand_attmod (); - expand_word (); - expand_expression (); // Configurable - postfix (); + if (is_new_style () && context.config.getBoolean ("expressions")) + { + context.debug ("Filter --> new"); + expand_sequence (); + expand_tokens (); + postfix (); + } + else + { + context.debug ("Filter --> old"); + expand_sequence (); + implicit_and (); + expand_tag (); + expand_pattern (); + expand_attr (); + expand_attmod (); + expand_word (); + expand_expression (); + postfix (); + } } //////////////////////////////////////////////////////////////////////////////// @@ -174,6 +185,42 @@ void Expression::expand_sequence () _args.dump ("Expression::expand_sequence"); } +//////////////////////////////////////////////////////////////////////////////// +// Nibble the whole thing. +void Expression::expand_tokens () +{ + Arguments temp; + + // Get a list of all operators. + std::vector operators = Arguments::operator_list (); + + // Look at all args. + std::string s; + int i; + double d; + std::vector >::iterator arg; + for (arg = _args.begin (); arg != _args.end (); ++arg) + { + Nibbler n (arg->first); + + if (n.getQuoted ('"', s, true) || + n.getQuoted ('\'', s, true)) + temp.push_back (std::make_pair (s, "string")); + + else if (n.getNumber (d)) + temp.push_back (std::make_pair (format (d), "number")); + + else if (n.getInt (i)) + temp.push_back (std::make_pair (format (i), "int")); + + else + temp.push_back (*arg); + } + + _args.swap (temp); + _args.dump ("Expression::expand_tokens"); +} + //////////////////////////////////////////////////////////////////////////////// // Inserts the 'and' operator by default between terms that are not separated by // at least one operator. @@ -230,7 +277,7 @@ void Expression::expand_tag () temp.push_back (std::make_pair ("tags", "lvalue")); temp.push_back (std::make_pair (type == '+' ? "~" : "!~", "op")); - temp.push_back (std::make_pair (value, "rvalue")); + temp.push_back (std::make_pair (value, "string")); delta = true; } else @@ -262,7 +309,7 @@ void Expression::expand_pattern () temp.push_back (std::make_pair ("description", "lvalue")); temp.push_back (std::make_pair ("~", "op")); - temp.push_back (std::make_pair (value, "rvalue")); + temp.push_back (std::make_pair (value, "rx")); delta = true; } else @@ -293,6 +340,7 @@ void Expression::expand_attr () std::string name; std::string value; Arguments::extract_attr (arg->first, name, value); + Arguments::is_attribute (name, name); // Always quote the value, so that empty values, or values containing spaces // are preserved. @@ -327,13 +375,13 @@ void Expression::expand_attmod () { if (arg->second == "attmod") { - // TODO Should canonicalize 'name'. std::string name; - // TODO Should canonicalize 'mod'. std::string mod; std::string value; std::string sense; Arguments::extract_attmod (arg->first, name, mod, value, sense); + Arguments::is_attribute (name, name); + Arguments::is_modifier (mod); // Always quote the value, so that empty values, or values containing spaces // are preserved. @@ -356,13 +404,13 @@ void Expression::expand_attmod () { temp.push_back (std::make_pair (name, "lvalue")); temp.push_back (std::make_pair ("==", "op")); - temp.push_back (std::make_pair ("\"\"", "rvalue")); + temp.push_back (std::make_pair ("\"\"", "string")); } else if (mod == "any") { temp.push_back (std::make_pair (name, "lvalue")); temp.push_back (std::make_pair ("!=", "op")); - temp.push_back (std::make_pair ("\"\"", "rvalue")); + temp.push_back (std::make_pair ("\"\"", "string")); } else if (mod == "is" || mod == "equals") { @@ -443,7 +491,7 @@ void Expression::expand_word () { temp.push_back (std::make_pair ("description", "lvalue")); temp.push_back (std::make_pair ("~", "op")); - temp.push_back (std::make_pair (arg->first, "rvalue")); + temp.push_back (std::make_pair ("\"" + arg->first + "\"", "rvalue")); delta = true; } @@ -477,34 +525,75 @@ void Expression::expand_expression () { if (arg->second == "exp") { - // Remove quotes. - arg->first = unquoteText (arg->first); + // Split expression into space-separated tokens. + std::vector tokens; + split (tokens, unquoteText (arg->first), ' '); - if (Date::valid (arg->first, context.config.get ("dateformat"))) - temp.push_back (std::make_pair (arg->first, "date")); - - else if (Duration::valid (arg->first)) - temp.push_back (std::make_pair (arg->first, "duration")); - - // The expression does not appear to be syntactic sugar, so it should be - // lexed. - else + std::vector ::iterator token; + for (token = tokens.begin (); token != tokens.end (); ++token) { - Lexer lexer (arg->first); - lexer.skipWhitespace (true); - lexer.coalesceAlpha (true); - lexer.coalesceDigits (true); - lexer.coalesceQuoted (true); + if (Date::valid (*token, context.config.get ("dateformat"))) + temp.push_back (std::make_pair (*token, "date")); - std::vector tokens; - lexer.tokenize (tokens); + else if (Duration::valid (*token)) + temp.push_back (std::make_pair (*token, "duration")); - std::vector ::iterator token; - for (token = tokens.begin (); token != tokens.end (); ++token) - temp.push_back ( - std::make_pair ( - *token, - (_args.is_operator (*token) ? "op" : "dom"))); + else if (Arguments::is_id (*token)) + temp.push_back (std::make_pair (*token, "int")); + + else if (Arguments::is_uuid (*token)) + temp.push_back (std::make_pair (*token, "string")); + + else if (Arguments::is_operator (*token)) + temp.push_back (std::make_pair (*token, "op")); + + // The expression does not appear to be syntactic sugar, so it should be + // lexed. + else + { + Lexer lexer (*token); + lexer.skipWhitespace (true); + lexer.coalesceAlpha (true); + lexer.coalesceDigits (true); + lexer.coalesceQuoted (true); + + // Each operator of length > 1 is a special token. + std::vector ::iterator op; + for (op = operators.begin (); op != operators.end (); ++op) + if (op->length () > 1) + lexer.specialToken (*op); + + std::vector ltokens; + lexer.tokenize (ltokens); + + std::vector ::iterator ltoken; + for (ltoken = ltokens.begin (); ltoken != ltokens.end (); ++ltoken) + { + if (Date::valid (*ltoken, context.config.get ("dateformat"))) + temp.push_back (std::make_pair (*ltoken, "date")); + + else if (Duration::valid (*ltoken)) + temp.push_back (std::make_pair (*ltoken, "duration")); + + else if (Arguments::is_id (*ltoken)) + temp.push_back (std::make_pair (*ltoken, "int")); + + else if (Arguments::is_uuid (*ltoken)) + temp.push_back (std::make_pair (*ltoken, "string")); + + else if (Arguments::is_operator (*ltoken)) + temp.push_back (std::make_pair (*ltoken, "op")); + + else if (Arguments::is_id (*ltoken)) + temp.push_back (std::make_pair (*ltoken, "int")); + + else if (Arguments::is_uuid (*ltoken)) + temp.push_back (std::make_pair (*ltoken, "string")); + + else + temp.push_back (std::make_pair (*ltoken, "lvalue")); + } + } } delta = true; @@ -624,3 +713,21 @@ void Expression::postfix () } //////////////////////////////////////////////////////////////////////////////// +// Test whether the _original arguments are old style or new style. +// +// Old style: no single argument corresponds to an operator, ie no 'and', 'or', +// etc. +// +// New style: at least one argument that is an operator. +// +bool Expression::is_new_style () +{ + std::vector >::iterator arg; + for (arg = _args.begin (); arg != _args.end (); ++arg) + if (Arguments::is_symbol_operator (arg->first)) + return true; + + return false; +} + +//////////////////////////////////////////////////////////////////////////////// diff --git a/src/Expression.h b/src/Expression.h index 4eea000fe..d92d333a9 100644 --- a/src/Expression.h +++ b/src/Expression.h @@ -49,8 +49,11 @@ private: void expand_attmod (); void expand_word (); void expand_expression (); + void expand_tokens (); void postfix (); + bool is_new_style (); + private: Arguments _args; }; diff --git a/src/commands/CmdShow.cpp b/src/commands/CmdShow.cpp index dcb84e662..f214480e4 100644 --- a/src/commands/CmdShow.cpp +++ b/src/commands/CmdShow.cpp @@ -53,7 +53,6 @@ CmdShow::CmdShow () int CmdShow::execute (std::string& output) { int rc = 0; -/* std::stringstream out; // Obtain the arguments from the description. That way, things like '--' @@ -68,42 +67,141 @@ int CmdShow::execute (std::string& output) // Note that there is a leading and trailing space, to make it easier to // search for whole words. std::string recognized = - " annotations avoidlastcolumn bulk burndown.bias calendar.details " - "calendar.details.report calendar.holidays calendar.legend color " - "calendar.offset calendar.offset.value color.active color.due " - "color.due.today color.blocked color.burndown.done color.burndown.pending " - "color.burndown.started color.overdue color.pri.H color.pri.L color.pri.M " - "color.pri.none color.recurring color.tagged color.footnote color.header " - "color.debug color.alternate color.calendar.today color.calendar.due " - "color.calendar.due.today color.calendar.overdue regex " - "color.calendar.weekend color.calendar.holiday color.calendar.weeknumber " - "color.summary.background color.summary.bar color.history.add " - "color.history.done color.history.delete color.undo.before color.label " - "color.sync.added color.sync.changed color.sync.rejected color.undo.after " - "confirmation data.location dateformat dateformat.holiday " - "dateformat.report dateformat.annotation debug default.command default.due " - "default.priority default.project defaultwidth dependency.indicator due " - "dependency.confirmation dependency.reminder detection locale " - "displayweeknumber export.ical.class echo.command fontunderline gc locking " - "monthsperline nag journal.time journal.time.start.annotation journal.info " - "journal.time.stop.annotation project shadow.command shadow.file " - "shadow.notify weekstart editor edit.verbose import.synonym.id " - "import.synonym.uuid complete.all.projects complete.all.tags " - "search.case.sensitive extensions active.indicator tag.indicator " - "recurrence.indicator recurrence.limit list.all.projects list.all.tags " - "undo.style verbose rule.precedence.color merge.autopush merge.default.uri " - "pull.default.uri push.default.uri xterm.title shell.prompt " - "indent.annotation indent.report column.spacing row.padding column.padding " - "import.synonym.status import.synonym.tags import.synonym.entry " - "import.synonym.start import.synonym.due import.synonym.recur " - "import.synonym.end import.synonym.project import.synonym.priority " - "import.synonym.fg import.synonym.bg import.synonym.description " - - "urgency.next.coefficient urgency.blocking.coefficient " - "urgency.blocked.coefficient urgency.due.coefficient " - "urgency.priority.coefficient urgency.waiting.coefficient " - "urgency.active.coefficient urgency.project.coefficient " - "urgency.tags.coefficient urgency.annotations.coefficient "; + " active.indicator" + " annotations" + " avoidlastcolumn" + " bulk" + " burndown.bias" + " calendar.details" + " calendar.details.report" + " calendar.holidays" + " calendar.legend" + " calendar.offset" + " calendar.offset.value" + " color" + " color.active" + " color.alternate" + " color.blocked" + " color.burndown.done" + " color.burndown.pending" + " color.burndown.started" + " color.calendar.due" + " color.calendar.due.today" + " color.calendar.holiday" + " color.calendar.overdue" + " color.calendar.today" + " color.calendar.weekend" + " color.calendar.weeknumber" + " color.debug" + " color.due" + " color.due.today" + " color.footnote" + " color.header" + " color.history.add" + " color.history.delete" + " color.history.done" + " color.label" + " color.overdue" + " color.pri.H" + " color.pri.L" + " color.pri.M" + " color.pri.none" + " color.recurring" + " color.summary.background" + " color.summary.bar" + " color.sync.added" + " color.sync.changed" + " color.sync.rejected" + " color.tagged" + " color.undo.after" + " color.undo.before" + " column.padding" + " column.spacing" + " complete.all.projects" + " complete.all.tags" + " confirmation" + " data.location" + " dateformat" + " dateformat.annotation" + " dateformat.holiday" + " dateformat.report" + " debug" + " default.command" + " default.due" + " default.priority" + " default.project" + " defaultwidth" + " dependency.confirmation" + " dependency.indicator" + " dependency.reminder" + " detection" + " displayweeknumber" + " due" + " echo.command" + " edit.verbose" + " editor" + " export.ical.class" + " expressions" + " extensions" + " fontunderline" + " gc" + " import.synonym.bg" + " import.synonym.description" + " import.synonym.due" + " import.synonym.end" + " import.synonym.entry" + " import.synonym.fg" + " import.synonym.id" + " import.synonym.priority" + " import.synonym.project" + " import.synonym.recur" + " import.synonym.start" + " import.synonym.status" + " import.synonym.tags" + " import.synonym.uuid" + " indent.annotation" + " indent.report" + " journal.info" + " journal.time" + " journal.time.start.annotation" + " journal.time.stop.annotation" + " list.all.projects" + " list.all.tags" + " locale" + " locking" + " merge.autopush" + " merge.default.uri" + " monthsperline" + " nag" + " patterns" + " project" + " pull.default.uri" + " push.default.uri" + " recurrence.indicator" + " recurrence.limit" + " regex" + " row.padding" + " rule.precedence.color" + " search.case.sensitive" + " shadow.command" + " shadow.file" + " shadow.notify" + " shell.prompt" + " tag.indicator" + " undo.style" + " urgency.active.coefficient" + " urgency.annotations.coefficient" + " urgency.blocked.coefficient" + " urgency.blocking.coefficient" + " urgency.due.coefficient" + " urgency.next.coefficient" + " urgency.priority.coefficient" + " urgency.project.coefficient" + " urgency.tags.coefficient" + " urgency.waiting.coefficient" + " verbose" + " weekstart" + " xterm.title"; // This configuration variable is supported, but not documented. It exists // so that unit tests can force color to be on even when the output from task @@ -159,8 +257,24 @@ int CmdShow::execute (std::string& output) std::string section; + // Look for the first plausible argument which could be a pattern + // TODO Replace this 'section' assessment with something that scans the + // arguments and pulls out either or strings to use as + // search items. +/* if (context.args.size () == 2) section = context.args[1]; +*/ +/* + Arguments args = context.args.extract_read_only_filter (); + std::vector >::iterator arg; + for (arg = args.begin (); arg != args.end (); ++arg) + { + if (arg->second == "string") + { + } + } +*/ if (section == "all") section = ""; @@ -309,7 +423,6 @@ int CmdShow::execute (std::string& output) } output = out.str (); -*/ return rc; } diff --git a/test/arguments.t.cpp b/test/arguments.t.cpp index 53d228107..c6e6a2860 100644 --- a/test/arguments.t.cpp +++ b/test/arguments.t.cpp @@ -34,7 +34,7 @@ Context context; //////////////////////////////////////////////////////////////////////////////// int main (int argc, char** argv) { - UnitTest t (113); + UnitTest t (103); const char* fake[] = { @@ -72,12 +72,6 @@ int main (int argc, char** argv) t.ok (Arguments::is_attr ("name:\"one\""), "name:\"one\" -> attr"); t.ok (Arguments::is_attr ("name:\"one two\""), "name:\"one two\" -> attr"); - t.ok (Arguments::is_attr ("name="), "name= -> attr"); - t.ok (Arguments::is_attr ("name=\"\""), "name=\"\" -> attr"); - t.ok (Arguments::is_attr ("name=one"), "name=one -> attr"); - t.ok (Arguments::is_attr ("name=\"one\""), "name=\"one\" -> attr"); - t.ok (Arguments::is_attr ("name=\"one two\""), "name=\"one two\" -> attr"); - t.notok (Arguments::is_attr ("name"), "name -> not attr"); t.notok (Arguments::is_attr ("(name=val and 1<2)"), "(name=val and 1<2) -> not attr"); @@ -88,12 +82,6 @@ int main (int argc, char** argv) t.ok (Arguments::is_attmod ("name.is:\"one\""), "name.is:\"one\" -> attmod"); t.ok (Arguments::is_attmod ("name.is:\"one two\""), "name.is:\"one two\" -> attmod"); - t.ok (Arguments::is_attmod ("name.is="), "name.is= -> attmod"); - t.ok (Arguments::is_attmod ("name.is=\"\""), "name.is=\"\" -> attmod"); - t.ok (Arguments::is_attmod ("name.is=one"), "name.is=one -> attmod"); - t.ok (Arguments::is_attmod ("name.is=\"one\""), "name.is=\"one\" -> attmod"); - t.ok (Arguments::is_attmod ("name.is=\"one two\""), "name.is=\"one two\" -> attmod"); - t.notok (Arguments::is_attmod ("name"), "name -> not attmod"); t.notok (Arguments::is_attmod ("(name=value and 1<2"), "(name=value and 1<2 -> not attmod"); @@ -203,24 +191,6 @@ int main (int argc, char** argv) t.ok (Arguments::valid_modifier ("noword"), "noword -> modifier"); t.notok (Arguments::valid_modifier ("duck"), "duck -> not modified"); - // TODO void extract_uuids (std::vector &); - // TODO void extract_filter (); - // TODO void extract_modifications (); - // TODO void extract_text (); - - // TODO bool extract_attr (const std::string&, std::string&, std::string&); - // TODO bool extract_attmod (const std::string&, std::string&, std::string&, std::string&, std::string&); - // TODO bool extract_subst (const std::string&, std::string&, std::string&, bool&); - // TODO bool extract_pattern (const std::string&, std::string&); - // TODO bool extract_id (const std::string&, std::vector &); - // TODO bool extract_uuid (const std::string&, std::vector &); - // TODO bool extract_tag (const std::string&, char&, std::string&); - // TODO bool extract_operator (const std::string&, std::string&); - - // TODO Arguments extract_read_only_filter (); - // TODO Arguments extract_write_filter (); - // TODO Arguments extract_modifications (); - return 0; }