diff options
-rwxr-xr-x | acprep | 2 | ||||
-rw-r--r-- | config.cc | 70 | ||||
-rw-r--r-- | config.h | 11 | ||||
-rw-r--r-- | format.h | 33 | ||||
-rw-r--r-- | main.cc | 27 | ||||
-rwxr-xr-x | main.py | 38 | ||||
-rw-r--r-- | sample.dat | 4 | ||||
-rw-r--r-- | textual.cc | 10 | ||||
-rw-r--r-- | walk.cc | 3 | ||||
-rw-r--r-- | walk.h | 35 |
10 files changed, 137 insertions, 96 deletions
@@ -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" @@ -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) ; @@ -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&) { @@ -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) {} @@ -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; @@ -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: @@ -20,3 +20,7 @@ 2004/05/29 Restaurant Expenses:Food $50.00 Liabilities:MasterCard + +2004/09/16 Foo + Assets:Foo $50 + Income:Bar @@ -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 @@ -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() { @@ -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 |