summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/precmd.cc10
-rw-r--r--src/query.cc73
-rw-r--r--src/query.h24
-rw-r--r--src/report.cc70
-rw-r--r--src/report.h1
5 files changed, 131 insertions, 47 deletions
diff --git a/src/precmd.cc b/src/precmd.cc
index d9977ab6..8ca27fd8 100644
--- a/src/precmd.cc
+++ b/src/precmd.cc
@@ -202,21 +202,19 @@ value_t query_command(call_scope_t& args)
query_t query(args.value(), report.what_to_keep(),
! report.HANDLED(collapse));
- if (query.has_predicate(query_t::QUERY_LIMIT)) {
+ if (query.has_query(query_t::QUERY_LIMIT)) {
call_scope_t sub_args(static_cast<scope_t&>(args));
- sub_args.push_back
- (string_value(query.get_predicate(query_t::QUERY_LIMIT).print_to_str()));
+ sub_args.push_back(string_value(query.get_query(query_t::QUERY_LIMIT)));
parse_command(sub_args);
}
- if (query.has_predicate(query_t::QUERY_SHOW)) {
+ if (query.has_query(query_t::QUERY_SHOW)) {
out << std::endl << _("====== Display predicate ======")
<< std::endl << std::endl;
call_scope_t disp_sub_args(static_cast<scope_t&>(args));
- disp_sub_args.push_back
- (string_value(query.get_predicate(query_t::QUERY_SHOW).print_to_str()));
+ disp_sub_args.push_back(string_value(query.get_query(query_t::QUERY_SHOW)));
parse_command(disp_sub_args);
}
diff --git a/src/query.cc b/src/query.cc
index 43e3ffed..bed6afae 100644
--- a/src/query.cc
+++ b/src/query.cc
@@ -55,6 +55,10 @@ query_t::lexer_t::token_t query_t::lexer_t::next_token()
resume:
switch (*arg_i) {
+ case '\0':
+ assert(false);
+ break;
+
case '\'':
case '"':
case '/': {
@@ -85,12 +89,17 @@ query_t::lexer_t::token_t query_t::lexer_t::next_token()
if (multiple_args && consume_next_arg) {
consume_next_arg = false;
token_t tok(token_t::TERM, string(arg_i, arg_end));
+ prev_arg_i = arg_i;
arg_i = arg_end;
return tok;
}
bool consume_next = false;
switch (*arg_i) {
+ case '\0':
+ assert(false);
+ break;
+
case ' ':
case '\t':
case '\r':
@@ -121,6 +130,10 @@ query_t::lexer_t::token_t query_t::lexer_t::next_token()
string::const_iterator beg = arg_i;
for (; arg_i != arg_end; ++arg_i) {
switch (*arg_i) {
+ case '\0':
+ assert(false);
+ break;
+
case ' ':
case '\t':
case '\n':
@@ -130,6 +143,7 @@ query_t::lexer_t::token_t query_t::lexer_t::next_token()
else
ident.push_back(*arg_i);
break;
+
case '(':
case ')':
case '&':
@@ -174,6 +188,12 @@ test_ident:
return token_t(token_t::TOK_SHOW);
else if (ident == "bold")
return token_t(token_t::TOK_BOLD);
+ else if (ident == "for")
+ return token_t(token_t::TOK_FOR);
+ else if (ident == "since")
+ return token_t(token_t::TOK_SINCE);
+ else if (ident == "until")
+ return token_t(token_t::TOK_UNTIL);
else if (ident == "expr") {
// The expr keyword takes the whole of the next string as its argument.
consume_next_arg = true;
@@ -230,6 +250,9 @@ query_t::parser_t::parse_query_term(query_t::lexer_t::token_t::kind_t tok_contex
switch (tok.kind) {
case lexer_t::token_t::TOK_SHOW:
case lexer_t::token_t::TOK_BOLD:
+ case lexer_t::token_t::TOK_FOR:
+ case lexer_t::token_t::TOK_SINCE:
+ case lexer_t::token_t::TOK_UNTIL:
case lexer_t::token_t::END_REACHED:
lexer.push_token(tok);
break;
@@ -423,7 +446,8 @@ query_t::parser_t::parse_query_expr(lexer_t::token_t::kind_t tok_context,
if (! subexpression) {
if (limiter)
query_map.insert
- (query_map_t::value_type(QUERY_LIMIT, predicate_t(limiter, what_to_keep)));
+ (query_map_t::value_type
+ (QUERY_LIMIT, predicate_t(limiter, what_to_keep).print_to_str()));
lexer_t::token_t tok = lexer.peek_token();
while (tok.kind != lexer_t::token_t::END_REACHED) {
@@ -445,7 +469,8 @@ query_t::parser_t::parse_query_expr(lexer_t::token_t::kind_t tok_context,
if (node)
query_map.insert
- (query_map_t::value_type(QUERY_SHOW, predicate_t(node, what_to_keep)));
+ (query_map_t::value_type
+ (QUERY_SHOW, predicate_t(node, what_to_keep).print_to_str()));
break;
}
@@ -462,7 +487,49 @@ query_t::parser_t::parse_query_expr(lexer_t::token_t::kind_t tok_context,
if (node)
query_map.insert
- (query_map_t::value_type(QUERY_BOLD, predicate_t(node, what_to_keep)));
+ (query_map_t::value_type
+ (QUERY_BOLD, predicate_t(node, what_to_keep).print_to_str()));
+ break;
+ }
+
+ case lexer_t::token_t::TOK_FOR:
+ case lexer_t::token_t::TOK_SINCE:
+ case lexer_t::token_t::TOK_UNTIL: {
+ tok = lexer.next_token();
+
+ string for_string;
+
+ if (tok.kind == lexer_t::token_t::TOK_SINCE)
+ for_string = "since";
+ else if (tok.kind == lexer_t::token_t::TOK_UNTIL)
+ for_string = "until";
+
+ lexer.consume_next_arg = true;
+ tok = lexer.peek_token();
+
+ while (tok.kind != lexer_t::token_t::END_REACHED) {
+ tok = lexer.next_token();
+ assert(tok.kind == lexer_t::token_t::TERM);
+
+ if (*tok.value == "show" || *tok.value == "bold" ||
+ *tok.value == "for" || *tok.value == "since" ||
+ *tok.value == "until") {
+ lexer.token_cache = lexer_t::token_t();
+ lexer.arg_i = lexer.prev_arg_i;
+ lexer.consume_next_arg = false;
+ break;
+ }
+
+ if (! for_string.empty())
+ for_string += " ";
+ for_string += *tok.value;
+
+ lexer.consume_next_arg = true;
+ tok = lexer.peek_token();
+ }
+
+ if (! for_string.empty())
+ query_map.insert(query_map_t::value_type(QUERY_FOR, for_string));
break;
}
diff --git a/src/query.h b/src/query.h
index e953206a..5a4651a0 100644
--- a/src/query.h
+++ b/src/query.h
@@ -60,6 +60,7 @@ public:
value_t::sequence_t::const_iterator begin;
value_t::sequence_t::const_iterator end;
+ string::const_iterator prev_arg_i;
string::const_iterator arg_i;
string::const_iterator arg_end;
@@ -90,6 +91,9 @@ public:
TOK_SHOW,
TOK_BOLD,
+ TOK_FOR,
+ TOK_SINCE,
+ TOK_UNTIL,
TERM,
@@ -141,6 +145,9 @@ public:
case TOK_EXPR: return "TOK_EXPR";
case TOK_SHOW: return "TOK_SHOW";
case TOK_BOLD: return "TOK_BOLD";
+ case TOK_FOR: return "TOK_FOR";
+ case TOK_SINCE: return "TOK_SINCE";
+ case TOK_UNTIL: return "TOK_UNTIL";
case TERM: return string("TERM(") + *value + ")";
case END_REACHED: return "END_REACHED";
}
@@ -164,6 +171,9 @@ public:
case TOK_EXPR: return "expr";
case TOK_SHOW: return "show";
case TOK_BOLD: return "bold";
+ case TOK_FOR: return "for";
+ case TOK_SINCE: return "since";
+ case TOK_UNTIL: return "until";
case END_REACHED: return "<EOF>";
@@ -201,8 +211,7 @@ public:
arg_i(lexer.arg_i), arg_end(lexer.arg_end),
consume_whitespace(lexer.consume_whitespace),
consume_next_arg(lexer.consume_next_arg),
- multiple_args(lexer.multiple_args),
- token_cache(lexer.token_cache)
+ multiple_args(lexer.multiple_args), token_cache(lexer.token_cache)
{
TRACE_CTOR(query_t::lexer_t, "copy");
}
@@ -225,10 +234,11 @@ public:
enum kind_t {
QUERY_LIMIT,
QUERY_SHOW,
- QUERY_BOLD
+ QUERY_BOLD,
+ QUERY_FOR
};
- typedef std::map<kind_t, predicate_t> query_map_t;
+ typedef std::map<kind_t, string> query_map_t;
protected:
class parser_t
@@ -315,16 +325,16 @@ public:
return parser->parse(subexpression);
}
- bool has_predicate(const kind_t& id) const {
+ bool has_query(const kind_t& id) const {
return parser && parser->query_map.find(id) != parser->query_map.end();
}
- predicate_t get_predicate(const kind_t& id) const {
+ string get_query(const kind_t& id) const {
if (parser) {
query_map_t::const_iterator i = parser->query_map.find(id);
if (i != parser->query_map.end())
return (*i).second;
}
- return predicate_t();
+ return empty_string;
}
bool tokens_remaining() {
diff --git a/src/report.cc b/src/report.cc
index 4a7ed2e5..9d733674 100644
--- a/src/report.cc
+++ b/src/report.cc
@@ -145,26 +145,8 @@ void report_t::normalize_options(const string& verb)
// using -b or -e). Then, if no _duration_ was specified (such as monthly),
// then ignore the period since the begin/end are the only interesting
// details.
- if (HANDLED(period_)) {
- date_interval_t interval(HANDLER(period_).str());
-
- optional<date_t> begin = interval.begin();
- optional<date_t> end = interval.end();
-
- if (! HANDLED(begin_) && begin) {
- string predicate = "date>=[" + to_iso_extended_string(*begin) + "]";
- HANDLER(limit_).on(string("?normalize"), predicate);
- }
- if (! HANDLED(end_) && end) {
- string predicate = "date<[" + to_iso_extended_string(*end) + "]";
- HANDLER(limit_).on(string("?normalize"), predicate);
- }
-
- if (! interval.duration)
- HANDLER(period_).off();
- else if (! HANDLED(sort_all_))
- HANDLER(sort_xacts_).on_only(string("?normalize"));
- }
+ if (HANDLED(period_))
+ normalize_period();
// If -j or -J were specified, set the appropriate format string now so as
// to avoid option ordering issues were we to have done it during the
@@ -254,26 +236,52 @@ void report_t::normalize_options(const string& verb)
}
}
+void report_t::normalize_period()
+{
+ date_interval_t interval(HANDLER(period_).str());
+
+ optional<date_t> begin = interval.begin();
+ optional<date_t> end = interval.end();
+
+ if (! HANDLED(begin_) && begin) {
+ string predicate = "date>=[" + to_iso_extended_string(*begin) + "]";
+ HANDLER(limit_).on(string("?normalize"), predicate);
+ }
+ if (! HANDLED(end_) && end) {
+ string predicate = "date<[" + to_iso_extended_string(*end) + "]";
+ HANDLER(limit_).on(string("?normalize"), predicate);
+ }
+
+ if (! interval.duration)
+ HANDLER(period_).off();
+ else if (! HANDLED(sort_all_))
+ HANDLER(sort_xacts_).on_only(string("?normalize"));
+}
+
void report_t::parse_query_args(const value_t& args, const string& whence)
{
query_t query(args, what_to_keep());
- if (query.has_predicate(query_t::QUERY_LIMIT)) {
- HANDLER(limit_)
- .on(whence, query.get_predicate(query_t::QUERY_LIMIT).print_to_str());
- DEBUG("report.predicate", "Predicate = " << HANDLER(limit_).str());
+ if (query.has_query(query_t::QUERY_LIMIT)) {
+ HANDLER(limit_).on(whence, query.get_query(query_t::QUERY_LIMIT));
+ DEBUG("report.predicate", "Limit predicate = " << HANDLER(limit_).str());
}
- if (query.has_predicate(query_t::QUERY_SHOW)) {
- HANDLER(display_)
- .on(whence, query.get_predicate(query_t::QUERY_SHOW).print_to_str());
+ if (query.has_query(query_t::QUERY_SHOW)) {
+ HANDLER(display_).on(whence, query.get_query(query_t::QUERY_SHOW));
DEBUG("report.predicate", "Display predicate = " << HANDLER(display_).str());
}
- if (query.has_predicate(query_t::QUERY_BOLD)) {
- HANDLER(bold_if_)
- .set_expr(whence, query.get_predicate(query_t::QUERY_BOLD).print_to_str());
- DEBUG("report.predicate", "Bolding predicate = " << HANDLER(display_).str());
+ if (query.has_query(query_t::QUERY_BOLD)) {
+ HANDLER(bold_if_).set_expr(whence, query.get_query(query_t::QUERY_BOLD));
+ DEBUG("report.predicate", "Bolding predicate = " << HANDLER(bold_if_).str());
+ }
+
+ if (query.has_query(query_t::QUERY_FOR)) {
+ HANDLER(period_).on(whence, query.get_query(query_t::QUERY_FOR));
+ DEBUG("report.predicate", "Report period = " << HANDLER(period_).str());
+
+ normalize_period(); // it needs normalization
}
}
diff --git a/src/report.h b/src/report.h
index fc2fc1a2..59a632e6 100644
--- a/src/report.h
+++ b/src/report.h
@@ -126,6 +126,7 @@ public:
}
void normalize_options(const string& verb);
+ void normalize_period();
void parse_query_args(const value_t& args, const string& whence);
void posts_report(post_handler_ptr handler);