diff options
Diffstat (limited to 'src')
-rw-r--r-- | src/account.h | 11 | ||||
-rw-r--r-- | src/accum.h | 11 | ||||
-rw-r--r-- | src/annotate.cc | 6 | ||||
-rw-r--r-- | src/annotate.h | 9 | ||||
-rw-r--r-- | src/commodity.h | 4 | ||||
-rw-r--r-- | src/csv.h | 4 | ||||
-rw-r--r-- | src/draft.cc | 4 | ||||
-rw-r--r-- | src/draft.h | 16 | ||||
-rw-r--r-- | src/expr.h | 1 | ||||
-rw-r--r-- | src/filters.cc | 15 | ||||
-rw-r--r-- | src/filters.h | 1 | ||||
-rw-r--r-- | src/global.cc | 21 | ||||
-rw-r--r-- | src/global.h | 1 | ||||
-rw-r--r-- | src/history.cc | 7 | ||||
-rw-r--r-- | src/iterators.cc | 8 | ||||
-rw-r--r-- | src/iterators.h | 103 | ||||
-rw-r--r-- | src/journal.cc | 1 | ||||
-rw-r--r-- | src/journal.h | 1 | ||||
-rw-r--r-- | src/main.cc | 1 | ||||
-rw-r--r-- | src/pool.cc | 37 | ||||
-rw-r--r-- | src/pstream.h | 5 | ||||
-rw-r--r-- | src/py_journal.cc | 5 | ||||
-rw-r--r-- | src/report.cc | 9 | ||||
-rw-r--r-- | src/report.h | 23 | ||||
-rw-r--r-- | src/scope.h | 14 | ||||
-rw-r--r-- | src/session.cc | 3 | ||||
-rw-r--r-- | src/session.h | 2 | ||||
-rw-r--r-- | src/temps.h | 4 | ||||
-rw-r--r-- | src/textual.cc | 15 | ||||
-rw-r--r-- | src/timelog.cc | 101 | ||||
-rw-r--r-- | src/timelog.h | 2 | ||||
-rw-r--r-- | src/utils.cc | 110 |
32 files changed, 416 insertions, 139 deletions
diff --git a/src/account.h b/src/account.h index 4ddd85e7..fee12595 100644 --- a/src/account.h +++ b/src/account.h @@ -189,7 +189,16 @@ public: posts_cleared_count(0), posts_last_7_count(0), posts_last_30_count(0), - posts_this_month_count(0) {} + posts_this_month_count(0) { + TRACE_CTOR(account_t::xdata_t::details_t, ""); + } + // A copy copies nothing + details_t(const details_t&) { + TRACE_CTOR(account_t::xdata_t::details_t, "copy"); + } + ~details_t() throw() { + TRACE_DTOR(account_t::xdata_t::details_t); + } details_t& operator+=(const details_t& other); diff --git a/src/accum.h b/src/accum.h index dde93c30..628a6b36 100644 --- a/src/accum.h +++ b/src/accum.h @@ -51,7 +51,12 @@ protected: std::string::size_type index; public: - straccbuf() : index(0) {} + straccbuf() : index(0) { + TRACE_CTOR(straccbuf, ""); + } + ~straccbuf() throw() { + TRACE_DTOR(straccbuf); + } protected: virtual std::streamsize xsputn(const char * s, std::streamsize num); @@ -66,8 +71,12 @@ protected: public: straccstream() : std::ostream(0) { + TRACE_CTOR(straccstream, ""); rdbuf(&buf); } + ~straccstream() throw() { + TRACE_DTOR(straccstream); + } void clear() { std::ostream::clear(); diff --git a/src/annotate.cc b/src/annotate.cc index 2b118e76..25f0e582 100644 --- a/src/annotate.cc +++ b/src/annotate.cc @@ -56,6 +56,7 @@ bool annotation_t::operator<(const annotation_t& rhs) const return true; if (price->commodity().symbol() > rhs.price->commodity().symbol()) return false; + if (*price < *rhs.price) return true; if (*price > *rhs.price) return false; } @@ -68,9 +69,12 @@ bool annotation_t::operator<(const annotation_t& rhs) const if (*tag > *rhs.tag) return false; } if (value_expr) { + DEBUG("annotate.less", "Comparing (" << value_expr->text() + << ") < (" << rhs.value_expr->text()); if (value_expr->text() < rhs.value_expr->text()) return true; - if (value_expr->text() > rhs.value_expr->text()) return false; + //if (value_expr->text() > rhs.value_expr->text()) return false; } + return false; } diff --git a/src/annotate.h b/src/annotate.h index 044ebc4d..163ffac5 100644 --- a/src/annotate.h +++ b/src/annotate.h @@ -72,7 +72,7 @@ struct annotation_t : public supports_flags<>, : supports_flags<>(), price(_price), date(_date), tag(_tag), value_expr(_value_expr) { TRACE_CTOR(annotation_t, - "const optional<amount_t>& + date_t + string + expr_t"); + "optional<amount_t> + date_t + string + expr_t"); } annotation_t(const annotation_t& other) : supports_flags<>(other.flags()), @@ -91,9 +91,9 @@ struct annotation_t : public supports_flags<>, bool operator<(const annotation_t& rhs) const; bool operator==(const annotation_t& rhs) const { - return (price == rhs.price && - date == rhs.date && - tag == rhs.tag && + return (price == rhs.price && + date == rhs.date && + tag == rhs.tag && (value_expr && rhs.value_expr ? value_expr->text() == rhs.value_expr->text() : value_expr == rhs.value_expr)); @@ -228,6 +228,7 @@ protected: : 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; } public: diff --git a/src/commodity.h b/src/commodity.h index 148a3636..ba47a572 100644 --- a/src/commodity.h +++ b/src/commodity.h @@ -132,10 +132,10 @@ protected: static_cast<uint_least16_t>(COMMODITY_STYLE_DECIMAL_COMMA) : static_cast<uint_least16_t>(COMMODITY_STYLE_DEFAULTS)), symbol(_symbol), precision(0) { - TRACE_CTOR(base_t, "const string&"); + TRACE_CTOR(commodity_t::base_t, "const string&"); } virtual ~base_t() { - TRACE_DTOR(base_t); + TRACE_DTOR(commodity_t::base_t); } #if defined(HAVE_BOOST_SERIALIZATION) @@ -91,8 +91,12 @@ public: cost_mask("cost"), total_mask("total"), note_mask("note") { + TRACE_CTOR(csv_reader, "parse_context_t&"); read_index(*context.stream.get()); } + ~csv_reader() { + TRACE_DTOR(csv_reader); + } void read_index(std::istream& in); string read_field(std::istream& in); diff --git a/src/draft.cc b/src/draft.cc index 74a6f4d2..7edf7edc 100644 --- a/src/draft.cc +++ b/src/draft.cc @@ -109,12 +109,12 @@ void draft_t::parse_args(const value_t& args) } else if (check_for_date && bool(weekday = string_to_day_of_week(what[0]))) { -#if defined(__GNUC__) && __GNUC__ >= 4 && __GNUC_MINOR__ >= 6 +#if defined(__GNUC__) && __GNUC__ >= 4 && __GNUC_MINOR__ >= 7 #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wmaybe-uninitialized" #endif short dow = static_cast<short>(*weekday); -#if defined(__GNUC__) && __GNUC__ >= 4 && __GNUC_MINOR__ >= 6 +#if defined(__GNUC__) && __GNUC__ >= 4 && __GNUC_MINOR__ >= 7 #pragma GCC diagnostic pop #endif date_t date = CURRENT_DATE() - date_duration(1); diff --git a/src/draft.h b/src/draft.h index 41485731..e5d29134 100644 --- a/src/draft.h +++ b/src/draft.h @@ -68,12 +68,22 @@ class draft_t : public expr_base_t<value_t> optional<string> cost_operator; optional<amount_t> cost; - post_template_t() : from(false) {} + post_template_t() : from(false) { + TRACE_CTOR(post_template_t, ""); + } + ~post_template_t() throw() { + TRACE_DTOR(post_template_t); + } }; std::list<post_template_t> posts; - xact_template_t() {} + xact_template_t() { + TRACE_CTOR(xact_template_t, ""); + } + ~xact_template_t() throw() { + TRACE_DTOR(xact_template_t); + } void dump(std::ostream& out) const; }; @@ -86,7 +96,7 @@ public: if (! args.empty()) parse_args(args); } - virtual ~draft_t() { + virtual ~draft_t() throw() { TRACE_DTOR(draft_t); } @@ -162,7 +162,6 @@ public: : expr_t(), term(_term), base_expr(expr), merge_operator(merge_op) { TRACE_CTOR(merged_expr_t, "string, string, string"); } - virtual ~merged_expr_t() { TRACE_DTOR(merged_expr_t); } diff --git a/src/filters.cc b/src/filters.cc index d5cb8ebb..749efc77 100644 --- a/src/filters.cc +++ b/src/filters.cc @@ -593,6 +593,7 @@ changed_value_posts::changed_value_posts report.HANDLER(display_total_).expr), display_total_expr(report.HANDLER(display_total_).expr), changed_values_only(report.HANDLED(revalued_only)), + historical_prices_only(report.HANDLED(historical)), for_accounts_report(_for_accounts_report), show_unrealized(_show_unrealized), last_post(NULL), display_filter(_display_filter) @@ -624,9 +625,11 @@ changed_value_posts::changed_value_posts void changed_value_posts::flush() { if (last_post && last_post->date() <= report.terminus.date()) { - if (! for_accounts_report) - output_intermediate_prices(*last_post, report.terminus.date()); - output_revaluation(*last_post, report.terminus.date()); + if (! historical_prices_only) { + if (! for_accounts_report) + output_intermediate_prices(*last_post, report.terminus.date()); + output_revaluation(*last_post, report.terminus.date()); + } last_post = NULL; } item_handler<post_t>::flush(); @@ -807,7 +810,7 @@ void changed_value_posts::output_intermediate_prices(post_t& post, void changed_value_posts::operator()(post_t& post) { if (last_post) { - if (! for_accounts_report) + if (! for_accounts_report && ! historical_prices_only) output_intermediate_prices(*last_post, post.value_date()); output_revaluation(*last_post, post.value_date()); } @@ -835,7 +838,7 @@ void subtotal_posts::report_subtotal(const char * spec_fmt, foreach (post_t * post, component_posts) { date_t date = post->date(); date_t value_date = post->value_date(); -#if defined(__GNUC__) && __GNUC__ >= 4 && __GNUC_MINOR__ >= 6 +#if defined(__GNUC__) && __GNUC__ >= 4 && __GNUC_MINOR__ >= 7 #pragma GCC diagnostic push #pragma GCC diagnostic ignored "-Wmaybe-uninitialized" #endif @@ -843,7 +846,7 @@ void subtotal_posts::report_subtotal(const char * spec_fmt, range_start = date; if (! range_finish || value_date > *range_finish) range_finish = value_date; -#if defined(__GNUC__) && __GNUC__ >= 4 && __GNUC_MINOR__ >= 6 +#if defined(__GNUC__) && __GNUC__ >= 4 && __GNUC_MINOR__ >= 7 #pragma GCC diagnostic pop #endif } diff --git a/src/filters.h b/src/filters.h index 1ef92bbe..d73fff86 100644 --- a/src/filters.h +++ b/src/filters.h @@ -576,6 +576,7 @@ class changed_value_posts : public item_handler<post_t> expr_t& total_expr; expr_t& display_total_expr; bool changed_values_only; + bool historical_prices_only; bool for_accounts_report; bool show_unrealized; post_t * last_post; diff --git a/src/global.cc b/src/global.cc index d7742161..b5ceb614 100644 --- a/src/global.cc +++ b/src/global.cc @@ -272,6 +272,7 @@ void global_scope_t::report_options(report_t& report, std::ostream& out) HANDLER(trace_).report(out); HANDLER(verbose).report(out); HANDLER(verify).report(out); + HANDLER(verify_memory).report(out); out << std::endl << "[Session scope options]" << std::endl; report.session.report_options(out); @@ -315,6 +316,7 @@ option_t<global_scope_t> * global_scope_t::lookup_option(const char * p) case 'v': OPT_(verbose); else OPT(verify); + else OPT(verify_memory); else OPT(version); break; } @@ -452,29 +454,36 @@ void handle_debug_options(int argc, char * argv[]) if (std::strcmp(argv[i], "--args-only") == 0) { args_only = true; } + else if (std::strcmp(argv[i], "--verify-memory") == 0) { +#if defined(VERIFY_ON) + verify_enabled = true; + + _log_level = LOG_DEBUG; + _log_category = "memory\\.counts"; +#endif + } else if (std::strcmp(argv[i], "--verify") == 0) { #if defined(VERIFY_ON) - verify_enabled = true; // global in utils.h + verify_enabled = true; #endif } else if (std::strcmp(argv[i], "--verbose") == 0 || std::strcmp(argv[i], "-v") == 0) { #if defined(LOGGING_ON) - _log_level = LOG_INFO; // global in utils.h + _log_level = LOG_INFO; #endif } else if (i + 1 < argc && std::strcmp(argv[i], "--debug") == 0) { #if defined(DEBUG_ON) - _log_level = LOG_DEBUG; // global in utils.h - _log_category = argv[i + 1]; // global in utils.h + _log_level = LOG_DEBUG; + _log_category = argv[i + 1]; i++; #endif } else if (i + 1 < argc && std::strcmp(argv[i], "--trace") == 0) { #if defined(TRACING_ON) - _log_level = LOG_TRACE; // global in utils.h + _log_level = LOG_TRACE; try { - // global in utils.h _trace_level = boost::lexical_cast<uint8_t>(argv[i + 1]); } catch (const boost::bad_lexical_cast&) { diff --git a/src/global.h b/src/global.h index 0c11e025..5786bb89 100644 --- a/src/global.h +++ b/src/global.h @@ -158,6 +158,7 @@ See LICENSE file included with the distribution for details and disclaimer."); OPTION(global_scope_t, trace_); OPTION(global_scope_t, verbose); OPTION(global_scope_t, verify); + OPTION(global_scope_t, verify_memory); OPTION_(global_scope_t, version, DO() { // -v parent->show_version_info(std::cout); diff --git a/src/history.cc b/src/history.cc index f1e88401..d94ec647 100644 --- a/src/history.cc +++ b/src/history.cc @@ -423,7 +423,12 @@ commodity_history_t::find_price(const commodity_t& source, template <class Name> class label_writer { public: - label_writer(Name _name) : name(_name) {} + label_writer(Name _name) : name(_name) { + TRACE_CTOR(label_writer<Name>, "Name"); + } + ~label_writer() throw() { + TRACE_DTOR(label_writer<Name>); + } template <class VertexOrEdge> void operator()(std::ostream& out, const VertexOrEdge& v) const { diff --git a/src/iterators.cc b/src/iterators.cc index acbb581f..7cc1291a 100644 --- a/src/iterators.cc +++ b/src/iterators.cc @@ -88,7 +88,13 @@ namespace { create_price_xact(journal_t& _journal, account_t * _account, temporaries_t& _temps, xacts_list& _xact_temps) : journal(_journal), account(_account), temps(_temps), - xact_temps(_xact_temps) {} + xact_temps(_xact_temps) { + TRACE_CTOR(create_price_xact, + "journal_t&, account_t *, temporaries_t&, xacts_list&"); + } + ~create_price_xact() throw() { + TRACE_DTOR(create_price_xact); + } void operator()(datetime_t& date, const amount_t& price) { xact_t * xact; diff --git a/src/iterators.h b/src/iterators.h index 5bb9de6f..922ebccd 100644 --- a/src/iterators.h +++ b/src/iterators.h @@ -58,7 +58,15 @@ class iterator_facade_base typedef Value node_base; public: - iterator_facade_base() : m_node(NULL) {} + iterator_facade_base() : m_node(NULL) { + TRACE_CTOR(iterator_facade_base, ""); + } + iterator_facade_base(const iterator_facade_base& i) : m_node(i.m_node) { + TRACE_CTOR(iterator_facade_base, "copy"); + } + ~iterator_facade_base() throw() { + TRACE_DTOR(iterator_facade_base); + } explicit iterator_facade_base(node_base p) : m_node(p) {} @@ -87,12 +95,24 @@ class xact_posts_iterator bool posts_uninitialized; public: - xact_posts_iterator() : posts_uninitialized(true) {} + xact_posts_iterator() : posts_uninitialized(true) { + TRACE_CTOR(xact_posts_iterator, ""); + } xact_posts_iterator(xact_t& xact) : posts_uninitialized(true) { + TRACE_CTOR(xact_posts_iterator, "xact_t&"); reset(xact); } - ~xact_posts_iterator() throw() {} + xact_posts_iterator(const xact_posts_iterator& i) + : iterator_facade_base<xact_posts_iterator, post_t *, + boost::forward_traversal_tag>(i), + posts_i(i.posts_i), posts_end(i.posts_end), + posts_uninitialized(i.posts_uninitialized) { + TRACE_CTOR(xact_posts_iterator, "copy"); + } + ~xact_posts_iterator() throw() { + TRACE_DTOR(xact_posts_iterator); + } void reset(xact_t& xact) { posts_i = xact.posts.begin(); @@ -121,15 +141,28 @@ public: bool xacts_uninitialized; - xacts_iterator() : xacts_uninitialized(true) {} + xacts_iterator() : xacts_uninitialized(true) { + TRACE_CTOR(xacts_iterator, ""); + } xacts_iterator(journal_t& journal) : xacts_uninitialized(false) { + TRACE_CTOR(xacts_iterator, "journal_t&"); reset(journal); } xacts_iterator(xacts_list::iterator beg, xacts_list::iterator end) : xacts_uninitialized(false) { + TRACE_CTOR(xacts_iterator, "xacts_list::iterator, xacts_list::iterator"); reset(beg, end); } - ~xacts_iterator() throw() {} + xacts_iterator(const xacts_iterator& i) + : iterator_facade_base<xacts_iterator, xact_t *, + boost::forward_traversal_tag>(i), + xacts_i(i.xacts_i), xacts_end(i.xacts_end), + xacts_uninitialized(i.xacts_uninitialized) { + TRACE_CTOR(xacts_iterator, "copy"); + } + ~xacts_iterator() throw() { + TRACE_DTOR(xacts_iterator); + } void reset(journal_t& journal); @@ -150,11 +183,22 @@ class journal_posts_iterator xact_posts_iterator posts; public: - journal_posts_iterator() {} + journal_posts_iterator() { + TRACE_CTOR(journal_posts_iterator, ""); + } journal_posts_iterator(journal_t& journal) { + TRACE_CTOR(journal_posts_iterator, "journal_t&"); reset(journal); } - ~journal_posts_iterator() throw() {} + journal_posts_iterator(const journal_posts_iterator& i) + : iterator_facade_base<journal_posts_iterator, post_t *, + boost::forward_traversal_tag>(i), + xacts(i.xacts), posts(i.posts) { + TRACE_CTOR(journal_posts_iterator, "copy"); + } + ~journal_posts_iterator() throw() { + TRACE_DTOR(journal_posts_iterator); + } void reset(journal_t& journal); @@ -173,11 +217,23 @@ protected: temporaries_t temps; public: - posts_commodities_iterator() {} + posts_commodities_iterator() { + TRACE_CTOR(posts_commodities_iterator, ""); + } posts_commodities_iterator(journal_t& journal) { + TRACE_CTOR(posts_commodities_iterator, "journal_t&"); reset(journal); } - ~posts_commodities_iterator() throw() {} + posts_commodities_iterator(const posts_commodities_iterator& i) + : iterator_facade_base<posts_commodities_iterator, post_t *, + boost::forward_traversal_tag>(i), + journal_posts(i.journal_posts), xacts(i.xacts), posts(i.posts), + xact_temps(i.xact_temps), temps(i.temps) { + TRACE_CTOR(posts_commodities_iterator, "copy"); + } + ~posts_commodities_iterator() throw() { + TRACE_DTOR(posts_commodities_iterator); + } void reset(journal_t& journal); @@ -192,12 +248,23 @@ class basic_accounts_iterator std::list<accounts_map::const_iterator> accounts_end; public: - basic_accounts_iterator() {} + basic_accounts_iterator() { + TRACE_CTOR(basic_accounts_iterator, ""); + } basic_accounts_iterator(account_t& account) { + TRACE_CTOR(basic_accounts_iterator, "account_t&"); push_back(account); increment(); } - ~basic_accounts_iterator() throw() {} + basic_accounts_iterator(const basic_accounts_iterator& i) + : iterator_facade_base<basic_accounts_iterator, account_t *, + boost::forward_traversal_tag>(i), + accounts_i(i.accounts_i), accounts_end(i.accounts_end) { + TRACE_CTOR(basic_accounts_iterator, "copy"); + } + ~basic_accounts_iterator() throw() { + TRACE_DTOR(basic_accounts_iterator); + } void increment(); @@ -225,10 +292,22 @@ public: sorted_accounts_iterator(account_t& account, const expr_t& _sort_cmp, bool _flatten_all) : sort_cmp(_sort_cmp), flatten_all(_flatten_all) { + TRACE_CTOR(sorted_accounts_iterator, "account_t&, expr_t, bool"); push_back(account); increment(); } - ~sorted_accounts_iterator() throw() {} + sorted_accounts_iterator(const sorted_accounts_iterator& i) + : iterator_facade_base<sorted_accounts_iterator, account_t *, + boost::forward_traversal_tag>(i), + sort_cmp(i.sort_cmp), flatten_all(i.flatten_all), + accounts_list(i.accounts_list), + sorted_accounts_i(i.sorted_accounts_i), + sorted_accounts_end(i.sorted_accounts_end) { + TRACE_CTOR(sorted_accounts_iterator, "copy"); + } + ~sorted_accounts_iterator() throw() { + TRACE_DTOR(sorted_accounts_iterator); + } void increment(); 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/main.cc b/src/main.cc index 9d2ba311..0130d5c6 100644 --- a/src/main.cc +++ b/src/main.cc @@ -58,6 +58,7 @@ int main(int argc, char * argv[], char * envp[]) // --verbose ; turns on logging // --debug CATEGORY ; turns on debug logging // --trace LEVEL ; turns on trace logging + // --memory ; turns on memory usage tracing handle_debug_options(argc, argv); #if defined(VERIFY_ON) IF_VERIFY() initialize_memory_tracing(); diff --git a/src/pool.cc b/src/pool.cc index 5813c0f6..be26de3b 100644 --- a/src/pool.cc +++ b/src/pool.cc @@ -102,7 +102,7 @@ commodity_t * commodity_pool_t::find_or_create(const string& symbol) commodity_t * commodity_pool_t::alias(const string& name, commodity_t& referent) { - commodities_map::const_iterator i = commodities.find(referent.symbol()); + commodities_map::const_iterator i = commodities.find(referent.base_symbol()); assert(i != commodities.end()); std::pair<commodities_map::iterator, bool> result @@ -130,20 +130,16 @@ commodity_pool_t::find(const string& symbol, const annotation_t& details) DEBUG("pool.commodities", "commodity_pool_t::find[ann] " << "symbol " << symbol << std::endl << details); - if (details) { - annotated_commodities_map::const_iterator i = - annotated_commodities.find - (annotated_commodities_map::key_type(symbol, details)); - if (i != annotated_commodities.end()) { - DEBUG("pool.commodities", "commodity_pool_t::find[ann] found " - << "symbol " << (*i).second->symbol() << std::endl - << as_annotated_commodity(*(*i).second.get()).details); - return (*i).second.get(); - } else { - return NULL; - } + annotated_commodities_map::const_iterator i = + annotated_commodities.find + (annotated_commodities_map::key_type(symbol, details)); + if (i != annotated_commodities.end()) { + DEBUG("pool.commodities", "commodity_pool_t::find[ann] found " + << "symbol " << (*i).second->base_symbol() << std::endl + << as_annotated_commodity(*(*i).second.get()).details); + return (*i).second.get(); } else { - return find(symbol); + return NULL; } } @@ -170,10 +166,10 @@ commodity_t * commodity_pool_t::find_or_create(commodity_t& comm, const annotation_t& details) { DEBUG("pool.commodities", "commodity_pool_t::find_or_create[ann:comm] " - << "symbol " << comm.symbol() << std::endl << details); + << "symbol " << comm.base_symbol() << std::endl << details); if (details) { - if (commodity_t * ann_comm = find(comm.symbol(), details)) { + if (commodity_t * ann_comm = find(comm.base_symbol(), details)) { assert(ann_comm->annotated && as_annotated_commodity(*ann_comm).details); return ann_comm; } else { @@ -189,7 +185,7 @@ commodity_pool_t::create(commodity_t& comm, const annotation_t& details) { DEBUG("pool.commodities", "commodity_pool_t::create[ann:comm] " - << "symbol " << comm.symbol() << std::endl << details); + << "symbol " << comm.base_symbol() << std::endl << details); assert(comm); assert(! comm.has_annotation()); @@ -206,11 +202,8 @@ commodity_pool_t::create(commodity_t& comm, comm.add_flags(COMMODITY_SAW_ANN_PRICE_FLOAT); } - commodity->qualified_symbol = comm.symbol(); - assert(! commodity->qualified_symbol->empty()); - DEBUG("pool.commodities", "Creating annotated commodity " - << "symbol " << commodity->symbol() + << "symbol " << commodity->base_symbol() << std::endl << details); #if defined(DEBUG_ON) @@ -218,7 +211,7 @@ commodity_pool_t::create(commodity_t& comm, #endif annotated_commodities.insert(annotated_commodities_map::value_type (annotated_commodities_map::key_type - (comm.symbol(), details), commodity)); + (comm.base_symbol(), details), commodity)); #if defined(DEBUG_ON) assert(result.second); #endif diff --git a/src/pstream.h b/src/pstream.h index a894325d..dfb27056 100644 --- a/src/pstream.h +++ b/src/pstream.h @@ -58,6 +58,8 @@ 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); @@ -65,6 +67,9 @@ class ptristream : public std::istream ptr, // read position ptr+len); // end position } + ~ptrinbuf() throw() { + TRACE_DTOR(ptrinbuf); + } protected: virtual int_type underflow() { diff --git a/src/py_journal.cc b/src/py_journal.cc index 550fb14e..50a52be9 100644 --- a/src/py_journal.cc +++ b/src/py_journal.cc @@ -151,8 +151,11 @@ namespace { collector_wrapper(journal_t& _journal, report_t& base) : journal(_journal), report(base), - posts_collector(new collect_posts) {} + posts_collector(new collect_posts) { + TRACE_CTOR(collector_wrapper, "journal_t&, report_t&"); + } ~collector_wrapper() { + TRACE_DTOR(collector_wrapper); journal.clear_xdata(); } diff --git a/src/report.cc b/src/report.cc index 91de2eb5..28836d0f 100644 --- a/src/report.cc +++ b/src/report.cc @@ -321,7 +321,12 @@ namespace { report_t& report; posts_flusher(post_handler_ptr _handler, report_t& _report) - : handler(_handler), report(_report) {} + : handler(_handler), report(_report) { + TRACE_CTOR(posts_flusher, "post_handler_ptr, report_t&"); + } + ~posts_flusher() throw() { + TRACE_DTOR(posts_flusher); + } void operator()(const value_t&) { report.session.journal->clear_xdata(); @@ -1113,7 +1118,7 @@ option_t<report_t> * report_t::lookup_option(const char * p) else OPT_(display_); else OPT(display_amount_); else OPT(display_total_); - else OPT_ALT(dow, days-of-week); + else OPT_ALT(dow, days_of_week); else OPT(date_width_); break; case 'e': diff --git a/src/report.h b/src/report.h index aca4f466..37123377 100644 --- a/src/report.h +++ b/src/report.h @@ -119,9 +119,19 @@ public: explicit report_t(session_t& _session) : session(_session), terminus(CURRENT_TIME()), - budget_flags(BUDGET_NO_BUDGET) {} + budget_flags(BUDGET_NO_BUDGET) { + TRACE_CTOR(report_t, "session_t&"); + } + report_t(const report_t& report) + : session(report.session), + output_stream(report.output_stream), + terminus(report.terminus), + budget_flags(report.budget_flags) { + TRACE_CTOR(report_t, "copy"); + } virtual ~report_t() { + TRACE_DTOR(report_t); output_stream.close(); } @@ -1045,7 +1055,16 @@ class reporter public: reporter(shared_ptr<item_handler<Type> > _handler, report_t& _report, const string& _whence) - : handler(_handler), report(_report), whence(_whence) {} + : handler(_handler), report(_report), whence(_whence) { + TRACE_CTOR(reporter, "item_handler<Type>, report_t&, string"); + } + reporter(const reporter& other) + : handler(other.handler), report(other.report), whence(other.whence) { + TRACE_CTOR(reporter, "copy"); + } + ~reporter() throw() { + TRACE_DTOR(reporter); + } value_t operator()(call_scope_t& args) { diff --git a/src/scope.h b/src/scope.h index 134babb2..9318fc5c 100644 --- a/src/scope.h +++ b/src/scope.h @@ -142,6 +142,13 @@ private: class empty_scope_t : public scope_t { public: + empty_scope_t() { + TRACE_CTOR(empty_scope_t, ""); + } + ~empty_scope_t() throw() { + TRACE_DTOR(empty_scope_t); + } + virtual string description() { return _("<empty>"); } @@ -683,7 +690,12 @@ class value_scope_t : public child_scope_t public: value_scope_t(scope_t& _parent, const value_t& _value) - : child_scope_t(_parent), value(_value) {} + : child_scope_t(_parent), value(_value) { + TRACE_CTOR(value_scope_t, "scope_t&, value_t"); + } + ~value_scope_t() throw() { + TRACE_DTOR(value_scope_t); + } virtual string description() { return parent->description(); 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> * 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/temps.h b/src/temps.h index ad4e5672..f41c487c 100644 --- a/src/temps.h +++ b/src/temps.h @@ -51,7 +51,11 @@ class temporaries_t optional<std::list<account_t> > acct_temps; public: + temporaries_t() { + TRACE_CTOR(temporaries_t, ""); + } ~temporaries_t() { + TRACE_DTOR(temporaries_t); clear(); } diff --git a/src/textual.cc b/src/textual.cc index 3555ea4d..0cb7fb81 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 @@ -983,27 +982,23 @@ void instance_t::account_alias_directive(account_t * account, string alias) // (account), add a reference to the account in the `account_aliases' // map, which is used by the post parser to resolve alias references. trim(alias); -#if defined(DEBUG_ON) std::pair<accounts_map::iterator, bool> result = -#endif context.journal->account_aliases.insert (accounts_map::value_type(alias, account)); -#if defined(DEBUG_ON) - assert(result.second); -#endif + if (! result.second) + (*result.first).second = account; } void instance_t::alias_directive(char * line) { - char * b = next_element(line); - if (char * e = std::strchr(b, '=')) { + if (char * e = std::strchr(line, '=')) { char * z = e - 1; while (std::isspace(*z)) *z-- = '\0'; *e++ = '\0'; e = skip_ws(e); - account_alias_directive(top_account()->find_account(e), b); + account_alias_directive(top_account()->find_account(e), line); } } 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_xact_t>& 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<xact_t> 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_xact_t>& 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<xact_t> 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/src/utils.cc b/src/utils.cc index 628fb158..5a364008 100644 --- a/src/utils.cc +++ b/src/utils.cc @@ -270,13 +270,79 @@ void operator delete[](void * ptr, const std::nothrow_t&) throw() { namespace ledger { -inline 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) << pair.second.first - << " " << std::right << std::setw(7) << pair.second.second - << " " << std::left << pair.first - << std::endl; +namespace { + void stream_commified_number(std::ostream& out, std::size_t num) + { + std::ostringstream buf; + std::ostringstream obuf; + + buf << num; + + int integer_digits = 0; + // Count the number of integer digits + for (const char * p = buf.str().c_str(); *p; p++) { + if (*p == '.') + break; + else if (*p != '-') + integer_digits++; + } + + for (const char * p = buf.str().c_str(); *p; p++) { + if (*p == '.') { + obuf << *p; + assert(integer_digits <= 3); + } + else if (*p == '-') { + obuf << *p; + } + else { + obuf << *p; + + if (integer_digits > 3 && --integer_digits % 3 == 0) + obuf << ','; + } + } + + out << obuf.str(); + } + + void stream_memory_size(std::ostream& out, std::size_t size) + { + std::ostringstream obuf; + + if (size > 10 * 1024 * 1024) + obuf << "\033[1m"; + if (size > 100 * 1024 * 1024) + obuf << "\033[31m"; + + obuf << std::setw(7); + + if (size < 1024) + obuf << size << 'b'; + else if (size < (1024 * 1024)) + obuf << int(double(size) / 1024.0) << 'K'; + else if (size < (1024 * 1024 * 1024)) + obuf << int(double(size) / (1024.0 * 1024.0)) << 'M'; + else + obuf << int(double(size) / (1024.0 * 1024.0 * 1024.0)) << 'G'; + + if (size > 10 * 1024 * 1024) + obuf << "\033[0m"; + + out << obuf.str(); + } + + 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); + stream_commified_number(out, pair.second.first); + out << " " << std::right << std::setw(7); + stream_memory_size(out, pair.second.second); + out << " " << std::left << pair.first + << std::endl; + } + } } std::size_t current_objects_size() @@ -354,7 +420,7 @@ void trace_dtor_func(void * ptr, const char * cls_name, std::size_t cls_size) void report_memory(std::ostream& out, bool report_all) { - if (! live_memory || ! memory_tracing_active) return; + if (! live_memory) return; if (live_memory_count->size() > 0) { out << "NOTE: There may be memory held by Boost " @@ -366,11 +432,13 @@ void report_memory(std::ostream& out, bool report_all) if (live_memory->size() > 0) { out << "Live memory:" << std::endl; - foreach (const memory_map::value_type& pair, *live_memory) + foreach (const memory_map::value_type& pair, *live_memory) { out << " " << std::right << std::setw(12) << pair.first - << " " << std::right << std::setw(7) << pair.second.second - << " " << std::left << pair.second.first + << " " << std::right << std::setw(7); + stream_memory_size(out, pair.second.second); + out << " " << std::left << pair.second.first << std::endl; + } } if (report_all && total_memory_count->size() > 0) { @@ -386,11 +454,13 @@ void report_memory(std::ostream& out, bool report_all) if (live_objects->size() > 0) { out << "Live objects:" << std::endl; - foreach (const objects_map::value_type& pair, *live_objects) + foreach (const objects_map::value_type& pair, *live_objects) { out << " " << std::right << std::setw(12) << pair.first - << " " << std::right << std::setw(7) << pair.second.second - << " " << std::left << pair.second.first + << " " << std::right << std::setw(7); + stream_memory_size(out, pair.second.second); + out << " " << std::left << pair.second.first << std::endl; + } } if (report_all) { @@ -529,18 +599,6 @@ std::ostringstream _log_buffer; uint8_t _trace_level; #endif -static inline void stream_memory_size(std::ostream& out, std::size_t size) -{ - if (size < 1024) - out << size << 'b'; - else if (size < (1024 * 1024)) - out << (double(size) / 1024.0) << 'K'; - else if (size < (1024 * 1024 * 1024)) - out << (double(size) / (1024.0 * 1024.0)) << 'M'; - else - out << (double(size) / (1024.0 * 1024.0 * 1024.0)) << 'G'; -} - static bool logger_has_run = false; static ptime logger_start; |