summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Wiegley <johnw@newartisans.com>2008-08-03 23:44:18 -0400
committerJohn Wiegley <johnw@newartisans.com>2008-08-03 23:44:18 -0400
commitbcffbc96ba88bd19f5f8ac00015ff38131fd6466 (patch)
tree7f4a9646bb05f138b00cdc7127dd45cc05142cb5
parent8a21391d0a6d6187855b40530f25b1d8beb0d67a (diff)
downloadfork-ledger-bcffbc96ba88bd19f5f8ac00015ff38131fd6466.tar.gz
fork-ledger-bcffbc96ba88bd19f5f8ac00015ff38131fd6466.tar.bz2
fork-ledger-bcffbc96ba88bd19f5f8ac00015ff38131fd6466.zip
Regular expressions are working again, such that very basic register reports
are now possible.
-rw-r--r--format.cc413
-rw-r--r--main.cc110
-rw-r--r--mask.cc29
-rw-r--r--mask.h5
-rw-r--r--op.cc42
-rw-r--r--report.cc123
-rw-r--r--report.h23
-rw-r--r--xact.cc6
8 files changed, 158 insertions, 593 deletions
diff --git a/format.cc b/format.cc
index 035f9268..65dfce95 100644
--- a/format.cc
+++ b/format.cc
@@ -272,430 +272,33 @@ void format_t::format(std::ostream& out_str, scope_t& scope)
try {
elem->expr.compile(scope);
+ value_t value;
if (elem->expr.is_function()) {
call_scope_t args(scope);
args.push_back(long(elem->max_width));
- elem->expr.get_function()(args).dump(out, elem->min_width);
+ value = elem->expr.get_function()(args);
} else {
- elem->expr.calc(scope).dump(out, elem->min_width);
+ value = elem->expr.calc(scope);
}
+ value.strip_annotations().dump(out, elem->min_width);
}
catch (const calc_error&) {
out << (string("%") + elem->chars);
}
break;
-#if 0
- case element_t::ACCOUNT_FULLNAME:
- scope.resolve("account").dump(out, elem->min_width);
- break;
- case element_t::ACCOUNT_NAME:
- scope.resolve("account_base").dump(out, elem->min_width);
- break;
-
- case element_t::AMOUNT:
- out << "a";
- //out << scope.resolve("amount");
- break;
- case element_t::TOTAL:
- out << "T";
- //out << scope.resolve("total");
- break;
-
- case element_t::VALUE_EXPR: {
- expr_t * calc;
- switch (elem->type) {
- case element_t::AMOUNT:
- assert(value_expr::amount_expr.get());
- calc = value_expr::amount_expr.get();
- break;
- case element_t::TOTAL:
- assert(value_expr::total_expr.get());
- calc = value_expr::total_expr.get();
- break;
- case element_t::VALUE_EXPR:
- calc = const_cast<value_expr *>(&elem->val_expr);
- break;
- default:
- assert(false);
- break;
- }
- if (! calc)
- break;
-
- value_t value;
- const balance_t * bal = NULL;
-
- calc->compute(value, details);
-
- if (! amount_t::keep_price ||
- ! amount_t::keep_date ||
- ! amount_t::keep_tag) {
- switch (value.type()) {
- case value_t::AMOUNT:
- case value_t::BALANCE:
- case value_t::BALANCE_PAIR:
- value = value.strip_annotations();
- break;
- default:
- break;
- }
- }
-
- bool highlighted = false;
-
- switch (value.type()) {
- case value_t::BOOLEAN:
- out << (value.as_boolean() ? "true" : "false");
- break;
-
- case value_t::INTEGER:
- if (ansi_codes && elem->flags & ELEMENT_HIGHLIGHT) {
- if (ansi_invert) {
- if (value.as_long() > 0) {
- mark_red(out, elem);
- highlighted = true;
- }
- } else {
- if (value.as_long() < 0) {
- mark_red(out, elem);
- highlighted = true;
- }
- }
- }
- out << value.as_long();
- break;
-
- case value_t::DATETIME:
- out << value.as_datetime();
- break;
-
- case value_t::AMOUNT:
- if (ansi_codes && elem->flags & ELEMENT_HIGHLIGHT) {
- if (ansi_invert) {
- if (value.as_amount().sign() > 0) {
- mark_red(out, elem);
- highlighted = true;
- }
- } else {
- if (value.as_amount().sign() < 0) {
- mark_red(out, elem);
- highlighted = true;
- }
- }
- }
- out << value.as_amount();
- break;
-
- case value_t::BALANCE:
- bal = &(value.as_balance());
- // fall through...
-
- case value_t::BALANCE_PAIR:
- if (! bal)
- bal = &(value.as_balance_pair().quantity());
-
- if (ansi_codes && elem->flags & ELEMENT_HIGHLIGHT) {
- if (ansi_invert) {
- if (*bal > 0) {
- mark_red(out, elem);
- highlighted = true;
- }
- } else {
- if (*bal < 0) {
- mark_red(out, elem);
- highlighted = true;
- }
- }
- }
- bal->print(out, elem->min_width,
- (elem->max_width > 0 ?
- elem->max_width : elem->min_width));
-
- ignore_max_width = true;
- break;
- default:
- assert(false);
- break;
- }
-
- if (highlighted)
- mark_plain(out);
- break;
- }
-
- case element_t::OPT_AMOUNT:
- if (details.xact) {
- string disp;
- bool use_disp = false;
-
- if (details.xact->cost && details.xact->amount) {
- std::ostringstream stream;
- if (! details.xact->amount_expr.expr_str.empty())
- stream << details.xact->amount_expr.expr_str;
- else
- stream << details.xact->amount.strip_annotations();
-
- if (details.xact->cost_expr)
- stream << details.xact->cost_expr->expr_str;
- else
- stream << " @ " << amount_t(*details.xact->cost /
- details.xact->amount).unround();
- disp = stream.str();
- use_disp = true;
- }
- else if (details.entry) {
- unsigned int xacts_count = 0;
- xact_t * first = NULL;
- xact_t * last = NULL;
-
- foreach (const transaction_t * xact, details.entry->xacts) {
- if (xact_has_xdata(*xact) &&
- xact_xdata_(*xact).dflags & XACT_TO_DISPLAY) {
- xacts_count++;
- if (! first)
- first = xact;
- last = xact;
- }
- }
-
- use_disp = (xacts_count == 2 && details.xact == last &&
- first->amount == - last->amount);
- }
-
- if (! use_disp) {
- if (! details.xact->amount_expr.expr_str.empty())
- out << details.xact->amount_expr.expr_str;
- else
- out << details.xact->amount.strip_annotations();
- } else {
- out << disp;
- }
- }
- break;
-
- case element_t::SOURCE:
- if (details.entry && details.entry->journal) {
- int idx = details.entry->src_idx;
- foreach (const path& path, details.entry->journal->sources)
- if (! idx--) {
- out << path;
- break;
- }
- }
- break;
-
- case element_t::ENTRY_BEG_POS:
- if (details.entry)
- out << (unsigned long)details.entry->beg_pos;
- break;
-
- case element_t::ENTRY_BEG_LINE:
- if (details.entry)
- out << details.entry->beg_line;
- break;
-
- case element_t::ENTRY_END_POS:
- if (details.entry)
- out << (unsigned long)details.entry->end_pos;
- break;
-
- case element_t::ENTRY_END_LINE:
- if (details.entry)
- out << details.entry->end_line;
- break;
-
- case element_t::XACT_BEG_POS:
- if (details.xact)
- out << (unsigned long)details.xact->beg_pos;
- break;
-
- case element_t::XACT_BEG_LINE:
- if (details.xact)
- out << details.xact->beg_line;
- break;
-
- case element_t::XACT_END_POS:
- if (details.xact)
- out << (unsigned long)details.xact->end_pos;
- break;
-
- case element_t::XACT_END_LINE:
- if (details.xact)
- out << details.xact->end_line;
- break;
-
- case element_t::DATE_STRING:
- out << format_date(scope.resolve("date").as_date());
- break;
-
- case element_t::COMPLETE_DATE_STRING: {
- date_t actual_date;
- date_t effective_date;
- if (details.xact) {
- actual_date = details.xact->actual_date();
- effective_date = details.xact->effective_date();
- }
- else if (details.entry) {
- actual_date = details.entry->actual_date();
- effective_date = details.entry->effective_date();
- }
-
- char abuf[256];
-#if 0
- // jww (2008-04-20): This needs to be rewritten
- std::strftime(abuf, 255, elem->chars.c_str(), actual_date.localtime());
-#else
- abuf[0] = '\0';
-#endif
-
- if (is_valid(effective_date) && effective_date != actual_date) {
- char buf[512];
- char ebuf[256];
-#if 0
- // jww (2008-04-20): This needs to be rewritten
- std::strftime(ebuf, 255, elem->chars.c_str(),
- effective_date.localtime());
-#else
- ebuf[0] = '\0';
-#endif
-
- std::strcpy(buf, abuf);
- std::strcat(buf, "=");
- std::strcat(buf, ebuf);
-
- out << (elem->max_width == 0 ? buf : truncate(buf, elem->max_width));
- } else {
- out << (elem->max_width == 0 ? abuf : truncate(abuf, elem->max_width));
- }
- break;
- }
-
- case element_t::CLEARED:
- if (details.xact) {
- switch (details.xact->state) {
- case xact_t::CLEARED:
- out << "* ";
- break;
- case xact_t::PENDING:
- out << "! ";
- break;
- case xact_t::UNCLEARED:
- break;
- }
- }
- break;
-
- case element_t::ENTRY_CLEARED:
- if (details.entry) {
- xact_t::state_t state;
- if (details.entry->get_state(&state))
- switch (state) {
- case xact_t::CLEARED:
- out << "* ";
- break;
- case xact_t::PENDING:
- out << "! ";
- break;
- case xact_t::UNCLEARED:
- break;
- }
- }
- break;
-
- case element_t::CODE: {
- string temp;
- if (details.entry && details.entry->code) {
- temp += "(";
- temp += *details.entry->code;
- temp += ") ";
- }
- out << temp;
- break;
- }
-
- case element_t::PAYEE:
- scope.resolve("payee").dump(out, elem->min_width);
- break;
-
- case element_t::OPT_NOTE:
- if (details.xact && details.xact->note)
- out << " ; ";
- // fall through...
-
- case element_t::NOTE:
- if (details.xact)
- out << (elem->max_width == 0 ?
- details.xact->note : truncate(*details.xact->note,
- elem->max_width));
- break;
-
- case element_t::OPT_ACCOUNT:
- if (details.entry && details.xact) {
- xact_t::state_t state;
- if (! details.entry->get_state(&state))
- switch (details.xact->state) {
- case xact_t::CLEARED:
- name = "* ";
- break;
- case xact_t::PENDING:
- name = "! ";
- break;
- case xact_t::UNCLEARED:
- break;
- }
- }
- // fall through...
-
- case element_t::ACCOUNT_NAME:
- case element_t::ACCOUNT_FULLNAME:
- if (details.account) {
- name += (elem->type == element_t::ACCOUNT_FULLNAME ?
- details.account->fullname() :
- partial_account_name(*details.account));
-
- if (details.xact && details.xact->has_flags(XACT_VIRTUAL)) {
- if (elem->max_width > 2)
- name = truncate(name, elem->max_width - 2, true);
-
- if (details.xact->has_flags(XACT_BALANCE))
- name = string("[") + name + "]";
- else
- name = string("(") + name + ")";
- }
- else if (elem->max_width > 0)
- name = truncate(name, elem->max_width, true);
-
- out << name;
- } else {
- out << " ";
- }
- break;
-
- case element_t::DEPTH_SPACER:
- for (const account_t * acct = details.account;
- acct;
- acct = acct->parent)
- if (account_has_xdata(*acct) &&
- account_xdata_(*acct).dflags & ACCOUNT_DISPLAYED) {
- if (elem->min_width > 0 || elem->max_width > 0)
- out.width(elem->min_width > elem->max_width ?
- elem->min_width : elem->max_width);
- out << " ";
- }
- break;
-#endif
-
default:
assert(false);
break;
}
string temp = out.str();
+
if (! ignore_max_width &&
elem->max_width > 0 && elem->max_width < temp.length())
- truncate(temp, elem->max_width);
- out_str << temp;
+ out_str << truncate(temp, elem->max_width);
+ else
+ out_str << temp;
}
}
diff --git a/main.cc b/main.cc
index e3a3544a..3365df15 100644
--- a/main.cc
+++ b/main.cc
@@ -52,6 +52,102 @@
#endif
namespace ledger {
+ string args_to_predicate(value_t::sequence_t::const_iterator begin,
+ value_t::sequence_t::const_iterator end)
+ {
+ string acct_value_expr;
+ string payee_value_expr;
+ string note_value_expr;
+
+ string * value_expr;
+
+ enum regexp_kind_t {
+ ACCOUNT_REGEXP,
+ PAYEE_REGEXP,
+ NOTE_REGEXP
+ }
+ kind = ACCOUNT_REGEXP;
+
+ value_expr = &acct_value_expr;
+
+ for ( ; begin != end; begin++) {
+ const string& arg((*begin).as_string());
+
+ if (arg == "--") {
+ kind = PAYEE_REGEXP;
+ value_expr = &payee_value_expr;
+ }
+ else if (arg == "/") {
+ kind = NOTE_REGEXP;
+ value_expr = &note_value_expr;
+ }
+ else {
+ if (! value_expr->empty())
+ *value_expr += "|";
+
+ switch (kind) {
+ case ACCOUNT_REGEXP:
+ *value_expr += "account =~ ";
+ break;
+ case PAYEE_REGEXP:
+ *value_expr += "payee =~ ";
+ break;
+ case NOTE_REGEXP:
+ *value_expr += "note =~ ";
+ break;
+ }
+
+ const char * p = arg.c_str();
+ if (*p == '-') {
+ *value_expr += "!";
+ p++;
+ }
+
+ *value_expr += "/";
+ while (*p) {
+ if (*p == '/')
+ *value_expr += "\\";
+ *value_expr += *p;
+ p++;
+ }
+ *value_expr += "/";
+ }
+ }
+
+ string final_value_expr;
+
+ if (! acct_value_expr.empty()) {
+ if (! payee_value_expr.empty() ||
+ ! note_value_expr.empty())
+ final_value_expr = string("(") + acct_value_expr + ")";
+ else
+ final_value_expr = acct_value_expr;
+ }
+
+ if (! payee_value_expr.empty()) {
+ if (! acct_value_expr.empty())
+ final_value_expr += string("&(") + payee_value_expr + ")";
+ else if (! note_value_expr.empty())
+ final_value_expr = string("(") + payee_value_expr + ")";
+ else
+ final_value_expr = payee_value_expr;
+ }
+
+ if (! note_value_expr.empty()) {
+ if (! acct_value_expr.empty() ||
+ ! payee_value_expr.empty())
+ final_value_expr += string("&(") + note_value_expr + ")";
+ else if (acct_value_expr.empty() &&
+ payee_value_expr.empty())
+ final_value_expr = note_value_expr;
+ }
+
+ DEBUG("report.predicate",
+ "Regexp predicate expression = " << final_value_expr);
+
+ return final_value_expr;
+ }
+
template <class Formatter = format_xacts>
class xacts_report
{
@@ -65,9 +161,19 @@ namespace ledger {
{
ptr_t<std::ostream> ostream(args, 0);
var_t<string> format(args, format_name);
+ report_t& report(find_scope<report_t>(args));
+
+ if (! report.format_string.empty())
+ *format = report.format_string;
+
+ if (! report.predicate.empty())
+ report.predicate = string("(") + report.predicate + ")&";
+ report.predicate +=
+ args_to_predicate(++args.value().as_sequence().begin(),
+ args.value().as_sequence().end());
- find_scope<report_t>(args).xacts_report
- (xact_handler_ptr(new Formatter(*ostream, *format)));
+ report.xacts_report(xact_handler_ptr(new Formatter(*ostream,
+ *format)));
return true;
}
};
diff --git a/mask.cc b/mask.cc
index d3ad539e..b32be359 100644
--- a/mask.cc
+++ b/mask.cc
@@ -34,7 +34,7 @@
namespace ledger {
-mask_t::mask_t(const string& pat) : exclude(false), expr()
+mask_t::mask_t(const string& pat) : expr()
{
TRACE_CTOR(mask_t, "const string&");
*this = pat;
@@ -42,40 +42,17 @@ mask_t::mask_t(const string& pat) : exclude(false), expr()
mask_t& mask_t::operator=(const string& pat)
{
- exclude = false;
-
- const char * p = pat.c_str();
-
- if (*p == '-') {
- exclude = true;
- p++;
- while (std::isspace(*p))
- p++;
- }
- else if (*p == '+') {
- p++;
- while (std::isspace(*p))
- p++;
- }
-
- expr.assign(p);
-
+ expr.assign(pat.c_str(), regex::perl | regex::icase);
return *this;
}
void mask_t::read(const char *& data)
{
- binary::read_number(data, exclude);
-
- string pattern;
- binary::read_string(data, pattern);
-
- *this = pattern;
+ *this = binary::read_string(data);
}
void mask_t::write(std::ostream& out) const
{
- binary::write_number(out, exclude);
binary::write_string(out, expr.str());
}
diff --git a/mask.h b/mask.h
index 538316be..06161d12 100644
--- a/mask.h
+++ b/mask.h
@@ -41,12 +41,11 @@ class mask_t
mask_t();
public:
- bool exclude;
boost::regex expr;
explicit mask_t(const string& pattern);
- mask_t(const mask_t& m) : exclude(m.exclude), expr(m.expr) {
+ mask_t(const mask_t& m) : expr(m.expr) {
TRACE_CTOR(mask_t, "copy");
}
~mask_t() throw() {
@@ -56,7 +55,7 @@ public:
mask_t& operator=(const string& other);
bool match(const string& str) const {
- return boost::regex_match(str, expr) && ! exclude;
+ return boost::regex_search(str, expr);
}
void read(const char *& data);
diff --git a/op.cc b/op.cc
index 15ba749a..b412c47f 100644
--- a/op.cc
+++ b/op.cc
@@ -428,48 +428,6 @@ void expr_t::op_t::compute(value_t& result,
break;
}
- case F_CODE_MASK:
- if (details.entry && details.entry->code)
- result = as_mask().match(*details.entry->code);
- else
- result = false;
- break;
-
- case F_PAYEE_MASK:
- if (details.entry)
- result = as_mask().match(details.entry->payee);
- else
- result = false;
- break;
-
- case F_NOTE_MASK:
- if (details.xact && details.xact->note)
- result = as_mask().match(*details.xact->note);
- else
- result = false;
- break;
-
- case F_ACCOUNT_MASK:
- if (details.account)
- result = as_mask().match(details.account->fullname());
- else
- result = false;
- break;
-
- case F_SHORT_ACCOUNT_MASK:
- if (details.account)
- result = as_mask().match(details.account->name);
- else
- result = false;
- break;
-
- case F_COMMODITY_MASK:
- if (details.xact)
- result = as_mask().match(details.xact->amount.commodity().base_symbol());
- else
- result = false;
- break;
-
case O_ARG: {
long arg_index = 0;
assert(left()->kind == INDEX);
diff --git a/report.cc b/report.cc
index f746b3a0..d5667381 100644
--- a/report.cc
+++ b/report.cc
@@ -35,96 +35,6 @@
namespace ledger {
#if 0
-void
-report_t::regexps_to_predicate(const std::string& command,
- std::list<std::string>::const_iterator begin,
- std::list<std::string>::const_iterator end,
- const bool account_regexp,
- const bool add_account_short_masks,
- const bool logical_and)
-{
- std::string regexps[2];
-
- assert(begin != end);
-
- // Treat the remaining command-line arguments as regular
- // expressions, used for refining report results.
-
- for (std::list<std::string>::const_iterator i = begin;
- i != end;
- i++)
- if ((*i)[0] == '-') {
- if (! regexps[1].empty())
- regexps[1] += "|";
- regexps[1] += (*i).substr(1);
- }
- else if ((*i)[0] == '+') {
- if (! regexps[0].empty())
- regexps[0] += "|";
- regexps[0] += (*i).substr(1);
- }
- else {
- if (! regexps[0].empty())
- regexps[0] += "|";
- regexps[0] += *i;
- }
-
- for (int i = 0; i < 2; i++) {
- if (regexps[i].empty())
- continue;
-
- if (! predicate.empty())
- predicate += logical_and ? "&" : "|";
-
- int add_predicate = 0; // 1 adds /.../, 2 adds ///.../
- if (i == 1) {
- predicate += "!";
- }
- else if (add_account_short_masks) {
- if (regexps[i].find(':') != std::string::npos ||
- regexps[i].find('.') != std::string::npos ||
- regexps[i].find('*') != std::string::npos ||
- regexps[i].find('+') != std::string::npos ||
- regexps[i].find('[') != std::string::npos ||
- regexps[i].find('(') != std::string::npos) {
- show_subtotal = true;
- add_predicate = 1;
- } else {
- add_predicate = 2;
- }
- }
- else {
- add_predicate = 1;
- }
-
- if (i != 1 && command == "b" && account_regexp) {
- if (! show_related && ! show_all_related) {
- if (! display_predicate.empty())
- display_predicate += "&";
- if (! show_empty)
- display_predicate += "T&";
-
- if (add_predicate == 2)
- display_predicate += "//";
- display_predicate += "/(?:";
- display_predicate += regexps[i];
- display_predicate += ")/";
- }
- else if (! show_empty) {
- if (! display_predicate.empty())
- display_predicate += "&";
- display_predicate += "T";
- }
- }
-
- if (! account_regexp)
- predicate += "/";
- predicate += "/(?:";
- predicate += regexps[i];
- predicate += ")/";
- }
-}
-
void report_t::process_options(const std::string& command,
strings_list::iterator arg,
strings_list::iterator args_end)
@@ -342,8 +252,11 @@ report_t::chain_xact_handlers(xact_handler_ptr base_handler,
// This filter_xacts will only pass through xacts
// matching the `predicate'.
- if (! predicate.empty())
+ if (! predicate.empty()) {
+ DEBUG("report.predicate",
+ "Report predicate expression = " << predicate);
handler.reset(new filter_xacts(handler, predicate));
+ }
#if 0
// budget_xacts takes a set of xacts from a data
@@ -493,31 +406,30 @@ expr_t::ptr_op_t report_t::lookup(const string& name)
if (std::strncmp(p, "opt_", 4) == 0) {
p = p + 4;
switch (*p) {
+#if 0
case 'a':
if (std::strcmp(p, "amount") == 0)
return MAKE_FUNCTOR(report_t::option_amount);
break;
+#endif
case 'b':
- if (std::strcmp(p, "bar") == 0)
- return MAKE_FUNCTOR(report_t::option_bar);
+ if (std::strcmp(p, "bar_") == 0)
+ return MAKE_FUNCTOR(report_t::option_bar_);
break;
case 'f':
- if (std::strcmp(p, "format") == 0)
- return MAKE_FUNCTOR(report_t::option_format);
- else if (name.find("fmt_") == 0) {
- switch (name[4]) {
- case 't':
- return MAKE_FUNCTOR(report_t::get_amount_expr);
-#if 0
- case 'T':
- return MAKE_FUNCTOR(report_t::get_total_expr);
-#endif
- }
- }
+ if (std::strcmp(p, "F_") == 0 ||
+ std::strcmp(p, "format_") == 0)
+ return MAKE_FUNCTOR(report_t::option_format_);
break;
+ case 'l':
+ if (std::strcmp(p, "l_") || std::strcmp(p, "limit_"))
+ return MAKE_FUNCTOR(report_t::option_limit_);
+ break;
+
+#if 0
case 't':
if (! *(p + 1))
return MAKE_FUNCTOR(report_t::option_amount);
@@ -529,6 +441,7 @@ expr_t::ptr_op_t report_t::lookup(const string& name)
if (! *(p + 1))
return MAKE_FUNCTOR(report_t::option_total);
break;
+#endif
}
}
break;
diff --git a/report.h b/report.h
index 6bcd8e88..b6da2bc8 100644
--- a/report.h
+++ b/report.h
@@ -198,6 +198,7 @@ public:
// Config options
//
+#if 0
void eval(const string& expr) {
expr_t(expr).calc(*this);
}
@@ -206,22 +207,23 @@ public:
return NULL_VALUE;
}
- value_t option_amount(call_scope_t& args) {
+ value_t option_amount_(call_scope_t& args) {
eval(string("t=") + args[0].as_string());
return NULL_VALUE;
}
- value_t option_total(call_scope_t& args) {
+ value_t option_total_(call_scope_t& args) {
eval(string("T()=") + args[0].as_string());
return NULL_VALUE;
}
- value_t option_format(call_scope_t& args) {
- format_string = args[0].as_string();
+ value_t option_raw(call_scope_t&) {
+ raw_mode = true;
return NULL_VALUE;
}
+#endif
- value_t option_raw(call_scope_t&) {
- raw_mode = true;
+ value_t option_format_(call_scope_t& args) {
+ format_string = args[0].as_string();
return NULL_VALUE;
}
@@ -229,11 +231,18 @@ public:
std::cout << "This is foo" << std::endl;
return NULL_VALUE;
}
- value_t option_bar(call_scope_t& args) {
+ value_t option_bar_(call_scope_t& args) {
std::cout << "This is bar: " << args[0] << std::endl;
return args[0];
}
+ value_t option_limit_(call_scope_t& args) {
+ if (! predicate.empty())
+ predicate += "&";
+ predicate += args[0].as_string();
+ return true;
+ }
+
//
// Formatting functions
//
diff --git a/xact.cc b/xact.cc
index 02dc1842..dd4269a0 100644
--- a/xact.cc
+++ b/xact.cc
@@ -105,12 +105,12 @@ namespace {
{
xact_t& xact(downcast<xact_t>(*scope.parent));
- var_t<long> width(scope, 0);
+ var_t<long> max_width(scope, 0);
string name = xact.reported_account()->fullname();
- if (width && *width > 2)
- name = format_t::truncate(name, *width - 2, true);
+ if (max_width && *max_width > 2)
+ name = format_t::truncate(name, *max_width - 2, true);
if (xact.has_flags(XACT_VIRTUAL)) {
if (xact.must_balance())