Skip to content

Commit

Permalink
Added new "bold" modifier to query expressions
Browse files Browse the repository at this point in the history
For example:

  ledger bal assets bold checking

Or you can use expressions:

  ledger bal assets bold '=total > 1000'

This last is identical to saying:

  ledger bal -l 'account =~ /assets/' --bold-if='total > 1000'
  • Loading branch information
jwiegley committed Jun 22, 2010
1 parent 7da2701 commit 3f899c9
Show file tree
Hide file tree
Showing 7 changed files with 175 additions and 133 deletions.
18 changes: 8 additions & 10 deletions src/precmd.cc
Original file line number Diff line number Diff line change
Expand Up @@ -202,25 +202,23 @@ value_t query_command(call_scope_t& args)

query_t query(args.value(), report.what_to_keep(),
! report.HANDLED(collapse));
if (query) {
if (query.has_predicate(query_t::QUERY_LIMIT)) {
call_scope_t sub_args(static_cast<scope_t&>(args));
sub_args.push_back(string_value(query.text()));
sub_args.push_back
(string_value(query.get_predicate(query_t::QUERY_LIMIT).print_to_str()));

parse_command(sub_args);
}

if (query.tokens_remaining()) {
if (query.has_predicate(query_t::QUERY_SHOW)) {
out << std::endl << _("====== Display predicate ======")
<< std::endl << std::endl;

query.parse_again();
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()));

if (query) {
call_scope_t disp_sub_args(static_cast<scope_t&>(args));
disp_sub_args.push_back(string_value(query.text()));

parse_command(disp_sub_args);
}
parse_command(disp_sub_args);
}

return NULL_VALUE;
Expand Down
6 changes: 0 additions & 6 deletions src/predicate.cc
Original file line number Diff line number Diff line change
Expand Up @@ -37,10 +37,4 @@

namespace ledger {

predicate_t::predicate_t(const query_t& other)
: expr_t(other), what_to_keep(other.what_to_keep)
{
TRACE_CTOR(predicate_t, "query_t");
}

} // namespace ledger
20 changes: 12 additions & 8 deletions src/predicate.h
Original file line number Diff line number Diff line change
Expand Up @@ -48,8 +48,6 @@

namespace ledger {

class query_t;

class predicate_t : public expr_t
{
public:
Expand All @@ -63,15 +61,21 @@ class predicate_t : public expr_t
: expr_t(other), what_to_keep(other.what_to_keep) {
TRACE_CTOR(predicate_t, "copy");
}
predicate_t(const query_t& other);

predicate_t(const string& str, const keep_details_t& _what_to_keep,
const parse_flags_t& flags = PARSE_DEFAULT)
predicate_t(ptr_op_t _ptr,
const keep_details_t& _what_to_keep,
scope_t * _context = NULL)
: expr_t(_ptr, _context), what_to_keep(_what_to_keep) {
TRACE_CTOR(predicate_t, "ptr_op_t, keep_details_t, scope_t *");
}
predicate_t(const string& str,
const keep_details_t& _what_to_keep,
const parse_flags_t& flags = PARSE_DEFAULT)
: expr_t(str, flags), what_to_keep(_what_to_keep) {
TRACE_CTOR(predicate_t, "string, keep_details_t, parse_flags_t");
}
predicate_t(std::istream& in, const keep_details_t& _what_to_keep,
const parse_flags_t& flags = PARSE_DEFAULT)
predicate_t(std::istream& in,
const keep_details_t& _what_to_keep,
const parse_flags_t& flags = PARSE_DEFAULT)
: expr_t(in, flags), what_to_keep(_what_to_keep) {
TRACE_CTOR(predicate_t, "std::istream&, keep_details_t, parse_flags_t");
}
Expand Down
136 changes: 76 additions & 60 deletions src/query.cc
Original file line number Diff line number Diff line change
Expand Up @@ -170,20 +170,10 @@ query_t::lexer_t::token_t query_t::lexer_t::next_token()
return token_t(token_t::TOK_META);
else if (ident == "data")
return token_t(token_t::TOK_META);
else if (ident == "show") {
// The "show" keyword is special, and separates a limiting predicate
// from a display predicate.
DEBUG("pred.show", "string = " << (*begin).as_string());
return token_t(token_t::END_REACHED);
}
#if 0
// jww (2009-11-06): This is disabled for the time being.
else if (ident == "date") {
// The date keyword takes the whole of the next string as its argument.
consume_whitespace = true;
return token_t(token_t::TOK_DATE);
}
#endif
else if (ident == "show")
return token_t(token_t::TOK_SHOW);
else if (ident == "bold")
return token_t(token_t::TOK_BOLD);
else if (ident == "expr") {
// The expr keyword takes the whole of the next string as its argument.
consume_next_arg = true;
Expand Down Expand Up @@ -238,10 +228,12 @@ query_t::parser_t::parse_query_term(query_t::lexer_t::token_t::kind_t tok_contex

lexer_t::token_t tok = lexer.next_token();
switch (tok.kind) {
case lexer_t::token_t::TOK_SHOW:
case lexer_t::token_t::TOK_BOLD:
case lexer_t::token_t::END_REACHED:
lexer.push_token(tok);
break;

case lexer_t::token_t::TOK_DATE:
case lexer_t::token_t::TOK_CODE:
case lexer_t::token_t::TOK_PAYEE:
case lexer_t::token_t::TOK_NOTE:
Expand All @@ -257,41 +249,6 @@ query_t::parser_t::parse_query_term(query_t::lexer_t::token_t::kind_t tok_contex
case lexer_t::token_t::TERM:
assert(tok.value);
switch (tok_context) {
case lexer_t::token_t::TOK_DATE: {
expr_t::ptr_op_t ident = new expr_t::op_t(expr_t::op_t::IDENT);
ident->set_ident("date");

date_interval_t interval(*tok.value);

if (interval.start) {
node = new expr_t::op_t(expr_t::op_t::O_GTE);
node->set_left(ident);

expr_t::ptr_op_t arg1 = new expr_t::op_t(expr_t::op_t::VALUE);
arg1->set_value(*interval.start);
node->set_right(arg1);
}

if (interval.finish) {
expr_t::ptr_op_t lt = new expr_t::op_t(expr_t::op_t::O_LT);
lt->set_left(ident);

expr_t::ptr_op_t arg1 = new expr_t::op_t(expr_t::op_t::VALUE);
arg1->set_value(*interval.finish);
lt->set_right(arg1);

if (node) {
expr_t::ptr_op_t prev(node);
node = new expr_t::op_t(expr_t::op_t::O_AND);
node->set_left(prev);
node->set_right(lt);
} else {
node = lt;
}
}
break;
}

case lexer_t::token_t::TOK_EXPR:
node = expr_t(*tok.value).get_op();
break;
Expand Down Expand Up @@ -357,7 +314,7 @@ query_t::parser_t::parse_query_term(query_t::lexer_t::token_t::kind_t tok_contex
break;

case lexer_t::token_t::LPAREN:
node = parse_query_expr(tok_context);
node = parse_query_expr(tok_context, true);
tok = lexer.next_token();
if (tok.kind != lexer_t::token_t::RPAREN)
tok.expected(')');
Expand Down Expand Up @@ -447,18 +404,77 @@ query_t::parser_t::parse_or_expr(lexer_t::token_t::kind_t tok_context)
}

expr_t::ptr_op_t
query_t::parser_t::parse_query_expr(lexer_t::token_t::kind_t tok_context)
query_t::parser_t::parse_query_expr(lexer_t::token_t::kind_t tok_context,
bool subexpression)
{
if (expr_t::ptr_op_t node = parse_or_expr(tok_context)) {
if (expr_t::ptr_op_t next = parse_query_expr(tok_context)) {
expr_t::ptr_op_t prev(node);
node = new expr_t::op_t(expr_t::op_t::O_OR);
node->set_left(prev);
node->set_right(next);
expr_t::ptr_op_t limiter;

while (expr_t::ptr_op_t next = parse_or_expr(tok_context)) {
if (! limiter) {
limiter = next;
} else {
expr_t::ptr_op_t prev(limiter);
limiter = new expr_t::op_t(expr_t::op_t::O_OR);
limiter->set_left(prev);
limiter->set_right(next);
}
return node;
}
return expr_t::ptr_op_t();

if (! subexpression) {
if (limiter)
query_map.insert
(query_map_t::value_type(QUERY_LIMIT, predicate_t(limiter, what_to_keep)));

lexer_t::token_t tok = lexer.peek_token();
while (tok.kind != lexer_t::token_t::END_REACHED) {
switch (tok.kind) {
case lexer_t::token_t::TOK_SHOW: {
lexer.next_token();

expr_t::ptr_op_t node;
while (expr_t::ptr_op_t next = parse_or_expr(tok_context)) {
if (! node) {
node = next;
} else {
expr_t::ptr_op_t prev(node);
node = new expr_t::op_t(expr_t::op_t::O_OR);
node->set_left(prev);
node->set_right(next);
}
}

if (node)
query_map.insert
(query_map_t::value_type(QUERY_SHOW, predicate_t(node, what_to_keep)));
break;
}

case lexer_t::token_t::TOK_BOLD: {
lexer.next_token();

expr_t::ptr_op_t node = parse_or_expr(tok_context);
while (expr_t::ptr_op_t next = parse_or_expr(tok_context)) {
expr_t::ptr_op_t prev(node);
node = new expr_t::op_t(expr_t::op_t::O_OR);
node->set_left(prev);
node->set_right(next);
}

if (node)
query_map.insert
(query_map_t::value_type(QUERY_BOLD, predicate_t(node, what_to_keep)));
break;
}

default:
break;
}

tok = lexer.peek_token();
}
}

return limiter;
}

} // namespace ledger
Loading

0 comments on commit 3f899c9

Please sign in to comment.