summaryrefslogtreecommitdiff
path: root/format.cc
diff options
context:
space:
mode:
Diffstat (limited to 'format.cc')
-rw-r--r--format.cc235
1 files changed, 133 insertions, 102 deletions
diff --git a/format.cc b/format.cc
index cb890926..bfcb81ba 100644
--- a/format.cc
+++ b/format.cc
@@ -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;