From bcffbc96ba88bd19f5f8ac00015ff38131fd6466 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Sun, 3 Aug 2008 23:44:18 -0400 Subject: Regular expressions are working again, such that very basic register reports are now possible. --- format.cc | 413 ++------------------------------------------------------------ 1 file changed, 8 insertions(+), 405 deletions(-) (limited to 'format.cc') 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(&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; } } -- cgit v1.2.3