summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Wiegley <johnw@newartisans.com>2004-07-31 07:42:34 -0400
committerJohn Wiegley <johnw@newartisans.com>2004-07-31 07:42:34 -0400
commitf570e6644fce27b612562282b11d00fd0691873d (patch)
treecc6da9b59aed82e17f9e946e6e1ac1ac92257280
parent2a9e778b7d359a009d7a1f2432bf6d0dcf2fab7d (diff)
downloadfork-ledger-f570e6644fce27b612562282b11d00fd0691873d.tar.gz
fork-ledger-f570e6644fce27b612562282b11d00fd0691873d.tar.bz2
fork-ledger-f570e6644fce27b612562282b11d00fd0691873d.zip
brought back the "print" and "equity" reports; this time much better!
-rw-r--r--amount.cc37
-rw-r--r--balance.h40
-rw-r--r--binary.cc2
-rw-r--r--expr.cc8
-rw-r--r--expr.h6
-rw-r--r--format.cc84
-rw-r--r--format.h11
-rw-r--r--item.cc169
-rw-r--r--item.h64
-rw-r--r--ledger.cc128
-rw-r--r--ledger.h18
-rw-r--r--main.cc500
-rw-r--r--textual.cc127
-rw-r--r--textual.h6
14 files changed, 633 insertions, 567 deletions
diff --git a/amount.cc b/amount.cc
index 80fd3ee9..d1dd6150 100644
--- a/amount.cc
+++ b/amount.cc
@@ -10,7 +10,7 @@
namespace ledger {
-static void mpz_round(mpz_t value, int precision)
+static void mpz_round(mpz_t out, mpz_t value, int precision)
{
mpz_t divisor;
@@ -33,17 +33,17 @@ static void mpz_round(mpz_t value, int precision)
mpz_ui_pow_ui(divisor, 10, MAX_PRECISION - precision);
mpz_add(remainder, divisor, remainder);
mpz_ui_sub(remainder, 0, remainder);
- mpz_add(value, value, remainder);
+ mpz_add(out, value, remainder);
} else {
- mpz_sub(value, value, remainder);
+ mpz_sub(out, value, remainder);
}
} else {
if (mpz_cmp(remainder, divisor) >= 0) {
mpz_ui_pow_ui(divisor, 10, MAX_PRECISION - precision);
mpz_sub(remainder, divisor, remainder);
- mpz_add(value, value, remainder);
+ mpz_add(out, value, remainder);
} else {
- mpz_sub(value, value, remainder);
+ mpz_sub(out, value, remainder);
}
}
@@ -357,7 +357,7 @@ amount_t amount_t::round(int precision) const
return *this;
} else {
amount_t temp = *this;
- mpz_round(MPZ(temp.quantity),
+ mpz_round(MPZ(temp.quantity), MPZ(temp.quantity),
precision == -1 ? commodity->precision : precision);
return temp;
}
@@ -380,8 +380,14 @@ std::ostream& operator<<(std::ostream& out, const amount_t& amt)
bool negative = false;
+ // Ensure the value is rounded to the commodity's precision before
+ // outputting it. NOTE: `rquotient' is used here as a temp variable!
+
+ if (amt.commodity->precision != MAX_PRECISION)
+ mpz_round(rquotient, MPZ(amt.quantity), amt.commodity->precision);
+
mpz_ui_pow_ui(divisor, 10, MAX_PRECISION);
- mpz_tdiv_qr(quotient, remainder, MPZ(amt.quantity), divisor);
+ mpz_tdiv_qr(quotient, remainder, rquotient, divisor);
if (mpz_sgn(quotient) < 0 || mpz_sgn(remainder) < 0)
negative = true;
@@ -392,10 +398,6 @@ std::ostream& operator<<(std::ostream& out, const amount_t& amt)
if (amt.commodity->precision == MAX_PRECISION) {
mpz_set(rquotient, remainder);
} else {
- // Ensure the value is rounded to the commodity's precision before
- // outputting it
- mpz_round(MPZ(amt.quantity), amt.commodity->precision);
-
assert(MAX_PRECISION - amt.commodity->precision > 0);
mpz_ui_pow_ui(divisor, 10, MAX_PRECISION - amt.commodity->precision);
mpz_tdiv_qr(rquotient, remainder, remainder, divisor);
@@ -681,6 +683,19 @@ void (*commodity_t::updater)(commodity_t * commodity,
commodities_map commodity_t::commodities;
+struct cleanup_commodities
+{
+ ~cleanup_commodities() {
+ for (commodities_map::iterator i
+ = commodity_t::commodities.begin();
+ i != commodity_t::commodities.end();
+ i++)
+ delete (*i).second;
+ }
+};
+
+static cleanup_commodities cleanup;
+
commodity_t * commodity_t::find_commodity(const std::string& symbol,
bool auto_create)
{
diff --git a/balance.h b/balance.h
index 3ecfd962..edc7db2f 100644
--- a/balance.h
+++ b/balance.h
@@ -274,6 +274,27 @@ class balance_t
return amount(amt.commodity) >= amt;
}
+ bool operator==(const balance_t& bal) const {
+ amounts_map::const_iterator i, j;
+ for (i = amounts.begin(), j = bal.amounts.begin();
+ i != amounts.end() && j != bal.amounts.end();
+ i++, j++) {
+ if (! ((*i).first == (*j).first &&
+ (*i).second == (*j).second))
+ return false;
+ }
+ return i == amounts.end() && j == bal.amounts.end();
+ }
+ bool operator==(const amount_t& amt) const {
+ return amounts.size() == 1 && (*amounts.begin()).second == amt;
+ }
+ bool operator!=(const balance_t& bal) const {
+ return ! (*this == bal);
+ }
+ bool operator!=(const amount_t& amt) const {
+ return ! (*this == amt);
+ }
+
// unary negation
balance_t& negate() {
for (amounts_map::iterator i = amounts.begin();
@@ -561,6 +582,25 @@ class balance_pair_t
return quantity >= amt;
}
+ bool operator==(const balance_pair_t& bal_pair) const {
+ return quantity == bal_pair.quantity;
+ }
+ bool operator==(const balance_t& bal) const {
+ return quantity == bal;
+ }
+ bool operator==(const amount_t& amt) const {
+ return quantity == amt;
+ }
+ bool operator!=(const balance_pair_t& bal_pair) const {
+ return ! (*this == bal_pair);
+ }
+ bool operator!=(const balance_t& bal) const {
+ return ! (*this == bal);
+ }
+ bool operator!=(const amount_t& amt) const {
+ return ! (*this == amt);
+ }
+
// unary negation
balance_pair_t& negate() {
quantity.negate();
diff --git a/binary.cc b/binary.cc
index 9400fc54..9f2bed96 100644
--- a/binary.cc
+++ b/binary.cc
@@ -15,7 +15,7 @@
namespace ledger {
unsigned long magic_number = 0xFFEED765;
-static unsigned long format_version = 0x00020008;
+static unsigned long format_version = 0x00020009;
static char buf[4096];
diff --git a/expr.cc b/expr.cc
index 7536c260..c49dc33b 100644
--- a/expr.cc
+++ b/expr.cc
@@ -129,15 +129,11 @@ balance_t node_t::compute(const item_t * item) const
break;
case CLEARED:
-#if 0
- temp = amount_t(item->state == CLEARED ? 1 : 0);
-#endif
+ temp = amount_t(item->state == entry_t::CLEARED ? 1 : 0);
break;
case REAL:
-#if 0
temp = amount_t(item->flags & TRANSACTION_VIRTUAL ? 0 : 1);
-#endif
break;
case INDEX:
@@ -162,7 +158,7 @@ balance_t node_t::compute(const item_t * item) const
case F_PAYEE_MASK:
assert(mask);
- temp = mask->match(item->payee);
+ temp = (mask->match(item->payee) || mask->match(item->note)) ? 1 : 0;
break;
case F_ACCOUNT_MASK:
diff --git a/expr.h b/expr.h
index 3994fe54..937e2fa8 100644
--- a/expr.h
+++ b/expr.h
@@ -136,7 +136,10 @@ class value_predicate
} else {
item_t temp;
temp.date = xact->entry->date;
+ temp.state = xact->entry->state;
+ temp.code = xact->entry->code;
temp.payee = xact->entry->payee;
+ temp.flags = xact->flags;
temp.account = xact->account;
return predicate->compute(&temp);
}
@@ -149,6 +152,8 @@ class value_predicate
item_t temp;
temp.date = entry->date;
temp.payee = entry->payee;
+ temp.state = entry->state;
+ temp.code = entry->code;
// Although there may be conflicting account masks for the whole
// set of transactions -- for example, /rent/&!/expenses/, which
@@ -159,6 +164,7 @@ class value_predicate
for (transactions_list::const_iterator i = entry->transactions.begin();
i != entry->transactions.end();
i++) {
+ temp.flags = (*i)->flags;
temp.account = (*i)->account;
if (predicate->compute(&temp))
return true;
diff --git a/format.cc b/format.cc
index 3fc65c2b..33adc15c 100644
--- a/format.cc
+++ b/format.cc
@@ -24,8 +24,8 @@ std::string maximal_account_name(const item_t * item, const item_t * parent)
return name;
}
-node_t * format_t::value_expr = NULL;
-node_t * format_t::total_expr = NULL;
+std::auto_ptr<node_t> format_t::value_expr;
+std::auto_ptr<node_t> format_t::total_expr;
element_t * format_t::parse_elements(const std::string& fmt)
{
@@ -110,9 +110,12 @@ element_t * format_t::parse_elements(const std::string& fmt)
current->chars = "%Y/%m/%d";
break;
+ case 'X': current->type = element_t::CLEARED; break;
+ case 'C': current->type = element_t::CODE; break;
case 'p': current->type = element_t::PAYEE; break;
case 'n': current->type = element_t::ACCOUNT_NAME; break;
case 'N': current->type = element_t::ACCOUNT_FULLNAME; break;
+ case 'o': current->type = element_t::OPT_AMOUNT; break;
case 't': current->type = element_t::VALUE; break;
case 'T': current->type = element_t::TOTAL; break;
case '_': current->type = element_t::SPACER; break;
@@ -174,28 +177,89 @@ void format_t::format_elements(std::ostream& out, const item_t * item,
}
break;
+ case element_t::CLEARED:
+ if (item->state == entry_t::CLEARED)
+ out << "* ";
+ else
+ out << "";
+ break;
+
+ case element_t::CODE:
+ if (! item->code.empty())
+ out << "(" << item->code << ") ";
+ else
+ out << "";
+ break;
+
case element_t::PAYEE:
out << (elem->max_width == 0 ?
item->payee : truncated(item->payee, elem->max_width));
break;
case element_t::ACCOUNT_NAME:
+ case element_t::ACCOUNT_FULLNAME:
if (item->account) {
- std::string name = maximal_account_name(item, displayed_parent);
- out << (elem->max_width == 0 ? name : truncated(name, elem->max_width));
+ std::string name = (elem->type == element_t::ACCOUNT_FULLNAME ?
+ item->account->fullname() :
+ maximal_account_name(item, displayed_parent));
+ if (elem->max_width > 0)
+ name = truncated(name, elem->max_width);
+
+ if (item->flags & TRANSACTION_VIRTUAL) {
+ if (item->flags & TRANSACTION_BALANCE)
+ name = "[" + name + "]";
+ else
+ name = "(" + name + ")";
+ }
+ out << name;
} else {
out << " ";
}
break;
- case element_t::ACCOUNT_FULLNAME:
- if (item->account)
- out << (elem->max_width == 0 ?
- item->account->fullname() :
- truncated(item->account->fullname(), elem->max_width));
+ case element_t::OPT_AMOUNT: {
+ std::string disp;
+ bool use_disp = false;
+
+ if (std::find(displayed_parent->subitems.begin(),
+ displayed_parent->subitems.end(), item) !=
+ displayed_parent->subitems.end()) {
+ if (displayed_parent->subitems.size() == 2 &&
+ item == displayed_parent->subitems.back() &&
+ (displayed_parent->subitems.front()->value.quantity ==
+ displayed_parent->subitems.front()->value.cost) &&
+ (displayed_parent->subitems.front()->value ==
+ - displayed_parent->subitems.back()->value)) {
+ use_disp = true;
+ }
+ else if (displayed_parent->subitems.size() != 2 &&
+ item->value.quantity != item->value.cost &&
+ item->value.quantity.amounts.size() == 1 &&
+ item->value.cost.amounts.size() == 1 &&
+ ((*item->value.quantity.amounts.begin()).first !=
+ (*item->value.cost.amounts.begin()).first)) {
+ amount_t unit_cost
+ = ((*item->value.cost.amounts.begin()).second /
+ (*item->value.quantity.amounts.begin()).second);
+ std::ostringstream stream;
+ stream << item->value.quantity << " @ " << unit_cost;
+ disp = stream.str();
+ use_disp = true;
+ }
+ }
+
+ if (use_disp)
+ out << disp;
else
- out << " ";
+ item->value.quantity.write(out, elem->min_width,
+ elem->max_width > 0 ?
+ elem->max_width : elem->min_width);
+
+ // jww (2004-07-31): this should be handled differently
+ if (! item->note.empty())
+ out << " ; " << item->note;
break;
+ }
case element_t::VALUE: {
balance_t value = compute_value(item);
diff --git a/format.h b/format.h
index 12af7d8e..f2bdad10 100644
--- a/format.h
+++ b/format.h
@@ -16,9 +16,12 @@ struct element_t
STRING,
VALUE_EXPR,
DATE_STRING,
+ CLEARED,
+ CODE,
PAYEE,
ACCOUNT_NAME,
ACCOUNT_FULLNAME,
+ OPT_AMOUNT,
VALUE,
TOTAL,
SPACER
@@ -47,8 +50,8 @@ struct format_t
{
element_t * elements;
- static node_t * value_expr;
- static node_t * total_expr;
+ static std::auto_ptr<node_t> value_expr;
+ static std::auto_ptr<node_t> total_expr;
format_t(const std::string& _format) {
elements = parse_elements(_format);
@@ -63,10 +66,10 @@ struct format_t
const item_t * displayed_parent = NULL) const;
static balance_t compute_value(const item_t * item) {
- return value_expr ? value_expr->compute(item) : balance_t();
+ return value_expr.get() ? value_expr->compute(item) : balance_t();
}
static balance_t compute_total(const item_t * item) {
- return total_expr ? total_expr->compute(item) : balance_t();
+ return total_expr.get() ? total_expr->compute(item) : balance_t();
}
};
diff --git a/item.cc b/item.cc
index 11203c10..62ea9b8c 100644
--- a/item.cc
+++ b/item.cc
@@ -3,51 +3,6 @@
namespace ledger {
-// jww (2004-07-21): If format.show_empty is set, then include all
-// subaccounts, empty, balanced or no
-
-item_t * walk_accounts(const account_t * account,
- const node_t * predicate,
- const bool show_subtotals)
-{
- item_t * item = new item_t;
- item->account = account;
-
- std::time_t latest = 0;
- for (transactions_list::const_iterator i
- = std::find_if(account->transactions.begin(),
- account->transactions.end(),
- value_predicate(predicate));
- i != account->transactions.end();
- i = std::find_if(++i, account->transactions.end(),
- value_predicate(predicate))) {
- if (std::difftime(latest, (*i)->entry->date) < 0)
- latest = (*i)->entry->date;
-
- item->value += *(*i);
- if (show_subtotals)
- item->total += *(*i);
- }
- item->date = latest;
-
- for (accounts_map::const_iterator i = account->accounts.begin();
- i != account->accounts.end();
- i++) {
- item_t * subitem = walk_accounts((*i).second, predicate, show_subtotals);
- subitem->parent = item;
-
- if (std::difftime(item->date, subitem->date) < 0)
- item->date = subitem->date;
-
- if (show_subtotals)
- item->total += subitem->total;
- if (show_subtotals ? subitem->total : subitem->value)
- item->subitems.push_back(subitem);
- }
-
- return item;
-}
-
static inline void sum_items(const item_t * top,
const bool show_subtotals,
item_t * item)
@@ -64,27 +19,88 @@ static inline void sum_items(const item_t * top,
sum_items(*i, show_subtotals, item);
}
-item_t * walk_items(const item_t * top,
- const account_t * account,
- const node_t * predicate,
- const bool show_subtotals)
+item_t * walk_accounts(const item_t * top,
+ account_t * account,
+ const node_t * predicate,
+ const bool show_subtotals,
+ const bool show_flattened)
{
item_t * item = new item_t;
item->account = account;
- sum_items(top, show_subtotals, item);
+ if (top) {
+ sum_items(top, show_subtotals, item);
+ } else {
+ std::time_t latest = 0;
+ for (transactions_list::iterator i
+ = std::find_if(account->transactions.begin(),
+ account->transactions.end(),
+ value_predicate(predicate));
+ i != account->transactions.end();
+ i = std::find_if(++i, account->transactions.end(),
+ value_predicate(predicate))) {
+ if (std::difftime(latest, (*i)->entry->date) < 0)
+ latest = (*i)->entry->date;
+
+ item->value += *(*i);
+ if (show_subtotals)
+ item->total += *(*i);
+ }
+ item->date = latest;
+ }
- for (accounts_map::const_iterator i = account->accounts.begin();
+ for (accounts_map::iterator i = account->accounts.begin();
i != account->accounts.end();
i++) {
- item_t * subitem = walk_items(top, (*i).second, predicate, show_subtotals);
+ std::auto_ptr<item_t>
+ subitem(walk_accounts(top, (*i).second, predicate, show_subtotals,
+ show_flattened));
subitem->parent = item;
+ if (std::difftime(item->date, subitem->date) < 0)
+ item->date = subitem->date;
+
+ if (show_flattened) {
+ item_t * ptr = item;
+ balance_pair_t total;
+
+ for (items_deque::const_iterator i = subitem->subitems.begin();
+ i != subitem->subitems.end();
+ i++)
+ if (show_subtotals ? (*i)->total : (*i)->value) {
+ if (! account->parent) {
+ if (! total) {
+ item_t * temp = new item_t;
+ temp->date = top ? top->date : item->date;
+ temp->payee = "Opening balance";
+ item->subitems.push_back(temp);
+ ptr = temp;
+ }
+ total += show_subtotals ? (*i)->total : (*i)->value;
+ }
+
+ ptr->subitems.push_back(new item_t(*i));
+ ptr->subitems.back()->date = ptr->date;
+ ptr->subitems.back()->payee = ptr->payee;
+ }
+
+ if (total) {
+ item_t * temp = new item_t;
+ temp->date = ptr->date;
+ temp->payee = ptr->payee;
+ temp->account = account->find_account("Equity:Opening Balances");
+ temp->value = total;
+ temp->value.negate();
+ ptr->subitems.push_back(temp);
+ }
+ }
+
if (show_subtotals)
item->total += subitem->total;
- if (show_subtotals ? subitem->total : subitem->value)
- item->subitems.push_back(subitem);
+ if ((! show_flattened || account->parent) &&
+ show_subtotals ? subitem->total : subitem->value)
+ item->subitems.push_back(subitem.release());
}
return item;
@@ -103,6 +119,7 @@ item_t * walk_entries(entries_list::const_iterator begin,
for (entries_list::const_iterator i = std::find_if(begin, end, pred_obj);
i != end;
i = std::find_if(++i, end, pred_obj)) {
+ transactions_list reckoned;
item_t * item = NULL;
for (transactions_list::const_iterator j
@@ -115,39 +132,32 @@ item_t * walk_entries(entries_list::const_iterator begin,
assert(*i == (*j)->entry);
if (! item) {
- item = new item_t;
+ item = new item_t(*i);
item->index = count++;
- item->date = (*i)->date;
- item->payee = (*i)->payee;
}
// If show_inverted is true, it implies show_related.
- if (! show_inverted) {
- item_t * subitem = new item_t;
- subitem->parent = item;
- subitem->date = item->date;
- subitem->payee = item->payee;
- subitem->account = (*j)->account;
- subitem->value = *(*j);
- item->value += subitem->value;
- item->subitems.push_back(subitem);
+ if (! show_inverted &&
+ std::find(reckoned.begin(),
+ reckoned.end(), *j) == reckoned.end()) {
+ item->add_item(new item_t(*j));
+ reckoned.push_back(*j);
}
if (show_related)
for (transactions_list::iterator k = (*i)->transactions.begin();
k != (*i)->transactions.end();
- k++)
- if (*k != *j && ! ((*k)->flags & TRANSACTION_VIRTUAL)) {
- item_t * subitem = new item_t;
- subitem->parent = item;
- subitem->date = item->date;
- subitem->payee = item->payee;
- subitem->account = (*k)->account;
- subitem->value = *(*k);
- if (show_inverted)
- subitem->value.negate();
- item->subitems.push_back(subitem);
- }
+ k++) {
+ if (*k == *j || ((*k)->flags & TRANSACTION_AUTO) ||
+ std::find(reckoned.begin(),
+ reckoned.end(), *k) != reckoned.end())
+ continue;
+
+ item->add_item(new item_t(*k));
+ if (show_inverted)
+ item->subitems.back()->value.negate();
+ reckoned.push_back(*k);
+ }
}
if (item) {
@@ -155,6 +165,9 @@ item_t * walk_entries(entries_list::const_iterator begin,
result = new item_t;
item->parent = result;
result->subitems.push_back(item);
+
+ if (std::difftime(result->date, item->date) < 0)
+ result->date = item->date;
}
}
diff --git a/item.h b/item.h
index e3da6107..15c710f3 100644
--- a/item.h
+++ b/item.h
@@ -14,17 +14,38 @@ typedef std::deque<item_t *> items_deque;
struct item_t
{
- struct item_t * parent;
- items_deque subitems;
+ struct item_t * parent;
+ items_deque subitems;
- unsigned int index;
- std::time_t date;
- std::string payee;
- const account_t * account;
- balance_pair_t value;
- balance_pair_t total;
+ unsigned int index;
+ std::time_t date;
+ entry_t::entry_state_t state;
+ std::string code;
+ std::string payee;
+ unsigned int flags;
+ const account_t * account;
+ balance_pair_t value;
+ balance_pair_t total;
+ std::string note;
- item_t() : parent(NULL), index(0), date(-1), account(NULL) {}
+ item_t() : parent(NULL), index(0), date(-1),
+ state(entry_t::UNCLEARED), flags(0), account(NULL) {}
+
+ item_t(const item_t * item)
+ : parent(NULL), index(0), date(item->date), state(item->state),
+ code(item->code), payee(item->payee), flags(item->flags),
+ account(item->account), value(item->value), total(item->total),
+ note(item->note) {}
+
+ item_t(const entry_t * entry)
+ : parent(NULL), index(0), date(entry->date), state(entry->state),
+ code(entry->code), payee(entry->payee) {}
+
+ item_t(const transaction_t * xact)
+ : parent(NULL), index(0), date(xact->entry->date),
+ state(xact->entry->state), code(xact->entry->code),
+ payee(xact->entry->payee), flags(xact->flags),
+ account(xact->account), value(*xact), note(xact->note) {}
~item_t() {
for (items_deque::iterator i = subitems.begin();
@@ -33,25 +54,28 @@ struct item_t
delete *i;
}
+ void add_item(item_t * item) {
+ item->parent = this;
+ value += item->value;
+ subitems.push_back(item);
+ }
+
void sort(const node_t * sort_order);
};
struct node_t;
-item_t * walk_accounts(const account_t * account,
- const node_t * predicate,
- const bool show_subtotals);
-
-item_t * walk_items(const item_t * top,
- const account_t * account,
- const node_t * predicate,
- const bool show_subtotals);
+item_t * walk_accounts(const item_t * top,
+ account_t * account,
+ const node_t * predicate = NULL,
+ const bool show_subtotals = true,
+ const bool show_flattened = false);
item_t * walk_entries(entries_list::const_iterator begin,
entries_list::const_iterator end,
- const node_t * predicate,
- const bool show_related,
- const bool show_inverted);
+ const node_t * predicate = NULL,
+ const bool show_related = false,
+ const bool show_inverted = false);
} // namespace report
diff --git a/ledger.cc b/ledger.cc
index 741dcbaf..25ac845f 100644
--- a/ledger.cc
+++ b/ledger.cc
@@ -1,4 +1,5 @@
#include "ledger.h"
+#include "expr.h"
#include "textual.h"
#include "binary.h"
@@ -52,6 +53,133 @@ bool ledger_t::remove_entry(entry_t * entry)
return true;
}
+entry_t * ledger_t::derive_entry(int argc, char **argv) const
+{
+ entry_t * added = new entry_t;
+ entry_t * matching = NULL;
+ int index = 0;
+
+ assert(index < argc);
+
+ if (! parse_date(argv[index++], &added->date)) {
+ std::cerr << "Error: Bad entry date: " << argv[index - 1]
+ << std::endl;
+ return false;
+ }
+
+ if (index == argc) {
+ std::cerr << "Error: Too few arguments to 'entry'." << std::endl;
+ return false;
+ }
+
+ mask_t regexp(argv[index++]);
+
+ for (entries_list::const_reverse_iterator i = entries.rbegin();
+ i != entries.rend();
+ i++)
+ if (regexp.match((*i)->payee)) {
+ matching = *i;
+ break;
+ }
+
+ added->payee = matching ? matching->payee : regexp.pattern;
+
+ if (index == argc) {
+ std::cerr << "Error: Too few arguments to 'entry'." << std::endl;
+ return false;
+ }
+
+ if (argv[index][0] == '-' || std::isdigit(argv[index][0])) {
+ if (! matching) {
+ std::cerr << "Error: Missing account name for non-matching entry."
+ << std::endl;
+ return false;
+ }
+
+ transaction_t * m_xact, * xact, * first;
+ m_xact = matching->transactions.front();
+
+ amount_t amt(argv[index++]);
+ first = xact = new transaction_t(added, m_xact->account, amt, amt);
+
+ if (xact->amount.commodity->symbol.empty()) {
+ xact->amount.commodity = m_xact->amount.commodity;
+ xact->cost.commodity = m_xact->amount.commodity;
+ }
+ added->add_transaction(xact);
+
+ m_xact = matching->transactions.back();
+
+ xact = new transaction_t(added, m_xact->account,
+ - first->amount, - first->amount);
+ added->add_transaction(xact);
+
+ if ((index + 1) < argc && std::string(argv[index]) == "-from")
+ if (account_t * acct = find_account(argv[++index]))
+ added->transactions.back()->account = acct;
+ } else {
+ while (index < argc && std::string(argv[index]) != "-from") {
+ mask_t acct_regex(argv[index++]);
+
+ account_t * acct = NULL;
+ commodity_t * cmdty = NULL;
+
+ if (matching) {
+ for (transactions_list::iterator x
+ = matching->transactions.begin();
+ x != matching->transactions.end();
+ x++) {
+ if (acct_regex.match((*x)->account->fullname())) {
+ acct = (*x)->account;
+ cmdty = (*x)->amount.commodity;
+ break;
+ }
+ }
+ }
+
+ if (! acct)
+ acct = find_account(acct_regex.pattern);
+
+ if (! acct) {
+ std::cerr << "Error: Could not find account name '"
+ << acct_regex.pattern << "'." << std::endl;
+ return false;
+ }
+
+ if (index == argc) {
+ std::cerr << "Error: Too few arguments to 'entry'." << std::endl;
+ return false;
+ }
+
+ amount_t amt(argv[index]++);
+ transaction_t * xact = new transaction_t(added, acct, amt, amt);
+
+ if (! xact->amount.commodity)
+ xact->amount.commodity = cmdty;
+
+ added->add_transaction(xact);
+ }
+
+ if ((index + 1) < argc && std::string(argv[index]) == "-from") {
+ if (account_t * acct = find_account(argv[++index])) {
+ transaction_t * xact = new transaction_t(NULL, acct);
+ added->add_transaction(xact);
+ }
+ } else {
+ if (! matching) {
+ std::cerr << "Error: Could not figure out the account to draw from."
+ << std::endl;
+ std::exit(1);
+ }
+ transaction_t * xact
+ = new transaction_t(added, matching->transactions.back()->account);
+ added->add_transaction(xact);
+ }
+ }
+
+ return added;
+}
+
int parse_ledger_file(char * p, ledger_t * journal)
{
char * sep = std::strrchr(p, '=');
diff --git a/ledger.h b/ledger.h
index 840d879d..5d9d0283 100644
--- a/ledger.h
+++ b/ledger.h
@@ -288,6 +288,7 @@ class commodity_t
#define TRANSACTION_NORMAL 0x0
#define TRANSACTION_VIRTUAL 0x1
#define TRANSACTION_BALANCE 0x2
+#define TRANSACTION_AUTO 0x4
class transaction_t
{
@@ -322,11 +323,13 @@ class entry_t
UNCLEARED, CLEARED, PENDING
};
- std::time_t date;
- enum entry_state_t state;
- std::string code;
- std::string payee;
- transactions_list transactions;
+ std::time_t date;
+ entry_state_t state;
+ std::string code;
+ std::string payee;
+ transactions_list transactions;
+
+ entry_t() : date(-1), state(UNCLEARED) {}
~entry_t() {
for (transactions_list::iterator i = transactions.begin();
@@ -429,9 +432,14 @@ class ledger_t
account_t * find_account(const std::string& name, bool auto_create = true) {
return master->find_account(name, auto_create);
}
+ account_t * find_account(const std::string& name) const {
+ return master->find_account(name, false);
+ }
bool add_entry(entry_t * entry);
bool remove_entry(entry_t * entry);
+
+ entry_t * derive_entry(int argc, char **argv) const;
};
int parse_ledger_file(char * p, ledger_t * journal);
diff --git a/main.cc b/main.cc
index 54b65e8e..c9cfdd66 100644
--- a/main.cc
+++ b/main.cc
@@ -83,11 +83,15 @@ void balance_report(std::ostream& out,
//////////////////////////////////////////////////////////////////////
//
-// The command-line register report
+// The command-line register and print report
//
static const std::string reg_fmt
- = "%10d %-.20p %-.22N %12.66t %12.80T\n%/%22_ %-.22N %12.66t %12.80T\n";
+ = "%10d %-.20p %-.22N %12.66t %12.80T\n\
+%/ %-.22N %12.66t %12.80T\n";
+
+static const std::string print_fmt
+ = "\n%10d %X%C%p\n %-34N %12o\n%/ %-34N %12o\n";
static bool show_commodities_revalued = false;
static bool show_commodities_revalued_only = false;
@@ -151,11 +155,11 @@ void register_report(std::ostream& out,
bool first = true;
if ((*i)->subitems.size() > 1 && ! show_expanded) {
- item_t summary;
- summary.date = (*i)->date;
+ item_t summary(*i);
summary.parent = *i;
summary.account = &splits;
+ summary.value = 0;
for (items_deque::const_iterator j = (*i)->subitems.begin();
j != (*i)->subitems.end();
j++)
@@ -171,7 +175,7 @@ void register_report(std::ostream& out,
if (show) {
if (! show_commodities_revalued_only)
- first_line_format.format_elements(out, *i, top);
+ first_line_format.format_elements(out, &summary, top);
if (show_commodities_revalued)
last_reported = balance;
@@ -215,139 +219,6 @@ void register_report(std::ostream& out,
}
-bool add_new_entry(int index, int argc, char **argv, ledger_t * ledger)
-{
- masks_list regexps;
- entry_t added;
- entry_t * matching = NULL;
-
- added.state = entry_t::UNCLEARED;
-
- assert(index < argc);
-
- if (! parse_date(argv[index++], &added.date)) {
- std::cerr << "Error: Bad entry date: " << argv[index - 1]
- << std::endl;
- return false;
- }
-
- if (index == argc) {
- std::cerr << "Error: Too few arguments to 'entry'." << std::endl;
- return false;
- }
-
- regexps.push_back(mask_t(argv[index++]));
-
- for (entries_list::reverse_iterator i = ledger->entries.rbegin();
- i != ledger->entries.rend();
- i++)
- if (matches(regexps, (*i)->payee)) {
- matching = *i;
- break;
- }
-
- added.payee = matching ? matching->payee : regexps.front().pattern;
-
- if (index == argc) {
- std::cerr << "Error: Too few arguments to 'entry'." << std::endl;
- return false;
- }
-
- if (argv[index][0] == '-' || std::isdigit(argv[index][0])) {
- if (! matching) {
- std::cerr << "Error: Missing account name for non-matching entry."
- << std::endl;
- return false;
- }
-
- transaction_t * m_xact, * xact, * first;
- m_xact = matching->transactions.front();
-
- amount_t amt(argv[index++]);
- first = xact = new transaction_t(&added, m_xact->account, amt, amt);
-
- if (xact->amount.commodity->symbol.empty()) {
- xact->amount.commodity = m_xact->amount.commodity;
- xact->cost.commodity = m_xact->amount.commodity;
- }
- added.add_transaction(xact);
-
- m_xact = matching->transactions.back();
-
- xact = new transaction_t(&added, m_xact->account,
- - first->amount, - first->amount);
- added.add_transaction(xact);
-
- if ((index + 1) < argc && std::string(argv[index]) == "-from")
- if (account_t * acct = ledger->find_account(argv[++index]))
- added.transactions.back()->account = acct;
- } else {
- while (index < argc && std::string(argv[index]) != "-from") {
- mask_t acct_regex(argv[index++]);
-
- account_t * acct = NULL;
- commodity_t * cmdty = NULL;
-
- if (matching) {
- for (transactions_list::iterator x
- = matching->transactions.begin();
- x != matching->transactions.end();
- x++) {
- if (acct_regex.match((*x)->account->fullname())) {
- acct = (*x)->account;
- cmdty = (*x)->amount.commodity;
- break;
- }
- }
- }
-
- if (! acct)
- acct = ledger->find_account(acct_regex.pattern);
-
- if (! acct) {
- std::cerr << "Error: Could not find account name '"
- << acct_regex.pattern << "'." << std::endl;
- return false;
- }
-
- if (index == argc) {
- std::cerr << "Error: Too few arguments to 'entry'." << std::endl;
- return false;
- }
-
- amount_t amt(argv[index]++);
- transaction_t * xact = new transaction_t(&added, acct, amt, amt);
-
- if (! xact->amount.commodity)
- xact->amount.commodity = cmdty;
-
- added.add_transaction(xact);
- }
-
- if ((index + 1) < argc && std::string(argv[index]) == "-from") {
- if (account_t * acct = ledger->find_account(argv[++index])) {
- transaction_t * xact = new transaction_t(NULL, acct);
- added.add_transaction(xact);
- }
- } else {
- if (! matching) {
- std::cerr << "Error: Could not figure out the account to draw from."
- << std::endl;
- std::exit(1);
- }
- transaction_t * xact
- = new transaction_t(&added, matching->transactions.back()->account);
- added.add_transaction(xact);
- }
- }
-
- // if (added.finalize())
- print_textual_entry(std::cout, &added);
-
- return true;
-}
-
-
void set_price_conversion(const std::string& setting)
{
char buf[128];
@@ -468,23 +339,24 @@ static void show_help(std::ostream& out)
<< " balance show balance totals" << std::endl
<< " register display a register for ACCOUNT" << std::endl
<< " print print all ledger entries" << std::endl
- << " equity generate equity ledger for all entries" << std::endl
<< " entry output a newly formed entry, based on arguments" << std::endl
- << " price show the last known price for matching commodities" << std::endl;
+ << " equity output equity entries for specified accounts" << std::endl;
}
int main(int argc, char * argv[])
{
- std::list<std::string> files;
-
- std::string predicate_string;
- ledger::node_t * predicate = NULL;
- std::string format_string;
- std::string sort_string;
- ledger::node_t * sort_order = NULL;
- std::string value_expr = "a";
- std::string total_expr = "T";
- ledger::ledger_t * journal = new ledger::ledger_t;
+ std::auto_ptr<ledger::ledger_t> journal(new ledger::ledger_t);
+ std::list<std::string> files;
+ std::auto_ptr<ledger::node_t> predicate;
+ std::auto_ptr<ledger::node_t> display_predicate;
+ std::auto_ptr<ledger::node_t> sort_order;
+
+ std::string predicate_string;
+ std::string display_predicate_string;
+ std::string format_string;
+ std::string sort_string;
+ std::string value_expr = "a";
+ std::string total_expr = "T";
bool show_subtotals = true;
bool show_expanded = false;
@@ -521,11 +393,9 @@ int main(int argc, char * argv[])
if (access(p, R_OK) != -1) {
std::ifstream instr(p);
if (! ledger::read_binary_ledger(instr, std::getenv("LEDGER"),
- journal)) {
- // We need to throw away what we've read, and create a new
- // ledger
- delete journal;
- journal = new ledger::ledger_t;
+ journal.get())) {
+ // Throw away what's been read, and create a new journal
+ journal.reset(new ledger::ledger_t);
} else {
ledger::cache_dirty = false;
}
@@ -652,6 +522,14 @@ int main(int argc, char * argv[])
predicate_string += ")";
break;
+ case 'd':
+ if (! display_predicate_string.empty())
+ display_predicate_string += "&";
+ display_predicate_string += "(";
+ display_predicate_string += optarg;
+ display_predicate_string += ")";
+ break;
+
// Commodity reporting
case 'P':
ledger::price_db = optarg;
@@ -747,14 +625,14 @@ int main(int argc, char * argv[])
if (files.empty()) {
if (char * p = std::getenv("LEDGER"))
for (p = std::strtok(p, ":"); p; p = std::strtok(NULL, ":"))
- entry_count += parse_ledger_file(p, journal);
+ entry_count += parse_ledger_file(p, journal.get());
} else {
for (std::list<std::string>::iterator i = files.begin();
i != files.end(); i++) {
char buf[4096];
char * p = buf;
std::strcpy(p, (*i).c_str());
- entry_count += parse_ledger_file(p, journal);
+ entry_count += parse_ledger_file(p, journal.get());
}
}
@@ -765,7 +643,8 @@ int main(int argc, char * argv[])
const char * path = ledger::price_db.c_str();
std::ifstream db(path);
journal->sources.push_back(path);
- entry_count += ledger::parse_textual_ledger(db, journal, journal->master);
+ entry_count += ledger::parse_textual_ledger(db, journal.get(),
+ journal->master);
}
}
catch (ledger::error& err) {
@@ -780,52 +659,98 @@ int main(int argc, char * argv[])
}
}
- // Read the command word, and handle the "entry" command specially,
- // without any other processing.
+ // Read the command word, and then check and simplify it
- const std::string command = argv[index++];
+ std::string command = argv[index++];
- if (command == "entry")
- return add_new_entry(index, argc, argv, journal) ? 0 : 1;
+ if (command == "balance" || command == "bal" || command == "b")
+ command = "b";
+ else if (command == "register" || command == "reg" || command == "r")
+ command = "r";
+ else if (command == "print" || command == "p")
+ command = "p";
+ else if (command == "entry")
+ command = "e";
+ else if (command == "equity")
+ command = "E";
+ else {
+ std::cerr << "Error: Unrecognized command '" << command << "'."
+ << std::endl;
+ return 1;
+ }
- // Interpret the remaining arguments as regular expressions, used
- // for refining report results.
+ // Process the remaining command-line arguments
- for (; index < argc; index++) {
- if (std::strcmp(argv[index], "--") == 0) {
- index++;
- break;
- }
+ std::auto_ptr<ledger::entry_t> new_entry;
+ if (command == "entry") {
+ new_entry.reset(journal->derive_entry(argc - index, &argv[index]));
+ } else {
+ // Treat the remaining command-line arguments as regular
+ // expressions, used for refining report results.
- show_expanded = true;
+ bool have_regexps = index < argc;
+ bool first = true;
- if (! predicate_string.empty())
- predicate_string += "&";
+ for (; index < argc; index++) {
+ if (std::strcmp(argv[index], "--") == 0) {
+ index++;
+ if (! first && index < argc)
+ predicate_string += ")";
+ break;
+ }
- if (argv[index][0] == '-') {
- predicate_string += "(!/";
- predicate_string += argv[index] + 1;
- } else {
- predicate_string += "(/";
- predicate_string += argv[index];
+ if (! show_expanded && command == "b")
+ show_expanded = true;
+
+ if (first) {
+ if (! predicate_string.empty())
+ predicate_string += "&(";
+ else
+ predicate_string += "(";
+ first = false;
+ } else {
+ predicate_string += "|";
+ }
+
+ if (argv[index][0] == '-') {
+ predicate_string += "!/";
+ predicate_string += argv[index] + 1;
+ } else {
+ predicate_string += "/";
+ predicate_string += argv[index];
+ }
+ predicate_string += "/";
}
- predicate_string += "/)";
- }
- for (; index < argc; index++) {
- show_expanded = true;
+ if (index < argc) {
+ if (! predicate_string.empty())
+ predicate_string += "&(";
+ else
+ predicate_string += "(";
+ }
- if (! predicate_string.empty())
- predicate_string += "&";
+ first = true;
+ for (; index < argc; index++) {
+ if (! show_expanded && command == "b")
+ show_expanded = true;
- if (argv[index][0] == '-') {
- predicate_string += "(!//";
- predicate_string += argv[index] + 1;
- } else {
- predicate_string += "(//";
- predicate_string += argv[index];
+ if (first)
+ first = false;
+ else
+ predicate_string += "|";
+
+ if (argv[index][0] == '-') {
+ predicate_string += "!//";
+ predicate_string += argv[index] + 1;
+ } else {
+ predicate_string += "//";
+ predicate_string += argv[index];
+ }
+ predicate_string += "/";
}
- predicate_string += "/)";
+
+ if (have_regexps)
+ predicate_string += ")";
}
// Compile the predicate
@@ -835,122 +760,110 @@ int main(int argc, char * argv[])
if (debug)
std::cerr << "predicate = " << predicate_string << std::endl;
#endif
- predicate = ledger::parse_expr(predicate_string);
+ predicate.reset(ledger::parse_expr(predicate_string));
+ }
+
+ if (! display_predicate_string.empty()) {
+#ifdef DEBUG
+ if (debug)
+ std::cerr << "display predicate = " << display_predicate_string
+ << std::endl;
+#endif
+ display_predicate.reset(ledger::parse_expr(display_predicate_string));
}
// Compile the sorting string
if (! sort_string.empty())
- sort_order = ledger::parse_expr(sort_string);
+ sort_order.reset(ledger::parse_expr(sort_string));
// Setup the meaning of %t and %T encountered in format strings
- ledger::format_t::value_expr = ledger::parse_expr(value_expr);
- ledger::format_t::total_expr = ledger::parse_expr(total_expr);
+ ledger::format_t::value_expr.reset(ledger::parse_expr(value_expr));
+ ledger::format_t::total_expr.reset(ledger::parse_expr(total_expr));
// Now handle the command that was identified above.
- if (command == "print") {
-#if 0
- if (ledger::item_t * top
- = ledger::walk_entries(journal->entries.begin(),
- journal->entries.end(), predicate,
- show_related, show_inverted)) {
- ledger::format_t * format = new ledger::format_t(format_string);
- ledger::entry_report(std::cout, top, *format);
-#ifdef DEBUG
- delete top;
- delete format;
-#endif
- }
-#endif
+ if (command == "p" || command == "e") {
+ show_related = true;
+ show_expanded = true;
}
- else if (command == "equity") {
-#if 0
- if (ledger::item_t * top
- = ledger::walk_accounts(journal->master, predicate, show_subtotals)) {
- ledger::format_t * format = new ledger::format_t(format_string);
- ledger::entry_report(std::cout, top, predicate, *format);
-#ifdef DEBUG
- delete top;
- delete format;
-#endif
- }
-#endif
+ else if (command == "E") {
+ show_expanded = true;
}
- else if (! sort_order && ! show_related &&
- (command == "balance" || command == "bal")) {
- if (ledger::item_t * top
- = ledger::walk_accounts(journal->master, predicate, show_subtotals)) {
- ledger::format_t * format
- = new ledger::format_t(format_string.empty() ?
- ledger::bal_fmt : format_string);
- ledger::balance_report(std::cout, top, predicate, sort_order, *format,
- show_expanded, show_subtotals);
-#ifdef DEBUG
- delete format;
- delete top;
-#endif
- }
+ else if (show_related && command == "r") {
+ show_inverted = true;
}
- else if (command == "balance" || command == "bal") {
- if (ledger::item_t * list
- = ledger::walk_entries(journal->entries.begin(),
- journal->entries.end(), predicate,
- show_related, show_inverted))
- if (ledger::item_t * top
- = ledger::walk_items(list, journal->master, predicate,
- show_subtotals)) {
- ledger::format_t * format
- = new ledger::format_t(format_string.empty() ?
- ledger::bal_fmt : format_string);
- ledger::balance_report(std::cout, top, predicate, sort_order, *format,
- show_expanded, show_subtotals);
-#ifdef DEBUG
- delete format;
- delete top;
- delete list;
-#endif
- }
+
+ std::auto_ptr<ledger::item_t> top;
+ std::auto_ptr<ledger::item_t> list;
+
+ if (command == "e") {
+ top.reset(new ledger::item_t);
+ ledger::item_t * item = new ledger::item_t(new_entry.get());
+ for (ledger::transactions_list::const_iterator i
+ = new_entry->transactions.begin();
+ i != new_entry->transactions.end();
+ i++)
+ item->add_item(new ledger::item_t(*i));
+ top->add_item(item);
+ }
+ else if ((! show_related || ! predicate.get()) &&
+ (command == "b" || command == "E")) {
+ top.reset(ledger::walk_accounts(NULL, journal->master, predicate.get(),
+ command != "E" && show_subtotals,
+ command == "E"));
}
- else if (command == "register" || command == "reg") {
- if (show_related)
- show_inverted = true;
-
- if (ledger::item_t * top
- = ledger::walk_entries(journal->entries.begin(),
- journal->entries.end(), predicate,
- show_related, show_inverted)) {
+ else {
+ top.reset(ledger::walk_entries(journal->entries.begin(),
+ journal->entries.end(), predicate.get(),
+ show_related, show_inverted));
+ if (top.get() && command == "b" || command == "E") {
+ list.reset(top.release());
+ top.reset(ledger::walk_accounts(list.get(), journal->master,
+ predicate.get(),
+ command != "E" && show_subtotals,
+ command == "E"));
+ }
+ }
+
+ if (top.get()) {
+ const char * f;
+ if (! format_string.empty())
+ f = format_string.c_str();
+ else if (command == "b")
+ f = ledger::bal_fmt.c_str();
+ else if (command == "r")
+ f = ledger::reg_fmt.c_str();
+ else
+ f = ledger::print_fmt.c_str();
+
+ if (command == "b") {
+ std::auto_ptr<ledger::format_t> format(new ledger::format_t(f));
+ ledger::balance_report(std::cout, top.get(), display_predicate.get(),
+ sort_order.get(), *format, show_expanded,
+ show_subtotals);
+ } else {
std::string first_line_format;
std::string next_lines_format;
- const char * f = (format_string.empty() ?
- ledger::reg_fmt.c_str() : format_string.c_str());
if (const char * p = std::strstr(f, "%/")) {
first_line_format = std::string(f, 0, p - f);
next_lines_format = std::string(p + 2);
} else {
- first_line_format = format_string;
- next_lines_format = format_string;
+ first_line_format = next_lines_format = f;
}
- ledger::format_t * format = new ledger::format_t(first_line_format);
- ledger::format_t * nformat = new ledger::format_t(next_lines_format);
+ std::auto_ptr<ledger::format_t>
+ format(new ledger::format_t(first_line_format));
+ std::auto_ptr<ledger::format_t>
+ nformat(new ledger::format_t(next_lines_format));
- ledger::register_report(std::cout, top, predicate, sort_order,
- *format, *nformat, show_expanded);
-#ifdef DEBUG
- delete nformat;
- delete format;
- delete top;
-#endif
+ ledger::register_report(std::cout, top.get(), display_predicate.get(),
+ sort_order.get(), *format, *nformat,
+ show_expanded);
}
}
- else {
- std::cerr << "Error: Unrecognized command '" << command << "'."
- << std::endl;
- return 1;
- }
// Save the cache, if need be
@@ -958,31 +871,10 @@ int main(int argc, char * argv[])
if (const char * p = std::getenv("LEDGER_CACHE")) {
std::ofstream outstr(p);
assert(std::getenv("LEDGER"));
- ledger::write_binary_ledger(outstr, journal, std::getenv("LEDGER"));
+ ledger::write_binary_ledger(outstr, journal.get(),
+ std::getenv("LEDGER"));
}
-#ifdef DEBUG
- delete journal;
-
- if (predicate)
- delete predicate;
- if (sort_order)
- delete sort_order;
-
- if (ledger::format_t::value_expr)
- delete ledger::format_t::value_expr;
- if (ledger::format_t::total_expr)
- delete ledger::format_t::total_expr;
-
- // jww (2004-07-30): This should be moved into some kind of
- // "ledger::shutdown" function.
- for (ledger::commodities_map::iterator i
- = ledger::commodity_t::commodities.begin();
- i != ledger::commodity_t::commodities.end();
- i++)
- delete (*i).second;
-#endif
-
return 0;
}
diff --git a/textual.cc b/textual.cc
index 6fc2f7ec..e262d864 100644
--- a/textual.cc
+++ b/textual.cc
@@ -294,7 +294,8 @@ void automated_transaction_t::extend_entry(entry_t * entry)
amt = (*t)->amount;
transaction_t * xact
- = new transaction_t(entry, (*t)->account, amt, amt, (*t)->flags);
+ = new transaction_t(entry, (*t)->account, amt, amt,
+ (*t)->flags | TRANSACTION_AUTO);
entry->add_transaction(xact);
}
}
@@ -603,8 +604,9 @@ unsigned int parse_textual_ledger(std::istream& in, ledger_t * journal,
amt.parse(buf);
time_commodity = amt.commodity;
- transaction_t * xact = new transaction_t(curr, last_account, amt, amt,
- TRANSACTION_VIRTUAL);
+ transaction_t * xact
+ = new transaction_t(curr, last_account, amt, amt,
+ TRANSACTION_VIRTUAL);
curr->add_transaction(xact);
if (! finalize_entry(curr) || ! journal->add_entry(curr))
@@ -777,123 +779,4 @@ unsigned int parse_textual_ledger(std::istream& in, ledger_t * journal,
return count;
}
-//////////////////////////////////////////////////////////////////////
-//
-// Textual ledger printing code
-//
-
-void print_transaction(std::ostream& out, transaction_t * xact,
- bool display_amount, bool display_cost)
-{
- std::ostringstream s;
- s << *(xact->account);
- std::string acct_name = s.str();
-
- if (xact->flags & TRANSACTION_VIRTUAL) {
- if (xact->flags & TRANSACTION_BALANCE)
- acct_name = std::string("[") + acct_name + "]";
- else
- acct_name = std::string("(") + acct_name + ")";
- }
-
- out.width(30);
- out.fill(' ');
- out << std::left << acct_name;
-
- if (xact->amount && display_amount) {
- out << " ";
- out.width(12);
- out.fill(' ');
- std::ostringstream s;
- s << xact->amount;
- out << std::right << s.str();
- }
-
- if (xact->amount && display_cost &&
- xact->amount != xact->cost) {
- out << " @ ";
- out << xact->cost / xact->amount;
- }
-
- if (! xact->note.empty())
- out << " ; " << xact->note;
-
- out << std::endl;
-}
-
-void print_textual_entry(std::ostream& out, entry_t * entry, bool shortcut)
-{
- char buf[32];
- std::strftime(buf, 31, "%Y/%m/%d ", std::gmtime(&entry->date));
- out << buf;
-
- if (entry->state == entry_t::CLEARED)
- out << "* ";
- if (! entry->code.empty())
- out << '(' << entry->code << ") ";
- if (! entry->payee.empty())
- out << entry->payee;
-
- out << std::endl;
-
- const commodity_t * comm = NULL;
- int size = 0;
-
- for (transactions_list::const_iterator x
- = entry->transactions.begin();
- x != entry->transactions.end();
- x++) {
- if ((*x)->flags & TRANSACTION_VIRTUAL &&
- ! ((*x)->flags & TRANSACTION_BALANCE))
- continue;
-
- if (! comm)
- comm = (*x)->amount.commodity;
- else if (comm != (*x)->amount.commodity)
- shortcut = false;
-
- size++;
- }
-
- if (shortcut && size != 2)
- shortcut = false;
-
- for (transactions_list::const_iterator x
- = entry->transactions.begin();
- x != entry->transactions.end();
- x++) {
- out << " ";
- print_transaction(out, *x,
- (! shortcut || x == entry->transactions.begin() ||
- ((*x)->flags & TRANSACTION_VIRTUAL &&
- ! ((*x)->flags & TRANSACTION_BALANCE))),
- size != 2);
- }
-
- out << std::endl;
-}
-
-void print_textual_ledger(std::ostream& out, ledger_t * journal,
- bool shortcut)
-{
- for (entries_list::const_iterator i = journal->entries.begin();
- i != journal->entries.end();
- i++)
- print_textual_entry(out, *i, shortcut);
-}
-
} // namespace ledger
-
-#ifdef PARSE_TEST
-
-int main(int argc, char *argv[])
-{
- journal.sources.push_back(argv[1]);
- std::ifstream stream(argv[1]);
- ledger::ledger_t journal;
- int count = parse_textual_ledger(stream, &journal, journal.master);
- std::cout << "Read " << count << " entries." << std::endl;
- print_textual_ledger(std::cout, &journal, true);
-}
-
-#endif // PARSE_TEST
diff --git a/textual.h b/textual.h
index 4ed705bf..55d7da97 100644
--- a/textual.h
+++ b/textual.h
@@ -13,12 +13,6 @@ extern bool parse_date_mask(const char * date_str, struct std::tm * result);
extern bool parse_date(const char * date_str, std::time_t * result,
const int year = -1);
-extern void print_textual_ledger(std::ostream& out, ledger_t * ledger,
- bool shortcut = true);
-
-extern void print_textual_entry(std::ostream& out, entry_t * entry,
- bool shortcut = true);
-
} // namespace ledger
#endif // _TEXTUAL_H