From 50a9caa541bc7d64e04d6e552dca8e213285c01d Mon Sep 17 00:00:00 2001 From: Paul Beckingham Date: Fri, 15 Apr 2016 19:50:19 -0400 Subject: [PATCH] helper: Reimplemented createFilterFromCLI based on updated CLI --- src/helper.cpp | 163 ++++++++++++++++++++++++++++++++++++++++++------- 1 file changed, 140 insertions(+), 23 deletions(-) diff --git a/src/helper.cpp b/src/helper.cpp index e54fd0f6..65045b55 100644 --- a/src/helper.cpp +++ b/src/helper.cpp @@ -26,6 +26,8 @@ #include #include +#include +#include #include #include #include @@ -112,42 +114,157 @@ bool expandIntervalHint ( //////////////////////////////////////////////////////////////////////////////// // A filter is a placeholder for a start datetime, end datetime and a set of // tags, which makes it essentially an interval. +// +// Supported interval forms: +// ["from"] ["to"|"-" ] +// ["from"] "for" +// ["before"|"after" ] +// Filter createFilterFromCLI (const CLI& cli) { Filter filter; std::string start; std::string end; + std::string duration; + + std::vector args; for (auto& arg : cli._args) { - if (arg.hasTag ("BINARY") || - arg.hasTag ("CMD") || - arg.hasTag ("EXT")) - continue; - - if (arg.hasTag ("HINT")) + if (arg.hasTag ("FILTER")) { - expandIntervalHint (arg.attribute ("canonical"), start, end); - } - else if (arg._lextype == Lexer::Type::date) - { - if (start == "") - start = arg.attribute ("raw"); - else if (end == "") - end = arg.attribute ("raw"); + auto canonical = arg.attribute ("canonical"); + auto raw = arg.attribute ("raw"); - // TODO Is this workable? Using excess date fields as tags. Might just - // be a coincidence. + if (arg.hasTag ("HINT")) + { + if (expandIntervalHint (canonical, start, end)) + { + args.push_back (""); + args.push_back ("-"); + args.push_back (""); + } + + // Hints that are not expandable to a date range are ignored. + } + else if (arg._lextype == Lexer::Type::date) + { + if (start == "") + start = raw; + else if (end == "") + end = raw; + + args.push_back (""); + } + else if (arg._lextype == Lexer::Type::duration) + { + if (duration == "") + duration = raw; + + args.push_back (""); + } + else if (arg.hasTag ("KEYWORD")) + { + args.push_back (raw); + } else - filter.tag (arg.attribute ("raw")); - } - else - { - filter.tag (arg.attribute ("raw")); + { + filter.tag (raw); + } } } - if (start != "") filter.start (Datetime (start)); - if (end != "") filter.end (Datetime (end)); + // + if (args.size () == 1 && + args[0] == "") + { + filter.start (Datetime (start)); + filter.end (Datetime ("now")); + } + + // from + else if (args.size () == 2 && + args[0] == "from" && + args[1] == "") + { + filter.start (Datetime (start)); + filter.end (Datetime ("now")); + } + + // to/- + else if (args.size () == 3 && + args[0] == "" && + (args[1] == "to" || args[1] == "-") && + args[2] == "") + { + filter.start (Datetime (start)); + filter.end (Datetime (end)); + } + + // from/since to/- + else if (args.size () == 4 && + args[0] == "from" && + args[1] == "" && + (args[2] == "to" || args[2] == "-") && + args[3] == "") + { + filter.start (Datetime (start)); + filter.end (Datetime (end)); + } + + // for + else if (args.size () == 3 && + args[0] == "" && + args[1] == "for" && + args[2] == "") + { + filter.start (Datetime (start)); + filter.end (Datetime (start) + Duration (duration).toTime_t ()); + } + + // from/since for + else if (args.size () == 4 && + (args[0] == "from" || args[0] == "since") && + args[1] == "" && + args[2] == "for" && + args[3] == "") + { + filter.start (Datetime (start)); + filter.end (Datetime (start) + Duration (duration).toTime_t ()); + } + + // before + else if (args.size () == 3 && + args[0] == "" && + args[1] == "before" && + args[2] == "") + { + filter.end (Datetime (start) - Duration (duration).toTime_t ()); + filter.end (Datetime (start)); + } + + // after + else if (args.size () == 3 && + args[0] == "" && + args[1] == "after" && + args[2] == "") + { + filter.start (Datetime (start)); + filter.end (Datetime (start) + Duration (duration).toTime_t ()); + } + + // + else if (args.size () == 1 && + args[0] == "") + { + filter.start (Datetime ("now") - Duration (duration).toTime_t ()); + filter.end (Datetime ("now")); + } + + // Unrecognized date range construct. + else if (args.size ()) + { + throw std::string ("Unrecognized date range: '") + join (" ", args) + "'."; + } return filter; }