From 61bc7362ca974543c9b851f8fc81fe981569ad6c Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Mon, 27 Feb 2012 02:29:42 -0600 Subject: Added new account/payee/commodity directives Also added supporting options: --explicit, --permissive, --pedantic, as well as new behavior for --strict. --- src/session.cc | 13 +++++++++++++ 1 file changed, 13 insertions(+) (limited to 'src/session.cc') diff --git a/src/session.cc b/src/session.cc index 72e29895..cc069efe 100644 --- a/src/session.cc +++ b/src/session.cc @@ -97,6 +97,16 @@ std::size_t session_t::read_data(const string& master_account) if (HANDLED(price_db_)) price_db_path = resolve_path(HANDLER(price_db_).str()); + if (HANDLED(explicit)) + journal->force_checking = true; + + if (HANDLED(permissive)) + journal->checking_style = journal_t::CHECK_PERMISSIVE; + else if (HANDLED(pedantic)) + journal->checking_style = journal_t::CHECK_ERROR; + else if (HANDLED(strict)) + journal->checking_style = journal_t::CHECK_WARNING; + #if defined(HAVE_BOOST_SERIALIZATION) optional cache; if (HANDLED(cache_) && master_account.empty()) @@ -251,6 +261,7 @@ option_t * session_t::lookup_option(const char * p) break; case 'l': OPT_ALT(price_exp_, leeway_); + else OPT(explicit); break; case 'm': OPT(master_account_); @@ -258,6 +269,8 @@ option_t * session_t::lookup_option(const char * p) case 'p': OPT(price_db_); else OPT(price_exp_); + else OPT(pedantic); + else OPT(permissive); break; case 's': OPT(strict); -- cgit v1.2.3 From 5532a1a8b756f0f7499570afccb1d4fc3e9bc76d Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Mon, 27 Feb 2012 11:52:23 -0600 Subject: Added --check-payees option --- doc/ledger.1 | 1 + src/journal.cc | 36 +++++++++++++++++++----------------- src/journal.h | 1 + src/session.cc | 3 +++ src/session.h | 2 ++ test/baseline/opt-check-payees.test | 0 6 files changed, 26 insertions(+), 17 deletions(-) create mode 100644 test/baseline/opt-check-payees.test (limited to 'src/session.cc') diff --git a/doc/ledger.1 b/doc/ledger.1 index 5e280889..656a3866 100644 --- a/doc/ledger.1 +++ b/doc/ledger.1 @@ -281,6 +281,7 @@ transactions they are contained in. See the manual for more information. .It Fl \-budget-format Ar FMT .It Fl \-by-payee Pq Fl P .It Fl \-cache Ar FILE +.It Fl \-check-payees .It Fl \-cleared Pq Fl C .It Fl \-cleared-format Ar FMT .It Fl \-collapse Pq Fl n diff --git a/src/journal.cc b/src/journal.cc index 8f382125..355f3ee6 100644 --- a/src/journal.cc +++ b/src/journal.cc @@ -89,6 +89,7 @@ void journal_t::initialize() fixed_metadata = false; was_loaded = false; force_checking = false; + check_payees = false; checking_style = CHECK_PERMISSIVE; } @@ -160,26 +161,27 @@ string journal_t::register_payee(const string& name, xact_t *, const string&) { string payee; -#if 0 - std::set::iterator i = known_payees.find(name); + if (check_payees && + (checking_style == CHECK_WARNING || checking_style == CHECK_ERROR)) { + std::set::iterator i = known_payees.find(name); - if (i == known_payees.end()) { - if (! xact) { - if (force_checking) - fixed_payees = true; - known_payees.insert(name); - } - else if (! fixed_payees && xact->_state != item_t::UNCLEARED) { - known_payees.insert(name); - } - else if (checking_style == CHECK_WARNING) { - warning_(_("%1Unknown payee '%2'") << location << name); - } - else if (checking_style == CHECK_ERROR) { - throw_(parse_error, _("Unknown payee '%1'") << name); + if (i == known_payees.end()) { + if (! xact) { + if (force_checking) + fixed_payees = true; + known_payees.insert(name); + } + else if (! fixed_payees && xact->_state != item_t::UNCLEARED) { + known_payees.insert(name); + } + else if (checking_style == CHECK_WARNING) { + warning_(_("%1Unknown payee '%2'") << location << name); + } + else if (checking_style == CHECK_ERROR) { + throw_(parse_error, _("Unknown payee '%1'") << name); + } } } -#endif foreach (payee_mapping_t& value, payee_mappings) { if (value.first.match(name)) { diff --git a/src/journal.h b/src/journal.h index 9c42ec6a..d7cf94da 100644 --- a/src/journal.h +++ b/src/journal.h @@ -134,6 +134,7 @@ public: tag_check_exprs_map tag_check_exprs; bool was_loaded; bool force_checking; + bool check_payees; enum checking_style_t { CHECK_PERMISSIVE, diff --git a/src/session.cc b/src/session.cc index cc069efe..797ee3e5 100644 --- a/src/session.cc +++ b/src/session.cc @@ -99,6 +99,8 @@ std::size_t session_t::read_data(const string& master_account) if (HANDLED(explicit)) journal->force_checking = true; + if (HANDLED(check_payees)) + journal->check_payees = true; if (HANDLED(permissive)) journal->checking_style = journal_t::CHECK_PERMISSIVE; @@ -248,6 +250,7 @@ option_t * session_t::lookup_option(const char * p) break; case 'c': OPT(cache_); + else OPT(check_payees); break; case 'd': OPT(download); // -Q diff --git a/src/session.h b/src/session.h index 5d6d4bed..680b8a0e 100644 --- a/src/session.h +++ b/src/session.h @@ -87,6 +87,7 @@ public: void report_options(std::ostream& out) { HANDLER(cache_).report(out); + HANDLER(check_payees).report(out); HANDLER(download).report(out); HANDLER(decimal_comma).report(out); HANDLER(file_).report(out); @@ -110,6 +111,7 @@ public: */ OPTION(session_t, cache_); + OPTION(session_t, check_payees); OPTION(session_t, download); // -Q OPTION_(session_t, decimal_comma, DO() { diff --git a/test/baseline/opt-check-payees.test b/test/baseline/opt-check-payees.test new file mode 100644 index 00000000..e69de29b -- cgit v1.2.3 From c1ab9cad30c76449a3b5d463e7aa3b6874b83199 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Mon, 27 Feb 2012 12:37:53 -0600 Subject: --explicit wasn't being handled correctly --- src/session.cc | 4 +++- 1 file changed, 3 insertions(+), 1 deletion(-) (limited to 'src/session.cc') diff --git a/src/session.cc b/src/session.cc index 797ee3e5..31122daa 100644 --- a/src/session.cc +++ b/src/session.cc @@ -256,6 +256,9 @@ option_t * session_t::lookup_option(const char * p) OPT(download); // -Q else OPT(decimal_comma); break; + case 'e': + OPT(explicit); + break; case 'f': OPT_(file_); // -f break; @@ -264,7 +267,6 @@ option_t * session_t::lookup_option(const char * p) break; case 'l': OPT_ALT(price_exp_, leeway_); - else OPT(explicit); break; case 'm': OPT(master_account_); -- cgit v1.2.3 From e2afc783db0dff1927b00dc506390353d9e3bbd2 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Wed, 29 Feb 2012 22:32:23 -0600 Subject: Increased file copyrights to 2012 --- src/account.cc | 2 +- src/account.h | 2 +- src/accum.cc | 2 +- src/accum.h | 2 +- src/amount.cc | 2 +- src/amount.h | 2 +- src/annotate.cc | 2 +- src/annotate.h | 2 +- src/archive.cc | 2 +- src/archive.h | 2 +- src/balance.cc | 2 +- src/balance.h | 2 +- src/chain.cc | 2 +- src/chain.h | 2 +- src/commodity.cc | 2 +- src/commodity.h | 2 +- src/compare.cc | 2 +- src/compare.h | 2 +- src/convert.cc | 2 +- src/convert.h | 2 +- src/csv.cc | 2 +- src/csv.h | 2 +- src/draft.cc | 2 +- src/draft.h | 2 +- src/emacs.cc | 2 +- src/emacs.h | 2 +- src/error.cc | 2 +- src/error.h | 2 +- src/expr.cc | 2 +- src/expr.h | 2 +- src/exprbase.h | 2 +- src/filters.cc | 2 +- src/filters.h | 2 +- src/flags.h | 2 +- src/format.cc | 2 +- src/format.h | 2 +- src/generate.cc | 2 +- src/generate.h | 2 +- src/global.cc | 2 +- src/global.h | 4 ++-- src/item.cc | 2 +- src/item.h | 2 +- src/iterators.cc | 2 +- src/iterators.h | 2 +- src/journal.cc | 2 +- src/journal.h | 2 +- src/lookup.cc | 2 +- src/lookup.h | 2 +- src/main.cc | 2 +- src/mask.cc | 2 +- src/mask.h | 2 +- src/op.cc | 2 +- src/op.h | 2 +- src/option.cc | 2 +- src/option.h | 2 +- src/org.cc | 2 +- src/org.h | 2 +- src/output.cc | 2 +- src/output.h | 2 +- src/parser.cc | 2 +- src/parser.h | 2 +- src/pool.cc | 2 +- src/pool.h | 2 +- src/post.cc | 2 +- src/post.h | 2 +- src/precmd.cc | 2 +- src/precmd.h | 2 +- src/predicate.cc | 2 +- src/predicate.h | 2 +- src/print.cc | 2 +- src/print.h | 2 +- src/pstream.h | 2 +- src/py_account.cc | 2 +- src/py_amount.cc | 2 +- src/py_balance.cc | 2 +- src/py_commodity.cc | 2 +- src/py_expr.cc | 2 +- src/py_format.cc | 2 +- src/py_item.cc | 2 +- src/py_journal.cc | 2 +- src/py_post.cc | 2 +- src/py_times.cc | 2 +- src/py_utils.cc | 2 +- src/py_value.cc | 2 +- src/py_xact.cc | 2 +- src/pyfstream.h | 2 +- src/pyinterp.cc | 2 +- src/pyinterp.h | 2 +- src/pyledger.cc | 2 +- src/pyutils.h | 2 +- src/query.cc | 2 +- src/query.h | 2 +- src/quotes.cc | 2 +- src/quotes.h | 2 +- src/report.cc | 2 +- src/report.h | 2 +- src/scope.cc | 2 +- src/scope.h | 2 +- src/series.h | 2 +- src/session.cc | 2 +- src/session.h | 2 +- src/stats.cc | 2 +- src/stats.h | 2 +- src/stream.cc | 2 +- src/stream.h | 2 +- src/system.hh.in | 2 +- src/temps.cc | 2 +- src/temps.h | 2 +- src/textual.cc | 2 +- src/timelog.cc | 2 +- src/timelog.h | 2 +- src/times.cc | 2 +- src/times.h | 2 +- src/token.cc | 2 +- src/token.h | 2 +- src/unistring.h | 2 +- src/utils.cc | 2 +- src/utils.h | 2 +- src/value.cc | 2 +- src/value.h | 2 +- src/xact.cc | 2 +- src/xact.h | 2 +- src/xml.cc | 2 +- src/xml.h | 2 +- 124 files changed, 125 insertions(+), 125 deletions(-) (limited to 'src/session.cc') diff --git a/src/account.cc b/src/account.cc index 42c10839..40ddf70b 100644 --- a/src/account.cc +++ b/src/account.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/account.h b/src/account.h index 7a632b35..8f0f915f 100644 --- a/src/account.h +++ b/src/account.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/accum.cc b/src/accum.cc index 0187995e..3add051b 100644 --- a/src/accum.cc +++ b/src/accum.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/accum.h b/src/accum.h index 411bcbe6..349aeba9 100644 --- a/src/accum.h +++ b/src/accum.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/src/amount.cc b/src/amount.cc index 85afc3d8..4d26a688 100644 --- a/src/amount.cc +++ b/src/amount.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/amount.h b/src/amount.h index f7e877a7..3a8e06b9 100644 --- a/src/amount.h +++ b/src/amount.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/src/annotate.cc b/src/annotate.cc index 8ba46f4f..cd1733ca 100644 --- a/src/annotate.cc +++ b/src/annotate.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/annotate.h b/src/annotate.h index b590ca45..3c6db8e8 100644 --- a/src/annotate.h +++ b/src/annotate.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/archive.cc b/src/archive.cc index 28760512..72ec0419 100644 --- a/src/archive.cc +++ b/src/archive.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/archive.h b/src/archive.h index 1ebf3496..4ce5e0e7 100644 --- a/src/archive.h +++ b/src/archive.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/balance.cc b/src/balance.cc index 7ce9d994..4fba7344 100644 --- a/src/balance.cc +++ b/src/balance.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/balance.h b/src/balance.h index ac22f3e7..57e6ace4 100644 --- a/src/balance.h +++ b/src/balance.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/chain.cc b/src/chain.cc index 61388840..fc1be5bd 100644 --- a/src/chain.cc +++ b/src/chain.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/chain.h b/src/chain.h index 7bd76712..080c4231 100644 --- a/src/chain.h +++ b/src/chain.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/commodity.cc b/src/commodity.cc index 5fd54d11..643d0d1e 100644 --- a/src/commodity.cc +++ b/src/commodity.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/commodity.h b/src/commodity.h index d7747b2a..68f788e3 100644 --- a/src/commodity.h +++ b/src/commodity.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/compare.cc b/src/compare.cc index cdc96a86..e2a298c2 100644 --- a/src/compare.cc +++ b/src/compare.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/compare.h b/src/compare.h index 0e7bf5e5..e1abbca1 100644 --- a/src/compare.h +++ b/src/compare.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/convert.cc b/src/convert.cc index 15995d05..1b1bf814 100644 --- a/src/convert.cc +++ b/src/convert.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/convert.h b/src/convert.h index 6d02f24a..de958108 100644 --- a/src/convert.h +++ b/src/convert.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/csv.cc b/src/csv.cc index 82c28ff3..823238c7 100644 --- a/src/csv.cc +++ b/src/csv.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/csv.h b/src/csv.h index 909439ff..4d6e1253 100644 --- a/src/csv.h +++ b/src/csv.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/draft.cc b/src/draft.cc index 9f9ec6e8..7c95caf7 100644 --- a/src/draft.cc +++ b/src/draft.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/draft.h b/src/draft.h index 59039f77..41485731 100644 --- a/src/draft.h +++ b/src/draft.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/emacs.cc b/src/emacs.cc index 5048a348..41c67cc6 100644 --- a/src/emacs.cc +++ b/src/emacs.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/emacs.h b/src/emacs.h index 97292728..a018ce68 100644 --- a/src/emacs.h +++ b/src/emacs.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/error.cc b/src/error.cc index 88adfbdb..4a16f4e3 100644 --- a/src/error.cc +++ b/src/error.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/error.h b/src/error.h index b9960b03..7630f017 100644 --- a/src/error.h +++ b/src/error.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/expr.cc b/src/expr.cc index b3d4abcd..74d16ecc 100644 --- a/src/expr.cc +++ b/src/expr.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/expr.h b/src/expr.h index 79ae2864..e082efa5 100644 --- a/src/expr.h +++ b/src/expr.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/exprbase.h b/src/exprbase.h index e0e2824f..0b1ef243 100644 --- a/src/exprbase.h +++ b/src/exprbase.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/filters.cc b/src/filters.cc index fa1f6fa2..72ce9c32 100644 --- a/src/filters.cc +++ b/src/filters.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/filters.h b/src/filters.h index c972de82..22f2d2cb 100644 --- a/src/filters.h +++ b/src/filters.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/flags.h b/src/flags.h index 09b7eec4..e2046c08 100644 --- a/src/flags.h +++ b/src/flags.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/format.cc b/src/format.cc index 65c06488..a391fdf1 100644 --- a/src/format.cc +++ b/src/format.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/format.h b/src/format.h index f30b8184..74d77768 100644 --- a/src/format.h +++ b/src/format.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/generate.cc b/src/generate.cc index 963cd845..bf9a8036 100644 --- a/src/generate.cc +++ b/src/generate.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/generate.h b/src/generate.h index abf719d4..1b22004b 100644 --- a/src/generate.h +++ b/src/generate.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/global.cc b/src/global.cc index 34427f4b..ee921fc5 100644 --- a/src/global.cc +++ b/src/global.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/global.h b/src/global.h index 6504230d..28bffc3a 100644 --- a/src/global.h +++ b/src/global.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions @@ -113,7 +113,7 @@ public: out << "Ledger " << ledger::version << _(", the command-line accounting tool"); out << - _("\n\nCopyright (c) 2003-2010, John Wiegley. All rights reserved.\n\n\ + _("\n\nCopyright (c) 2003-2012, John Wiegley. All rights reserved.\n\n\ This program is made available under the terms of the BSD Public License.\n\ See LICENSE file included with the distribution for details and disclaimer."); out << std::endl; diff --git a/src/item.cc b/src/item.cc index d123ee5a..3a2b0b60 100644 --- a/src/item.cc +++ b/src/item.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/item.h b/src/item.h index af3992c0..3a9c55bb 100644 --- a/src/item.h +++ b/src/item.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/iterators.cc b/src/iterators.cc index b398646e..72e0481c 100644 --- a/src/iterators.cc +++ b/src/iterators.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/iterators.h b/src/iterators.h index 93782400..6d490259 100644 --- a/src/iterators.h +++ b/src/iterators.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/journal.cc b/src/journal.cc index ea90fa05..2ebe90fb 100644 --- a/src/journal.cc +++ b/src/journal.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/journal.h b/src/journal.h index 70820cbd..6d10ffda 100644 --- a/src/journal.h +++ b/src/journal.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/lookup.cc b/src/lookup.cc index 452727d6..ce22529d 100644 --- a/src/lookup.cc +++ b/src/lookup.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/lookup.h b/src/lookup.h index 8e83b84e..ba64b0b5 100644 --- a/src/lookup.h +++ b/src/lookup.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/main.cc b/src/main.cc index 9031341f..2202a5de 100644 --- a/src/main.cc +++ b/src/main.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/mask.cc b/src/mask.cc index 52907cfe..5bc10d5f 100644 --- a/src/mask.cc +++ b/src/mask.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/mask.h b/src/mask.h index e72347ad..15929b2e 100644 --- a/src/mask.h +++ b/src/mask.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/op.cc b/src/op.cc index 6dff031c..372101f0 100644 --- a/src/op.cc +++ b/src/op.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/op.h b/src/op.h index c4d353dc..192c1f5e 100644 --- a/src/op.h +++ b/src/op.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/option.cc b/src/option.cc index 2843c775..170b94af 100644 --- a/src/option.cc +++ b/src/option.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/option.h b/src/option.h index 8f89d081..dc1099db 100644 --- a/src/option.h +++ b/src/option.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/org.cc b/src/org.cc index 7c8e8c0d..3c897f54 100644 --- a/src/org.cc +++ b/src/org.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/org.h b/src/org.h index ed023be2..0b34b610 100644 --- a/src/org.h +++ b/src/org.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/output.cc b/src/output.cc index b26881a3..aaf81f60 100644 --- a/src/output.cc +++ b/src/output.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/output.h b/src/output.h index ac3925c4..281f69b6 100644 --- a/src/output.h +++ b/src/output.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/parser.cc b/src/parser.cc index 6197af6b..2c9069d7 100644 --- a/src/parser.cc +++ b/src/parser.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/parser.h b/src/parser.h index 09e12d95..75fd9a41 100644 --- a/src/parser.h +++ b/src/parser.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/pool.cc b/src/pool.cc index 65edbd6a..ba408fc5 100644 --- a/src/pool.cc +++ b/src/pool.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/pool.h b/src/pool.h index 4b935f69..87b315f9 100644 --- a/src/pool.h +++ b/src/pool.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/post.cc b/src/post.cc index 125947e4..e0ca149f 100644 --- a/src/post.cc +++ b/src/post.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/post.h b/src/post.h index 0cfd3e90..ce33fefc 100644 --- a/src/post.h +++ b/src/post.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/precmd.cc b/src/precmd.cc index 663b638d..6f8becb6 100644 --- a/src/precmd.cc +++ b/src/precmd.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/precmd.h b/src/precmd.h index 277933c3..1c52d8a7 100644 --- a/src/precmd.h +++ b/src/precmd.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/predicate.cc b/src/predicate.cc index fd301a7d..58d6c752 100644 --- a/src/predicate.cc +++ b/src/predicate.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/predicate.h b/src/predicate.h index 673f1d5d..7d58dc2f 100644 --- a/src/predicate.h +++ b/src/predicate.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/print.cc b/src/print.cc index 63f38d80..c544c4e0 100644 --- a/src/print.cc +++ b/src/print.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/print.h b/src/print.h index 527f1912..42bfc8b6 100644 --- a/src/print.h +++ b/src/print.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/pstream.h b/src/pstream.h index 8134495d..a894325d 100644 --- a/src/pstream.h +++ b/src/pstream.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions diff --git a/src/py_account.cc b/src/py_account.cc index 5ef86871..64a7ae54 100644 --- a/src/py_account.cc +++ b/src/py_account.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/py_amount.cc b/src/py_amount.cc index 9ce4a02d..f10595e8 100644 --- a/src/py_amount.cc +++ b/src/py_amount.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/py_balance.cc b/src/py_balance.cc index 0140a625..6c9ccb24 100644 --- a/src/py_balance.cc +++ b/src/py_balance.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/py_commodity.cc b/src/py_commodity.cc index 6d8a29b3..11ebe844 100644 --- a/src/py_commodity.cc +++ b/src/py_commodity.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/py_expr.cc b/src/py_expr.cc index 027125e2..dd9df1f5 100644 --- a/src/py_expr.cc +++ b/src/py_expr.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/py_format.cc b/src/py_format.cc index fc2103c7..482eaf5b 100644 --- a/src/py_format.cc +++ b/src/py_format.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/py_item.cc b/src/py_item.cc index a12784ff..e3e49457 100644 --- a/src/py_item.cc +++ b/src/py_item.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/py_journal.cc b/src/py_journal.cc index bd781225..4f5427f5 100644 --- a/src/py_journal.cc +++ b/src/py_journal.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/py_post.cc b/src/py_post.cc index cace419f..bd599604 100644 --- a/src/py_post.cc +++ b/src/py_post.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/py_times.cc b/src/py_times.cc index c2e0b8f8..17f9ec7e 100644 --- a/src/py_times.cc +++ b/src/py_times.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/py_utils.cc b/src/py_utils.cc index 710dca4b..45ffe545 100644 --- a/src/py_utils.cc +++ b/src/py_utils.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/py_value.cc b/src/py_value.cc index f8f36453..3b67c4c6 100644 --- a/src/py_value.cc +++ b/src/py_value.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/py_xact.cc b/src/py_xact.cc index af1fcdd5..97d5df47 100644 --- a/src/py_xact.cc +++ b/src/py_xact.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/pyfstream.h b/src/pyfstream.h index 49b072f2..972f976f 100644 --- a/src/pyfstream.h +++ b/src/pyfstream.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/pyinterp.cc b/src/pyinterp.cc index e48f16c6..44bea2cd 100644 --- a/src/pyinterp.cc +++ b/src/pyinterp.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/pyinterp.h b/src/pyinterp.h index ea947c5a..ae8dd9c2 100644 --- a/src/pyinterp.h +++ b/src/pyinterp.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/pyledger.cc b/src/pyledger.cc index 4a53532a..cf5e362e 100644 --- a/src/pyledger.cc +++ b/src/pyledger.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/pyutils.h b/src/pyutils.h index 7e016502..44bb6d90 100644 --- a/src/pyutils.h +++ b/src/pyutils.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/query.cc b/src/query.cc index 812123cb..8bdabb38 100644 --- a/src/query.cc +++ b/src/query.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/query.h b/src/query.h index 8f7917b2..52168539 100644 --- a/src/query.h +++ b/src/query.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/quotes.cc b/src/quotes.cc index 0cc8d06b..b29eb8bd 100644 --- a/src/quotes.cc +++ b/src/quotes.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/quotes.h b/src/quotes.h index 376d8918..52092fbc 100644 --- a/src/quotes.h +++ b/src/quotes.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/report.cc b/src/report.cc index 530e7727..2c0c3970 100644 --- a/src/report.cc +++ b/src/report.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/report.h b/src/report.h index 2b521aae..35d45437 100644 --- a/src/report.h +++ b/src/report.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/scope.cc b/src/scope.cc index 2b9851b0..b2a7b17b 100644 --- a/src/scope.cc +++ b/src/scope.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/scope.h b/src/scope.h index 2720e8fc..6fcd67e9 100644 --- a/src/scope.h +++ b/src/scope.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/series.h b/src/series.h index 40f34051..75b98194 100644 --- a/src/series.h +++ b/src/series.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/session.cc b/src/session.cc index 31122daa..9d994a9b 100644 --- a/src/session.cc +++ b/src/session.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/session.h b/src/session.h index 680b8a0e..93bee8ba 100644 --- a/src/session.h +++ b/src/session.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/stats.cc b/src/stats.cc index 524f5a87..0966fee2 100644 --- a/src/stats.cc +++ b/src/stats.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/stats.h b/src/stats.h index b7bf94c5..7b00fec8 100644 --- a/src/stats.h +++ b/src/stats.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/stream.cc b/src/stream.cc index 5d4cf5e0..ce40bfcc 100644 --- a/src/stream.cc +++ b/src/stream.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/stream.h b/src/stream.h index 42c85534..c317ebdf 100644 --- a/src/stream.h +++ b/src/stream.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/system.hh.in b/src/system.hh.in index 42a82e41..e14166b2 100644 --- a/src/system.hh.in +++ b/src/system.hh.in @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/temps.cc b/src/temps.cc index 365c33c5..cb471d41 100644 --- a/src/temps.cc +++ b/src/temps.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/temps.h b/src/temps.h index 1e7eb69f..ad4e5672 100644 --- a/src/temps.h +++ b/src/temps.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/textual.cc b/src/textual.cc index 4977852c..15642cae 100644 --- a/src/textual.cc +++ b/src/textual.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/timelog.cc b/src/timelog.cc index 5ab6a25c..8d3d69c1 100644 --- a/src/timelog.cc +++ b/src/timelog.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/timelog.h b/src/timelog.h index 020ae4f2..12083302 100644 --- a/src/timelog.h +++ b/src/timelog.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/times.cc b/src/times.cc index 8ea90892..21ec1859 100644 --- a/src/times.cc +++ b/src/times.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/times.h b/src/times.h index bc462efa..6eadcad3 100644 --- a/src/times.h +++ b/src/times.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/token.cc b/src/token.cc index 77092d49..9449d9b7 100644 --- a/src/token.cc +++ b/src/token.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/token.h b/src/token.h index cbdf1258..01ff7ee9 100644 --- a/src/token.h +++ b/src/token.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/unistring.h b/src/unistring.h index 4be36b0d..a33c6e3f 100644 --- a/src/unistring.h +++ b/src/unistring.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/utils.cc b/src/utils.cc index 5260fd42..09526267 100644 --- a/src/utils.cc +++ b/src/utils.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/utils.h b/src/utils.h index c7aaac52..e37f37aa 100644 --- a/src/utils.h +++ b/src/utils.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/value.cc b/src/value.cc index 61066f03..5fa748f6 100644 --- a/src/value.cc +++ b/src/value.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/value.h b/src/value.h index f8495002..1e4d0ce9 100644 --- a/src/value.h +++ b/src/value.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/xact.cc b/src/xact.cc index 8e1951a5..0fedb42a 100644 --- a/src/xact.cc +++ b/src/xact.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/xact.h b/src/xact.h index ff4b7bc2..cb7bdeb3 100644 --- a/src/xact.h +++ b/src/xact.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/xml.cc b/src/xml.cc index 90efd4b3..560db805 100644 --- a/src/xml.cc +++ b/src/xml.cc @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are diff --git a/src/xml.h b/src/xml.h index 5d14dab3..871fd120 100644 --- a/src/xml.h +++ b/src/xml.h @@ -1,5 +1,5 @@ /* - * Copyright (c) 2003-2010, John Wiegley. All rights reserved. + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. * * Redistribution and use in source and binary forms, with or without * modification, are permitted provided that the following conditions are -- cgit v1.2.3 From 944e580825f0d9ce060b6dcdffe8990b6c2cca20 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Thu, 1 Mar 2012 03:31:28 -0600 Subject: Refactored the notion of "the current parsing context" --- src/accum.h | 10 +- src/context.h | 151 ++++++++++++++ src/convert.cc | 12 +- src/csv.cc | 81 ++++---- src/csv.h | 33 +--- src/generate.cc | 10 +- src/global.cc | 7 +- src/journal.cc | 139 ++++++------- src/journal.h | 32 ++- src/precmd.cc | 10 +- src/py_commodity.cc | 2 +- src/py_journal.cc | 11 +- src/pyinterp.cc | 35 +++- src/scope.h | 2 +- src/session.cc | 31 ++- src/session.h | 3 + src/textual.cc | 448 +++++++++++++++++++----------------------- src/timelog.cc | 15 +- src/timelog.h | 11 +- src/xact.cc | 6 +- src/xact.h | 3 +- test/baseline/dir-tag.test | 2 +- test/baseline/feat-check.test | 2 +- 23 files changed, 598 insertions(+), 458 deletions(-) create mode 100644 src/context.h (limited to 'src/session.cc') diff --git a/src/accum.h b/src/accum.h index 349aeba9..dde93c30 100644 --- a/src/accum.h +++ b/src/accum.h @@ -86,10 +86,16 @@ public: extern straccstream _accum; extern std::ostringstream _accum_buffer; +inline string str_helper_func() { + string buf = _accum_buffer.str(); + _accum_buffer.clear(); + _accum_buffer.str(""); + return buf; +} + #define STR(msg) \ ((_accum_buffer << ACCUM(_accum << msg)), \ - _accum.clear(), \ - _accum_buffer.str()) + _accum.clear(), str_helper_func()) } // namespace ledger diff --git a/src/context.h b/src/context.h new file mode 100644 index 00000000..0533536f --- /dev/null +++ b/src/context.h @@ -0,0 +1,151 @@ +/* + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of New Artisans LLC nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +/** + * @addtogroup data + */ + +/** + * @file context.h + * @author John Wiegley + * + * @ingroup data + */ +#ifndef _CONTEXT_H +#define _CONTEXT_H + +#include "utils.h" +#include "times.h" + +namespace ledger { + +class journal_t; +class account_t; +class scope_t; + +class parse_context_t +{ +public: + static const std::size_t MAX_LINE = 4096; + + shared_ptr stream; + + path pathname; + path current_directory; + journal_t * journal; + account_t * master; + scope_t * scope; + char linebuf[MAX_LINE + 1]; + istream_pos_type line_beg_pos; + istream_pos_type curr_pos; + std::size_t linenum; + std::size_t errors; + std::size_t count; + std::size_t sequence; + + explicit parse_context_t(shared_ptr _stream, + const path& cwd) + : stream(_stream), current_directory(cwd), master(NULL), + scope(NULL), linenum(0), errors(0), count(0), sequence(1) {} + + parse_context_t(const parse_context_t& context) + : stream(context.stream), + pathname(context.pathname), + current_directory(context.current_directory), + journal(context.journal), + master(context.master), + scope(context.scope), + line_beg_pos(context.line_beg_pos), + curr_pos(context.curr_pos), + linenum(context.linenum), + errors(context.errors), + count(context.count), + sequence(context.sequence) { + std::memcpy(linebuf, context.linebuf, MAX_LINE); + } + + string location() const { + return file_context(pathname, linenum); + } + + void warning(const string& what) const { + warning_func(location() + what); + } +}; + +inline parse_context_t open_for_reading(const path& pathname, + const path& cwd) +{ + path filename = resolve_path(pathname); + + if (! exists(filename)) + throw_(std::runtime_error, + _("Cannot read journal file %1") << filename); + + path parent(filesystem::absolute(pathname, cwd).parent_path()); + shared_ptr stream(new ifstream(filename)); + parse_context_t context(stream, parent); + context.pathname = filename; + return context; +} + +class parse_context_stack_t +{ + std::list parsing_context; + +public: + void push(shared_ptr stream, + const path& cwd = filesystem::current_path()) { + parsing_context.push_front(parse_context_t(stream, cwd)); + } + void push(const path& pathname, + const path& cwd = filesystem::current_path()) { + parsing_context.push_front(open_for_reading(pathname, cwd)); + } + + void push(const parse_context_t& context) { + parsing_context.push_front(context); + } + + void pop() { + assert(! parsing_context.empty()); + parsing_context.pop_front(); + } + + parse_context_t& get_current() { + assert(! parsing_context.empty()); + return parsing_context.front(); + } +}; + +} // namespace ledger + +#endif // _CONTEXT_H diff --git a/src/convert.cc b/src/convert.cc index 1b1bf814..e8ca241e 100644 --- a/src/convert.cc +++ b/src/convert.cc @@ -63,12 +63,16 @@ value_t convert_command(call_scope_t& args) print_xacts formatter(report); path csv_file_path(args.get(0)); - ifstream data(csv_file_path); - csv_reader reader(data, csv_file_path); + + report.session.parsing_context.push(csv_file_path); + parse_context_t& context(report.session.parsing_context.get_current()); + context.journal = &journal; + context.master = bucket; + + csv_reader reader(context); try { - while (xact_t * xact = reader.read_xact(journal, bucket, - report.HANDLED(rich_data))) { + while (xact_t * xact = reader.read_xact(report.HANDLED(rich_data))) { if (report.HANDLED(invert)) { foreach (post_t * post, xact->posts) post->amount.in_place_negate(); diff --git a/src/csv.cc b/src/csv.cc index 823238c7..305db992 100644 --- a/src/csv.cc +++ b/src/csv.cc @@ -40,27 +40,27 @@ namespace ledger { -string csv_reader::read_field(std::istream& sin) +string csv_reader::read_field(std::istream& in) { string field; char c; - if (sin.peek() == '"' || sin.peek() == '|') { - sin.get(c); + if (in.peek() == '"' || in.peek() == '|') { + in.get(c); char x; - while (sin.good() && ! sin.eof()) { - sin.get(x); + while (in.good() && ! in.eof()) { + in.get(x); if (x == '\\') { - sin.get(x); + in.get(x); } - else if (x == '"' && sin.peek() == '"') { - sin.get(x); + else if (x == '"' && in.peek() == '"') { + in.get(x); } else if (x == c) { if (x == '|') - sin.unget(); - else if (sin.peek() == ',') - sin.get(c); + in.unget(); + else if (in.peek() == ',') + in.get(c); break; } if (x != '\0') @@ -68,9 +68,9 @@ string csv_reader::read_field(std::istream& sin) } } else { - while (sin.good() && ! sin.eof()) { - sin.get(c); - if (sin.good()) { + while (in.good() && ! in.eof()) { + in.get(c); + if (in.good()) { if (c == ',') break; if (c != '\0') @@ -82,22 +82,22 @@ string csv_reader::read_field(std::istream& sin) return field; } -char * csv_reader::next_line(std::istream& sin) +char * csv_reader::next_line(std::istream& in) { - while (sin.good() && ! sin.eof() && sin.peek() == '#') - sin.getline(linebuf, MAX_LINE); + while (in.good() && ! in.eof() && in.peek() == '#') + in.getline(context.linebuf, parse_context_t::MAX_LINE); - if (! sin.good() || sin.eof()) + if (! in.good() || in.eof()) return NULL; - sin.getline(linebuf, MAX_LINE); + in.getline(context.linebuf, parse_context_t::MAX_LINE); - return linebuf; + return context.linebuf; } -void csv_reader::read_index(std::istream& sin) +void csv_reader::read_index(std::istream& in) { - char * line = next_line(sin); + char * line = next_line(in); if (! line) return; @@ -130,13 +130,12 @@ void csv_reader::read_index(std::istream& sin) } } -xact_t * csv_reader::read_xact(journal_t& journal, account_t * bucket, - bool rich_data) +xact_t * csv_reader::read_xact(bool rich_data) { - char * line = next_line(in); + char * line = next_line(*context.stream.get()); if (! line || index.empty()) return NULL; - linenum++; + context.linenum++; std::istringstream instr(line); @@ -146,18 +145,18 @@ xact_t * csv_reader::read_xact(journal_t& journal, account_t * bucket, xact->set_state(item_t::CLEARED); xact->pos = position_t(); - xact->pos->pathname = pathname; - xact->pos->beg_pos = in.tellg(); - xact->pos->beg_line = linenum; - xact->pos->sequence = sequence++; + xact->pos->pathname = context.pathname; + xact->pos->beg_pos = context.stream->tellg(); + xact->pos->beg_line = context.linenum; + xact->pos->sequence = context.sequence++; post->xact = xact.get(); post->pos = position_t(); - post->pos->pathname = pathname; - post->pos->beg_pos = in.tellg(); - post->pos->beg_line = linenum; - post->pos->sequence = sequence++; + post->pos->pathname = context.pathname; + post->pos->beg_pos = context.stream->tellg(); + post->pos->beg_line = context.linenum; + post->pos->sequence = context.sequence++; post->set_state(item_t::CLEARED); post->account = NULL; @@ -186,7 +185,7 @@ xact_t * csv_reader::read_xact(journal_t& journal, account_t * bucket, case FIELD_PAYEE: { bool found = false; - foreach (payee_mapping_t& value, journal.payee_mappings) { + foreach (payee_mapping_t& value, context.journal->payee_mappings) { DEBUG("csv.mappings", "Looking for payee mapping: " << value.first); if (value.first.match(field)) { xact->payee = value.second; @@ -244,7 +243,7 @@ xact_t * csv_reader::read_xact(journal_t& journal, account_t * bucket, // Translate the account name, if we have enough information to do so - foreach (account_mapping_t& value, journal.account_mappings) { + foreach (account_mapping_t& value, context.journal->account_mappings) { if (value.first.match(xact->payee)) { post->account = value.second; break; @@ -260,13 +259,13 @@ xact_t * csv_reader::read_xact(journal_t& journal, account_t * bucket, post->xact = xact.get(); post->pos = position_t(); - post->pos->pathname = pathname; - post->pos->beg_pos = in.tellg(); - post->pos->beg_line = linenum; - post->pos->sequence = sequence++; + post->pos->pathname = context.pathname; + post->pos->beg_pos = context.stream->tellg(); + post->pos->beg_line = context.linenum; + post->pos->sequence = context.sequence++; post->set_state(item_t::CLEARED); - post->account = bucket; + post->account = context.master; if (! amt.is_null()) post->amount = - amt; diff --git a/src/csv.h b/src/csv.h index 4d6e1253..24ea9121 100644 --- a/src/csv.h +++ b/src/csv.h @@ -43,6 +43,7 @@ #define _CSV_H #include "value.h" +#include "context.h" namespace ledger { @@ -52,13 +53,7 @@ class account_t; class csv_reader { - static const std::size_t MAX_LINE = 4096; - - std::istream& in; - path pathname; - char linebuf[MAX_LINE]; - std::size_t linenum; - std::size_t sequence; + parse_context_t context; enum headers_t { FIELD_DATE = 0, @@ -86,9 +81,8 @@ class csv_reader std::vector names; public: - csv_reader(std::istream& _in, const path& _pathname) - : in(_in), pathname(_pathname), - linenum(0), sequence(0), + csv_reader(parse_context_t& _context) + : context(_context), date_mask("date"), date_aux_mask("posted( ?date)?"), code_mask("code"), @@ -97,32 +91,23 @@ public: cost_mask("cost"), total_mask("total"), note_mask("note") { - read_index(in); + read_index(*context.stream.get()); } void read_index(std::istream& in); string read_field(std::istream& in); char * next_line(std::istream& in); - xact_t * read_xact(journal_t& journal, account_t * bucket, bool rich_data); + xact_t * read_xact(bool rich_data); const char * get_last_line() const { - return linebuf; + return context.linebuf; } - path get_pathname() const { - return pathname; + return context.pathname; } std::size_t get_linenum() const { - return linenum; - } - - void reset() { - pathname.clear(); - index.clear(); - names.clear(); - linenum = 0; - sequence = 0; + return context.linenum; } }; diff --git a/src/generate.cc b/src/generate.cc index bf9a8036..edd58632 100644 --- a/src/generate.cc +++ b/src/generate.cc @@ -360,9 +360,15 @@ void generate_posts_iterator::increment() DEBUG("generate.post", "The post we intend to parse:\n" << buf.str()); - std::istringstream in(buf.str()); try { - if (session.journal->parse(in, session) != 0) { + shared_ptr in(new std::istringstream(buf.str())); + + parse_context_stack_t parsing_context; + parsing_context.push(in); + parsing_context.get_current().journal = session.journal.get(); + parsing_context.get_current().scope = &session; + + if (session.journal->read(parsing_context) != 0) { VERIFY(session.journal->xacts.back()->valid()); posts.reset(*session.journal->xacts.back()); post = *posts++; diff --git a/src/global.cc b/src/global.cc index ee921fc5..5b7bb1c1 100644 --- a/src/global.cc +++ b/src/global.cc @@ -112,9 +112,12 @@ void global_scope_t::read_init() if (exists(init_file)) { TRACE_START(init, 1, "Read initialization file"); - ifstream init(init_file); + parse_context_stack_t parsing_context; + parsing_context.push(init_file); + parsing_context.get_current().journal = session().journal.get(); + parsing_context.get_current().scope = &report(); - if (session().journal->read(init_file, NULL, &report()) > 0 || + if (session().journal->read(parsing_context) > 0 || session().journal->auto_xacts.size() > 0 || session().journal->period_xacts.size() > 0) { throw_(parse_error, _("Transactions found in initialization file '%1'") diff --git a/src/journal.cc b/src/journal.cc index 2ebe90fb..55c89dd9 100644 --- a/src/journal.cc +++ b/src/journal.cc @@ -32,6 +32,7 @@ #include #include "journal.h" +#include "context.h" #include "amount.h" #include "commodity.h" #include "pool.h" @@ -47,6 +48,7 @@ journal_t::journal_t() initialize(); } +#if 0 journal_t::journal_t(const path& pathname) { TRACE_CTOR(journal_t, "path"); @@ -60,6 +62,7 @@ journal_t::journal_t(const string& str) initialize(); read(str); } +#endif journal_t::~journal_t() { @@ -87,6 +90,7 @@ void journal_t::initialize() fixed_payees = false; fixed_commodities = false; fixed_metadata = false; + current_context = NULL; was_loaded = false; force_checking = false; check_payees = false; @@ -114,7 +118,6 @@ account_t * journal_t::find_account_re(const string& regexp) } account_t * journal_t::register_account(const string& name, post_t * post, - const string& location, account_t * master_account) { account_t * result = NULL; @@ -147,8 +150,8 @@ account_t * journal_t::register_account(const string& name, post_t * post, result->add_flags(ACCOUNT_KNOWN); } else if (checking_style == CHECK_WARNING) { - warning_(_("%1Unknown account '%2'") << location - << result->fullname()); + current_context->warning(STR(_("Unknown account '%1'") + << result->fullname())); } else if (checking_style == CHECK_ERROR) { throw_(parse_error, _("Unknown account '%1'") << result->fullname()); @@ -159,8 +162,7 @@ account_t * journal_t::register_account(const string& name, post_t * post, return result; } -string journal_t::register_payee(const string& name, xact_t * xact, - const string& location) +string journal_t::register_payee(const string& name, xact_t * xact) { string payee; @@ -178,7 +180,7 @@ string journal_t::register_payee(const string& name, xact_t * xact, known_payees.insert(name); } else if (checking_style == CHECK_WARNING) { - warning_(_("%1Unknown payee '%2'") << location << name); + current_context->warning(STR(_("Unknown payee '%1'") << name)); } else if (checking_style == CHECK_ERROR) { throw_(parse_error, _("Unknown payee '%1'") << name); @@ -197,8 +199,7 @@ string journal_t::register_payee(const string& name, xact_t * xact, } void journal_t::register_commodity(commodity_t& comm, - variant context, - const string& location) + variant context) { if (checking_style == CHECK_WARNING || checking_style == CHECK_ERROR) { if (! comm.has_flags(COMMODITY_KNOWN)) { @@ -215,7 +216,7 @@ void journal_t::register_commodity(commodity_t& comm, comm.add_flags(COMMODITY_KNOWN); } else if (checking_style == CHECK_WARNING) { - warning_(_("%1Unknown commodity '%2'") << location << comm); + current_context->warning(STR(_("Unknown commodity '%1'") << comm)); } else if (checking_style == CHECK_ERROR) { throw_(parse_error, _("Unknown commodity '%1'") << comm); @@ -224,40 +225,8 @@ void journal_t::register_commodity(commodity_t& comm, } } -namespace { - void check_metadata(journal_t& journal, - const string& key, const value_t& value, - variant context, - const string& location) - { - std::pair range = - journal.tag_check_exprs.equal_range(key); - - for (tag_check_exprs_map::iterator i = range.first; - i != range.second; - ++i) { - value_scope_t val_scope - (context.which() == 1 ? - static_cast(*boost::get(context)) : - static_cast(*boost::get(context)), value); - - if (! (*i).second.first.calc(val_scope).to_boolean()) { - if ((*i).second.second == expr_t::EXPR_ASSERTION) - throw_(parse_error, - _("Metadata assertion failed for (%1: %2): %3") - << key << value << (*i).second.first); - else - warning_(_("%1Metadata check failed for (%2: %3): %4") - << location << key << value << (*i).second.first); - } - } - } -} - void journal_t::register_metadata(const string& key, const value_t& value, - variant context, - const string& location) + variant context) { if (checking_style == CHECK_WARNING || checking_style == CHECK_ERROR) { std::set::iterator i = known_tags.find(key); @@ -276,7 +245,7 @@ void journal_t::register_metadata(const string& key, const value_t& value, known_tags.insert(key); } else if (checking_style == CHECK_WARNING) { - warning_(_("%1Unknown metadata tag '%2'") << location << key); + current_context->warning(STR(_("Unknown metadata tag '%1'") << key)); } else if (checking_style == CHECK_ERROR) { throw_(parse_error, _("Unknown metadata tag '%1'") << key); @@ -284,8 +253,33 @@ void journal_t::register_metadata(const string& key, const value_t& value, } } - if (! value.is_null()) - check_metadata(*this, key, value, context, location); + if (! value.is_null()) { + std::pair range = + tag_check_exprs.equal_range(key); + + for (tag_check_exprs_map::iterator i = range.first; + i != range.second; + ++i) { + bind_scope_t bound_scope + (*current_context->scope, + context.which() == 1 ? + static_cast(*boost::get(context)) : + static_cast(*boost::get(context))); + value_scope_t val_scope(bound_scope, value); + + if (! (*i).second.first.calc(val_scope).to_boolean()) { + if ((*i).second.second == expr_t::EXPR_ASSERTION) + throw_(parse_error, + _("Metadata assertion failed for (%1: %2): %3") + << key << value << (*i).second.first); + else + current_context->warning + (STR(_("Metadata check failed for (%1: %2): %3") + << key << value << (*i).second.first)); + } + } + } } namespace { @@ -300,13 +294,10 @@ namespace { xact ? *xact->metadata : *post->metadata) { const string& key(pair.first); - // jww (2012-02-27): We really need to know the parsing context, - // both here and for the call to warning_ in - // xact_t::extend_xact. if (optional value = pair.second.first) - journal.register_metadata(key, *value, context, ""); + journal.register_metadata(key, *value, context); else - journal.register_metadata(key, NULL_VALUE, context, ""); + journal.register_metadata(key, NULL_VALUE, context); } } } @@ -351,7 +342,7 @@ bool journal_t::add_xact(xact_t * xact) void journal_t::extend_xact(xact_base_t * xact) { foreach (auto_xact_t * auto_xact, auto_xacts) - auto_xact->extend_xact(*xact); + auto_xact->extend_xact(*xact, *current_context); } bool journal_t::remove_xact(xact_t * xact) @@ -372,25 +363,36 @@ bool journal_t::remove_xact(xact_t * xact) return true; } -std::size_t journal_t::read(std::istream& in, - const path& pathname, - account_t * master_alt, - scope_t * scope) +std::size_t journal_t::read(parse_context_stack_t& context) { std::size_t count = 0; try { - if (! scope) - scope = scope_t::default_scope; + parse_context_t& current(context.get_current()); + current_context = ¤t; + + current.count = 0; + if (! current.scope) + current.scope = scope_t::default_scope; - if (! scope) + if (! current.scope) throw_(std::runtime_error, _("No default scope in which to read journal file '%1'") - << pathname); + << current.pathname); - count = parse(in, *scope, master_alt ? master_alt : master, &pathname); + if (! current.master) + current.master = master; + + count = read_textual(context); + if (count > 0) { + if (! current.pathname.empty()) + sources.push_back(fileinfo_t(current.pathname)); + else + sources.push_back(fileinfo_t()); + } } catch (...) { clear_xdata(); + current_context = NULL; throw; } @@ -402,23 +404,6 @@ std::size_t journal_t::read(std::istream& in, return count; } -std::size_t journal_t::read(const path& pathname, - account_t * master_account, - scope_t * scope) -{ - path filename = resolve_path(pathname); - - if (! exists(filename)) - throw_(std::runtime_error, - _("Cannot read journal file %1") << filename); - - ifstream stream(filename); - std::size_t count = read(stream, filename, master_account, scope); - if (count > 0) - sources.push_back(fileinfo_t(filename)); - return count; -} - bool journal_t::has_xdata() { foreach (xact_t * xact, xacts) diff --git a/src/journal.h b/src/journal.h index 6d10ffda..8b750993 100644 --- a/src/journal.h +++ b/src/journal.h @@ -55,7 +55,8 @@ class auto_xact_t; class period_xact_t; class post_t; class account_t; -class scope_t; +class parse_context_t; +class parse_context_stack_t; typedef std::list xacts_list; typedef std::list auto_xacts_list; @@ -132,6 +133,7 @@ public: account_mappings_t payees_for_unknown_accounts; checksum_map_t checksum_map; tag_check_exprs_map tag_check_exprs; + parse_context_t * current_context; bool was_loaded; bool force_checking; bool check_payees; @@ -143,8 +145,10 @@ public: } checking_style; journal_t(); +#if 0 journal_t(const path& pathname); journal_t(const string& str); +#endif ~journal_t(); void initialize(); @@ -162,16 +166,12 @@ public: account_t * find_account_re(const string& regexp); account_t * register_account(const string& name, post_t * post, - const string& location, account_t * master = NULL); - string register_payee(const string& name, xact_t * xact, - const string& location); + string register_payee(const string& name, xact_t * xact); void register_commodity(commodity_t& comm, - variant context, - const string& location); + variant context); void register_metadata(const string& key, const value_t& value, - variant context, - const string& location); + variant context); bool add_xact(xact_t * xact); void extend_xact(xact_base_t * xact); @@ -196,24 +196,16 @@ public: return period_xacts.end(); } - std::size_t read(std::istream& in, - const path& pathname, - account_t * master = NULL, - scope_t * scope = NULL); - std::size_t read(const path& pathname, - account_t * master = NULL, - scope_t * scope = NULL); - - std::size_t parse(std::istream& in, - scope_t& session_scope, - account_t * master = NULL, - const path * original_file = NULL); + std::size_t read(parse_context_stack_t& context); bool has_xdata(); void clear_xdata(); bool valid() const; +private: + std::size_t read_textual(parse_context_stack_t& context); + #if defined(HAVE_BOOST_SERIALIZATION) private: /** Serialization. */ diff --git a/src/precmd.cc b/src/precmd.cc index 6f8becb6..6b106a8b 100644 --- a/src/precmd.cc +++ b/src/precmd.cc @@ -83,8 +83,14 @@ namespace { out << _("--- Context is first posting of the following transaction ---") << std::endl << str << std::endl; { - std::istringstream in(str); - report.session.journal->parse(in, report.session); + shared_ptr in(new std::istringstream(str)); + + parse_context_stack_t parsing_context; + parsing_context.push(in); + parsing_context.get_current().journal = report.session.journal.get(); + parsing_context.get_current().scope = &report.session; + + report.session.journal->read(parsing_context); report.session.journal->clear_xdata(); } } diff --git a/src/py_commodity.cc b/src/py_commodity.cc index 11ebe844..ffa903f4 100644 --- a/src/py_commodity.cc +++ b/src/py_commodity.cc @@ -113,7 +113,7 @@ namespace { if (i == pool.commodities.end()) { PyErr_SetString(PyExc_ValueError, (string("Could not find commodity ") + symbol).c_str()); - throw boost::python::error_already_set(); + throw_error_already_set(); } return (*i).second; } diff --git a/src/py_journal.cc b/src/py_journal.cc index 4f5427f5..a72b8528 100644 --- a/src/py_journal.cc +++ b/src/py_journal.cc @@ -135,10 +135,12 @@ namespace { return journal.find_account(name, auto_create); } +#if 0 std::size_t py_read(journal_t& journal, const string& pathname) { - return journal.read(pathname); + return journal.read(context_stack); } +#endif struct collector_wrapper { @@ -264,9 +266,10 @@ void export_journal() ; class_< journal_t, boost::noncopyable > ("Journal") +#if 0 .def(init()) .def(init()) - +#endif .add_property("master", make_getter(&journal_t::master, return_internal_reference<1, @@ -311,9 +314,9 @@ void export_journal() (&journal_t::period_xacts_begin, &journal_t::period_xacts_end)) .def("sources", python::range > (&journal_t::sources_begin, &journal_t::sources_end)) - +#if 0 .def("read", py_read) - +#endif .def("has_xdata", &journal_t::has_xdata) .def("clear_xdata", &journal_t::clear_xdata) diff --git a/src/pyinterp.cc b/src/pyinterp.cc index 44bea2cd..de9c94cb 100644 --- a/src/pyinterp.cc +++ b/src/pyinterp.cc @@ -194,18 +194,19 @@ object python_interpreter_t::import_option(const string& str) if (! is_initialized) initialize(); - path file(str); - string name(str); - python::object sys_module = python::import("sys"); python::object sys_dict = sys_module.attr("__dict__"); + path file(str); + string name(str); python::list paths(sys_dict["path"]); if (contains(str, ".py")) { #if BOOST_VERSION >= 103700 - path& cwd(get_parsing_context().current_directory); - paths.insert(0, filesystem::absolute(file, cwd).parent_path().string()); + path& cwd(parsing_context.get_current().current_directory); + path parent(filesystem::absolute(file, cwd).parent_path()); + DEBUG("python.interp", "Adding " << parent << " to PYTHONPATH"); + paths.insert(0, parent.string()); sys_dict["path"] = paths; #if BOOST_VERSION >= 104600 @@ -220,7 +221,24 @@ object python_interpreter_t::import_option(const string& str) #endif // BOOST_VERSION >= 103700 } - return python::import(python::str(name.c_str())); + try { + if (contains(str, ".py")) { + import_into_main(name); + } else { + object obj = python::import(python::str(name.c_str())); + main_nspace[name.c_str()] = obj; + return obj; + } + } + catch (const error_already_set&) { + PyErr_Print(); + throw_(std::runtime_error, _("Python failed to import: %1") << str); + } + catch (...) { + throw; + } + + return object(); } object python_interpreter_t::eval(std::istream& in, py_eval_mode_t mode) @@ -348,13 +366,13 @@ value_t python_interpreter_t::server_command(call_scope_t& args) functor_t func(main_function, "main"); try { func(args); + return true; } catch (const error_already_set&) { PyErr_Print(); throw_(std::runtime_error, _("Error while invoking ledger.server's main() function")); } - return true; } else { throw_(std::runtime_error, _("The ledger.server module is missing its main() function!")); @@ -455,6 +473,7 @@ value_t python_interpreter_t::functor_t::operator()(call_scope_t& args) if (! PyCallable_Check(func.ptr())) { extract val(func); + DEBUG("python.interp", "Value of Python '" << name << "': " << val); std::signal(SIGINT, sigint_handler); if (val.check()) return val(); @@ -476,6 +495,8 @@ value_t python_interpreter_t::functor_t::operator()(call_scope_t& args) value_t result; if (xval.check()) { result = xval(); + DEBUG("python.interp", + "Return from Python '" << name << "': " << result); Py_DECREF(val); } else { Py_DECREF(val); diff --git a/src/scope.h b/src/scope.h index 6fcd67e9..c42ec66b 100644 --- a/src/scope.h +++ b/src/scope.h @@ -664,7 +664,7 @@ public: if (name == "value") return MAKE_FUNCTOR(value_scope_t::get_value); - return NULL; + return child_scope_t::lookup(kind, name); } }; diff --git a/src/session.cc b/src/session.cc index 9d994a9b..e07026b6 100644 --- a/src/session.cc +++ b/src/session.cc @@ -120,8 +120,17 @@ std::size_t session_t::read_data(const string& master_account) #endif // HAVE_BOOST_SERIALIZATION if (price_db_path) { if (exists(*price_db_path)) { - if (journal->read(*price_db_path) > 0) - throw_(parse_error, _("Transactions not allowed in price history file")); + parsing_context.push(*price_db_path); + parsing_context.get_current().journal = journal.get(); + try { + if (journal->read(parsing_context) > 0) + throw_(parse_error, _("Transactions not allowed in price history file")); + } + catch (...) { + parsing_context.pop(); + throw; + } + parsing_context.pop(); } } @@ -140,12 +149,22 @@ std::size_t session_t::read_data(const string& master_account) } buffer.flush(); - std::istringstream buf_in(buffer.str()); - xact_count += journal->read(buf_in, "/dev/stdin", acct); - journal->sources.push_back(journal_t::fileinfo_t()); + shared_ptr stream(new std::istringstream(buffer.str())); + parsing_context.push(stream); } else { - xact_count += journal->read(pathname, acct); + parsing_context.push(pathname); + } + + parsing_context.get_current().journal = journal.get(); + parsing_context.get_current().master = acct; + try { + xact_count += journal->read(parsing_context); + } + catch (...) { + parsing_context.pop(); + throw; } + parsing_context.pop(); } DEBUG("ledger.read", "xact_count [" << xact_count diff --git a/src/session.h b/src/session.h index 93bee8ba..54b9912a 100644 --- a/src/session.h +++ b/src/session.h @@ -44,6 +44,7 @@ #include "account.h" #include "journal.h" +#include "context.h" #include "option.h" #include "commodity.h" @@ -57,7 +58,9 @@ class session_t : public symbol_scope_t public: bool flush_on_next_data_file; + std::auto_ptr journal; + parse_context_stack_t parsing_context; explicit session_t(); virtual ~session_t() { diff --git a/src/textual.cc b/src/textual.cc index 15642cae..97c80e4f 100644 --- a/src/textual.cc +++ b/src/textual.cc @@ -32,6 +32,7 @@ #include #include "journal.h" +#include "context.h" #include "xact.h" #include "post.h" #include "account.h" @@ -53,8 +54,10 @@ namespace { struct application_t { string label; - variant value; + variant, account_t *, string, fixed_rate_t> value; + application_t(string _label, optional epoch) + : label(_label), value(epoch) {} application_t(string _label, account_t * acct) : label(_label), value(acct) {} application_t(string _label, string tag) @@ -63,24 +66,27 @@ namespace { : label(_label), value(rate) {} }; - class parse_context_t : public noncopyable + class instance_t : public noncopyable, public scope_t { + public: - std::list apply_stack; + parse_context_stack_t& context_stack; + parse_context_t& context; + std::istream& in; + instance_t * parent; - journal_t& journal; - scope_t& scope; + std::list apply_stack; #if defined(TIMELOG_SUPPORT) - time_log_t timelog; + time_log_t timelog; #endif - std::size_t count; - std::size_t errors; - std::size_t sequence; - - parse_context_t(journal_t& _journal, scope_t& _scope) - : journal(_journal), scope(_scope), timelog(journal, scope), - count(0), errors(0), sequence(1) { - timelog.context_count = &count; + + instance_t(parse_context_stack_t& _context_stack, + parse_context_t& _context, instance_t * _parent = NULL) + : context_stack(_context_stack), context(_context), + in(*context.stream.get()), parent(_parent), timelog(context) {} + + virtual string description() { + return _("textual parser"); } account_t * top_account() { @@ -90,40 +96,10 @@ namespace { return NULL; } - void close() { - timelog.close(); - } - }; - - class instance_t : public noncopyable, public scope_t - { - static const std::size_t MAX_LINE = 1024; - - public: - parse_context_t& context; - instance_t * parent; - const path * original_file; - path pathname; - std::istream& in; - char linebuf[MAX_LINE + 1]; - std::size_t linenum; - istream_pos_type line_beg_pos; - istream_pos_type curr_pos; - optional prev_epoch; - - instance_t(parse_context_t& _context, - std::istream& _in, - const path * _original_file = NULL, - instance_t * _parent = NULL); - - ~instance_t(); - - virtual string description() { - return _("textual parser"); - } - void parse(); + std::streamsize read_line(char *& line); + bool peek_whitespace_line() { return (in.good() && ! in.eof() && (in.peek() == ' ' || in.peek() == '\t')); @@ -229,37 +205,17 @@ namespace { } } -instance_t::instance_t(parse_context_t& _context, - std::istream& _in, - const path * _original_file, - instance_t * _parent) - : context(_context), parent(_parent), original_file(_original_file), - pathname(original_file ? *original_file : "/dev/stdin"), in(_in) -{ - TRACE_CTOR(instance_t, "..."); - DEBUG("times.epoch", "Saving epoch " << epoch); - prev_epoch = epoch; // declared in times.h -} - -instance_t::~instance_t() -{ - TRACE_DTOR(instance_t); - epoch = prev_epoch; - DEBUG("times.epoch", "Restored epoch to " << epoch); -} - void instance_t::parse() { - INFO("Parsing file '" << pathname.string() << "'"); + INFO("Parsing file " << context.pathname); - TRACE_START(instance_parse, 1, - "Done parsing file '" << pathname.string() << "'"); + TRACE_START(instance_parse, 1, "Done parsing file " << context.pathname); if (! in.good() || in.eof()) return; - linenum = 0; - curr_pos = in.tellg(); + context.linenum = 0; + context.curr_pos = in.tellg(); while (in.good() && ! in.eof()) { try { @@ -278,11 +234,9 @@ void instance_t::parse() foreach (instance_t * instance, instances) add_error_context(_("In file included from %1") - << file_context(instance->pathname, - instance->linenum)); + << instance->context.location()); } - add_error_context(_("While parsing file %1") - << file_context(pathname, linenum)); + add_error_context(_("While parsing file %1") << context.location()); if (caught_signal != NONE_CAUGHT) throw; @@ -307,26 +261,26 @@ std::streamsize instance_t::read_line(char *& line) assert(in.good()); assert(! in.eof()); // no one should call us in that case - line_beg_pos = curr_pos; + context.line_beg_pos = context.curr_pos; check_for_signal(); - in.getline(linebuf, MAX_LINE); + in.getline(context.linebuf, parse_context_t::MAX_LINE); std::streamsize len = in.gcount(); if (len > 0) { - if (linenum == 0 && utf8::is_bom(linebuf)) - line = &linebuf[3]; + if (context.linenum == 0 && utf8::is_bom(context.linebuf)) + line = &context.linebuf[3]; else - line = linebuf; + line = context.linebuf; if (line[len - 1] == '\r') // strip Windows CRLF down to LF line[--len] = '\0'; - linenum++; + context.linenum++; - curr_pos = line_beg_pos; - curr_pos += len; + context.curr_pos = context.line_beg_pos; + context.curr_pos += len; return len - 1; // LF is being silently dropped } @@ -446,19 +400,19 @@ void instance_t::clock_in_directive(char * line, bool /*capitalized*/) end = NULL; position_t position; - position.pathname = pathname; - position.beg_pos = line_beg_pos; - position.beg_line = linenum; - position.end_pos = curr_pos; - position.end_line = linenum; + position.pathname = context.pathname; + position.beg_pos = context.line_beg_pos; + position.beg_line = context.linenum; + position.end_pos = context.curr_pos; + position.end_line = context.linenum; position.sequence = context.sequence++; time_xact_t event(position, parse_datetime(datetime), - p ? context.top_account()->find_account(p) : NULL, + p ? top_account()->find_account(p) : NULL, n ? n : "", end ? end : ""); - context.timelog.clock_in(event); + timelog.clock_in(event); } void instance_t::clock_out_directive(char * line, bool /*capitalized*/) @@ -475,19 +429,19 @@ void instance_t::clock_out_directive(char * line, bool /*capitalized*/) end = NULL; position_t position; - position.pathname = pathname; - position.beg_pos = line_beg_pos; - position.beg_line = linenum; - position.end_pos = curr_pos; - position.end_line = linenum; + position.pathname = context.pathname; + position.beg_pos = context.line_beg_pos; + position.beg_line = context.linenum; + position.end_pos = context.curr_pos; + position.end_line = context.linenum; position.sequence = context.sequence++; time_xact_t event(position, parse_datetime(datetime), - p ? context.top_account()->find_account(p) : NULL, + p ? top_account()->find_account(p) : NULL, n ? n : "", end ? end : ""); - context.timelog.clock_out(event); + timelog.clock_out(event); context.count++; } @@ -503,8 +457,8 @@ void instance_t::default_commodity_directive(char * line) void instance_t::default_account_directive(char * line) { - context.journal.bucket = context.top_account()->find_account(skip_ws(line + 1)); - context.journal.bucket->add_flags(ACCOUNT_KNOWN); + context.journal->bucket = top_account()->find_account(skip_ws(line + 1)); + context.journal->bucket->add_flags(ACCOUNT_KNOWN); } void instance_t::price_conversion_directive(char * line) @@ -543,13 +497,14 @@ void instance_t::option_directive(char * line) *p++ = '\0'; } - if (! process_option(pathname.string(), line + 2, context.scope, p, line)) + if (! process_option(context.pathname.string(), line + 2, + *context.scope, p, line)) throw_(option_error, _("Illegal option --%1") << line + 2); } void instance_t::automated_xact_directive(char * line) { - istream_pos_type pos= line_beg_pos; + istream_pos_type pos = context.line_beg_pos; bool reveal_context = true; @@ -562,9 +517,9 @@ void instance_t::automated_xact_directive(char * line) std::auto_ptr ae(new auto_xact_t(predicate_t(expr, keeper))); ae->pos = position_t(); - ae->pos->pathname = pathname; - ae->pos->beg_pos = line_beg_pos; - ae->pos->beg_line = linenum; + ae->pos->pathname = context.pathname; + ae->pos->beg_pos = context.line_beg_pos; + ae->pos->beg_line = context.linenum; ae->pos->sequence = context.sequence++; post_t * last_post = NULL; @@ -586,9 +541,9 @@ void instance_t::automated_xact_directive(char * line) item = ae.get(); // This is a trailing note, and possibly a metadata info tag - item->append_note(p + 1, context.scope, true); + item->append_note(p + 1, *context.scope, true); item->add_flags(ITEM_NOTE_ON_NEXT_LINE); - item->pos->end_pos = curr_pos; + item->pos->end_pos = context.curr_pos; item->pos->end_line++; // If there was no last_post yet, then deferred notes get applied to @@ -619,8 +574,7 @@ void instance_t::automated_xact_directive(char * line) reveal_context = false; if (post_t * post = - parse_post(p, len - (p - line), context.top_account(), - NULL, true)) { + parse_post(p, len - (p - line), top_account(), NULL, true)) { reveal_context = true; ae->add_post(post); last_post = post; @@ -629,18 +583,19 @@ void instance_t::automated_xact_directive(char * line) } } - context.journal.auto_xacts.push_back(ae.get()); + context.journal->auto_xacts.push_back(ae.get()); - ae->journal = &context.journal; - ae->pos->end_pos = curr_pos; - ae->pos->end_line = linenum; + ae->journal = context.journal; + ae->pos->end_pos = context.curr_pos; + ae->pos->end_line = context.linenum; ae.release(); } catch (const std::exception&) { if (reveal_context) { add_error_context(_("While parsing automated transaction:")); - add_error_context(source_context(pathname, pos, curr_pos, "> ")); + add_error_context(source_context(context.pathname, pos, + context.curr_pos, "> ")); } throw; } @@ -648,7 +603,7 @@ void instance_t::automated_xact_directive(char * line) void instance_t::period_xact_directive(char * line) { - istream_pos_type pos = line_beg_pos; + istream_pos_type pos = context.line_beg_pos; bool reveal_context = true; @@ -656,23 +611,23 @@ void instance_t::period_xact_directive(char * line) std::auto_ptr pe(new period_xact_t(skip_ws(line + 1))); pe->pos = position_t(); - pe->pos->pathname = pathname; - pe->pos->beg_pos = line_beg_pos; - pe->pos->beg_line = linenum; + pe->pos->pathname = context.pathname; + pe->pos->beg_pos = context.line_beg_pos; + pe->pos->beg_line = context.linenum; pe->pos->sequence = context.sequence++; reveal_context = false; - if (parse_posts(context.top_account(), *pe.get())) { + if (parse_posts(top_account(), *pe.get())) { reveal_context = true; - pe->journal = &context.journal; + pe->journal = context.journal; if (pe->finalize()) { - context.journal.extend_xact(pe.get()); - context.journal.period_xacts.push_back(pe.get()); + context.journal->extend_xact(pe.get()); + context.journal->period_xacts.push_back(pe.get()); - pe->pos->end_pos = curr_pos; - pe->pos->end_line = linenum; + pe->pos->end_pos = context.curr_pos; + pe->pos->end_line = context.linenum; pe.release(); } else { @@ -686,7 +641,8 @@ void instance_t::period_xact_directive(char * line) catch (const std::exception&) { if (reveal_context) { add_error_context(_("While parsing periodic transaction:")); - add_error_context(source_context(pathname, pos, curr_pos, "> ")); + add_error_context(source_context(context.pathname, pos, + context.curr_pos, "> ")); } throw; } @@ -696,10 +652,10 @@ void instance_t::xact_directive(char * line, std::streamsize len) { TRACE_START(xacts, 1, "Time spent handling transactions:"); - if (xact_t * xact = parse_xact(line, len, context.top_account())) { + if (xact_t * xact = parse_xact(line, len, top_account())) { std::auto_ptr manager(xact); - if (context.journal.add_xact(xact)) { + if (context.journal->add_xact(xact)) { manager.release(); // it's owned by the journal now context.count++; } @@ -721,12 +677,13 @@ void instance_t::include_directive(char * line) if (line[0] != '/' && line[0] != '\\' && line[0] != '~') { DEBUG("textual.include", "received a relative path"); - DEBUG("textual.include", "parent file path: " << pathname.string()); - string::size_type pos = pathname.string().rfind('/'); + DEBUG("textual.include", "parent file path: " << context.pathname); + string pathstr(context.pathname.string()); + string::size_type pos = pathstr.rfind('/'); if (pos == string::npos) - pos = pathname.string().rfind('\\'); + pos = pathstr.rfind('\\'); if (pos != string::npos) { - filename = path(string(pathname.string(), 0, pos + 1)) / line; + filename = path(string(pathstr, 0, pos + 1)) / line; DEBUG("textual.include", "normalized path: " << filename.string()); } else { filename = path(string(".")) / line; @@ -773,10 +730,24 @@ void instance_t::include_directive(char * line) string base = (*iter).leaf(); #endif // BOOST_VERSION >= 103700 if (glob.match(base)) { - path inner_file(*iter); - ifstream stream(inner_file); - instance_t instance(context, stream, &inner_file, this); - instance.parse(); + journal_t * journal = context.journal; + account_t * master = context.master; + + context_stack.push(*iter); + + context_stack.get_current().journal = journal; + context_stack.get_current().master = master; + try { + instance_t instance(context_stack, + context_stack.get_current(), this); + instance.parse(); + } + catch (...) { + context_stack.pop(); + throw; + } + context_stack.pop(); + files_found = true; } } @@ -805,8 +776,8 @@ void instance_t::apply_directive(char * line) void instance_t::apply_account_directive(char * line) { - if (account_t * acct = context.top_account()->find_account(line)) - context.apply_stack.push_front(application_t("account", acct)); + if (account_t * acct = top_account()->find_account(line)) + apply_stack.push_front(application_t("account", acct)); #if !defined(NO_ASSERTS) else assert("Failed to create account" == NULL); @@ -820,14 +791,14 @@ void instance_t::apply_tag_directive(char * line) if (tag.find(':') == string::npos) tag = string(":") + tag + ":"; - context.apply_stack.push_front(application_t("tag", tag)); + apply_stack.push_front(application_t("tag", tag)); } void instance_t::apply_rate_directive(char * line) { if (optional > price_point = commodity_pool_t::current_pool->parse_price_directive(trim_ws(line), true)) { - context.apply_stack.push_front + apply_stack.push_front (application_t("fixed", fixed_rate_t(price_point->first, price_point->second.price))); } else { @@ -837,11 +808,13 @@ void instance_t::apply_rate_directive(char * line) void instance_t::apply_year_directive(char * line) { - unsigned short year(lexical_cast(skip_ws(line + 1))); - DEBUG("times.epoch", "Setting current year to " << year); + apply_stack.push_front(application_t("year", epoch)); + // This must be set to the last day of the year, otherwise partial // dates like "11/01" will refer to last year's november, not the // current year. + unsigned short year(lexical_cast(skip_ws(line + 1))); + DEBUG("times.epoch", "Setting current year to " << year); epoch = datetime_t(date_t(year, 12, 31)); } @@ -850,28 +823,30 @@ void instance_t::end_apply_directive(char * kind) char * b = next_element(kind); string name(b ? b : " "); - if (context.apply_stack.size() <= 1) + if (apply_stack.size() <= 1) throw_(std::runtime_error, _("'end apply %1' found, but no enclosing 'apply %2' directive") << name << name); - if (name != " " && name != context.apply_stack.front().label) + if (name != " " && name != apply_stack.front().label) throw_(std::runtime_error, _("'end apply %1' directive does not match 'apply %2' directive") - << name << context.apply_stack.front().label); + << name << apply_stack.front().label); + + if (apply_stack.front().value.type() == typeid(optional)) + epoch = boost::get >(apply_stack.front().value); - context.apply_stack.pop_front(); + apply_stack.pop_front(); } void instance_t::account_directive(char * line) { - istream_pos_type beg_pos = line_beg_pos; - std::size_t beg_linenum = linenum; + istream_pos_type beg_pos = context.line_beg_pos; + std::size_t beg_linenum = context.linenum; char * p = skip_ws(line); account_t * account = - context.journal.register_account(p, NULL, file_context(pathname, linenum), - context.top_account()); + context.journal->register_account(p, NULL, top_account()); std::auto_ptr ae; while (peek_whitespace_line()) { @@ -900,7 +875,7 @@ void instance_t::account_directive(char * line) ae.reset(new auto_xact_t(pred)); ae->pos = position_t(); - ae->pos->pathname = pathname; + ae->pos->pathname = context.pathname; ae->pos->beg_pos = beg_pos; ae->pos->beg_line = beg_linenum; ae->pos->sequence = context.sequence++; @@ -916,7 +891,7 @@ void instance_t::account_directive(char * line) else if (keyword == "eval" || keyword == "expr") { // jww (2012-02-27): Make account into symbol scopes so that this // can be used to override definitions within the account. - bind_scope_t bound_scope(context.scope, *account); + bind_scope_t bound_scope(*context.scope, *account); expr_t(b).calc(bound_scope); } else if (keyword == "note") { @@ -925,11 +900,11 @@ void instance_t::account_directive(char * line) } if (ae.get()) { - context.journal.auto_xacts.push_back(ae.get()); + context.journal->auto_xacts.push_back(ae.get()); - ae->journal = &context.journal; + ae->journal = context.journal; ae->pos->end_pos = in.tellg(); - ae->pos->end_line = linenum; + ae->pos->end_line = context.linenum; ae.release(); } @@ -943,7 +918,7 @@ void instance_t::account_alias_directive(account_t * account, string alias) trim(alias); std::pair result = context.journal - .account_aliases.insert(accounts_map::value_type(alias, account)); + ->account_aliases.insert(accounts_map::value_type(alias, account)); assert(result.second); } @@ -957,26 +932,25 @@ void instance_t::alias_directive(char * line) *e++ = '\0'; e = skip_ws(e); - account_alias_directive(context.top_account()->find_account(e), b); + account_alias_directive(top_account()->find_account(e), b); } } void instance_t::account_payee_directive(account_t * account, string payee) { trim(payee); - context.journal.payees_for_unknown_accounts + context.journal->payees_for_unknown_accounts .push_back(account_mapping_t(mask_t(payee), account)); } void instance_t::account_default_directive(account_t * account) { - context.journal.bucket = account; + context.journal->bucket = account; } void instance_t::payee_directive(char * line) { - string payee = context.journal - .register_payee(line, NULL, file_context(pathname, linenum)); + string payee = context.journal->register_payee(line, NULL); while (peek_whitespace_line()) { read_line(line); @@ -994,7 +968,7 @@ void instance_t::payee_directive(char * line) void instance_t::payee_alias_directive(const string& payee, string alias) { trim(alias); - context.journal.payee_mappings + context.journal->payee_mappings .push_back(payee_mapping_t(mask_t(alias), payee)); } @@ -1006,8 +980,7 @@ void instance_t::commodity_directive(char * line) if (commodity_t * commodity = commodity_pool_t::current_pool->find_or_create(symbol)) { - context.journal.register_commodity(*commodity, 0, - file_context(pathname, linenum)); + context.journal->register_commodity(*commodity, 0); while (peek_whitespace_line()) { read_line(line); @@ -1067,8 +1040,7 @@ void instance_t::commodity_default_directive(commodity_t& comm) void instance_t::tag_directive(char * line) { char * p = skip_ws(line); - context.journal.register_metadata(p, NULL_VALUE, 0, - file_context(pathname, linenum)); + context.journal->register_metadata(p, NULL_VALUE, 0); while (peek_whitespace_line()) { read_line(line); @@ -1079,7 +1051,7 @@ void instance_t::tag_directive(char * line) char * b = next_element(q); string keyword(q); if (keyword == "assert" || keyword == "check") { - context.journal.tag_check_exprs.insert + context.journal->tag_check_exprs.insert (tag_check_exprs_map::value_type (string(p), expr_t::check_expr_pair(expr_t(b), @@ -1093,22 +1065,21 @@ void instance_t::tag_directive(char * line) void instance_t::eval_directive(char * line) { expr_t expr(line); - expr.calc(context.scope); + expr.calc(*context.scope); } void instance_t::assert_directive(char * line) { expr_t expr(line); - if (! expr.calc(context.scope).to_boolean()) + if (! expr.calc(*context.scope).to_boolean()) throw_(parse_error, _("Assertion failed: %1") << line); } void instance_t::check_directive(char * line) { expr_t expr(line); - if (! expr.calc(context.scope).to_boolean()) - warning_(_("%1Check failed: %2") - << file_context(pathname, linenum) << line); + if (! expr.calc(*context.scope).to_boolean()) + context.warning(STR(_("Check failed: %1") << line)); } void instance_t::comment_directive(char * line) @@ -1242,12 +1213,12 @@ post_t * instance_t::parse_post(char * line, post->xact = xact; // this could be NULL post->pos = position_t(); - post->pos->pathname = pathname; - post->pos->beg_pos = line_beg_pos; - post->pos->beg_line = linenum; + post->pos->pathname = context.pathname; + post->pos->beg_pos = context.line_beg_pos; + post->pos->beg_line = context.linenum; post->pos->sequence = context.sequence++; - char buf[MAX_LINE + 1]; + char buf[parse_context_t::MAX_LINE + 1]; std::strcpy(buf, line); std::streamsize beg = 0; @@ -1264,14 +1235,14 @@ post_t * instance_t::parse_post(char * line, case '*': post->set_state(item_t::CLEARED); p = skip_ws(p + 1); - DEBUG("textual.parse", "line " << linenum << ": " + DEBUG("textual.parse", "line " << context.linenum << ": " << "Parsed the CLEARED flag"); break; case '!': post->set_state(item_t::PENDING); p = skip_ws(p + 1); - DEBUG("textual.parse", "line " << linenum << ": " + DEBUG("textual.parse", "line " << context.linenum << ": " << "Parsed the PENDING flag"); break; } @@ -1294,25 +1265,23 @@ post_t * instance_t::parse_post(char * line, if ((*p == '[' && *(e - 1) == ']') || (*p == '(' && *(e - 1) == ')')) { post->add_flags(POST_VIRTUAL); - DEBUG("textual.parse", "line " << linenum << ": " + DEBUG("textual.parse", "line " << context.linenum << ": " << "Parsed a virtual account name"); if (*p == '[') { post->add_flags(POST_MUST_BALANCE); - DEBUG("textual.parse", "line " << linenum << ": " + DEBUG("textual.parse", "line " << context.linenum << ": " << "Posting must balance"); } p++; e--; } string name(p, static_cast(e - p)); - DEBUG("textual.parse", "line " << linenum << ": " + DEBUG("textual.parse", "line " << context.linenum << ": " << "Parsed account name " << name); post->account = - context.journal.register_account(name, post.get(), - file_context(pathname, linenum), - account); + context.journal->register_account(name, post.get(), account); // Parse the optional amount @@ -1323,16 +1292,15 @@ post_t * instance_t::parse_post(char * line, if (*next != '(') // indicates a value expression post->amount.parse(stream, PARSE_NO_REDUCE); else - parse_amount_expr(stream, context.scope, *post.get(), post->amount, + parse_amount_expr(stream, *context.scope, *post.get(), post->amount, PARSE_NO_REDUCE | PARSE_SINGLE | PARSE_NO_ASSIGN, defer_expr, &post->amount_expr); if (! post->amount.is_null() && post->amount.has_commodity()) { - context.journal.register_commodity(post->amount.commodity(), post.get(), - file_context(pathname, linenum)); + context.journal->register_commodity(post->amount.commodity(), post.get()); if (! post->amount.has_annotation()) { - foreach (application_t& state, context.apply_stack) { + foreach (application_t& state, apply_stack) { if (state.value.type() == typeid(fixed_rate_t)) { fixed_rate_t& rate(boost::get(state.value)); if (*rate.first == post->amount.commodity()) { @@ -1346,7 +1314,7 @@ post_t * instance_t::parse_post(char * line, } } - DEBUG("textual.parse", "line " << linenum << ": " + DEBUG("textual.parse", "line " << context.linenum << ": " << "post amount = " << post->amount); if (stream.eof()) { @@ -1357,7 +1325,7 @@ post_t * instance_t::parse_post(char * line, // Parse the optional cost (@ PER-UNIT-COST, @@ TOTAL-COST) if (*next == '@') { - DEBUG("textual.parse", "line " << linenum << ": " + DEBUG("textual.parse", "line " << context.linenum << ": " << "Found a price indicator"); bool per_unit = true; @@ -1365,7 +1333,7 @@ post_t * instance_t::parse_post(char * line, if (*++next == '@') { per_unit = false; post->add_flags(POST_COST_IN_FULL); - DEBUG("textual.parse", "line " << linenum << ": " + DEBUG("textual.parse", "line " << context.linenum << ": " << "And it's for a total price"); } @@ -1389,7 +1357,7 @@ post_t * instance_t::parse_post(char * line, if (*p != '(') // indicates a value expression post->cost->parse(cstream, PARSE_NO_MIGRATE); else - parse_amount_expr(cstream, context.scope, *post.get(), *post->cost, + parse_amount_expr(cstream, *context.scope, *post.get(), *post->cost, PARSE_NO_MIGRATE | PARSE_SINGLE | PARSE_NO_ASSIGN); if (post->cost->sign() < 0) @@ -1412,9 +1380,9 @@ post_t * instance_t::parse_post(char * line, if (fixed_cost) post->add_flags(POST_COST_FIXATED); - DEBUG("textual.parse", "line " << linenum << ": " + DEBUG("textual.parse", "line " << context.linenum << ": " << "Total cost is " << *post->cost); - DEBUG("textual.parse", "line " << linenum << ": " + DEBUG("textual.parse", "line " << context.linenum << ": " << "Annotated amount is " << post->amount); if (cstream.eof()) @@ -1431,7 +1399,7 @@ post_t * instance_t::parse_post(char * line, // Parse the optional balance assignment if (xact && next && *next == '=') { - DEBUG("textual.parse", "line " << linenum << ": " + DEBUG("textual.parse", "line " << context.linenum << ": " << "Found a balance assignment indicator"); beg = static_cast(++next - line); @@ -1446,7 +1414,7 @@ post_t * instance_t::parse_post(char * line, if (*p != '(') // indicates a value expression post->assigned_amount->parse(stream, PARSE_NO_MIGRATE); else - parse_amount_expr(stream, context.scope, *post.get(), + parse_amount_expr(stream, *context.scope, *post.get(), *post->assigned_amount, PARSE_SINGLE | PARSE_NO_MIGRATE); @@ -1457,17 +1425,17 @@ post_t * instance_t::parse_post(char * line, throw parse_error(_("Balance assertion must evaluate to a constant")); } - DEBUG("textual.parse", "line " << linenum << ": " + DEBUG("textual.parse", "line " << context.linenum << ": " << "POST assign: parsed amt = " << *post->assigned_amount); amount_t& amt(*post->assigned_amount); value_t account_total (post->account->amount().strip_annotations(keep_details_t())); + DEBUG("post.assign", "line " << context.linenum << ": " + << "account balance = " << account_total); DEBUG("post.assign", - "line " << linenum << ": " "account balance = " << account_total); - DEBUG("post.assign", - "line " << linenum << ": " "post amount = " << amt); + "line " << context.linenum << ": " << "post amount = " << amt); amount_t diff = amt; @@ -1487,9 +1455,9 @@ post_t * instance_t::parse_post(char * line, } DEBUG("post.assign", - "line " << linenum << ": " << "diff = " << diff); - DEBUG("textual.parse", - "line " << linenum << ": " << "POST assign: diff = " << diff); + "line " << context.linenum << ": " << "diff = " << diff); + DEBUG("textual.parse", "line " << context.linenum << ": " + << "POST assign: diff = " << diff); if (! diff.is_zero()) { if (! post->amount.is_null()) { @@ -1498,7 +1466,7 @@ post_t * instance_t::parse_post(char * line, throw_(parse_error, _("Balance assertion off by %1") << diff); } else { post->amount = diff; - DEBUG("textual.parse", "line " << linenum << ": " + DEBUG("textual.parse", "line " << context.linenum << ": " << "Overwrite null posting"); } } @@ -1515,9 +1483,9 @@ post_t * instance_t::parse_post(char * line, // Parse the optional note if (next && *next == ';') { - post->append_note(++next, context.scope, true); + post->append_note(++next, *context.scope, true); next = line + len; - DEBUG("textual.parse", "line " << linenum << ": " + DEBUG("textual.parse", "line " << context.linenum << ": " << "Parsed a posting note"); } @@ -1528,14 +1496,14 @@ post_t * instance_t::parse_post(char * line, _("Unexpected char '%1' (Note: inline math requires parentheses)") << *next); - post->pos->end_pos = curr_pos; - post->pos->end_line = linenum; + post->pos->end_pos = context.curr_pos; + post->pos->end_line = context.linenum; - if (! context.apply_stack.empty()) { - foreach (const application_t& state, context.apply_stack) + if (! apply_stack.empty()) { + foreach (const application_t& state, apply_stack) if (state.value.type() == typeid(string)) post->parse_tags(boost::get(state.value).c_str(), - context.scope, true); + *context.scope, true); } TRACE_STOP(post_details, 1); @@ -1587,9 +1555,9 @@ xact_t * instance_t::parse_xact(char * line, unique_ptr xact(new xact_t); xact->pos = position_t(); - xact->pos->pathname = pathname; - xact->pos->beg_pos = line_beg_pos; - xact->pos->beg_line = linenum; + xact->pos->pathname = context.pathname; + xact->pos->beg_pos = context.line_beg_pos; + xact->pos->beg_line = context.linenum; xact->pos->sequence = context.sequence++; bool reveal_context = true; @@ -1635,9 +1603,7 @@ xact_t * instance_t::parse_xact(char * line, if (next && *next) { char * p = next_element(next, true); - xact->payee = - context.journal.register_payee(next, xact.get(), - file_context(pathname, linenum)); + xact->payee = context.journal->register_payee(next, xact.get()); next = p; } else { xact->payee = _(""); @@ -1646,7 +1612,7 @@ xact_t * instance_t::parse_xact(char * line, // Parse the xact note if (next && *next == ';') - xact->append_note(++next, context.scope, false); + xact->append_note(++next, *context.scope, false); TRACE_STOP(xact_text, 1); @@ -1673,9 +1639,9 @@ xact_t * instance_t::parse_xact(char * line, if (*p == ';') { // This is a trailing note, and possibly a metadata info tag - item->append_note(p + 1, context.scope, true); + item->append_note(p + 1, *context.scope, true); item->add_flags(ITEM_NOTE_ON_NEXT_LINE); - item->pos->end_pos = curr_pos; + item->pos->end_pos = context.curr_pos; item->pos->end_line++; } else if ((remlen > 7 && *p == 'a' && @@ -1687,7 +1653,7 @@ xact_t * instance_t::parse_xact(char * line, const char c = *p; p = skip_ws(&p[*p == 'a' ? 6 : (*p == 'c' ? 5 : 4)]); expr_t expr(p); - bind_scope_t bound_scope(context.scope, *item); + bind_scope_t bound_scope(*context.scope, *item); if (c == 'e') { expr.calc(bound_scope); } @@ -1695,8 +1661,7 @@ xact_t * instance_t::parse_xact(char * line, if (c == 'a') { throw_(parse_error, _("Transaction assertion failed: %1") << p); } else { - warning_(_("%1Transaction check failed: %2") - << file_context(pathname, linenum) << p); + context.warning(STR(_("Transaction check failed: %1") << p)); } } } @@ -1729,14 +1694,14 @@ xact_t * instance_t::parse_xact(char * line, } #endif - xact->pos->end_pos = curr_pos; - xact->pos->end_line = linenum; + xact->pos->end_pos = context.curr_pos; + xact->pos->end_line = context.linenum; - if (! context.apply_stack.empty()) { - foreach (const application_t& state, context.apply_stack) + if (! apply_stack.empty()) { + foreach (const application_t& state, apply_stack) if (state.value.type() == typeid(string)) xact->parse_tags(boost::get(state.value).c_str(), - context.scope, false); + *context.scope, false); } TRACE_STOP(xact_details, 1); @@ -1748,7 +1713,8 @@ xact_t * instance_t::parse_xact(char * line, if (reveal_context) { add_error_context(_("While parsing transaction:")); add_error_context(source_context(xact->pos->pathname, - xact->pos->beg_pos, curr_pos, "> ")); + xact->pos->beg_pos, + context.curr_pos, "> ")); } throw; } @@ -1757,26 +1723,18 @@ xact_t * instance_t::parse_xact(char * line, expr_t::ptr_op_t instance_t::lookup(const symbol_t::kind_t kind, const string& name) { - return context.scope.lookup(kind, name); + return context.scope->lookup(kind, name); } -std::size_t journal_t::parse(std::istream& in, - scope_t& scope, - account_t * master_account, - const path * original_file) +std::size_t journal_t::read_textual(parse_context_stack_t& context_stack) { TRACE_START(parsing_total, 1, "Total time spent parsing text:"); - - parse_context_t context(*this, scope); - if (master_account || this->master) - context.apply_stack.push_front(application_t("account", - master_account ? - master_account : this->master)); - - instance_t instance(context, in, original_file); - instance.parse(); - context.close(); - + { + instance_t instance(context_stack, context_stack.get_current()); + instance.apply_stack.push_front + (application_t("account", context_stack.get_current().master)); + instance.parse(); + } TRACE_STOP(parsing_total, 1); // These tracers were started in textual.cc @@ -1787,10 +1745,10 @@ std::size_t journal_t::parse(std::istream& in, TRACE_FINISH(instance_parse, 1); // report per-instance timers TRACE_FINISH(parsing_total, 1); - if (context.errors > 0) - throw static_cast(context.errors); + if (context_stack.get_current().errors > 0) + throw static_cast(context_stack.get_current().errors); - return context.count; + return context_stack.get_current().count; } } // namespace ledger diff --git a/src/timelog.cc b/src/timelog.cc index 8d3d69c1..67ea1015 100644 --- a/src/timelog.cc +++ b/src/timelog.cc @@ -36,14 +36,14 @@ #include "post.h" #include "account.h" #include "journal.h" +#include "context.h" namespace ledger { namespace { void clock_out_from_timelog(std::list& time_xacts, time_xact_t out_event, - journal_t& journal, - scope_t& scope) + parse_context_t& context) { time_xact_t event; @@ -95,7 +95,7 @@ namespace { curr->pos = event.position; if (! event.note.empty()) - curr->append_note(event.note.c_str(), scope); + curr->append_note(event.note.c_str(), *context.scope); char buf[32]; std::sprintf(buf, "%lds", long((out_event.checkin - event.checkin) @@ -110,7 +110,7 @@ namespace { curr->add_post(post); event.account->add_post(post); - if (! journal.add_xact(curr.get())) + if (! context.journal->add_xact(curr.get())) throw parse_error(_("Failed to record 'out' timelog transaction")); else curr.release(); @@ -129,9 +129,8 @@ void time_log_t::close() DEBUG("timelog", "Clocking out from account " << account->fullname()); clock_out_from_timelog(time_xacts, time_xact_t(none, CURRENT_TIME(), account), - journal, scope); - if (context_count) - (*context_count)++; + context); + context.count++; } assert(time_xacts.empty()); } @@ -154,7 +153,7 @@ void time_log_t::clock_out(time_xact_t event) if (time_xacts.empty()) throw std::logic_error(_("Timelog check-out event without a check-in")); - clock_out_from_timelog(time_xacts, event, journal, scope); + clock_out_from_timelog(time_xacts, event, context); } } // namespace ledger diff --git a/src/timelog.h b/src/timelog.h index 12083302..ed5a2d36 100644 --- a/src/timelog.h +++ b/src/timelog.h @@ -50,6 +50,7 @@ namespace ledger { class account_t; class journal_t; +class parse_context_t; class time_xact_t { @@ -86,15 +87,11 @@ public: class time_log_t : public boost::noncopyable { std::list time_xacts; - journal_t& journal; - scope_t& scope; + parse_context_t& context; public: - std::size_t * context_count; - - time_log_t(journal_t& _journal, scope_t& _scope) - : journal(_journal), scope(_scope), context_count(NULL) { - TRACE_CTOR(time_log_t, "journal_t&, scope_t&, std::size&"); + time_log_t(parse_context_t& _context) : context(_context) { + TRACE_CTOR(time_log_t, "parse_context_t&"); } ~time_log_t() { TRACE_DTOR(time_log_t); diff --git a/src/xact.cc b/src/xact.cc index 0fedb42a..0251edde 100644 --- a/src/xact.cc +++ b/src/xact.cc @@ -35,6 +35,7 @@ #include "post.h" #include "account.h" #include "journal.h" +#include "context.h" #include "pool.h" namespace ledger { @@ -608,7 +609,7 @@ namespace { } } -void auto_xact_t::extend_xact(xact_base_t& xact) +void auto_xact_t::extend_xact(xact_base_t& xact, parse_context_t& context) { posts_list initial_posts(xact.posts.begin(), xact.posts.end()); @@ -674,7 +675,8 @@ void auto_xact_t::extend_xact(xact_base_t& xact) throw_(parse_error, _("Transaction assertion failed: %1") << pair.first); else - warning_(_("Transaction check failed: %1") << pair.first); + context.warning(STR(_("Transaction check failed: %1") + << pair.first)); } } } diff --git a/src/xact.h b/src/xact.h index cb7bdeb3..7d7fb826 100644 --- a/src/xact.h +++ b/src/xact.h @@ -49,6 +49,7 @@ namespace ledger { class post_t; class journal_t; +class parse_context_t; typedef std::list posts_list; @@ -209,7 +210,7 @@ public: deferred_notes->push_back(deferred_tag_data_t(p, overwrite_existing)); } - virtual void extend_xact(xact_base_t& xact); + virtual void extend_xact(xact_base_t& xact, parse_context_t& context); #if defined(HAVE_BOOST_SERIALIZATION) private: diff --git a/test/baseline/dir-tag.test b/test/baseline/dir-tag.test index b1858146..496334a0 100644 --- a/test/baseline/dir-tag.test +++ b/test/baseline/dir-tag.test @@ -17,5 +17,5 @@ test reg 12-Feb-28 KFC food $20.00 $20.00 Assets:Cash $-20.00 0 __ERROR__ -Warning: Metadata check failed for (Happy: Summer): (value == "Valley") +Warning: "/Users/johnw/Projects/ledger/test/baseline/dir-tag.test", line 8: Metadata check failed for (Happy: Summer): (value == "Valley") end test diff --git a/test/baseline/feat-check.test b/test/baseline/feat-check.test index 9a2e72df..a9db1ec4 100644 --- a/test/baseline/feat-check.test +++ b/test/baseline/feat-check.test @@ -13,6 +13,6 @@ test bal -------------------- 0 __ERROR__ -Warning: Transaction check failed: (account =~ /Foo/) +Warning: "$sourcepath/test/baseline/feat-check.test", line 6: Transaction check failed: (account =~ /Foo/) Warning: "$sourcepath/test/baseline/feat-check.test", line 8: Check failed: account("Assets:Checking").all(account =~ /Expense/) end test -- cgit v1.2.3 From 9ec9cdf41e5176f7fcf06da5f75593d9ba3d4028 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Thu, 1 Mar 2012 05:50:07 -0600 Subject: Started writing Python unit tests --- src/error.h | 6 +++ src/global.h | 2 +- src/main.cc | 7 ++-- src/py_amount.cc | 2 +- src/py_commodity.cc | 40 +++++++++----------- src/py_journal.cc | 93 ++++++++++++++++++++++------------------------ src/py_post.cc | 2 +- src/py_session.cc | 76 +++++++++++++++++++++++++++++++++++++ src/py_xact.cc | 8 ++++ src/pyinterp.cc | 2 + src/session.cc | 39 +++++++++++++++++-- src/session.h | 4 +- src/system.hh.in | 2 + src/textual.cc | 2 +- src/utils.cc | 3 +- test/python/JournalTest.py | 25 ++++++++----- tools/Makefile.am | 1 + 17 files changed, 220 insertions(+), 94 deletions(-) create mode 100644 src/py_session.cc (limited to 'src/session.cc') diff --git a/src/error.h b/src/error.h index 7630f017..86d9de76 100644 --- a/src/error.h +++ b/src/error.h @@ -101,6 +101,12 @@ string source_context(const path& file, virtual ~name() throw() {} \ } +struct error_count { + std::size_t count; + explicit error_count(std::size_t _count) : count(_count) {} + const char * what() const { return ""; } +}; + } // namespace ledger #endif // _ERROR_H diff --git a/src/global.h b/src/global.h index 28bffc3a..2cb7842e 100644 --- a/src/global.h +++ b/src/global.h @@ -155,7 +155,7 @@ See LICENSE file included with the distribution for details and disclaimer."); OPTION_(global_scope_t, version, DO() { // -v parent->show_version_info(std::cout); - throw int(0); // exit immediately + throw error_count(0); // exit immediately }); }; diff --git a/src/main.cc b/src/main.cc index 2202a5de..aafbdbcb 100644 --- a/src/main.cc +++ b/src/main.cc @@ -191,9 +191,10 @@ int main(int argc, char * argv[], char * envp[]) std::cerr << "Exception during initialization: " << err.what() << std::endl; } - catch (int _status) { - status = _status; // used for a "quick" exit, and is used only - // if help text (such as --help) was displayed + catch (const error_count& errors) { + // used for a "quick" exit, and is used only if help text (such as + // --help) was displayed + status = static_cast(errors.count); } // If memory verification is being performed (which can be very slow), clean diff --git a/src/py_amount.cc b/src/py_amount.cc index f10595e8..25ec8e26 100644 --- a/src/py_amount.cc +++ b/src/py_amount.cc @@ -263,7 +263,7 @@ internal precision.")) .add_property("commodity", make_function(&amount_t::commodity, - return_value_policy()), + return_internal_reference<>()), make_function(&amount_t::set_commodity, with_custodian_and_ward<1, 2>())) .def("has_commodity", &amount_t::has_commodity) diff --git a/src/py_commodity.cc b/src/py_commodity.cc index ffa903f4..b5230850 100644 --- a/src/py_commodity.cc +++ b/src/py_commodity.cc @@ -269,18 +269,14 @@ void export_commodity() .def("make_qualified_name", &commodity_pool_t::make_qualified_name) - .def("create", py_create_1, - return_value_policy()) - .def("create", py_create_2, - return_value_policy()) + .def("create", py_create_1, return_internal_reference<>()) + .def("create", py_create_2, return_internal_reference<>()) - .def("find_or_create", py_find_or_create_1, - return_value_policy()) - .def("find_or_create", py_find_or_create_2, - return_value_policy()) + .def("find_or_create", py_find_or_create_1, return_internal_reference<>()) + .def("find_or_create", py_find_or_create_2, return_internal_reference<>()) - .def("find", py_find_1, return_value_policy()) - .def("find", py_find_2, return_value_policy()) + .def("find", py_find_1, return_internal_reference<>()) + .def("find", py_find_2, return_internal_reference<>()) .def("exchange", py_exchange_2, with_custodian_and_ward<1, 2>()) .def("exchange", py_exchange_3, with_custodian_and_ward<1, 2>()) @@ -288,23 +284,23 @@ void export_commodity() .def("parse_price_directive", &commodity_pool_t::parse_price_directive) .def("parse_price_expression", &commodity_pool_t::parse_price_expression, - return_value_policy()) + return_internal_reference<>()) .def("__getitem__", py_pool_getitem, - return_value_policy()) + return_internal_reference<>()) .def("keys", py_pool_keys) .def("has_key", py_pool_contains) .def("__contains__", py_pool_contains) .def("__iter__", - python::range > + python::range > (py_pool_commodities_begin, py_pool_commodities_end)) .def("iteritems", - python::range > + python::range > (py_pool_commodities_begin, py_pool_commodities_end)) .def("iterkeys", python::range<>(py_pool_commodities_keys_begin, py_pool_commodities_keys_end)) .def("itervalues", - python::range > + python::range > (py_pool_commodities_values_begin, py_pool_commodities_values_end)) ; @@ -349,17 +345,17 @@ void export_commodity() .add_property("referent", make_function(py_commodity_referent, - return_value_policy())) + return_internal_reference<>())) .def("has_annotation", &commodity_t::has_annotation) .def("strip_annotations", py_strip_annotations_0, - return_value_policy()) + return_internal_reference<>()) .def("strip_annotations", py_strip_annotations_1, - return_value_policy()) + return_internal_reference<>()) .def("write_annotations", &commodity_t::write_annotations) .def("pool", &commodity_t::pool, - return_value_policy()) + return_internal_reference<>()) .add_property("base_symbol", &commodity_t::base_symbol) .add_property("symbol", &commodity_t::symbol) @@ -441,12 +437,12 @@ void export_commodity() .add_property("referent", make_function(py_annotated_commodity_referent, - return_value_policy())) + return_internal_reference<>())) .def("strip_annotations", py_strip_ann_annotations_0, - return_value_policy()) + return_internal_reference<>()) .def("strip_annotations", py_strip_ann_annotations_1, - return_value_policy()) + return_internal_reference<>()) .def("write_annotations", &annotated_commodity_t::write_annotations) ; } diff --git a/src/py_journal.cc b/src/py_journal.cc index a72b8528..550fb14e 100644 --- a/src/py_journal.cc +++ b/src/py_journal.cc @@ -144,10 +144,10 @@ namespace { struct collector_wrapper { - journal_t& journal; - report_t report; - collect_posts * posts_collector; - post_handler_ptr chain; + journal_t& journal; + report_t report; + + post_handler_ptr posts_collector; collector_wrapper(journal_t& _journal, report_t& base) : journal(_journal), report(base), @@ -157,31 +157,32 @@ namespace { } std::size_t length() const { - return posts_collector->length(); + return dynamic_cast(posts_collector.get())->length(); } std::vector::iterator begin() { - return posts_collector->begin(); + return dynamic_cast(posts_collector.get())->begin(); } std::vector::iterator end() { - return posts_collector->end(); + return dynamic_cast(posts_collector.get())->end(); } }; - shared_ptr - py_collect(journal_t& journal, const string& query) + shared_ptr py_query(journal_t& journal, + const string& query) { if (journal.has_xdata()) { PyErr_SetString(PyExc_RuntimeError, - _("Cannot have multiple journal collections open at once")); + _("Cannot have more than one active journal query")); throw_error_already_set(); } report_t& current_report(downcast(*scope_t::default_scope)); - shared_ptr coll(new collector_wrapper(journal, - current_report)); - unique_ptr save_journal(current_report.session.journal.release()); - current_report.session.journal.reset(&journal); + shared_ptr + coll(new collector_wrapper(journal, current_report)); + + unique_ptr save_journal(coll->report.session.journal.release()); + coll->report.session.journal.reset(&coll->journal); try { strings_list remaining = @@ -191,60 +192,48 @@ namespace { value_t args; foreach (const string& arg, remaining) args.push_back(string_value(arg)); - coll->report.parse_query_args(args, "@Journal.collect"); + coll->report.parse_query_args(args, "@Journal.query"); - journal_posts_iterator walker(coll->journal); - coll->chain = - chain_post_handlers(post_handler_ptr(coll->posts_collector), - coll->report); - pass_down_posts(coll->chain, walker); + coll->report.posts_report(coll->posts_collector); } catch (...) { - current_report.session.journal.release(); - current_report.session.journal.reset(save_journal.release()); + coll->report.session.journal.release(); + coll->report.session.journal.reset(save_journal.release()); throw; } - current_report.session.journal.release(); - current_report.session.journal.reset(save_journal.release()); + coll->report.session.journal.release(); + coll->report.session.journal.reset(save_journal.release()); return coll; } post_t * posts_getitem(collector_wrapper& collector, long i) { - post_t * post = - collector.posts_collector->posts[static_cast(i)]; - std::cerr << typeid(post).name() << std::endl; - std::cerr << typeid(*post).name() << std::endl; - std::cerr << typeid(post->account).name() << std::endl; - std::cerr << typeid(*post->account).name() << std::endl; - return post; + return dynamic_cast(collector.posts_collector.get()) + ->posts[static_cast(i)]; } } // unnamed namespace +#define EXC_TRANSLATOR(type) \ + void exc_translate_ ## type(const type& err) { \ + PyErr_SetString(PyExc_RuntimeError, err.what()); \ + } + +EXC_TRANSLATOR(parse_error) +EXC_TRANSLATOR(error_count) + void export_journal() { class_< item_handler, shared_ptr >, boost::noncopyable >("PostHandler") ; - class_< collect_posts, bases >, - shared_ptr, boost::noncopyable >("PostCollector") - .def("__len__", &collect_posts::length) - .def("__iter__", python::range > > - (&collect_posts::begin, &collect_posts::end)) - ; - class_< collector_wrapper, shared_ptr, boost::noncopyable >("PostCollectorWrapper", no_init) .def("__len__", &collector_wrapper::length) - .def("__getitem__", posts_getitem, return_internal_reference<1, - with_custodian_and_ward_postcall<0, 1> >()) - .def("__iter__", - python::range > > + .def("__getitem__", posts_getitem, return_internal_reference<>()) + .def("__iter__", python::range > (&collector_wrapper::begin, &collector_wrapper::end)) ; @@ -286,13 +275,13 @@ void export_journal() .def("find_account", py_find_account_1, return_internal_reference<1, - with_custodian_and_ward_postcall<0, 1> >()) + with_custodian_and_ward_postcall<1, 0> >()) .def("find_account", py_find_account_2, return_internal_reference<1, - with_custodian_and_ward_postcall<0, 1> >()) + with_custodian_and_ward_postcall<1, 0> >()) .def("find_account_re", &journal_t::find_account_re, return_internal_reference<1, - with_custodian_and_ward_postcall<0, 1> >()) + with_custodian_and_ward_postcall<1, 0> >()) .def("add_xact", &journal_t::add_xact) .def("remove_xact", &journal_t::remove_xact) @@ -301,7 +290,7 @@ void export_journal() #if 0 .def("__getitem__", xacts_getitem, return_internal_reference<1, - with_custodian_and_ward_postcall<0, 1> >()) + with_custodian_and_ward_postcall<1, 0> >()) #endif .def("__iter__", python::range > @@ -320,10 +309,16 @@ void export_journal() .def("has_xdata", &journal_t::has_xdata) .def("clear_xdata", &journal_t::clear_xdata) - .def("collect", py_collect, with_custodian_and_ward_postcall<0, 1>()) + .def("query", py_query) .def("valid", &journal_t::valid) ; + +#define EXC_TRANSLATE(type) \ + register_exception_translator(&exc_translate_ ## type); + + EXC_TRANSLATE(parse_error); + EXC_TRANSLATE(error_count); } } // namespace ledger diff --git a/src/py_post.cc b/src/py_post.cc index bd599604..2789082e 100644 --- a/src/py_post.cc +++ b/src/py_post.cc @@ -116,7 +116,7 @@ void export_post() make_setter(&post_t::xdata_t::datetime)) .add_property("account", make_getter(&post_t::xdata_t::account, - return_value_policy()), + return_internal_reference<>()), make_setter(&post_t::xdata_t::account, with_custodian_and_ward<1, 2>())) .add_property("sort_values", diff --git a/src/py_session.cc b/src/py_session.cc new file mode 100644 index 00000000..f411d5e1 --- /dev/null +++ b/src/py_session.cc @@ -0,0 +1,76 @@ +/* + * Copyright (c) 2003-2012, John Wiegley. All rights reserved. + * + * Redistribution and use in source and binary forms, with or without + * modification, are permitted provided that the following conditions are + * met: + * + * - Redistributions of source code must retain the above copyright + * notice, this list of conditions and the following disclaimer. + * + * - Redistributions in binary form must reproduce the above copyright + * notice, this list of conditions and the following disclaimer in the + * documentation and/or other materials provided with the distribution. + * + * - Neither the name of New Artisans LLC nor the names of its + * contributors may be used to endorse or promote products derived from + * this software without specific prior written permission. + * + * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS + * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT + * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR + * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT + * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL, + * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT + * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE, + * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY + * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT + * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE + * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. + */ + +#include + +#include "pyinterp.h" +#include "pyutils.h" +#include "session.h" + +namespace ledger { + +using namespace boost::python; + +namespace { + journal_t * py_read_journal(const string& pathname) + { + return python_session->read_journal(path(pathname)); + } + + journal_t * py_read_journal_from_string(const string& data) + { + return python_session->read_journal_from_string(data); + } +} + +void export_session() +{ + class_< session_t, boost::noncopyable > ("Session") + .def("read_journal", &session_t::read_journal, + return_internal_reference<>()) + .def("read_journal_from_string", &session_t::read_journal_from_string, + return_internal_reference<>()) + .def("read_journal_files", &session_t::read_journal_files, + return_internal_reference<>()) + .def("close_journal_files", &session_t::close_journal_files) + ; + + scope().attr("session") = + object(ptr(static_cast(python_session.get()))); + scope().attr("read_journal") = + python::make_function(&py_read_journal, + return_internal_reference<>()); + scope().attr("read_journal_from_string") = + python::make_function(&py_read_journal_from_string, + return_internal_reference<>()); +} + +} // namespace ledger diff --git a/src/py_xact.cc b/src/py_xact.cc index 97d5df47..3d792c7b 100644 --- a/src/py_xact.cc +++ b/src/py_xact.cc @@ -76,6 +76,12 @@ namespace { return **elem; } + string py_xact_to_string(xact_t&) + { + // jww (2012-03-01): TODO + return empty_string; + } + } // unnamed namespace using namespace boost::python; @@ -110,6 +116,8 @@ void export_xact() .def("id", &xact_t::id) .def("seq", &xact_t::seq) + .def("__str__", py_xact_to_string) + .add_property("code", make_getter(&xact_t::code), make_setter(&xact_t::code)) diff --git a/src/pyinterp.cc b/src/pyinterp.cc index de9c94cb..4dbb7134 100644 --- a/src/pyinterp.cc +++ b/src/pyinterp.cc @@ -51,6 +51,7 @@ void export_commodity(); void export_expr(); void export_format(); void export_item(); +void export_session(); void export_journal(); void export_post(); void export_times(); @@ -72,6 +73,7 @@ void initialize_for_python() export_item(); export_post(); export_xact(); + export_session(); export_journal(); } diff --git a/src/session.cc b/src/session.cc index e07026b6..db01fbf6 100644 --- a/src/session.cc +++ b/src/session.cc @@ -89,8 +89,10 @@ std::size_t session_t::read_data(const string& master_account) std::size_t xact_count = 0; - account_t * acct = journal->master; - if (! master_account.empty()) + account_t * acct; + if (master_account.empty()) + acct = journal->master; + else acct = journal->find_account(master_account); optional price_db_path; @@ -185,7 +187,7 @@ std::size_t session_t::read_data(const string& master_account) return journal->xacts.size(); } -void session_t::read_journal_files() +journal_t * session_t::read_journal_files() { INFO_START(journal, "Read journal file"); @@ -203,6 +205,37 @@ void session_t::read_journal_files() #if defined(DEBUG_ON) INFO("Found " << count << " transactions"); #endif + + return journal.get(); +} + +journal_t * session_t::read_journal(const path& pathname) +{ + HANDLER(file_).data_files.clear(); + HANDLER(file_).data_files.push_back(pathname); + + return read_journal_files(); +} + +journal_t * session_t::read_journal_from_string(const string& data) +{ + HANDLER(file_).data_files.clear(); + + shared_ptr stream(new std::istringstream(data)); + parsing_context.push(stream); + + parsing_context.get_current().journal = journal.get(); + parsing_context.get_current().master = journal->master; + try { + journal->read(parsing_context); + } + catch (...) { + parsing_context.pop(); + throw; + } + parsing_context.pop(); + + return journal.get(); } void session_t::close_journal_files() diff --git a/src/session.h b/src/session.h index 54b9912a..38062b78 100644 --- a/src/session.h +++ b/src/session.h @@ -75,9 +75,11 @@ public: flush_on_next_data_file = truth; } + journal_t * read_journal(const path& pathname); + journal_t * read_journal_from_string(const string& data); std::size_t read_data(const string& master_account = ""); - void read_journal_files(); + journal_t * read_journal_files(); void close_journal_files(); value_t fn_account(call_scope_t& scope); diff --git a/src/system.hh.in b/src/system.hh.in index e14166b2..3aa60f71 100644 --- a/src/system.hh.in +++ b/src/system.hh.in @@ -257,4 +257,6 @@ void serialize(Archive& ar, istream_pos_type& pos, const unsigned int) #include #include +#include + #endif // HAVE_BOOST_PYTHON diff --git a/src/textual.cc b/src/textual.cc index 97c80e4f..2f09c063 100644 --- a/src/textual.cc +++ b/src/textual.cc @@ -1746,7 +1746,7 @@ std::size_t journal_t::read_textual(parse_context_stack_t& context_stack) TRACE_FINISH(parsing_total, 1); if (context_stack.get_current().errors > 0) - throw static_cast(context_stack.get_current().errors); + throw error_count(context_stack.get_current().errors); return context_stack.get_current().count; } diff --git a/src/utils.cc b/src/utils.cc index 09526267..eb1d8009 100644 --- a/src/utils.cc +++ b/src/utils.cc @@ -612,8 +612,7 @@ optional _log_category_re; struct __maybe_enable_debugging { __maybe_enable_debugging() { - const char * p = std::getenv("LEDGER_DEBUG"); - if (p != NULL) { + if (const char * p = std::getenv("LEDGER_DEBUG")) { _log_level = LOG_DEBUG; _log_category = p; } diff --git a/test/python/JournalTest.py b/test/python/JournalTest.py index 66447f87..e65c671d 100644 --- a/test/python/JournalTest.py +++ b/test/python/JournalTest.py @@ -1,22 +1,27 @@ # -*- coding: utf-8 -*- import unittest -import exceptions -import operator from ledger import * -from StringIO import * -from datetime import * class JournalTestCase(unittest.TestCase): - def setUp(self): - pass - def tearDown(self): - pass + session.close_journal_files() + + def testBasicRead(self): + journal = read_journal_from_string(""" +2012-03-01 KFC + Expenses:Food $21.34 + Assets:Cash +""") + self.assertEqual(type(journal), Journal) + + for xact in journal: + self.assertEqual(xact.payee, "KFC") - def test_(self): - pass + for post in journal.query("food"): + self.assertEqual(str(post.account), "Expenses:Food") + self.assertEqual(post.amount, Amount("$21.34")) def suite(): return unittest.TestLoader().loadTestsFromTestCase(JournalTestCase) diff --git a/tools/Makefile.am b/tools/Makefile.am index fe0681e5..4fdd8393 100644 --- a/tools/Makefile.am +++ b/tools/Makefile.am @@ -226,6 +226,7 @@ libledger_python_la_SOURCES = \ src/py_expr.cc \ src/py_format.cc \ src/py_item.cc \ + src/py_session.cc \ src/py_journal.cc \ src/py_post.cc \ src/py_times.cc \ -- cgit v1.2.3 From a125f24d29fd8275be7283a2edca9abc125703d7 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Thu, 1 Mar 2012 23:40:02 -0600 Subject: Allow --options to be added by the user in Python --- src/context.h | 7 +++++++ src/option.cc | 1 - src/pyinterp.cc | 11 ++++++++++- src/session.cc | 2 ++ src/session.h | 1 + src/textual.cc | 5 +++-- test/baseline/feat-option_py.test | 14 ++++++++++++++ test/baseline/featoption.py | 5 +++++ 8 files changed, 42 insertions(+), 4 deletions(-) create mode 100644 test/baseline/feat-option_py.test create mode 100644 test/baseline/featoption.py (limited to 'src/session.cc') diff --git a/src/context.h b/src/context.h index d7999e5a..45bb9990 100644 --- a/src/context.h +++ b/src/context.h @@ -71,6 +71,10 @@ public: std::size_t count; std::size_t sequence; + explicit parse_context_t(const path& cwd) + : current_directory(cwd), master(NULL), scope(NULL), + linenum(0), errors(0), count(0), sequence(1) {} + explicit parse_context_t(shared_ptr _stream, const path& cwd) : stream(_stream), current_directory(cwd), master(NULL), @@ -126,6 +130,9 @@ class parse_context_stack_t std::list parsing_context; public: + void push() { + parsing_context.push_front(parse_context_t(filesystem::current_path())); + } void push(shared_ptr stream, const path& cwd = filesystem::current_path()) { parsing_context.push_front(parse_context_t(stream, cwd)); diff --git a/src/option.cc b/src/option.cc index 170b94af..418980bd 100644 --- a/src/option.cc +++ b/src/option.cc @@ -89,7 +89,6 @@ namespace { catch (const std::exception&) { if (name[0] == '-') add_error_context(_("While parsing option '%1'") << name); - else add_error_context(_("While parsing environent variable '%1'") << name); throw; diff --git a/src/pyinterp.cc b/src/pyinterp.cc index 048f5a39..3157079a 100644 --- a/src/pyinterp.cc +++ b/src/pyinterp.cc @@ -419,10 +419,19 @@ expr_t::ptr_op_t python_interpreter_t::lookup(const symbol_t::kind_t kind, } break; - case symbol_t::OPTION: + case symbol_t::OPTION: { if (option_t * handler = lookup_option(name.c_str())) return MAKE_OPT_HANDLER(python_interpreter_t, handler); + + string option_name(string("option_") + name); + if (is_initialized && main_nspace.has_key(option_name.c_str())) { + DEBUG("python.interp", "Python lookup option: " << option_name); + + if (python::object obj = main_nspace.get(option_name.c_str())) + return WRAP_FUNCTOR(functor_t(obj, option_name)); + } break; + } case symbol_t::PRECOMMAND: { const char * p = name.c_str(); diff --git a/src/session.cc b/src/session.cc index db01fbf6..3e7cdb3d 100644 --- a/src/session.cc +++ b/src/session.cc @@ -68,6 +68,8 @@ session_t::session_t() HANDLER(price_db_).on(none, (path(home_var) / ".pricedb").string()); else HANDLER(price_db_).on(none, path("./.pricedb").string()); + + parsing_context.push(); } std::size_t session_t::read_data(const string& master_account) diff --git a/src/session.h b/src/session.h index 38062b78..879efeb6 100644 --- a/src/session.h +++ b/src/session.h @@ -65,6 +65,7 @@ public: explicit session_t(); virtual ~session_t() { TRACE_DTOR(session_t); + parsing_context.pop(); } virtual string description() { diff --git a/src/textual.cc b/src/textual.cc index 2ec58898..a4e03435 100644 --- a/src/textual.cc +++ b/src/textual.cc @@ -508,8 +508,9 @@ void instance_t::option_directive(char * line) *p++ = '\0'; } - if (! process_option(context.pathname.string(), line + 2, - *context.scope, p, line)) + path abs_path(filesystem::absolute(context.pathname, + context.current_directory)); + if (! process_option(abs_path.string(), line + 2, *context.scope, p, line)) throw_(option_error, _("Illegal option --%1") << line + 2); } diff --git a/test/baseline/feat-option_py.test b/test/baseline/feat-option_py.test new file mode 100644 index 00000000..a67b27c3 --- /dev/null +++ b/test/baseline/feat-option_py.test @@ -0,0 +1,14 @@ +python + def option_pyfirst(context): + print "In --pyfirst (from %s)" % context + + def option_pysecond(context, val): + print "In --pysecond=%s (from %s)" % (val, context) + +--pyfirst +--pysecond Hey + +test reg +In --pyfirst (from $sourcepath/test/baseline/feat-option_py.test) +In --pysecond=Hey (from $sourcepath/test/baseline/feat-option_py.test) +end test diff --git a/test/baseline/featoption.py b/test/baseline/featoption.py new file mode 100644 index 00000000..caa4f2bc --- /dev/null +++ b/test/baseline/featoption.py @@ -0,0 +1,5 @@ +def option_pyfirst(context): + print "In --pyfirst (from %s)" % context + +def option_pysecond(context, val): + print "In --pysecond=%sh (from %s)" % (val, context) -- cgit v1.2.3 From b0cf90ab50ac42d3184d70cb1906778df034ddaa Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Fri, 9 Mar 2012 01:29:11 -0600 Subject: Added int and str value expression functions --- src/session.cc | 19 +++++++++++++++++++ src/session.h | 2 ++ 2 files changed, 21 insertions(+) (limited to 'src/session.cc') diff --git a/src/session.cc b/src/session.cc index 3e7cdb3d..7c546b82 100644 --- a/src/session.cc +++ b/src/session.cc @@ -268,6 +268,15 @@ value_t session_t::fn_max(call_scope_t& args) return args[1] > args[0] ? args[1] : args[0]; } +value_t session_t::fn_int(call_scope_t& args) +{ + return args[0].to_long(); +} +value_t session_t::fn_str(call_scope_t& args) +{ + return string_value(args[0].to_string()); +} + value_t session_t::fn_lot_price(call_scope_t& args) { amount_t amt(args.get(1, false)); @@ -360,6 +369,11 @@ expr_t::ptr_op_t session_t::lookup(const symbol_t::kind_t kind, return MAKE_FUNCTOR(session_t::fn_lot_tag); break; + case 'i': + if (is_eq(p, "int")) + return MAKE_FUNCTOR(session_t::fn_int); + break; + case 'm': if (is_eq(p, "min")) return MAKE_FUNCTOR(session_t::fn_min); @@ -367,6 +381,11 @@ expr_t::ptr_op_t session_t::lookup(const symbol_t::kind_t kind, return MAKE_FUNCTOR(session_t::fn_max); break; + case 's': + if (is_eq(p, "str")) + return MAKE_FUNCTOR(session_t::fn_str); + break; + default: break; } diff --git a/src/session.h b/src/session.h index cfeced39..b06c4a42 100644 --- a/src/session.h +++ b/src/session.h @@ -86,6 +86,8 @@ public: value_t fn_account(call_scope_t& scope); value_t fn_min(call_scope_t& scope); value_t fn_max(call_scope_t& scope); + value_t fn_int(call_scope_t& scope); + value_t fn_str(call_scope_t& scope); value_t fn_lot_price(call_scope_t& scope); value_t fn_lot_date(call_scope_t& scope); value_t fn_lot_tag(call_scope_t& scope); -- cgit v1.2.3 From 022059f2a856807cad7388ea230c2ad5bcbce75d Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Fri, 9 Mar 2012 20:11:38 -0600 Subject: Added --value-expr option --- doc/ledger.1 | 1 + src/session.cc | 2 ++ src/session.h | 3 +++ test/baseline/opt-value-expr.test | 0 4 files changed, 6 insertions(+) create mode 100644 test/baseline/opt-value-expr.test (limited to 'src/session.cc') diff --git a/doc/ledger.1 b/doc/ledger.1 index a948d5a6..a8e5dcc4 100644 --- a/doc/ledger.1 +++ b/doc/ledger.1 @@ -424,6 +424,7 @@ appeared in the original journal file. .It Fl \-unrealized-gains .It Fl \-unrealized-losses .It Fl \-unround +.It Fl \-value-expr Ar EXPR .It Fl \-verbose .It Fl \-verify .It Fl \-version diff --git a/src/session.cc b/src/session.cc index 7c546b82..d0cd4573 100644 --- a/src/session.cc +++ b/src/session.cc @@ -112,6 +112,8 @@ std::size_t session_t::read_data(const string& master_account) journal->checking_style = journal_t::CHECK_ERROR; else if (HANDLED(strict)) journal->checking_style = journal_t::CHECK_WARNING; + else if (HANDLED(value_expr)) + journal->value_expr = HANDLER(value_expr).str(); #if defined(HAVE_BOOST_SERIALIZATION) optional cache; diff --git a/src/session.h b/src/session.h index cb981346..f2b1dbef 100644 --- a/src/session.h +++ b/src/session.h @@ -61,6 +61,7 @@ public: unique_ptr journal; parse_context_stack_t parsing_context; + optional value_expr; explicit session_t(); virtual ~session_t() { @@ -107,6 +108,7 @@ public: HANDLER(price_db_).report(out); HANDLER(price_exp_).report(out); HANDLER(strict).report(out); + HANDLER(value_expr).report(out); } option_t * lookup_option(const char * p); @@ -154,6 +156,7 @@ public: OPTION(session_t, permissive); OPTION(session_t, price_db_); OPTION(session_t, strict); + OPTION(session_t, value_expr); }; /** diff --git a/test/baseline/opt-value-expr.test b/test/baseline/opt-value-expr.test new file mode 100644 index 00000000..e69de29b -- cgit v1.2.3 From 5e0efb5e8b117fa7c41d7377b506f386e3bbfefe Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Fri, 9 Mar 2012 20:16:44 -0600 Subject: Fixed options processing of --value-expr --- src/session.cc | 7 +++++-- src/session.h | 4 ++-- 2 files changed, 7 insertions(+), 4 deletions(-) (limited to 'src/session.cc') diff --git a/src/session.cc b/src/session.cc index d0cd4573..76061de7 100644 --- a/src/session.cc +++ b/src/session.cc @@ -112,8 +112,8 @@ std::size_t session_t::read_data(const string& master_account) journal->checking_style = journal_t::CHECK_ERROR; else if (HANDLED(strict)) journal->checking_style = journal_t::CHECK_WARNING; - else if (HANDLED(value_expr)) - journal->value_expr = HANDLER(value_expr).str(); + else if (HANDLED(value_expr_)) + journal->value_expr = HANDLER(value_expr_).str(); #if defined(HAVE_BOOST_SERIALIZATION) optional cache; @@ -345,6 +345,9 @@ option_t * session_t::lookup_option(const char * p) case 's': OPT(strict); break; + case 'v': + OPT(value_expr_); + break; } return NULL; } diff --git a/src/session.h b/src/session.h index f2b1dbef..962664ef 100644 --- a/src/session.h +++ b/src/session.h @@ -108,7 +108,7 @@ public: HANDLER(price_db_).report(out); HANDLER(price_exp_).report(out); HANDLER(strict).report(out); - HANDLER(value_expr).report(out); + HANDLER(value_expr_).report(out); } option_t * lookup_option(const char * p); @@ -156,7 +156,7 @@ public: OPTION(session_t, permissive); OPTION(session_t, price_db_); OPTION(session_t, strict); - OPTION(session_t, value_expr); + OPTION(session_t, value_expr_); }; /** -- cgit v1.2.3 From 22c1b867f03e4a495f9e47c899d1fdfcaec3a659 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Sat, 17 Mar 2012 05:27:43 -0500 Subject: Added option --day-break --- doc/ledger.1 | 3 +- src/journal.cc | 1 + src/journal.h | 1 + src/session.cc | 3 ++ src/session.h | 2 + src/textual.cc | 3 +- src/timelog.cc | 101 ++++++++++++++++++++++++++------------- src/timelog.h | 2 +- test/baseline/opt-day-break.test | 12 +++++ 9 files changed, 91 insertions(+), 37 deletions(-) create mode 100644 test/baseline/opt-day-break.test (limited to 'src/session.cc') diff --git a/doc/ledger.1 b/doc/ledger.1 index 63017452..cd76d5b0 100644 --- a/doc/ledger.1 +++ b/doc/ledger.1 @@ -1,4 +1,4 @@ -.Dd March 13, 2012 +.Dd March 17, 2012 .Dt ledger 1 .Sh NAME .Nm ledger @@ -300,6 +300,7 @@ See .It Fl \-date-format Ar DATEFMT Pq Fl y .It Fl \-datetime-format Ar FMT .It Fl \-date-width Ar INT +.It Fl \-day-break .It Fl \-dc .It Fl \-debug Ar STR .It Fl \-decimal-comma diff --git a/src/journal.cc b/src/journal.cc index 37eacdaf..be6a8e51 100644 --- a/src/journal.cc +++ b/src/journal.cc @@ -94,6 +94,7 @@ void journal_t::initialize() was_loaded = false; force_checking = false; check_payees = false; + day_break = false; checking_style = CHECK_PERMISSIVE; } diff --git a/src/journal.h b/src/journal.h index ca73c415..759826a0 100644 --- a/src/journal.h +++ b/src/journal.h @@ -130,6 +130,7 @@ public: bool was_loaded; bool force_checking; bool check_payees; + bool day_break; payee_mappings_t payee_mappings; account_mappings_t account_mappings; accounts_map account_aliases; diff --git a/src/session.cc b/src/session.cc index 76061de7..5c9e4fd4 100644 --- a/src/session.cc +++ b/src/session.cc @@ -105,6 +105,8 @@ std::size_t session_t::read_data(const string& master_account) journal->force_checking = true; if (HANDLED(check_payees)) journal->check_payees = true; + if (HANDLED(day_break)) + journal->day_break = true; if (HANDLED(permissive)) journal->checking_style = journal_t::CHECK_PERMISSIVE; @@ -320,6 +322,7 @@ option_t * session_t::lookup_option(const char * p) case 'd': OPT(download); // -Q else OPT(decimal_comma); + else OPT(day_break); break; case 'e': OPT(explicit); diff --git a/src/session.h b/src/session.h index 962664ef..a0aba91b 100644 --- a/src/session.h +++ b/src/session.h @@ -97,6 +97,7 @@ public: { HANDLER(cache_).report(out); HANDLER(check_payees).report(out); + HANDLER(day_break).report(out); HANDLER(download).report(out); HANDLER(decimal_comma).report(out); HANDLER(file_).report(out); @@ -122,6 +123,7 @@ public: OPTION(session_t, cache_); OPTION(session_t, check_payees); + OPTION(session_t, day_break); OPTION(session_t, download); // -Q OPTION_(session_t, decimal_comma, DO() { diff --git a/src/textual.cc b/src/textual.cc index 3555ea4d..8856af5d 100644 --- a/src/textual.cc +++ b/src/textual.cc @@ -486,8 +486,7 @@ void instance_t::clock_out_directive(char * line, bool /*capitalized*/) n ? n : "", end ? end : ""); - timelog.clock_out(event); - context.count++; + context.count += timelog.clock_out(event); } #endif // TIMELOG_SUPPORT diff --git a/src/timelog.cc b/src/timelog.cc index 00cefe10..e84e4188 100644 --- a/src/timelog.cc +++ b/src/timelog.cc @@ -41,9 +41,43 @@ namespace ledger { namespace { - void clock_out_from_timelog(std::list& time_xacts, - time_xact_t out_event, - parse_context_t& context) + void create_timelog_xact(const time_xact_t& in_event, + const time_xact_t& out_event, + parse_context_t& context) + { + unique_ptr curr(new xact_t); + curr->_date = in_event.checkin.date(); + curr->code = out_event.desc; // if it wasn't used above + curr->payee = in_event.desc; + curr->pos = in_event.position; + + if (! in_event.note.empty()) + curr->append_note(in_event.note.c_str(), *context.scope); + + char buf[32]; + std::sprintf(buf, "%lds", long((out_event.checkin - in_event.checkin) + .total_seconds())); + amount_t amt; + amt.parse(buf); + VERIFY(amt.valid()); + + post_t * post = new post_t(in_event.account, amt, POST_VIRTUAL); + post->set_state(item_t::CLEARED); + post->pos = in_event.position; + post->checkin = in_event.checkin; + post->checkout = out_event.checkin; + curr->add_post(post); + in_event.account->add_post(post); + + if (! context.journal->add_xact(curr.get())) + throw parse_error(_("Failed to record 'out' timelog transaction")); + else + curr.release(); + } + + std::size_t clock_out_from_timelog(std::list& time_xacts, + time_xact_t out_event, + parse_context_t& context) { time_xact_t event; @@ -93,34 +127,35 @@ namespace { if (! out_event.note.empty() && event.note.empty()) event.note = out_event.note; - unique_ptr curr(new xact_t); - curr->_date = event.checkin.date(); - curr->code = out_event.desc; // if it wasn't used above - curr->payee = event.desc; - curr->pos = event.position; - - if (! event.note.empty()) - curr->append_note(event.note.c_str(), *context.scope); - - char buf[32]; - std::sprintf(buf, "%lds", long((out_event.checkin - event.checkin) - .total_seconds())); - amount_t amt; - amt.parse(buf); - VERIFY(amt.valid()); - - post_t * post = new post_t(event.account, amt, POST_VIRTUAL); - post->set_state(item_t::CLEARED); - post->pos = event.position; - post->checkin = event.checkin; - post->checkout = out_event.checkin; - curr->add_post(post); - event.account->add_post(post); - - if (! context.journal->add_xact(curr.get())) - throw parse_error(_("Failed to record 'out' timelog transaction")); - else - curr.release(); + if (! context.journal->day_break) { + create_timelog_xact(event, out_event, context); + return 1; + } else { + time_xact_t begin(event); + std::size_t xact_count = 0; + + while (begin.checkin < out_event.checkin) { + DEBUG("timelog", "begin.checkin: " << begin.checkin); + datetime_t days_end(begin.checkin.date(), time_duration_t(23, 59, 59)); + days_end += seconds(1); + DEBUG("timelog", "days_end: " << days_end); + + if (out_event.checkin <= days_end) { + create_timelog_xact(begin, out_event, context); + ++xact_count; + break; + } else { + time_xact_t end(out_event); + end.checkin = days_end; + DEBUG("timelog", "end.checkin: " << end.checkin); + create_timelog_xact(begin, end, context); + ++xact_count; + + begin.checkin = end.checkin; + } + } + return xact_count; + } } } // unnamed namespace @@ -155,12 +190,12 @@ void time_log_t::clock_in(time_xact_t event) time_xacts.push_back(event); } -void time_log_t::clock_out(time_xact_t event) +std::size_t time_log_t::clock_out(time_xact_t event) { if (time_xacts.empty()) throw std::logic_error(_("Timelog check-out event without a check-in")); - clock_out_from_timelog(time_xacts, event, context); + return clock_out_from_timelog(time_xacts, event, context); } } // namespace ledger diff --git a/src/timelog.h b/src/timelog.h index ed5a2d36..857952ff 100644 --- a/src/timelog.h +++ b/src/timelog.h @@ -98,7 +98,7 @@ public: } void clock_in(time_xact_t event); - void clock_out(time_xact_t event); + std::size_t clock_out(time_xact_t event); void close(); }; diff --git a/test/baseline/opt-day-break.test b/test/baseline/opt-day-break.test new file mode 100644 index 00000000..18dde546 --- /dev/null +++ b/test/baseline/opt-day-break.test @@ -0,0 +1,12 @@ +i 05/10/2011 08:58:37 682 +o 05/12/2011 11:25:21 + +test reg --base +11-May-10 (682) 181604s 181604s +end test + +test reg --base --day-break +11-May-10 (682) 54083s 54083s +11-May-11 (682) 86400s 140483s +11-May-12 (682) 41121s 181604s +end test -- cgit v1.2.3 From 22505d9527edce59cd3cf90c5241e4bd809eb8a2 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Tue, 20 Mar 2012 02:10:40 -0500 Subject: Always call TRACE_CTOR at the end of constructors --- src/amount.cc | 10 +++++----- src/amount.h | 8 ++++---- src/annotate.h | 2 +- src/balance.cc | 6 +++--- src/balance.h | 6 +++--- src/csv.h | 2 +- src/draft.h | 2 +- src/expr.cc | 4 ++-- src/filters.cc | 12 ++++++------ src/filters.h | 15 +++++++-------- src/format.h | 2 +- src/generate.cc | 3 +-- src/global.cc | 4 ++-- src/item.h | 4 ++-- src/iterators.h | 14 +++++++------- src/journal.cc | 6 +++--- src/journal.h | 2 +- src/mask.cc | 2 +- src/option.h | 2 +- src/org.cc | 4 ++-- src/output.cc | 8 ++++---- src/pool.cc | 2 +- src/post.h | 2 +- src/pstream.h | 8 ++++---- src/pyfstream.h | 8 ++++---- src/query.h | 8 +++++--- src/scope.h | 2 +- src/session.cc | 4 ++-- src/times.h | 5 +++-- src/unistring.h | 4 ++-- src/utils.cc | 12 +++++++----- src/value.h | 34 ++++++++++++++++++---------------- 32 files changed, 106 insertions(+), 101 deletions(-) (limited to 'src/session.cc') diff --git a/src/amount.cc b/src/amount.cc index 5fa58528..8c5ae574 100644 --- a/src/amount.cc +++ b/src/amount.cc @@ -63,16 +63,16 @@ struct amount_t::bigint_t : public supports_flags<> #define MP(bigint) ((bigint)->val) bigint_t() : prec(0), refc(1) { - TRACE_CTOR(bigint_t, ""); mpq_init(val); + TRACE_CTOR(bigint_t, ""); } bigint_t(const bigint_t& other) : supports_flags<>(static_cast (other.flags() & ~BIGINT_BULK_ALLOC)), prec(other.prec), refc(1) { - TRACE_CTOR(bigint_t, "copy"); mpq_init(val); mpq_set(val, other.val); + TRACE_CTOR(bigint_t, "copy"); } ~bigint_t() { TRACE_DTOR(bigint_t); @@ -349,24 +349,24 @@ void amount_t::_release() amount_t::amount_t(const double val) : commodity_(NULL) { - TRACE_CTOR(amount_t, "const double"); quantity = new bigint_t; mpq_set_d(MP(quantity), val); quantity->prec = extend_by_digits; // an approximation + TRACE_CTOR(amount_t, "const double"); } amount_t::amount_t(const unsigned long val) : commodity_(NULL) { - TRACE_CTOR(amount_t, "const unsigned long"); quantity = new bigint_t; mpq_set_ui(MP(quantity), val, 1); + TRACE_CTOR(amount_t, "const unsigned long"); } amount_t::amount_t(const long val) : commodity_(NULL) { - TRACE_CTOR(amount_t, "const long"); quantity = new bigint_t; mpq_set_si(MP(quantity), val, 1); + TRACE_CTOR(amount_t, "const long"); } diff --git a/src/amount.h b/src/amount.h index 903a01cd..10e83552 100644 --- a/src/amount.h +++ b/src/amount.h @@ -155,17 +155,17 @@ public: commodity_t::null_commodity. The number may be of infinite precision. */ explicit amount_t(const string& val) : quantity(NULL) { - TRACE_CTOR(amount_t, "const string&"); parse(val); + TRACE_CTOR(amount_t, "const string&"); } /** Parse a pointer to a C string as an (optionally commoditized) amount. If no commodity is present, the resulting commodity is \c commodity_t::null_commodity. The number may be of infinite precision. */ explicit amount_t(const char * val) : quantity(NULL) { - TRACE_CTOR(amount_t, "const char *"); assert(val); parse(val); + TRACE_CTOR(amount_t, "const char *"); } /*@}*/ @@ -195,21 +195,21 @@ public: same memory used by the original via reference counting. The \c amount_t::bigint_t class in amount.cc maintains the reference. */ amount_t(const amount_t& amt) : quantity(NULL) { - TRACE_CTOR(amount_t, "copy"); if (amt.quantity) _copy(amt); else commodity_ = NULL; + TRACE_CTOR(amount_t, "copy"); } /** Copy an amount object, applying the given commodity annotation details afterward. This is equivalent to doing a normal copy (@see amount_t(const amount_t&)) and then calling amount_t::annotate(). */ amount_t(const amount_t& amt, const annotation_t& details) : quantity(NULL) { - TRACE_CTOR(amount_t, "const amount_t&, const annotation_t&"); assert(amt.quantity); _copy(amt); annotate(details); + TRACE_CTOR(amount_t, "const amount_t&, const annotation_t&"); } /** Assign an amount object. This is like copying if the amount was null beforehand, otherwise the previous value's reference is must diff --git a/src/annotate.h b/src/annotate.h index 163ffac5..85a34662 100644 --- a/src/annotate.h +++ b/src/annotate.h @@ -226,9 +226,9 @@ protected: explicit annotated_commodity_t(commodity_t * _ptr, const annotation_t& _details) : commodity_t(_ptr->parent_, _ptr->base), ptr(_ptr), details(_details) { - TRACE_CTOR(annotated_commodity_t, "commodity_t *, annotation_t"); annotated = true; qualified_symbol = _ptr->qualified_symbol; + TRACE_CTOR(annotated_commodity_t, "commodity_t *, annotation_t"); } public: diff --git a/src/balance.cc b/src/balance.cc index f87e8bbd..5c57cd99 100644 --- a/src/balance.cc +++ b/src/balance.cc @@ -41,23 +41,23 @@ namespace ledger { balance_t::balance_t(const double val) { - TRACE_CTOR(balance_t, "const double"); amounts.insert (amounts_map::value_type(commodity_pool_t::current_pool->null_commodity, val)); + TRACE_CTOR(balance_t, "const double"); } balance_t::balance_t(const unsigned long val) { - TRACE_CTOR(balance_t, "const unsigned long"); amounts.insert (amounts_map::value_type(commodity_pool_t::current_pool->null_commodity, val)); + TRACE_CTOR(balance_t, "const unsigned long"); } balance_t::balance_t(const long val) { - TRACE_CTOR(balance_t, "const long"); amounts.insert (amounts_map::value_type(commodity_pool_t::current_pool->null_commodity, val)); + TRACE_CTOR(balance_t, "const long"); } balance_t& balance_t::operator+=(const balance_t& bal) diff --git a/src/balance.h b/src/balance.h index 5f0d52ed..11c370bb 100644 --- a/src/balance.h +++ b/src/balance.h @@ -108,26 +108,26 @@ public: TRACE_CTOR(balance_t, ""); } balance_t(const amount_t& amt) { - TRACE_CTOR(balance_t, "const amount_t&"); if (amt.is_null()) throw_(balance_error, _("Cannot initialize a balance from an uninitialized amount")); if (! amt.is_realzero()) amounts.insert(amounts_map::value_type(&amt.commodity(), amt)); + TRACE_CTOR(balance_t, "const amount_t&"); } balance_t(const double val); balance_t(const unsigned long val); balance_t(const long val); explicit balance_t(const string& val) { - TRACE_CTOR(balance_t, "const string&"); amount_t temp(val); amounts.insert(amounts_map::value_type(&temp.commodity(), temp)); + TRACE_CTOR(balance_t, "const string&"); } explicit balance_t(const char * val) { - TRACE_CTOR(balance_t, "const char *"); amount_t temp(val); amounts.insert(amounts_map::value_type(&temp.commodity(), temp)); + TRACE_CTOR(balance_t, "const char *"); } /** diff --git a/src/csv.h b/src/csv.h index d98c0567..7d5098d2 100644 --- a/src/csv.h +++ b/src/csv.h @@ -91,8 +91,8 @@ public: cost_mask("cost"), total_mask("total"), note_mask("note") { - TRACE_CTOR(csv_reader, "parse_context_t&"); read_index(*context.stream.get()); + TRACE_CTOR(csv_reader, "parse_context_t&"); } ~csv_reader() { TRACE_DTOR(csv_reader); diff --git a/src/draft.h b/src/draft.h index e5d29134..46aa26e1 100644 --- a/src/draft.h +++ b/src/draft.h @@ -92,9 +92,9 @@ class draft_t : public expr_base_t public: draft_t(const value_t& args) : base_type() { - TRACE_CTOR(draft_t, "value_t"); if (! args.empty()) parse_args(args); + TRACE_CTOR(draft_t, "value_t"); } virtual ~draft_t() throw() { TRACE_DTOR(draft_t); diff --git a/src/expr.cc b/src/expr.cc index b22572f8..25967207 100644 --- a/src/expr.cc +++ b/src/expr.cc @@ -55,16 +55,16 @@ expr_t::expr_t(ptr_op_t _ptr, scope_t * _context) expr_t::expr_t(const string& _str, const parse_flags_t& flags) : base_type() { - TRACE_CTOR(expr_t, "string, parse_flags_t"); if (! _str.empty()) parse(_str, flags); + TRACE_CTOR(expr_t, "string, parse_flags_t"); } expr_t::expr_t(std::istream& in, const parse_flags_t& flags) : base_type() { - TRACE_CTOR(expr_t, "std::istream&, parse_flags_t"); parse(in, flags); + TRACE_CTOR(expr_t, "std::istream&, parse_flags_t"); } expr_t::~expr_t() { diff --git a/src/filters.cc b/src/filters.cc index 73ee200d..5915ad3c 100644 --- a/src/filters.cc +++ b/src/filters.cc @@ -512,8 +512,8 @@ display_filter_posts::display_filter_posts(post_handler_ptr handler, display_total_expr(report.HANDLER(display_total_).expr), show_rounding(_show_rounding) { - TRACE_CTOR(display_filter_posts, "post_handler_ptr, report_t&, bool"); create_accounts(); + TRACE_CTOR(display_filter_posts, "post_handler_ptr, report_t&, bool"); } bool display_filter_posts::output_rounding(post_t& post) @@ -598,9 +598,6 @@ changed_value_posts::changed_value_posts show_unrealized(_show_unrealized), last_post(NULL), display_filter(_display_filter) { - TRACE_CTOR(changed_value_posts, - "post_handler_ptr, report_t&, bool, bool, display_filter_posts *"); - string gains_equity_account_name; if (report.HANDLED(unrealized_gains_)) gains_equity_account_name = report.HANDLER(unrealized_gains_).str(); @@ -620,6 +617,9 @@ changed_value_posts::changed_value_posts losses_equity_account->add_flags(ACCOUNT_GENERATED); create_accounts(); + + TRACE_CTOR(changed_value_posts, + "post_handler_ptr, report_t&, bool, bool, display_filter_posts *"); } void changed_value_posts::flush() @@ -1417,8 +1417,6 @@ inject_posts::inject_posts(post_handler_ptr handler, account_t * master) : item_handler(handler) { - TRACE_CTOR(inject_posts, "post_handler_ptr, string, account_t *"); - scoped_array buf(new char[tag_list.length() + 1]); std::strcpy(buf.get(), tag_list.c_str()); @@ -1435,6 +1433,8 @@ inject_posts::inject_posts(post_handler_ptr handler, tags_list.push_back (tags_list_pair(q, tag_mapping_pair(account, tag_injected_set()))); } + + TRACE_CTOR(inject_posts, "post_handler_ptr, string, account_t *"); } void inject_posts::operator()(post_t& post) diff --git a/src/filters.h b/src/filters.h index 3e766863..ab226429 100644 --- a/src/filters.h +++ b/src/filters.h @@ -75,8 +75,8 @@ public: expr_t& _group_by_expr) : post_chain(_post_chain), report(_report), group_by_expr(_group_by_expr) { + preflush_func = bind(&post_splitter::print_title, this, _1); TRACE_CTOR(post_splitter, "scope_t&, post_handler_ptr, expr_t"); - preflush_func = bind(&post_splitter::print_title, this, _1); } virtual ~post_splitter() { TRACE_DTOR(post_splitter); @@ -154,8 +154,6 @@ class pass_down_posts : public item_handler public: pass_down_posts(post_handler_ptr handler, Iterator& iter) : item_handler(handler) { - TRACE_CTOR(pass_down_posts, "post_handler_ptr, posts_iterator"); - while (post_t * post = *iter) { try { item_handler::operator()(*post); @@ -168,6 +166,8 @@ public: } item_handler::flush(); + + TRACE_CTOR(pass_down_posts, "post_handler_ptr, posts_iterator"); } virtual ~pass_down_posts() { @@ -448,8 +448,8 @@ public: only_predicate(_only_predicate), count(0), last_xact(NULL), last_post(NULL), only_collapse_if_zero(_only_collapse_if_zero), report(_report) { - TRACE_CTOR(collapse_posts, "post_handler_ptr, ..."); create_accounts(); + TRACE_CTOR(collapse_posts, "post_handler_ptr, ..."); } virtual ~collapse_posts() { TRACE_DTOR(collapse_posts); @@ -499,8 +499,7 @@ public: const bool _also_matching = false) : item_handler(handler), also_matching(_also_matching) { - TRACE_CTOR(related_posts, - "post_handler_ptr, const bool"); + TRACE_CTOR(related_posts, "post_handler_ptr, const bool"); } virtual ~related_posts() throw() { TRACE_DTOR(related_posts); @@ -722,9 +721,9 @@ public: : subtotal_posts(_handler, amount_expr), start_interval(_interval), interval(start_interval), exact_periods(_exact_periods), generate_empty_posts(_generate_empty_posts) { + create_accounts(); TRACE_CTOR(interval_posts, "post_handler_ptr, expr_t&, date_interval_t, bool, bool"); - create_accounts(); } virtual ~interval_posts() throw() { TRACE_DTOR(interval_posts); @@ -774,8 +773,8 @@ public: posts_as_equity(post_handler_ptr _handler, report_t& _report, expr_t& amount_expr) : subtotal_posts(_handler, amount_expr), report(_report) { - TRACE_CTOR(posts_as_equity, "post_handler_ptr, expr_t&"); create_accounts(); + TRACE_CTOR(posts_as_equity, "post_handler_ptr, expr_t&"); } virtual ~posts_as_equity() throw() { TRACE_DTOR(posts_as_equity); diff --git a/src/format.h b/src/format.h index 60ae2abe..cc48bdda 100644 --- a/src/format.h +++ b/src/format.h @@ -125,9 +125,9 @@ public: } format_t(const string& _str, scope_t * context = NULL) : base_type(context) { - TRACE_CTOR(format_t, "const string&"); if (! _str.empty()) parse_format(_str); + TRACE_CTOR(format_t, "const string&"); } virtual ~format_t() { TRACE_DTOR(format_t); diff --git a/src/generate.cc b/src/generate.cc index edd58632..8769c99c 100644 --- a/src/generate.cc +++ b/src/generate.cc @@ -63,8 +63,6 @@ generate_posts_iterator::generate_posts_iterator neg_number_range(-10000, -1), neg_number_gen(rnd_gen, neg_number_range), pos_number_range(1, 10000), pos_number_gen(rnd_gen, pos_number_range) { - TRACE_CTOR(generate_posts_iterator, "bool"); - std::ostringstream next_date_buf; generate_date(next_date_buf); next_date = parse_date(next_date_buf.str()); @@ -73,6 +71,7 @@ generate_posts_iterator::generate_posts_iterator generate_date(next_aux_date_buf); next_aux_date = parse_date(next_aux_date_buf.str()); + TRACE_CTOR(generate_posts_iterator, "bool"); } void generate_posts_iterator::generate_string(std::ostream& out, int len, diff --git a/src/global.cc b/src/global.cc index b5ceb614..6dc8d150 100644 --- a/src/global.cc +++ b/src/global.cc @@ -47,8 +47,6 @@ static bool args_only = false; global_scope_t::global_scope_t(char ** envp) { - TRACE_CTOR(global_scope_t, ""); - epoch = CURRENT_TIME(); #if defined(HAVE_BOOST_PYTHON) @@ -89,6 +87,8 @@ global_scope_t::global_scope_t(char ** envp) } else { session().HANDLER(price_db_).off(); } + + TRACE_CTOR(global_scope_t, ""); } global_scope_t::~global_scope_t() diff --git a/src/item.h b/src/item.h index e7415918..a1160329 100644 --- a/src/item.h +++ b/src/item.h @@ -60,8 +60,8 @@ struct position_t TRACE_CTOR(position_t, ""); } position_t(const position_t& pos) { - TRACE_CTOR(position_t, "copy"); *this = pos; + TRACE_CTOR(position_t, "copy"); } ~position_t() throw() { TRACE_DTOR(position_t); @@ -125,8 +125,8 @@ public: } item_t(const item_t& item) : supports_flags(), scope_t() { - TRACE_CTOR(item_t, "copy"); copy_details(item); + TRACE_CTOR(item_t, "copy"); } virtual ~item_t() { TRACE_DTOR(item_t); diff --git a/src/iterators.h b/src/iterators.h index 922ebccd..53814666 100644 --- a/src/iterators.h +++ b/src/iterators.h @@ -100,8 +100,8 @@ public: } xact_posts_iterator(xact_t& xact) : posts_uninitialized(true) { - TRACE_CTOR(xact_posts_iterator, "xact_t&"); reset(xact); + TRACE_CTOR(xact_posts_iterator, "xact_t&"); } xact_posts_iterator(const xact_posts_iterator& i) : iterator_facade_base& _prepend_format) : report(_report), last_xact(NULL), last_post(NULL) { - TRACE_CTOR(posts_to_org_table, "report&, optional"); - first_line_format.parse_format ("|%(format_date(date))" "|%(code)" @@ -79,6 +77,8 @@ posts_to_org_table::posts_to_org_table(report_t& _report, if (_prepend_format) prepend_format.parse_format(*_prepend_format); + + TRACE_CTOR(posts_to_org_table, "report&, optional"); } void posts_to_org_table::flush() diff --git a/src/output.cc b/src/output.cc index aaf81f60..742000bd 100644 --- a/src/output.cc +++ b/src/output.cc @@ -47,8 +47,6 @@ format_posts::format_posts(report_t& _report, : report(_report), prepend_width(_prepend_width), last_xact(NULL), last_post(NULL), first_report_title(true) { - TRACE_CTOR(format_posts, "report&, const string&, bool"); - const char * f = format.c_str(); if (const char * p = std::strstr(f, "%/")) { @@ -70,6 +68,8 @@ format_posts::format_posts(report_t& _report, if (_prepend_format) prepend_format.parse_format(*_prepend_format); + + TRACE_CTOR(format_posts, "report&, const string&, bool"); } void format_posts::flush() @@ -131,8 +131,6 @@ format_accounts::format_accounts(report_t& _report, : report(_report), prepend_width(_prepend_width), disp_pred(), first_report_title(true) { - TRACE_CTOR(format_accounts, "report&, const string&"); - const char * f = format.c_str(); if (const char * p = std::strstr(f, "%/")) { @@ -154,6 +152,8 @@ format_accounts::format_accounts(report_t& _report, if (_prepend_format) prepend_format.parse_format(*_prepend_format); + + TRACE_CTOR(format_accounts, "report&, const string&"); } std::size_t format_accounts::post_account(account_t& account, const bool flat) diff --git a/src/pool.cc b/src/pool.cc index be26de3b..61b5bef2 100644 --- a/src/pool.cc +++ b/src/pool.cc @@ -47,9 +47,9 @@ commodity_pool_t::commodity_pool_t() quote_leeway(86400), get_quotes(false), get_commodity_quote(commodity_quote_from_script) { - TRACE_CTOR(commodity_pool_t, ""); null_commodity = create(""); null_commodity->add_flags(COMMODITY_BUILTIN | COMMODITY_NOMARKET); + TRACE_CTOR(commodity_pool_t, ""); } commodity_t * commodity_pool_t::create(const string& symbol) diff --git a/src/post.h b/src/post.h index d6004c9f..76a89a33 100644 --- a/src/post.h +++ b/src/post.h @@ -96,8 +96,8 @@ public: assigned_amount(post.assigned_amount), xdata_(post.xdata_) { - TRACE_CTOR(post_t, "copy"); copy_details(post); + TRACE_CTOR(post_t, "copy"); } virtual ~post_t() { TRACE_DTOR(post_t); diff --git a/src/pstream.h b/src/pstream.h index dfb27056..6e38158a 100644 --- a/src/pstream.h +++ b/src/pstream.h @@ -58,14 +58,14 @@ class ptristream : public std::istream public: ptrinbuf(char * _ptr, std::size_t _len) : ptr(_ptr), len(_len) { - TRACE_CTOR(ptrinbuf, "char *, std::size_t"); - if (*ptr && len == 0) len = std::strlen(ptr); - setg(ptr, // beginning of putback area - ptr, // read position + setg(ptr, // beginning of putback area + ptr, // read position ptr+len); // end position + + TRACE_CTOR(ptrinbuf, "char *, std::size_t"); } ~ptrinbuf() throw() { TRACE_DTOR(ptrinbuf); diff --git a/src/pyfstream.h b/src/pyfstream.h index 972f976f..18f28bc4 100644 --- a/src/pyfstream.h +++ b/src/pyfstream.h @@ -86,8 +86,8 @@ protected: public: pyofstream (PyFileObject * fo) : std::ostream(0), buf(fo) { - TRACE_CTOR(pyofstream, "PyFileObject *"); rdbuf(&buf); + TRACE_CTOR(pyofstream, "PyFileObject *"); } ~pyofstream() throw() { TRACE_DTOR(pyofstream); @@ -121,11 +121,11 @@ public: * => force underflow() */ pyinbuf (PyFileObject * _fo) : fo(_fo) { - TRACE_CTOR(pyinbuf, "PyFileObject *"); - setg (buffer+pbSize, // beginning of putback area buffer+pbSize, // read position buffer+pbSize); // end position + + TRACE_CTOR(pyinbuf, "PyFileObject *"); } ~pyinbuf() throw() { TRACE_DTOR(pyinbuf); @@ -191,8 +191,8 @@ protected: public: pyifstream (PyFileObject * fo) : std::istream(0), buf(fo) { - TRACE_CTOR(pyifstream, "PyFileObject *"); rdbuf(&buf); + TRACE_CTOR(pyifstream, "PyFileObject *"); } ~pyifstream() throw() { TRACE_DTOR(pyifstream); diff --git a/src/query.h b/src/query.h index c694d099..fe52eb35 100644 --- a/src/query.h +++ b/src/query.h @@ -204,10 +204,11 @@ public: consume_whitespace(false), consume_next_arg(false), multiple_args(_multiple_args) { - TRACE_CTOR(query_t::lexer_t, ""); assert(begin != end); arg_i = (*begin).as_string().begin(); arg_end = (*begin).as_string().end(); + + TRACE_CTOR(query_t::lexer_t, ""); } lexer_t(const lexer_t& lexer) : begin(lexer.begin), end(lexer.end), @@ -302,18 +303,19 @@ public: query_t(const string& arg, const keep_details_t& what_to_keep = keep_details_t(), bool multiple_args = true) { - TRACE_CTOR(query_t, "string, keep_details_t, bool"); if (! arg.empty()) { value_t temp(string_value(arg)); parse_args(temp.to_sequence(), what_to_keep, multiple_args); } + TRACE_CTOR(query_t, "string, keep_details_t, bool"); } query_t(const value_t& args, const keep_details_t& what_to_keep = keep_details_t(), bool multiple_args = true) { - TRACE_CTOR(query_t, "value_t, keep_details_t, bool"); if (! args.empty()) parse_args(args, what_to_keep, multiple_args); + + TRACE_CTOR(query_t, "value_t, keep_details_t, bool"); } virtual ~query_t() { TRACE_DTOR(query_t); diff --git a/src/scope.h b/src/scope.h index 9318fc5c..acaf7194 100644 --- a/src/scope.h +++ b/src/scope.h @@ -209,9 +209,9 @@ public: explicit bind_scope_t(scope_t& _parent, scope_t& _grandchild) : child_scope_t(_parent), grandchild(_grandchild) { - TRACE_CTOR(bind_scope_t, "scope_t&, scope_t&"); DEBUG("scope.symbols", "Binding scope " << &_parent << " with " << &_grandchild); + TRACE_CTOR(bind_scope_t, "scope_t&, scope_t&"); } virtual ~bind_scope_t() { TRACE_DTOR(bind_scope_t); diff --git a/src/session.cc b/src/session.cc index 5c9e4fd4..9a77d341 100644 --- a/src/session.cc +++ b/src/session.cc @@ -62,14 +62,14 @@ void set_session_context(session_t * session) session_t::session_t() : flush_on_next_data_file(false), journal(new journal_t) { - TRACE_CTOR(session_t, ""); - if (const char * home_var = std::getenv("HOME")) HANDLER(price_db_).on(none, (path(home_var) / ".pricedb").string()); else HANDLER(price_db_).on(none, path("./.pricedb").string()); parsing_context.push(); + + TRACE_CTOR(session_t, ""); } std::size_t session_t::read_data(const string& master_account) diff --git a/src/times.h b/src/times.h index e3134665..3bb95903 100644 --- a/src/times.h +++ b/src/times.h @@ -307,13 +307,14 @@ public: } date_specifier_t(const date_t& date, const optional& traits = none) { - TRACE_CTOR(date_specifier_t, "date_t, date_traits_t"); if (! traits || traits->has_year) year = date.year(); if (! traits || traits->has_month) month = date.month(); if (! traits || traits->has_day) day = date.day(); + + TRACE_CTOR(date_specifier_t, "date_t, date_traits_t"); } date_specifier_t(const date_specifier_t& other) : year(other.year), month(other.month), @@ -538,8 +539,8 @@ public: TRACE_CTOR(date_interval_t, ""); } date_interval_t(const string& str) : aligned(false) { - TRACE_CTOR(date_interval_t, "const string&"); parse(str); + TRACE_CTOR(date_interval_t, "const string&"); } date_interval_t(const date_interval_t& other) : range(other.range), diff --git a/src/unistring.h b/src/unistring.h index a33c6e3f..b2278796 100644 --- a/src/unistring.h +++ b/src/unistring.h @@ -64,14 +64,14 @@ public: } unistring(const std::string& input) { - TRACE_CTOR(unistring, "std::string"); - const char * p = input.c_str(); std::size_t len = input.length(); assert(len < 1024); VERIFY(utf8::is_valid(p, p + len)); utf8::unchecked::utf8to32(p, p + len, std::back_inserter(utf32chars)); + + TRACE_CTOR(unistring, "std::string"); } ~unistring() { TRACE_DTOR(unistring); diff --git a/src/utils.cc b/src/utils.cc index 5a364008..17118904 100644 --- a/src/utils.cc +++ b/src/utils.cc @@ -278,16 +278,18 @@ namespace { buf << num; + string number(buf.str()); + int integer_digits = 0; // Count the number of integer digits - for (const char * p = buf.str().c_str(); *p; p++) { + for (const char * p = number.c_str(); *p; p++) { if (*p == '.') break; else if (*p != '-') integer_digits++; } - for (const char * p = buf.str().c_str(); *p; p++) { + for (const char * p = number.c_str(); *p; p++) { if (*p == '.') { obuf << *p; assert(integer_digits <= 3); @@ -335,7 +337,7 @@ namespace { void report_count_map(std::ostream& out, object_count_map& the_map) { foreach (object_count_map::value_type& pair, the_map) { - out << " " << std::right << std::setw(12); + out << " " << std::right << std::setw(18); stream_commified_number(out, pair.second.first); out << " " << std::right << std::setw(7); stream_memory_size(out, pair.second.second); @@ -433,7 +435,7 @@ void report_memory(std::ostream& out, bool report_all) out << "Live memory:" << std::endl; foreach (const memory_map::value_type& pair, *live_memory) { - out << " " << std::right << std::setw(12) << pair.first + out << " " << std::right << std::setw(18) << pair.first << " " << std::right << std::setw(7); stream_memory_size(out, pair.second.second); out << " " << std::left << pair.second.first @@ -455,7 +457,7 @@ void report_memory(std::ostream& out, bool report_all) out << "Live objects:" << std::endl; foreach (const objects_map::value_type& pair, *live_objects) { - out << " " << std::right << std::setw(12) << pair.first + out << " " << std::right << std::setw(18) << pair.first << " " << std::right << std::setw(7); stream_memory_size(out, pair.second.second); out << " " << std::left << pair.second.first diff --git a/src/value.h b/src/value.h index a95968c2..d128bb89 100644 --- a/src/value.h +++ b/src/value.h @@ -179,8 +179,8 @@ public: */ explicit storage_t(const storage_t& rhs) : type(rhs.type), refc(0) { - TRACE_CTOR(value_t::storage_t, "copy"); *this = rhs; + TRACE_CTOR(value_t::storage_t, "copy"); } storage_t& operator=(const storage_t& rhs); @@ -290,73 +290,75 @@ public: } value_t(const bool val) { - TRACE_CTOR(value_t, "const bool"); set_boolean(val); + TRACE_CTOR(value_t, "const bool"); } value_t(const datetime_t& val) { - TRACE_CTOR(value_t, "const datetime_t&"); set_datetime(val); + TRACE_CTOR(value_t, "const datetime_t&"); } value_t(const date_t& val) { - TRACE_CTOR(value_t, "const date_t&"); set_date(val); + TRACE_CTOR(value_t, "const date_t&"); } value_t(const long val) { - TRACE_CTOR(value_t, "const long"); set_long(val); + TRACE_CTOR(value_t, "const long"); } value_t(const unsigned long val) { - TRACE_CTOR(value_t, "const unsigned long"); set_amount(val); + TRACE_CTOR(value_t, "const unsigned long"); } value_t(const double val) { - TRACE_CTOR(value_t, "const double"); set_amount(val); + TRACE_CTOR(value_t, "const double"); } value_t(const amount_t& val) { - TRACE_CTOR(value_t, "const amount_t&"); set_amount(val); + TRACE_CTOR(value_t, "const amount_t&"); } value_t(const balance_t& val) { - TRACE_CTOR(value_t, "const balance_t&"); set_balance(val); + TRACE_CTOR(value_t, "const balance_t&"); } value_t(const mask_t& val) { - TRACE_CTOR(value_t, "const mask_t&"); set_mask(val); + TRACE_CTOR(value_t, "const mask_t&"); } explicit value_t(const string& val, bool literal = false) { - TRACE_CTOR(value_t, "const string&, bool"); if (literal) set_string(val); else set_amount(amount_t(val)); + + TRACE_CTOR(value_t, "const string&, bool"); } explicit value_t(const char * val, bool literal = false) { - TRACE_CTOR(value_t, "const char *"); if (literal) set_string(val); else set_amount(amount_t(val)); + + TRACE_CTOR(value_t, "const char *"); } value_t(const sequence_t& val) { - TRACE_CTOR(value_t, "const sequence_t&"); set_sequence(val); + TRACE_CTOR(value_t, "const sequence_t&"); } explicit value_t(scope_t * item) { - TRACE_CTOR(value_t, "scope_t *"); set_scope(item); + TRACE_CTOR(value_t, "scope_t *"); } #if 0 template explicit value_t(T& item) { - TRACE_CTOR(value_t, "T&"); set_any(item); + TRACE_CTOR(value_t, "T&"); } #endif @@ -375,8 +377,8 @@ public: * object. A true copy is only ever made prior to modification. */ value_t(const value_t& val) { - TRACE_CTOR(value_t, "copy"); *this = val; + TRACE_CTOR(value_t, "copy"); } value_t& operator=(const value_t& val) { if (! (this == &val || storage == val.storage)) -- cgit v1.2.3