diff options
Diffstat (limited to 'format.cc')
-rw-r--r-- | format.cc | 235 |
1 files changed, 133 insertions, 102 deletions
@@ -12,10 +12,10 @@ int format_t::abbrev_length = 2; bool format_t::ansi_codes = false; bool format_t::ansi_invert = false; -std::string format_t::truncate(const std::string& str, unsigned int width, +string format_t::truncate(const string& str, unsigned int width, const bool is_account) { - const int len = str.length(); + const unsigned int len = str.length(); if (len <= width) return str; @@ -43,28 +43,28 @@ std::string format_t::truncate(const std::string& str, unsigned int width, case ABBREVIATE: if (is_account) { - std::list<std::string> parts; - std::string::size_type beg = 0; - for (std::string::size_type pos = str.find(':'); - pos != std::string::npos; + std::list<string> parts; + string::size_type beg = 0; + for (string::size_type pos = str.find(':'); + pos != string::npos; beg = pos + 1, pos = str.find(':', beg)) - parts.push_back(std::string(str, beg, pos - beg)); - parts.push_back(std::string(str, beg)); + parts.push_back(string(str, beg, pos - beg)); + parts.push_back(string(str, beg)); - std::string result; - int newlen = len; - for (std::list<std::string>::iterator i = parts.begin(); + string result; + unsigned int newlen = len; + for (std::list<string>::iterator i = parts.begin(); i != parts.end(); i++) { // Don't contract the last element - std::list<std::string>::iterator x = i; + std::list<string>::iterator x = i; if (++x == parts.end()) { result += *i; break; } if (newlen > width) { - result += std::string(*i, 0, abbrev_length); + result += string(*i, 0, abbrev_length); result += ":"; newlen -= (*i).length() - abbrev_length; } else { @@ -98,9 +98,9 @@ std::string format_t::truncate(const std::string& str, unsigned int width, return buf; } -std::string partial_account_name(const account_t& account) +string partial_account_name(const account_t& account) { - std::string name; + string name; for (const account_t * acct = &account; acct && acct->parent; @@ -118,7 +118,7 @@ std::string partial_account_name(const account_t& account) return name; } -element_t * format_t::parse_elements(const std::string& fmt) +element_t * format_t::parse_elements(const string& fmt) { std::auto_ptr<element_t> result; @@ -143,7 +143,7 @@ element_t * format_t::parse_elements(const std::string& fmt) if (q != buf) { current->type = element_t::STRING; - current->chars = std::string(buf, q); + current->chars = string(buf, q); q = buf; current->next = new element_t; @@ -219,7 +219,7 @@ element_t * format_t::parse_elements(const std::string& fmt) current->type = element_t::VALUE_EXPR; assert(! current->val_expr); - current->val_expr = std::string(b, p); + current->val_expr = string(b, p); break; } @@ -238,7 +238,7 @@ element_t * format_t::parse_elements(const std::string& fmt) throw new format_error("Missing ']'"); current->type = element_t::DATE_STRING; - current->chars = std::string(b, p); + current->chars = string(b, p); break; } @@ -255,11 +255,11 @@ element_t * format_t::parse_elements(const std::string& fmt) case 'd': current->type = element_t::COMPLETE_DATE_STRING; - current->chars = datetime_t::output_format; + current->chars = output_time_format; break; case 'D': current->type = element_t::DATE_STRING; - current->chars = datetime_t::output_format; + current->chars = output_time_format; break; case 'S': current->type = element_t::SOURCE; break; @@ -294,7 +294,7 @@ element_t * format_t::parse_elements(const std::string& fmt) current = current->next; } current->type = element_t::STRING; - current->chars = std::string(buf, q); + current->chars = string(buf, q); } return result.release(); @@ -324,7 +324,7 @@ void format_t::format(std::ostream& out_str, const details_t& details) const { for (const element_t * elem = elements; elem; elem = elem->next) { std::ostringstream out; - std::string name; + string name; bool ignore_max_width = false; if (elem->flags & ELEMENT_ALIGN_LEFT) @@ -343,27 +343,35 @@ void format_t::format(std::ostream& out_str, const details_t& details) const case element_t::AMOUNT: case element_t::TOTAL: case element_t::VALUE_EXPR: { - value_expr calc; + value_expr * calc; switch (elem->type) { - case element_t::AMOUNT: calc = amount_expr; break; - case element_t::TOTAL: calc = total_expr; break; - case element_t::VALUE_EXPR: calc = elem->val_expr; break; + 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(0); + assert(false); break; } if (! calc) break; - value_t value; - balance_t * bal = NULL; + 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) { + switch (value.type()) { case value_t::AMOUNT: case value_t::BALANCE: case value_t::BALANCE_PAIR: @@ -376,56 +384,56 @@ void format_t::format(std::ostream& out_str, const details_t& details) const bool highlighted = false; - switch (value.type) { + switch (value.type()) { case value_t::BOOLEAN: - out << (*((bool *) value.data) ? "true" : "false"); + out << (value.as_boolean() ? "true" : "false"); break; case value_t::INTEGER: if (ansi_codes && elem->flags & ELEMENT_HIGHLIGHT) { if (ansi_invert) { - if (*((long *) value.data) > 0) { + if (value.as_long() > 0) { mark_red(out, elem); highlighted = true; } } else { - if (*((long *) value.data) < 0) { + if (value.as_long() < 0) { mark_red(out, elem); highlighted = true; } } } - out << *((long *) value.data); + out << value.as_long(); break; case value_t::DATETIME: - out << *((datetime_t *) value.data); + out << value.as_datetime(); break; case value_t::AMOUNT: if (ansi_codes && elem->flags & ELEMENT_HIGHLIGHT) { if (ansi_invert) { - if (*((amount_t *) value.data) > 0) { + if (value.as_amount().sign() > 0) { mark_red(out, elem); highlighted = true; } } else { - if (*((amount_t *) value.data) < 0) { + if (value.as_amount().sign() < 0) { mark_red(out, elem); highlighted = true; } } } - out << *((amount_t *) value.data); + out << value.as_amount(); break; case value_t::BALANCE: - bal = (balance_t *) value.data; + bal = &(value.as_balance()); // fall through... case value_t::BALANCE_PAIR: if (! bal) - bal = &((balance_pair_t *) value.data)->quantity; + bal = &(value.as_balance_pair().quantity()); if (ansi_codes && elem->flags & ELEMENT_HIGHLIGHT) { if (ansi_invert) { @@ -440,14 +448,14 @@ void format_t::format(std::ostream& out_str, const details_t& details) const } } } - bal->write(out, elem->min_width, + bal->print(out, elem->min_width, (elem->max_width > 0 ? elem->max_width : elem->min_width)); ignore_max_width = true; break; default: - assert(0); + assert(false); break; } @@ -458,18 +466,18 @@ void format_t::format(std::ostream& out_str, const details_t& details) const case element_t::OPT_AMOUNT: if (details.xact) { - std::string disp; + string disp; bool use_disp = false; if (details.xact->cost && details.xact->amount) { std::ostringstream stream; - if (! details.xact->amount_expr.expr.empty()) - stream << details.xact->amount_expr.expr; + 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.empty()) - stream << details.xact->cost_expr; + if (details.xact->cost_expr) + stream << details.xact->cost_expr->expr_str; else stream << " @ " << amount_t(*details.xact->cost / details.xact->amount).unround(); @@ -498,8 +506,8 @@ void format_t::format(std::ostream& out_str, const details_t& details) const } if (! use_disp) { - if (! details.xact->amount_expr.expr.empty()) - out << details.xact->amount_expr.expr; + if (! details.xact->amount_expr.expr_str.empty()) + out << details.xact->amount_expr.expr_str; else out << details.xact->amount.strip_annotations(); } else { @@ -511,7 +519,7 @@ void format_t::format(std::ostream& out_str, const details_t& details) const case element_t::SOURCE: if (details.entry && details.entry->journal) { int idx = details.entry->src_idx; - for (strings_list::iterator i = details.entry->journal->sources.begin(); + for (paths_list::const_iterator i = details.entry->journal->sources.begin(); i != details.entry->journal->sources.end(); i++) if (! idx--) { @@ -568,9 +576,12 @@ void format_t::format(std::ostream& out_str, const details_t& details) const else if (details.entry) date = details.entry->date(); +#if 0 + // jww (2008-04-20): This needs to be rewritten char buf[256]; std::strftime(buf, 255, elem->chars.c_str(), date.localtime()); out << (elem->max_width == 0 ? buf : truncate(buf, elem->max_width)); +#endif break; } @@ -587,13 +598,23 @@ void format_t::format(std::ostream& out_str, const details_t& details) const } 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 (effective_date && effective_date != actual_date) { + 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, "="); @@ -615,6 +636,8 @@ void format_t::format(std::ostream& out_str, const details_t& details) const case transaction_t::PENDING: out << "! "; break; + case transaction_t::UNCLEARED: + break; } } break; @@ -630,15 +653,17 @@ void format_t::format(std::ostream& out_str, const details_t& details) const case transaction_t::PENDING: out << "! "; break; + case transaction_t::UNCLEARED: + break; } } break; case element_t::CODE: { - std::string temp; - if (details.entry && ! details.entry->code.empty()) { + string temp; + if (details.entry && details.entry->code) { temp += "("; - temp += details.entry->code; + temp += *details.entry->code; temp += ") "; } out << temp; @@ -653,14 +678,14 @@ void format_t::format(std::ostream& out_str, const details_t& details) const break; case element_t::OPT_NOTE: - if (details.xact && ! details.xact->note.empty()) + 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, + details.xact->note : truncate(*details.xact->note, elem->max_width)); break; @@ -675,6 +700,8 @@ void format_t::format(std::ostream& out_str, const details_t& details) const case transaction_t::PENDING: name = "! "; break; + case transaction_t::UNCLEARED: + break; } } // fall through... @@ -686,14 +713,14 @@ void format_t::format(std::ostream& out_str, const details_t& details) const details.account->fullname() : partial_account_name(*details.account)); - if (details.xact && details.xact->flags & TRANSACTION_VIRTUAL) { + if (details.xact && details.xact->has_flags(TRANSACTION_VIRTUAL)) { if (elem->max_width > 2) name = truncate(name, elem->max_width - 2, true); - if (details.xact->flags & TRANSACTION_BALANCE) - name = "[" + name + "]"; + if (details.xact->has_flags(TRANSACTION_BALANCE)) + name = string("[") + name + "]"; else - name = "(" + name + ")"; + name = string("(") + name + ")"; } else if (elem->max_width > 0) name = truncate(name, elem->max_width, true); @@ -722,11 +749,11 @@ void format_t::format(std::ostream& out_str, const details_t& details) const break; default: - assert(0); + assert(false); break; } - std::string temp = out.str(); + string temp = out.str(); if (! ignore_max_width && elem->max_width > 0 && elem->max_width < temp.length()) temp.erase(elem->max_width); @@ -735,13 +762,15 @@ void format_t::format(std::ostream& out_str, const details_t& details) const } format_transactions::format_transactions(std::ostream& _output_stream, - const std::string& format) + const string& format) : output_stream(_output_stream), last_entry(NULL), last_xact(NULL) { + TRACE_CTOR(format_transactions, "std::ostream&, const string&"); + const char * f = format.c_str(); if (const char * p = std::strstr(f, "%/")) { - first_line_format.reset(std::string(f, 0, p - f)); - next_lines_format.reset(std::string(p + 2)); + first_line_format.reset(string(f, 0, p - f)); + next_lines_format.reset(string(p + 2)); } else { first_line_format.reset(format); next_lines_format.reset(format); @@ -798,18 +827,18 @@ void format_entries::operator()(transaction_t& xact) } void print_entry(std::ostream& out, const entry_base_t& entry_base, - const std::string& prefix) + const string& prefix) { - std::string print_format; + string print_format; - if (const entry_t * entry = dynamic_cast<const entry_t *>(&entry_base)) { + if (dynamic_cast<const entry_t *>(&entry_base)) { print_format = (prefix + "%D %X%C%P\n" + prefix + " %-34A %12o\n%/" + prefix + " %-34A %12o\n"); } else if (const auto_entry_t * entry = dynamic_cast<const auto_entry_t *>(&entry_base)) { - out << "= " << entry->predicate_string << '\n'; + out << "= " << entry->predicate.predicate.expr_str << '\n'; print_format = prefix + " %-34A %12o\n"; } else if (const period_entry_t * entry = @@ -818,9 +847,10 @@ void print_entry(std::ostream& out, const entry_base_t& entry_base, print_format = prefix + " %-34A %12o\n"; } else { - assert(0); + assert(false); } +#if 0 format_entries formatter(out, print_format); walk_transactions(const_cast<transactions_list&>(entry_base.transactions), formatter); @@ -829,15 +859,16 @@ void print_entry(std::ostream& out, const entry_base_t& entry_base, clear_transaction_xdata cleaner; walk_transactions(const_cast<transactions_list&>(entry_base.transactions), cleaner); +#endif } -bool disp_subaccounts_p(const account_t& account, - const item_predicate<account_t>& disp_pred, - const account_t *& to_show) +bool disp_subaccounts_p(const account_t& account, + const optional<item_predicate<account_t> >& disp_pred, + const account_t *& to_show) { bool display = false; unsigned int counted = 0; - bool matches = disp_pred(account); + bool matches = disp_pred ? (*disp_pred)(account) : true; value_t acct_total; bool computed = false; value_t result; @@ -847,7 +878,7 @@ bool disp_subaccounts_p(const account_t& account, for (accounts_map::const_iterator i = account.accounts.begin(); i != account.accounts.end(); i++) { - if (! disp_pred(*(*i).second)) + if (disp_pred && ! (*disp_pred)(*(*i).second)) continue; compute_total(result, details_t(*(*i).second)); @@ -868,7 +899,7 @@ bool disp_subaccounts_p(const account_t& account, } bool display_account(const account_t& account, - const item_predicate<account_t>& disp_pred) + const optional<item_predicate<account_t> >& disp_pred) { // Never display an account that has already been displayed. if (account_has_xdata(account) && @@ -886,10 +917,10 @@ bool display_account(const account_t& account, if (disp_subaccounts_p(account, disp_pred, account_to_show)) return true; - return ! account_to_show && disp_pred(account); + return ! account_to_show && (! disp_pred || (*disp_pred)(account)); } -void format_account::operator()(account_t& account) +void format_accounts::operator()(account_t& account) { if (display_account(account, disp_pred)) { if (! account.parent) { @@ -901,15 +932,15 @@ void format_account::operator()(account_t& account) } } -format_equity::format_equity(std::ostream& _output_stream, - const std::string& _format, - const std::string& display_predicate) +format_equity::format_equity(std::ostream& _output_stream, + const string& _format, + const string& display_predicate) : output_stream(_output_stream), disp_pred(display_predicate) { const char * f = _format.c_str(); if (const char * p = std::strstr(f, "%/")) { - first_line_format.reset(std::string(f, 0, p - f)); - next_lines_format.reset(std::string(p + 2)); + first_line_format.reset(string(f, 0, p - f)); + next_lines_format.reset(string(p + 2)); } else { first_line_format.reset(_format); next_lines_format.reset(_format); @@ -917,7 +948,7 @@ format_equity::format_equity(std::ostream& _output_stream, entry_t header_entry; header_entry.payee = "Opening Balances"; - header_entry._date = datetime_t::now; + header_entry._date = current_moment; first_line_format.format(output_stream, details_t(header_entry)); } @@ -929,16 +960,16 @@ void format_equity::flush() account_t summary(NULL, "Equity:Opening Balances"); summary.data = &xdata; - if (total.type >= value_t::BALANCE) { - balance_t * bal; - if (total.type == value_t::BALANCE) - bal = (balance_t *) total.data; - else if (total.type == value_t::BALANCE_PAIR) - bal = &((balance_pair_t *) total.data)->quantity; + if (total.type() >= value_t::BALANCE) { + const balance_t * bal; + if (total.is_type(value_t::BALANCE)) + bal = &(total.as_balance()); + else if (total.is_type(value_t::BALANCE_PAIR)) + bal = &(total.as_balance_pair().quantity()); else - assert(0); + assert(false); - for (amounts_map::const_iterator i = bal->amounts.begin(); + for (balance_t::amounts_map::const_iterator i = bal->amounts.begin(); i != bal->amounts.end(); i++) { xdata.value = (*i).second; @@ -957,16 +988,16 @@ void format_equity::operator()(account_t& account) if (account_has_xdata(account)) { value_t val = account_xdata_(account).value; - if (val.type >= value_t::BALANCE) { - balance_t * bal; - if (val.type == value_t::BALANCE) - bal = (balance_t *) val.data; - else if (val.type == value_t::BALANCE_PAIR) - bal = &((balance_pair_t *) val.data)->quantity; + if (val.type() >= value_t::BALANCE) { + const balance_t * bal; + if (val.is_type(value_t::BALANCE)) + bal = &(val.as_balance()); + else if (val.is_type(value_t::BALANCE_PAIR)) + bal = &(val.as_balance_pair().quantity()); else - assert(0); + assert(false); - for (amounts_map::const_iterator i = bal->amounts.begin(); + for (balance_t::amounts_map::const_iterator i = bal->amounts.begin(); i != bal->amounts.end(); i++) { account_xdata_(account).value = (*i).second; |