summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rwxr-xr-xacprep2
-rw-r--r--config.cc70
-rw-r--r--config.h11
-rw-r--r--format.h33
-rw-r--r--main.cc27
-rwxr-xr-xmain.py38
-rw-r--r--sample.dat4
-rw-r--r--textual.cc10
-rw-r--r--walk.cc3
-rw-r--r--walk.h35
10 files changed, 137 insertions, 96 deletions
diff --git a/acprep b/acprep
index 7a05fd5c..f479a924 100755
--- a/acprep
+++ b/acprep
@@ -19,7 +19,7 @@ LIBDIRS="-L/sw/lib -L/sw/lib/python2.3/config"
if [ "$1" = "--debug" ]; then
./configure CPPFLAGS="$INCDIRS" LDFLAGS="$LIBDIRS" CXXFLAGS="-g" \
- --enable-debug
+ --enable-debug --disable-shared
elif [ "$1" = "--opt" ]; then
./configure CPPFLAGS="$INCDIRS" LDFLAGS="$LIBDIRS" \
CXXFLAGS="-fomit-frame-pointer -fastf -mcpu=7450 -fPIC"
diff --git a/config.cc b/config.cc
index f000c536..a432b954 100644
--- a/config.cc
+++ b/config.cc
@@ -6,16 +6,6 @@
namespace ledger {
-std::string bal_fmt = "%20T %2_%-n\n";
-std::string reg_fmt
- = "%D %-.20P %-.22N %12.66t %12.80T\n%/%32|%-.22N %12.66t %12.80T\n";
-std::string plot_value_fmt = "%D %t\n";
-std::string plot_total_fmt = "%D %T\n";
-std::string print_fmt
- = "\n%D %X%C%P\n %-34N %12o\n%/ %-34N %12o\n";
-std::string equity_fmt
- = "\n%D %X%C%P\n%/ %-34N %12t\n";
-
config_t config;
std::list<option_t> config_options;
@@ -31,6 +21,14 @@ config_t::config_t()
value_expr = "a";
total_expr = "O";
pricing_leeway = 24 * 3600;
+ balance_format = "%20T %2_%-n\n";
+ register_format = ("%D %-.20P %-.22N %12.66t %12.80T\n%/"
+ "%32|%-.22N %12.66t %12.80T\n");
+ plot_value_format = "%D %t\n";
+ plot_total_format = "%D %T\n";
+ print_format = "\n%D %X%C%P\n %-34N %12o\n%/ %-34N %12o\n";
+ equity_format = "\n%D %X%C%P\n%/ %-34N %12t\n";
+
show_collapsed = false;
show_subtotal = false;
show_related = false;
@@ -200,33 +198,6 @@ void config_t::process_options(const std::string& command,
if (format_t::date_format.empty() && ! date_format.empty())
format_t::date_format = date_format;
-
- // Compile the format strings
-
- const char * f;
- if (! format_string.empty())
- f = format_string.c_str();
- else if (command == "b")
- f = bal_fmt.c_str();
- else if (command == "r")
- f = reg_fmt.c_str();
- else if (command == "E")
- f = equity_fmt.c_str();
- else
- f = print_fmt.c_str();
-
- std::string first_line_format;
- std::string next_lines_format;
-
- 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 = next_lines_format = f;
- }
-
- format.reset(first_line_format);
- nformat.reset(next_lines_format);
}
void parse_ledger_data(journal_t * journal,
@@ -464,27 +435,27 @@ OPT_BEGIN(date_format, "y:") {
} OPT_END(date_format);
OPT_BEGIN(balance_format, ":") {
- bal_fmt = optarg;
+ config.balance_format = optarg;
} OPT_END(balance_format);
OPT_BEGIN(register_format, ":") {
- reg_fmt = optarg;
+ config.register_format = optarg;
} OPT_END(register_format);
OPT_BEGIN(plot_value_format, ":") {
- plot_value_fmt = optarg;
+ config.plot_value_format = optarg;
} OPT_END(plot_value_format);
OPT_BEGIN(plot_total_format, ":") {
- plot_total_fmt = optarg;
+ config.plot_total_format = optarg;
} OPT_END(plot_total_format);
OPT_BEGIN(print_format, ":") {
- print_fmt = optarg;
+ config.print_format = optarg;
} OPT_END(print_format);
OPT_BEGIN(equity_format, ":") {
- equity_fmt = optarg;
+ config.equity_format = optarg;
} OPT_END(equity_format);
OPT_BEGIN(empty, "E") {
@@ -553,12 +524,12 @@ OPT_BEGIN(total_expr, "T:") {
OPT_BEGIN(value_data, "j") {
config.value_expr = "S" + config.value_expr;
- config.format_string = plot_value_fmt;
+ config.format_string = config.plot_value_format;
} OPT_END(value_data);
OPT_BEGIN(total_data, "J") {
config.total_expr = "S" + config.total_expr;
- config.format_string = plot_total_fmt;
+ config.format_string = config.plot_total_format;
} OPT_END(total_data);
//////////////////////////////////////////////////////////////////////
@@ -674,6 +645,12 @@ void export_config()
.def_readwrite("display_predicate", &config_t::display_predicate)
.def_readwrite("report_interval", &config_t::report_interval)
.def_readwrite("format_string", &config_t::format_string)
+ .def_readwrite("balance_format", &config_t::balance_format)
+ .def_readwrite("register_format", &config_t::register_format)
+ .def_readwrite("plot_value_format", &config_t::plot_value_format)
+ .def_readwrite("plot_total_format", &config_t::plot_total_format)
+ .def_readwrite("print_format", &config_t::print_format)
+ .def_readwrite("equity_format", &config_t::equity_format)
.def_readwrite("date_format", &config_t::date_format)
.def_readwrite("sort_string", &config_t::sort_string)
.def_readwrite("value_expr", &config_t::value_expr)
@@ -689,11 +666,8 @@ void export_config()
.def_readwrite("show_revalued", &config_t::show_revalued)
.def_readwrite("show_revalued_only", &config_t::show_revalued_only)
.def_readwrite("download_quotes", &config_t::download_quotes)
-
.def_readwrite("use_cache", &config_t::use_cache)
.def_readwrite("cache_dirty", &config_t::cache_dirty)
- .def_readwrite("format", &config_t::format)
- .def_readwrite("nformat", &config_t::nformat)
.def("process_options", py_process_options)
;
diff --git a/config.h b/config.h
index e12936b4..6a5124d1 100644
--- a/config.h
+++ b/config.h
@@ -36,6 +36,12 @@ struct config_t
std::string display_predicate;
std::string report_interval;
std::string format_string;
+ std::string balance_format;
+ std::string register_format;
+ std::string plot_value_format;
+ std::string plot_total_format;
+ std::string print_format;
+ std::string equity_format;
std::string date_format;
std::string sort_string;
std::string value_expr;
@@ -51,13 +57,8 @@ struct config_t
bool show_revalued;
bool show_revalued_only;
bool download_quotes;
-
- // These settings require processing of the above.
-
bool use_cache;
bool cache_dirty;
- format_t format;
- format_t nformat;
config_t();
config_t(const config_t&) {
diff --git a/format.h b/format.h
index 0b21c1c4..b388d40e 100644
--- a/format.h
+++ b/format.h
@@ -90,18 +90,24 @@ struct format_t
class format_transactions : public item_handler<transaction_t>
{
- std::ostream& output_stream;
- const format_t& first_line_format;
- const format_t& next_lines_format;
- entry_t * last_entry;
+ std::ostream& output_stream;
+ format_t first_line_format;
+ format_t next_lines_format;
+ entry_t * last_entry;
public:
- format_transactions(std::ostream& _output_stream,
- const format_t& _first_line_format,
- const format_t& _next_lines_format)
- : output_stream(_output_stream),
- first_line_format(_first_line_format),
- next_lines_format(_next_lines_format), last_entry(NULL) {}
+ format_transactions(std::ostream& _output_stream,
+ const std::string& format)
+ : output_stream(_output_stream), last_entry(NULL) {
+ 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));
+ } else {
+ first_line_format.reset(format);
+ next_lines_format.reset(format);
+ }
+ }
virtual void flush() {
output_stream.flush();
@@ -123,14 +129,15 @@ class format_transactions : public item_handler<transaction_t>
class format_account : public item_handler<account_t>
{
- std::ostream& output_stream;
- const format_t& format;
+ std::ostream& output_stream;
item_predicate<account_t> disp_pred;
public:
+ format_t format;
+
format_account(std::ostream& _output_stream,
- const format_t& _format,
+ const std::string& _format,
const std::string& display_predicate = NULL)
: output_stream(_output_stream), format(_format),
disp_pred(display_predicate) {}
diff --git a/main.cc b/main.cc
index 7cc054f0..145497d8 100644
--- a/main.cc
+++ b/main.cc
@@ -245,6 +245,20 @@ int parse_and_report(int argc, char * argv[], char * envp[])
if (! config.output_file.empty())
out = new std::ofstream(config.output_file.c_str());
+ // Compile the format strings
+
+ const std::string * format;
+ if (! config.format_string.empty())
+ format = &config.format_string;
+ else if (command == "b")
+ format = &config.balance_format;
+ else if (command == "r")
+ format = &config.register_format;
+ else if (command == "E")
+ format = &config.equity_format;
+ else
+ format = &config.print_format;
+
// Walk the entries based on the report type and the options
item_handler<transaction_t> * formatter;
@@ -254,7 +268,7 @@ int parse_and_report(int argc, char * argv[], char * envp[])
formatter = new set_account_value;
formatter = chain_formatters(command, formatter, formatter_ptrs);
} else {
- formatter = new format_transactions(*out, config.format, config.nformat);
+ formatter = new format_transactions(*out, *format);
formatter = chain_formatters(command, formatter, formatter_ptrs);
}
@@ -268,8 +282,7 @@ int parse_and_report(int argc, char * argv[], char * envp[])
// For the balance and equity reports, output the sum totals.
if (command == "b") {
- format_account acct_formatter(*out, config.format,
- config.display_predicate);
+ format_account acct_formatter(*out, *format, config.display_predicate);
sum_accounts(*journal->master);
walk_accounts(*journal->master, acct_formatter, config.sort_string);
acct_formatter.flush();
@@ -279,19 +292,21 @@ int parse_and_report(int argc, char * argv[], char * envp[])
xdata.value = xdata.total;
if (xdata.dflags & ACCOUNT_TO_DISPLAY) {
*out << "--------------------\n";
- config.format.format(*out, details_t(*journal->master));
+ acct_formatter.format.format(*out, details_t(*journal->master));
}
}
}
else if (command == "E") {
- format_equity acct_formatter(*out, config.format, config.nformat,
- config.display_predicate);
+ format_equity acct_formatter(*out, *format, config.display_predicate);
sum_accounts(*journal->master);
walk_accounts(*journal->master, acct_formatter, config.sort_string);
acct_formatter.flush();
}
#if DEBUG_LEVEL >= BETA
+ clear_transactions_xdata();
+ clear_accounts_xdata();
+
if (! config.output_file.empty())
delete out;
diff --git a/main.py b/main.py
index 6eb5ae31..458470f0 100755
--- a/main.py
+++ b/main.py
@@ -16,6 +16,7 @@
import sys
import os
+import string
from ledger import *
@@ -72,22 +73,31 @@ if command == "e":
if new_entry is None:
sys.exit (1)
+# Compile the format string
+
+if config.format_string:
+ format = config.format_string
+elif command == "b":
+ format = config.balance_format
+elif command == "r":
+ format = config.register_format
+elif command == "E":
+ format = config.equity_format
+else:
+ format = config.print_format
+
class FormatTransaction (TransactionHandler):
last_entry = None
output = None
- def __init__ (self, fmt = None):
- if fmt is None:
- self.formatter = config.format
- self.nformatter = config.nformat
- else:
- try:
- i = string.index (fmt, '%/')
- self.formatter = Format (fmt[: i])
- self.nformatter = Format (fmt[i + 2 :])
- except ValueError:
- self.formatter = Format (fmt)
- self.nformatter = None
+ def __init__ (self, fmt):
+ try:
+ i = string.index (fmt, '%/')
+ self.formatter = Format (fmt[: i])
+ self.nformatter = Format (fmt[i + 2 :])
+ except ValueError:
+ self.formatter = Format (fmt)
+ self.nformatter = None
self.last_entry = None
@@ -107,7 +117,7 @@ class FormatTransaction (TransactionHandler):
def __call__ (self, xact):
if self.nformatter is not None and self.last_entry is not None and \
- xact.entry.payee == self.last_entry.payee:
+ xact.entry == self.last_entry:
self.output.write(self.nformatter.format(xact))
else:
self.output.write(self.formatter.format(xact))
@@ -116,7 +126,7 @@ class FormatTransaction (TransactionHandler):
if command == "b" or command == "E":
handler = SetAccountValue()
else:
- handler = FormatTransaction()
+ handler = FormatTransaction(format)
if not (command == "b" or command == "E"):
if config.display_predicate:
diff --git a/sample.dat b/sample.dat
index 7460cd4b..4640f456 100644
--- a/sample.dat
+++ b/sample.dat
@@ -20,3 +20,7 @@
2004/05/29 Restaurant
Expenses:Food $50.00
Liabilities:MasterCard
+
+2004/09/16 Foo
+ Assets:Foo $50
+ Income:Bar
diff --git a/textual.cc b/textual.cc
index 57cb0089..e95d0eff 100644
--- a/textual.cc
+++ b/textual.cc
@@ -152,7 +152,7 @@ bool finalize_entry(entry_t * entry)
value_t balance;
- bool first = true;
+ bool no_amounts = true;
for (transactions_list::const_iterator x = entry->transactions.begin();
x != entry->transactions.end();
x++)
@@ -160,15 +160,19 @@ bool finalize_entry(entry_t * entry)
((*x)->flags & TRANSACTION_BALANCE)) {
amount_t * p = (*x)->cost ? (*x)->cost : &(*x)->amount;
if (*p) {
- if (first) {
+ if (no_amounts) {
balance = *p;
- first = false;
+ no_amounts = false;
} else {
balance += *p;
}
}
}
+ // If it's a null entry, then let the user have their fun
+ if (no_amounts)
+ return true;
+
// If one transaction of a two-line transaction is of a different
// commodity than the others, and it has no per-unit price,
// determine its price by dividing the unit count into the value of
diff --git a/walk.cc b/walk.cc
index aa7b7cb3..ae4624eb 100644
--- a/walk.cc
+++ b/walk.cc
@@ -4,7 +4,10 @@
namespace ledger {
std::list<transaction_xdata_t> transactions_xdata;
+std::list<void **> transactions_xdata_ptrs;
+
std::list<account_xdata_t> accounts_xdata;
+std::list<void **> accounts_xdata_ptrs;
void sort_transactions::flush()
{
diff --git a/walk.h b/walk.h
index 6d12de02..846ccfe1 100644
--- a/walk.h
+++ b/walk.h
@@ -90,11 +90,13 @@ inline bool transaction_has_xdata(const transaction_t& xact) {
}
extern std::list<transaction_xdata_t> transactions_xdata;
+extern std::list<void **> transactions_xdata_ptrs;
inline transaction_xdata_t& transaction_xdata(const transaction_t& xact) {
if (! xact.data) {
transactions_xdata.push_back(transaction_xdata_t());
xact.data = &transactions_xdata.back();
+ transactions_xdata_ptrs.push_back(&xact.data);
}
return *((transaction_xdata_t *) xact.data);
}
@@ -109,7 +111,6 @@ inline void walk_transactions(transactions_list::iterator begin,
item_handler<transaction_t>& handler) {
for (transactions_list::iterator i = begin; i != end; i++)
handler(**i);
- transactions_xdata.clear();
}
inline void walk_transactions(transactions_list& list,
@@ -122,7 +123,6 @@ inline void walk_transactions(transactions_deque::iterator begin,
item_handler<transaction_t>& handler) {
for (transactions_deque::iterator i = begin; i != end; i++)
handler(**i);
- transactions_xdata.clear();
}
inline void walk_transactions(transactions_deque& deque,
@@ -142,6 +142,15 @@ inline void walk_entries(entries_list& list,
walk_entries(list.begin(), list.end(), handler);
}
+inline void clear_transactions_xdata() {
+ transactions_xdata.clear();
+
+ for (std::list<void **>::iterator i = transactions_xdata_ptrs.begin();
+ i != transactions_xdata_ptrs.end();
+ i++)
+ **i = NULL;
+}
+
//////////////////////////////////////////////////////////////////////
class ignore_transactions : public item_handler<transaction_t>
@@ -414,11 +423,13 @@ inline bool account_has_xdata(const account_t& account) {
}
extern std::list<account_xdata_t> accounts_xdata;
+extern std::list<void **> accounts_xdata_ptrs;
inline account_xdata_t& account_xdata(const account_t& account) {
if (! account.data) {
accounts_xdata.push_back(account_xdata_t());
account.data = &accounts_xdata.back();
+ accounts_xdata_ptrs.push_back(&account.data);
}
return *((account_xdata_t *) account.data);
}
@@ -476,16 +487,28 @@ inline void walk_accounts(account_t& account,
for (accounts_map::const_iterator i = account.accounts.begin();
i != account.accounts.end();
i++)
- walk_accounts(*(*i).second, handler);
+ walk_accounts(*(*i).second, handler, NULL);
}
- accounts_xdata.clear();
}
inline void walk_accounts(account_t& account,
item_handler<account_t>& handler,
const std::string& sort_string) {
- std::auto_ptr<value_expr_t> sort_order(parse_value_expr(sort_string));
- walk_accounts(account, handler, sort_order.get());
+ if (! sort_string.empty()) {
+ std::auto_ptr<value_expr_t> sort_order(parse_value_expr(sort_string));
+ walk_accounts(account, handler, sort_order.get());
+ } else {
+ walk_accounts(account, handler);
+ }
+}
+
+inline void clear_accounts_xdata() {
+ accounts_xdata.clear();
+
+ for (std::list<void **>::iterator i = accounts_xdata_ptrs.begin();
+ i != accounts_xdata_ptrs.end();
+ i++)
+ **i = NULL;
}
} // namespace ledger