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/amount.h | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'src/amount.h') 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 -- cgit v1.2.3 From 8d6bf11334562d7781b339cf822a93ff42fee2b5 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Mon, 5 Mar 2012 01:48:21 -0600 Subject: All tests are working again but one --- src/amount.cc | 9 +- src/amount.h | 7 +- src/commodity.cc | 54 +++++++--- src/commodity.h | 4 + src/filters.cc | 52 +++++----- src/history.cc | 179 ++++++++++++++++++++++++--------- src/history.h | 61 ++++++++--- src/iterators.cc | 104 +++++++++---------- test/baseline/feat-fixated-prices.test | 2 + test/regress/25A099C9.test | 12 +-- test/unit/t_commodity.cc | 2 +- 11 files changed, 318 insertions(+), 168 deletions(-) (limited to 'src/amount.h') diff --git a/src/amount.cc b/src/amount.cc index 4d26a688..9704dd21 100644 --- a/src/amount.cc +++ b/src/amount.cc @@ -605,16 +605,13 @@ void amount_t::in_place_negate() } } -amount_t amount_t::inverted() const +void amount_t::in_place_invert() { if (! quantity) throw_(amount_error, _("Cannot invert an uninitialized amount")); - amount_t t(*this); - t._dup(); - mpq_inv(MP(t.quantity), MP(t.quantity)); - - return t; + _dup(); + mpq_inv(MP(quantity), MP(quantity)); } void amount_t::in_place_round() diff --git a/src/amount.h b/src/amount.h index 3a8e06b9..1db59b7e 100644 --- a/src/amount.h +++ b/src/amount.h @@ -327,7 +327,12 @@ public: return *this; } - amount_t inverted() const; + amount_t inverted() const { + amount_t temp(*this); + temp.in_place_invert(); + return temp; + } + void in_place_invert(); /** Yields an amount whose display precision when output is truncated to the display precision of its commodity. This is normally the diff --git a/src/commodity.cc b/src/commodity.cc index 5e55db31..7d473d74 100644 --- a/src/commodity.cc +++ b/src/commodity.cc @@ -43,11 +43,20 @@ bool commodity_t::decimal_comma_by_default = false; void commodity_t::add_price(const datetime_t& date, const amount_t& price, const bool reflexive) { - if (! reflexive) + if (reflexive) { + DEBUG("history.find", "Marking " + << price.commodity().symbol() << " as a primary commodity"); + price.commodity().add_flags(COMMODITY_PRIMARY); + } else { + DEBUG("history.find", "Marking " << symbol() << " as a primary commodity"); add_flags(COMMODITY_PRIMARY); + } + + DEBUG("history.find", "Adding price: " << symbol() + << " for " << price << " on " << date); + pool().commodity_price_history.add_price(*this, date, price); - DEBUG("commodity.prices.find", "Price added, clearing price_map"); base->price_map.clear(); // a price was added, invalid the map } @@ -55,27 +64,52 @@ void commodity_t::remove_price(const datetime_t& date, commodity_t& commodity) { pool().commodity_price_history.remove_price(*this, commodity, date); - DEBUG("commodity.prices.find", "Price removed, clearing price_map"); + DEBUG("history.find", "Removing price: " << symbol() << " on " << date); + base->price_map.clear(); // a price was added, invalid the map } +void commodity_t::map_prices(function fn, + const optional& moment, + const optional& _oldest) +{ + datetime_t when; + if (moment) + when = *moment; + else if (epoch) + when = *epoch; + else + when = CURRENT_TIME(); + + pool().commodity_price_history.map_prices(fn, *this, when, _oldest); +} + optional commodity_t::find_price(const optional& commodity, const optional& moment, const optional& oldest) const { + optional target; + if (commodity) + target = commodity; + else if (pool().default_commodity) + target = *pool().default_commodity; + + if (target && *this == *target) + return none; + optional pair = base_t::time_and_commodity_t(base_t::optional_time_pair_t(moment, oldest), commodity ? &(*commodity) : NULL); - DEBUG("commodity.prices.find", "looking for memoized args: " + DEBUG("history.find", "looking for memoized args: " << (moment ? format_datetime(*moment) : "NONE") << ", " << (oldest ? format_datetime(*oldest) : "NONE") << ", " << (commodity ? commodity->symbol() : "NONE")); { base_t::memoized_price_map::iterator i = base->price_map.find(*pair); if (i != base->price_map.end()) { - DEBUG("commodity.prices.find", "found! returning: " + DEBUG("history.find", "found! returning: " << ((*i).second ? (*i).second->price : amount_t(0L))); return (*i).second; } @@ -89,12 +123,6 @@ commodity_t::find_price(const optional& commodity, else when = CURRENT_TIME(); - optional target; - if (commodity) - target = commodity; - else if (pool().default_commodity) - target = *pool().default_commodity; - optional point = target ? pool().commodity_price_history.find_price(*this, *target, when, oldest) : @@ -102,13 +130,13 @@ commodity_t::find_price(const optional& commodity, if (pair) { if (base->price_map.size() > base_t::max_price_map_size) { - DEBUG("commodity.prices.find", + DEBUG("history.find", "price map has grown too large, clearing it by half"); for (std::size_t i = 0; i < base_t::max_price_map_size >> 1; i++) base->price_map.erase(base->price_map.begin()); } - DEBUG("commodity.prices.find", + DEBUG("history.find", "remembered: " << (point ? point->price : amount_t(0L))); base->price_map.insert (base_t::memoized_price_map::value_type(*pair, point)); diff --git a/src/commodity.h b/src/commodity.h index a1ad0147..524daaab 100644 --- a/src/commodity.h +++ b/src/commodity.h @@ -271,6 +271,10 @@ public: const bool reflexive = true); void remove_price(const datetime_t& date, commodity_t& commodity); + void map_prices(function fn, + const optional& moment = none, + const optional& _oldest = none); + optional find_price(const optional& commodity = none, const optional& moment = none, diff --git a/src/filters.cc b/src/filters.cc index 0c6222d7..6e52c40f 100644 --- a/src/filters.cc +++ b/src/filters.cc @@ -37,6 +37,7 @@ #include "report.h" #include "compare.h" #include "pool.h" +#include "history.h" namespace ledger { @@ -688,6 +689,27 @@ void changed_value_posts::output_revaluation(post_t& post, const date_t& date) } } +namespace { + struct create_price_xact { + post_t& post; + const date_t& current; + price_map_t& all_prices; + + create_price_xact(post_t& _post, const date_t& _current, + price_map_t& _all_prices) + : post(_post), current(_current), all_prices(_all_prices) {} + + void operator()(datetime_t& date, const amount_t& price) { + if (date.date() > post.value_date() && date.date() < current) { + DEBUG("filters.revalued", + post.value_date() << " < " << date << " < " << current); + DEBUG("filters.revalued", "inserting " << price << " at " << date); + all_prices.insert(price_map_t::value_type(date, price)); + } + } + }; +} + void changed_value_posts::output_intermediate_prices(post_t& post, const date_t& current) { @@ -754,38 +776,17 @@ void changed_value_posts::output_intermediate_prices(post_t& post, // fall through... case value_t::BALANCE: { -#if 0 - // jww (2012-03-04): TODO - commodity_t::history_map all_prices; + price_map_t all_prices; foreach (const balance_t::amounts_map::value_type& amt_comm, - display_total.as_balance().amounts) { - if (optional hist = - amt_comm.first->varied_history()) { - foreach - (const commodity_t::history_by_commodity_map::value_type& comm_hist, - hist->histories) { - foreach (const commodity_t::history_map::value_type& price, - comm_hist.second.prices) { - if (price.first.date() > post.value_date() && - price.first.date() < current) { - DEBUG("filters.revalued", post.value_date() << " < " - << price.first.date() << " < " << current); - DEBUG("filters.revalued", "inserting " - << price.second << " at " << price.first.date()); - all_prices.insert(price); - } - } - } - } - } + display_total.as_balance().amounts) + amt_comm.first->map_prices(create_price_xact(post, current, all_prices)); // Choose the last price from each day as the price to use typedef std::map date_map; date_map pricing_dates; - BOOST_REVERSE_FOREACH - (const commodity_t::history_map::value_type& price, all_prices) { + BOOST_REVERSE_FOREACH(const price_map_t::value_type& price, all_prices) { // This insert will fail if a later price has already been inserted // for that date. DEBUG("filters.revalued", @@ -799,7 +800,6 @@ void changed_value_posts::output_intermediate_prices(post_t& post, output_revaluation(post, price.first); last_total = repriced_total; } -#endif break; } default: diff --git a/src/history.cc b/src/history.cc index a3d9139b..95ed584f 100644 --- a/src/history.cc +++ b/src/history.cc @@ -67,6 +67,9 @@ void commodity_history_t::add_price(const commodity_t& source, if (! result.second) { // There is already an entry for this moment, so update it (*result.first).second = price; + } else { + last_reftime = none; // invalidate the FGraph cache + last_oldest = none; } } @@ -82,64 +85,128 @@ void commodity_history_t::remove_price(const commodity_t& source, // jww (2012-03-04): If it fails, should we give a warning? prices.erase(date); + + last_reftime = none; // invalidate the FGraph cache + last_oldest = none; +} + +void commodity_history_t::map_prices(function fn, + const commodity_t& source, + const datetime_t& moment, + const optional& _oldest) +{ + vertex_descriptor sv = vertex(*source.graph_index(), price_graph); + + reftime = moment; + oldest = _oldest; + + graph_traits::adjacency_iterator f_vi, f_vend; + for (tie(f_vi, f_vend) = adjacent_vertices(sv, fg); f_vi != f_vend; ++f_vi) { + std::pair edgePair = edge(sv, *f_vi, fg); + Graph::edge_descriptor edge = edgePair.first; + + const price_map_t& prices(get(ratiomap, edge)); + + foreach (const price_map_t::value_type& pair, prices) { + const datetime_t& when(pair.first); + + if ((! _oldest || when >= *_oldest) && when <= moment) { + if (pair.second.commodity() == source) { + amount_t price(pair.second); + price.in_place_invert(); + if (source == *get(namemap, sv)) + price.set_commodity(const_cast(*get(namemap, *f_vi))); + else + price.set_commodity(const_cast(*get(namemap, sv))); + } + fn(when, pair.second); + } + } + } } optional commodity_history_t::find_price(const commodity_t& source, const datetime_t& moment, - const optional& oldest) + const optional& _oldest) { vertex_descriptor sv = vertex(*source.graph_index(), price_graph); - // Filter out edges which came into being after the reference time - FGraph fg(price_graph, - recent_edge_weight - (get(edge_weight, price_graph), pricemap, ratiomap, - moment, oldest)); - + DEBUG("history.find", "sv commodity = " << get(namemap, sv)->symbol()); +#if defined(DEBUG_ON) + if (source.has_flags(COMMODITY_PRIMARY)) + DEBUG("history.find", "sv commodity is primary"); +#endif + DEBUG("history.find", "tv commodity = none "); + datetime_t most_recent = moment; amount_t price; + reftime = moment; + oldest = _oldest; + graph_traits::adjacency_iterator f_vi, f_vend; for (tie(f_vi, f_vend) = adjacent_vertices(sv, fg); f_vi != f_vend; ++f_vi) { std::pair edgePair = edge(sv, *f_vi, fg); Graph::edge_descriptor edge = edgePair.first; + DEBUG("history.find", "u commodity = " << get(namemap, sv)->symbol()); + DEBUG("history.find", "v commodity = " << get(namemap, *f_vi)->symbol()); + const price_point_t& point(get(pricemap, edge)); if (price.is_null() || point.when > most_recent) { most_recent = point.when; price = point.price; } + + DEBUG("history.find", "price was = " << price.unrounded()); + + if (price.commodity() == source) { + price.in_place_invert(); + if (source == *get(namemap, sv)) + price.set_commodity(const_cast(*get(namemap, *f_vi))); + else + price.set_commodity(const_cast(*get(namemap, sv))); + } + + DEBUG("history.find", "price is = " << price.unrounded()); } - if (price.is_null()) + last_reftime = reftime; // invalidate the FGraph cache + last_oldest = oldest; + + if (price.is_null()) { + DEBUG("history.find", "there is no final price"); return none; - else + } else { + DEBUG("history.find", "final price is = " << price.unrounded()); return price_point_t(most_recent, price); + } } optional commodity_history_t::find_price(const commodity_t& source, const commodity_t& target, const datetime_t& moment, - const optional& oldest) + const optional& _oldest) { vertex_descriptor sv = vertex(*source.graph_index(), price_graph); vertex_descriptor tv = vertex(*target.graph_index(), price_graph); - // Filter out edges which came into being after the reference time - FGraph fg(price_graph, - recent_edge_weight - (get(edge_weight, price_graph), pricemap, ratiomap, - moment, oldest)); - + DEBUG("history.find", "sv commodity = " << get(namemap, sv)->symbol()); + DEBUG("history.find", "tv commodity = " << get(namemap, tv)->symbol()); + std::vector predecessors(num_vertices(fg)); std::vector distances(num_vertices(fg)); PredecessorMap predecessorMap(&predecessors[0]); DistanceMap distanceMap(&distances[0]); + reftime = moment; + oldest = _oldest; + dijkstra_shortest_paths(fg, /* start= */ sv, predecessor_map(predecessorMap) .distance_map(distanceMap) @@ -149,7 +216,7 @@ commodity_history_t::find_price(const commodity_t& source, datetime_t least_recent = moment; amount_t price; - FNameMap ptrs = get(vertex_name, fg); + const commodity_t * last_target = ⌖ vertex_descriptor v = tv; for (vertex_descriptor u = predecessorMap[v]; @@ -161,73 +228,85 @@ commodity_history_t::find_price(const commodity_t& source, const price_point_t& point(get(pricemap, edge)); - const commodity_t * last_source = &source; - bool first_run = false; if (price.is_null()) { least_recent = point.when; - price = point.price; first_run = true; } else if (point.when < least_recent) { least_recent = point.when; } - DEBUG("history.find", "u commodity = " << get(ptrs, u)->symbol()); - DEBUG("history.find", "v commodity = " << get(ptrs, v)->symbol()); - DEBUG("history.find", "last source = " << last_source->symbol()); + DEBUG("history.find", "u commodity = " << get(namemap, u)->symbol()); + DEBUG("history.find", "v commodity = " << get(namemap, v)->symbol()); + DEBUG("history.find", "last target = " << last_target->symbol()); // Determine which direction we are converting in amount_t pprice(point.price); - DEBUG("history.find", "pprice = " << pprice); + DEBUG("history.find", "pprice = " << pprice.unrounded()); - DEBUG("history.find", "price was = " << price); if (! first_run) { - if (pprice.commodity() == *last_source) + DEBUG("history.find", "price was = " << price.unrounded()); + if (pprice.commodity() != *last_target) price *= pprice.inverted(); else price *= pprice; } - else if (price.commodity() == *last_source) { - price = price.inverted(); + else if (pprice.commodity() != *last_target) { + price = pprice.inverted(); + } + else { + price = pprice; } - DEBUG("history.find", "price is = " << price); + DEBUG("history.find", "price is = " << price.unrounded()); - if (*last_source == *get(ptrs, v)) - last_source = get(ptrs, u); + if (*last_target == *get(namemap, v)) + last_target = get(namemap, u); else - last_source = get(ptrs, v); + last_target = get(namemap, v); + + DEBUG("history.find", "last target now = " << last_target->symbol()); } - price.set_commodity(const_cast(target)); - DEBUG("history.find", "final price is = " << price); + last_reftime = reftime; // invalidate the FGraph cache + last_oldest = oldest; - if (price.is_null()) + if (price.is_null()) { + DEBUG("history.find", "there is no final price"); return none; - else + } else { + price.set_commodity(const_cast(target)); + DEBUG("history.find", "final price is = " << price.unrounded()); + return price_point_t(least_recent, price); + } } +template +class label_writer { +public: + label_writer(Name _name) : name(_name) {} + + template + void operator()(std::ostream& out, const VertexOrEdge& v) const { + out << "[label=\"" << name[v]->symbol() << "\"]"; + } + +private: + Name name; +}; + void commodity_history_t::print_map(std::ostream& out, const optional& moment) { -#if 0 - dynamic_properties p; - p.property("label", get(edge_weight, price_graph)); - p.property("weight", get(edge_weight, price_graph)); - p.property("node_id", get(vertex_index, price_graph)); - if (moment) { - // Filter out edges which came into being after the reference time - FGraph fg(price_graph, - recent_edge_weight - (get(edge_weight, price_graph), pricemap, ratiomap, - *moment)); - write_graphviz(out, fg, p); + reftime = *moment; + write_graphviz(out, fg, label_writer(namemap)); + last_reftime = reftime; } else { - write_graphviz(out, price_graph, p); + write_graphviz(out, price_graph, + label_writer(get(vertex_name, price_graph))); } -#endif } } // namespace ledger diff --git a/src/history.h b/src/history.h index 70831445..eaca07ac 100644 --- a/src/history.h +++ b/src/history.h @@ -70,36 +70,50 @@ public: PricePointMap price_point; PriceRatioMap ratios; - datetime_t reftime; - optional oldest; + datetime_t * reftime; + optional * last_reftime; + optional * oldest; + optional * last_oldest; recent_edge_weight() { } - recent_edge_weight(EdgeWeightMap _weight, - PricePointMap _price_point, - PriceRatioMap _ratios, - datetime_t _reftime, - const optional& _oldest = none) + recent_edge_weight(EdgeWeightMap _weight, + PricePointMap _price_point, + PriceRatioMap _ratios, + datetime_t * _reftime, + optional * _last_reftime, + optional * _oldest, + optional * _last_oldest) : weight(_weight), price_point(_price_point), ratios(_ratios), - reftime(_reftime), oldest(_oldest) { } + reftime(_reftime), last_reftime(_last_reftime), + oldest(_oldest), last_oldest(_last_oldest) { } template bool operator()(const Edge& e) const { + if (*last_reftime && *reftime == **last_reftime && + *oldest == *last_oldest) + return get(weight, e) != std::numeric_limits::max(); + const price_map_t& prices(get(ratios, e)); - if (prices.empty()) + if (prices.empty()) { + put(weight, e, std::numeric_limits::max()); return false; + } - price_map_t::const_iterator low = prices.upper_bound(reftime); + price_map_t::const_iterator low = prices.upper_bound(*reftime); if (low != prices.end() && low == prices.begin()) { + put(weight, e, std::numeric_limits::max()); return false; } else { --low; - assert(((*low).first <= reftime)); + assert(((*low).first <= *reftime)); - if (oldest && (*low).first < *oldest) + if (*oldest && (*low).first < **oldest) { + put(weight, e, std::numeric_limits::max()); return false; + } - long secs = (reftime - (*low).first).total_seconds(); + long secs = (*reftime - (*low).first).total_seconds(); assert(secs >= 0); put(weight, e, secs); @@ -160,10 +174,24 @@ public: PriceRatioMap> > FGraph; typedef property_map::type FNameMap; + FGraph fg; + FNameMap namemap; + + // jww (2012-03-05): Prevents threading + mutable datetime_t reftime; + mutable optional last_reftime; + mutable optional oldest; + mutable optional last_oldest; + commodity_history_t() : indexmap(get(vertex_index, price_graph)), pricemap(get(edge_price_point, price_graph)), - ratiomap(get(edge_price_ratio, price_graph)) {} + ratiomap(get(edge_price_ratio, price_graph)), + fg(price_graph, + recent_edge_weight + (get(edge_weight, price_graph), pricemap, ratiomap, + &reftime, &last_reftime, &oldest, &last_oldest)), + namemap(get(vertex_name, fg)) {} void add_commodity(commodity_t& comm); @@ -174,6 +202,11 @@ public: const commodity_t& target, const datetime_t& date); + void map_prices(function fn, + const commodity_t& source, + const datetime_t& moment, + const optional& _oldest = none); + optional find_price(const commodity_t& source, const datetime_t& moment, diff --git a/src/iterators.cc b/src/iterators.cc index b7ed011e..b994d59a 100644 --- a/src/iterators.cc +++ b/src/iterators.cc @@ -75,6 +75,55 @@ void journal_posts_iterator::increment() } } +namespace { + struct create_price_xact { + account_t * account; + temporaries_t& temps; + xacts_list& xact_temps; + + std::map xacts_by_commodity; + + create_price_xact(account_t * _account, temporaries_t& _temps, + xacts_list& _xact_temps) + : account(_account), temps(_temps), xact_temps(_xact_temps) {} + + void operator()(datetime_t& date, const amount_t& price) { + xact_t * xact; + string symbol = price.commodity().symbol(); + + std::map::iterator i = + xacts_by_commodity.find(symbol); + if (i != xacts_by_commodity.end()) { + xact = (*i).second; + } else { + xact = &temps.create_xact(); + xact_temps.push_back(xact); + xact->payee = symbol; + xact->_date = date.date(); + xacts_by_commodity.insert + (std::pair(symbol, xact)); + } + + bool post_already_exists = false; + + foreach (post_t * post, xact->posts) { + if (post->date() == date.date() && post->amount == price) { + post_already_exists = true; + break; + } + } + + if (! post_already_exists) { + post_t& temp = temps.create_post(*xact, account); + temp._date = date.date(); + temp.amount = price; + + temp.xdata().datetime = date; + } + } + }; +} + void posts_commodities_iterator::reset(journal_t& journal) { journal_posts.reset(journal); @@ -88,57 +137,10 @@ void posts_commodities_iterator::reset(journal_t& journal) commodities.insert(&comm); } - std::map xacts_by_commodity; - -#if 0 - // jww (2012-03-04): TODO - foreach (commodity_t * comm, commodities) { - if (optional history = - comm->varied_history()) { - account_t * account = journal.master->find_account(comm->symbol()); - - foreach (commodity_t::history_by_commodity_map::value_type& pair, - history->histories) { - foreach (commodity_t::history_map::value_type& hpair, - pair.second.prices) { - xact_t * xact; - string symbol = hpair.second.commodity().symbol(); - - std::map::iterator i = - xacts_by_commodity.find(symbol); - if (i != xacts_by_commodity.end()) { - xact = (*i).second; - } else { - xact = &temps.create_xact(); - xact_temps.push_back(xact); - xact->payee = symbol; - xact->_date = hpair.first.date(); - xacts_by_commodity.insert - (std::pair(symbol, xact)); - } - - bool post_already_exists = false; - - foreach (post_t * post, xact->posts) { - if (post->_date == hpair.first.date() && - post->amount == hpair.second) { - post_already_exists = true; - break; - } - } - - if (! post_already_exists) { - post_t& temp = temps.create_post(*xact, account); - temp._date = hpair.first.date(); - temp.amount = hpair.second; - - temp.xdata().datetime = hpair.first; - } - } - } - } - } -#endif + foreach (commodity_t * comm, commodities) + comm->map_prices + (create_price_xact(journal.master->find_account(comm->symbol()), + temps, xact_temps)); xacts.reset(xact_temps.begin(), xact_temps.end()); diff --git a/test/baseline/feat-fixated-prices.test b/test/baseline/feat-fixated-prices.test index f4370870..4767d866 100644 --- a/test/baseline/feat-fixated-prices.test +++ b/test/baseline/feat-fixated-prices.test @@ -1,3 +1,5 @@ +P 1989/01/15 12:00:00 GAL $3 + 1990/01/01 Payee Expenses:Gas 100 GAL {=$2} Liabilities:MasterCard $-200 diff --git a/test/regress/25A099C9.test b/test/regress/25A099C9.test index fc06449b..48b6814e 100644 --- a/test/regress/25A099C9.test +++ b/test/regress/25A099C9.test @@ -2,16 +2,16 @@ test -f $sourcepath/src/amount.h reg -> 7 __ERROR__ While parsing file "$sourcepath/src/amount.h", line 66: Error: No quantity specified for amount -While parsing file "$sourcepath/src/amount.h", line 726: +While parsing file "$sourcepath/src/amount.h", line 731: Error: Invalid date/time: line amount_t amoun -While parsing file "$sourcepath/src/amount.h", line 732: +While parsing file "$sourcepath/src/amount.h", line 737: Error: Invalid date/time: line string amount_ -While parsing file "$sourcepath/src/amount.h", line 738: +While parsing file "$sourcepath/src/amount.h", line 743: Error: Invalid date/time: line string amount_ -While parsing file "$sourcepath/src/amount.h", line 744: +While parsing file "$sourcepath/src/amount.h", line 749: Error: Invalid date/time: line string amount_ -While parsing file "$sourcepath/src/amount.h", line 750: +While parsing file "$sourcepath/src/amount.h", line 755: Error: Invalid date/time: line std::ostream& -While parsing file "$sourcepath/src/amount.h", line 757: +While parsing file "$sourcepath/src/amount.h", line 762: Error: Invalid date/time: line std::istream& end test diff --git a/test/unit/t_commodity.cc b/test/unit/t_commodity.cc index dc64dcfb..6a6f27aa 100644 --- a/test/unit/t_commodity.cc +++ b/test/unit/t_commodity.cc @@ -94,7 +94,7 @@ BOOST_AUTO_TEST_CASE(testPriceHistory) amt = x1.value(CURRENT_TIME(), euro); BOOST_CHECK(amt); - BOOST_CHECK_EQUAL(string("EUR 1366.87"), amt->rounded().to_string()); + BOOST_CHECK_EQUAL(string("EUR 1787.50"), amt->rounded().to_string()); // Add a newer Euro pricing aapl.add_price(jan17_07, amount_t("EUR 23.00")); -- cgit v1.2.3 From ec1f15a4b2ae706dd99aff0d506977486ffef08b Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Wed, 7 Mar 2012 10:32:35 -0600 Subject: Made amount_t::price return an optional --- src/amount.cc | 4 ++-- src/amount.h | 2 +- 2 files changed, 3 insertions(+), 3 deletions(-) (limited to 'src/amount.h') diff --git a/src/amount.cc b/src/amount.cc index 313f8d27..c80ca14e 100644 --- a/src/amount.cc +++ b/src/amount.cc @@ -787,7 +787,7 @@ amount_t::value(const optional& moment, return none; } -amount_t amount_t::price() const +optional amount_t::price() const { if (has_annotation() && annotation().price) { amount_t tmp(*annotation().price); @@ -795,7 +795,7 @@ amount_t amount_t::price() const DEBUG("amount.price", "Returning price of " << *this << " = " << tmp); return tmp; } - return *this; + return none; } diff --git a/src/amount.h b/src/amount.h index 1db59b7e..09256b5d 100644 --- a/src/amount.h +++ b/src/amount.h @@ -407,7 +407,7 @@ public: value(const optional& moment = none, const optional& in_terms_of = none) const; - amount_t price() const; + optional price() const; /*@}*/ -- cgit v1.2.3 From ca8f702a1b18f2f114cd580abe59f03fb85e4803 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Fri, 9 Mar 2012 03:19:38 -0600 Subject: Added amount_t::commodity_ptr() --- src/amount.cc | 9 +++++++-- src/amount.h | 1 + test/regress/25A099C9.test | 12 ++++++------ 3 files changed, 14 insertions(+), 8 deletions(-) (limited to 'src/amount.h') diff --git a/src/amount.cc b/src/amount.cc index c80ca14e..d1aa1655 100644 --- a/src/amount.cc +++ b/src/amount.cc @@ -867,10 +867,15 @@ bool amount_t::fits_in_long() const return mpfr_fits_slong_p(tempf, GMP_RNDN); } -commodity_t& amount_t::commodity() const +commodity_t * amount_t::commodity_ptr() const { return (has_commodity() ? - *commodity_ : *commodity_pool_t::current_pool->null_commodity); + commodity_ : commodity_pool_t::current_pool->null_commodity); +} + +commodity_t& amount_t::commodity() const +{ + return *commodity_ptr(); } bool amount_t::has_commodity() const diff --git a/src/amount.h b/src/amount.h index 09256b5d..7bf4fe51 100644 --- a/src/amount.h +++ b/src/amount.h @@ -533,6 +533,7 @@ public: number() returns a commodity-less version of an amount. This is useful for accessing just the numeric portion of an amount. */ + commodity_t * commodity_ptr() const; commodity_t& commodity() const; bool has_commodity() const; diff --git a/test/regress/25A099C9.test b/test/regress/25A099C9.test index 48b6814e..c43deb21 100644 --- a/test/regress/25A099C9.test +++ b/test/regress/25A099C9.test @@ -2,16 +2,16 @@ test -f $sourcepath/src/amount.h reg -> 7 __ERROR__ While parsing file "$sourcepath/src/amount.h", line 66: Error: No quantity specified for amount -While parsing file "$sourcepath/src/amount.h", line 731: +While parsing file "$sourcepath/src/amount.h", line 732: Error: Invalid date/time: line amount_t amoun -While parsing file "$sourcepath/src/amount.h", line 737: +While parsing file "$sourcepath/src/amount.h", line 738: Error: Invalid date/time: line string amount_ -While parsing file "$sourcepath/src/amount.h", line 743: +While parsing file "$sourcepath/src/amount.h", line 744: Error: Invalid date/time: line string amount_ -While parsing file "$sourcepath/src/amount.h", line 749: +While parsing file "$sourcepath/src/amount.h", line 750: Error: Invalid date/time: line string amount_ -While parsing file "$sourcepath/src/amount.h", line 755: +While parsing file "$sourcepath/src/amount.h", line 756: Error: Invalid date/time: line std::ostream& -While parsing file "$sourcepath/src/amount.h", line 762: +While parsing file "$sourcepath/src/amount.h", line 763: Error: Invalid date/time: line std::istream& end test -- cgit v1.2.3 From 363670d35bf451ff8ce636c071da73a0d93c514a Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Sun, 11 Mar 2012 03:55:25 -0500 Subject: Tighten up argument passing related to fn_market() --- src/amount.cc | 19 +++++------ src/amount.h | 8 +++-- src/annotate.cc | 16 +++++----- src/annotate.h | 6 ++-- src/balance.cc | 4 +-- src/balance.h | 4 +-- src/commodity.cc | 78 ++++++++++++++++++++++------------------------ src/commodity.h | 22 ++++++------- src/history.cc | 55 ++++++++++++++++---------------- src/history.h | 23 +++++++------- src/pool.h | 3 +- src/py_amount.cc | 6 ++-- src/py_balance.cc | 6 ++-- src/py_value.cc | 6 ++-- src/quotes.cc | 2 +- src/quotes.h | 2 +- src/report.cc | 9 +++--- src/value.cc | 16 +++++----- src/value.h | 10 +++--- test/regress/25A099C9.test | 12 +++---- test/unit/t_commodity.cc | 6 ++-- 21 files changed, 153 insertions(+), 160 deletions(-) (limited to 'src/amount.h') diff --git a/src/amount.cc b/src/amount.cc index 46eb5531..5fa58528 100644 --- a/src/amount.cc +++ b/src/amount.cc @@ -728,16 +728,16 @@ void amount_t::in_place_unreduce() } optional -amount_t::value(const optional& moment, - const optional& in_terms_of) const +amount_t::value(const datetime_t& moment, + const commodity_t * in_terms_of) const { if (quantity) { #if defined(DEBUG_ON) DEBUG("commodity.price.find", "amount_t::value of " << commodity().symbol()); - if (moment) + if (! moment.is_not_a_date_time()) DEBUG("commodity.price.find", - "amount_t::value: moment = " << *moment); + "amount_t::value: moment = " << moment); if (in_terms_of) DEBUG("commodity.price.find", "amount_t::value: in_terms_of = " << in_terms_of->symbol()); @@ -745,7 +745,7 @@ amount_t::value(const optional& moment, if (has_commodity() && (in_terms_of || ! commodity().has_flags(COMMODITY_PRIMARY))) { optional point; - optional comm(in_terms_of); + const commodity_t * comm(in_terms_of); if (has_annotation() && annotation().price) { if (annotation().has_flags(ANNOTATION_PRICE_FIXATED)) { @@ -755,7 +755,7 @@ amount_t::value(const optional& moment, "amount_t::value: fixated price = " << point->price); } else if (! comm) { - comm = annotation().price->commodity(); + comm = annotation().price->commodity_ptr(); } } @@ -869,15 +869,10 @@ bool amount_t::fits_in_long() const commodity_t * amount_t::commodity_ptr() const { - return (has_commodity() ? + return (commodity_ ? commodity_ : commodity_pool_t::current_pool->null_commodity); } -commodity_t& amount_t::commodity() const -{ - return *commodity_ptr(); -} - bool amount_t::has_commodity() const { return commodity_ && commodity_ != commodity_->pool().null_commodity; diff --git a/src/amount.h b/src/amount.h index 7bf4fe51..903a01cd 100644 --- a/src/amount.h +++ b/src/amount.h @@ -404,8 +404,8 @@ public: $100.00. */ optional - value(const optional& moment = none, - const optional& in_terms_of = none) const; + value(const datetime_t& moment = datetime_t(), + const commodity_t * in_terms_of = NULL) const; optional price() const; @@ -534,7 +534,9 @@ public: useful for accessing just the numeric portion of an amount. */ commodity_t * commodity_ptr() const; - commodity_t& commodity() const; + commodity_t& commodity() const { + return *commodity_ptr(); + } bool has_commodity() const; void set_commodity(commodity_t& comm) { diff --git a/src/annotate.cc b/src/annotate.cc index d2c7f983..2b118e76 100644 --- a/src/annotate.cc +++ b/src/annotate.cc @@ -241,16 +241,16 @@ bool annotated_commodity_t::operator==(const commodity_t& comm) const } optional -annotated_commodity_t::find_price(const optional& commodity, - const optional& moment, - const optional& oldest) const +annotated_commodity_t::find_price(const commodity_t * commodity, + const datetime_t& moment, + const datetime_t& oldest) const { DEBUG("commodity.price.find", "annotated_commodity_t::find_price(" << symbol() << ")"); datetime_t when; - if (moment) - when = *moment; + if (! moment.is_not_a_date_time()) + when = moment; else if (epoch) when = *epoch; else @@ -258,7 +258,7 @@ annotated_commodity_t::find_price(const optional& commodity, DEBUG("commodity.price.find", "reference time: " << when); - optional target; + const commodity_t * target = NULL; if (commodity) target = commodity; @@ -272,7 +272,7 @@ annotated_commodity_t::find_price(const optional& commodity, } else if (! target) { DEBUG("commodity.price.find", "setting target commodity from price"); - target = details.price->commodity(); + target = details.price->commodity_ptr(); } } @@ -285,7 +285,7 @@ annotated_commodity_t::find_price(const optional& commodity, return find_price_from_expr(const_cast(*details.value_expr), commodity, when); - return commodity_t::find_price(commodity, moment, oldest); + return commodity_t::find_price(target, moment, oldest); } commodity_t& diff --git a/src/annotate.h b/src/annotate.h index 606c6a60..044ebc4d 100644 --- a/src/annotate.h +++ b/src/annotate.h @@ -256,9 +256,9 @@ public: } optional - virtual find_price(const optional& commodity = none, - const optional& moment = none, - const optional& oldest = none) const; + virtual find_price(const commodity_t * commodity = NULL, + const datetime_t& moment = datetime_t(), + const datetime_t& oldest = datetime_t()) const; virtual commodity_t& strip_annotations(const keep_details_t& what_to_keep); virtual void write_annotations(std::ostream& out, diff --git a/src/balance.cc b/src/balance.cc index 08368dd8..f87e8bbd 100644 --- a/src/balance.cc +++ b/src/balance.cc @@ -185,8 +185,8 @@ balance_t& balance_t::operator/=(const amount_t& amt) } optional -balance_t::value(const optional& moment, - const optional& in_terms_of) const +balance_t::value(const datetime_t& moment, + const commodity_t * in_terms_of) const { balance_t temp; bool resolved = false; diff --git a/src/balance.h b/src/balance.h index 921f87ef..5f0d52ed 100644 --- a/src/balance.h +++ b/src/balance.h @@ -384,8 +384,8 @@ public: } optional - value(const optional& moment = none, - const optional& in_terms_of = none) const; + value(const datetime_t& moment = datetime_t(), + const commodity_t * in_terms_of = NULL) const; /** * Truth tests. An balance may be truth test in two ways: diff --git a/src/commodity.cc b/src/commodity.cc index 963fb646..8f0dc100 100644 --- a/src/commodity.cc +++ b/src/commodity.cc @@ -71,12 +71,12 @@ void commodity_t::remove_price(const datetime_t& date, commodity_t& commodity) } void commodity_t::map_prices(function fn, - const optional& moment, - const optional& _oldest) + const datetime_t& moment, + const datetime_t& _oldest) { datetime_t when; - if (moment) - when = *moment; + if (! moment.is_not_a_date_time()) + when = moment; else if (epoch) when = *epoch; else @@ -86,8 +86,7 @@ void commodity_t::map_prices(function fn, } optional -commodity_t::find_price_from_expr(expr_t& expr, - const optional& commodity, +commodity_t::find_price_from_expr(expr_t& expr, const commodity_t * commodity, const datetime_t& moment) const { #if defined(DEBUG_ON) @@ -114,31 +113,30 @@ commodity_t::find_price_from_expr(expr_t& expr, } optional -commodity_t::find_price(const optional& commodity, - const optional& moment, - const optional& oldest) const +commodity_t::find_price(const commodity_t * commodity, + const datetime_t& moment, + const datetime_t& oldest) const { DEBUG("commodity.price.find", "commodity_t::find_price(" << symbol() << ")"); - optional target; + const commodity_t * target = NULL; if (commodity) target = commodity; else if (pool().default_commodity) - target = *pool().default_commodity; + target = &*pool().default_commodity; - if (target && *this == *target) + if (target && this == target) return none; - optional - entry(base_t::memoized_price_entry(moment, oldest, - commodity ? &(*commodity) : NULL)); + base_t::memoized_price_entry entry(moment, oldest, + commodity ? commodity : NULL); DEBUG("commodity.price.find", "looking for memoized args: " - << (moment ? format_datetime(*moment) : "NONE") << ", " - << (oldest ? format_datetime(*oldest) : "NONE") << ", " + << (! moment.is_not_a_date_time() ? format_datetime(moment) : "NONE") << ", " + << (! oldest.is_not_a_date_time() ? format_datetime(oldest) : "NONE") << ", " << (commodity ? commodity->symbol() : "NONE")); { - base_t::memoized_price_map::iterator i = base->price_map.find(*entry); + base_t::memoized_price_map::iterator i = base->price_map.find(entry); if (i != base->price_map.end()) { DEBUG("commodity.price.find", "found! returning: " << ((*i).second ? (*i).second->price : amount_t(0L))); @@ -147,8 +145,8 @@ commodity_t::find_price(const optional& commodity, } datetime_t when; - if (moment) - when = *moment; + if (! moment.is_not_a_date_time()) + when = moment; else if (epoch) when = *epoch; else @@ -157,40 +155,40 @@ commodity_t::find_price(const optional& commodity, if (base->value_expr) return find_price_from_expr(*base->value_expr, commodity, when); - optional point = - target ? - pool().commodity_price_history.find_price(*this, *target, when, oldest) : - pool().commodity_price_history.find_price(*this, when, oldest); - - if (entry) { - if (base->price_map.size() > base_t::max_price_map_size) { - DEBUG("history.find", - "price map has grown too large, clearing it by half"); - for (std::size_t i = 0; i < base_t::max_price_map_size >> 1; i++) - base->price_map.erase(base->price_map.begin()); - } + optional + point(target ? + pool().commodity_price_history.find_price(*this, *target, + when, oldest) : + pool().commodity_price_history.find_price(*this, when, oldest)); + // Record this price point in the memoization map + if (base->price_map.size() > base_t::max_price_map_size) { DEBUG("history.find", - "remembered: " << (point ? point->price : amount_t(0L))); - base->price_map.insert(base_t::memoized_price_map::value_type(*entry, point)); + "price map has grown too large, clearing it by half"); + for (std::size_t i = 0; i < base_t::max_price_map_size >> 1; i++) + base->price_map.erase(base->price_map.begin()); } + DEBUG("history.find", + "remembered: " << (point ? point->price : amount_t(0L))); + base->price_map.insert(base_t::memoized_price_map::value_type(entry, point)); + return point; } optional commodity_t::check_for_updated_price(const optional& point, - const optional& moment, - const optional& in_terms_of) + const datetime_t& moment, + const commodity_t* in_terms_of) { if (pool().get_quotes && ! has_flags(COMMODITY_NOMARKET)) { bool exceeds_leeway = true; if (point) { time_duration_t::sec_type seconds_diff; - if (moment) { - seconds_diff = (*moment - point->when).total_seconds(); - DEBUG("commodity.download", "moment = " << *moment); + if (! moment.is_not_a_date_time()) { + seconds_diff = (moment - point->when).total_seconds(); + DEBUG("commodity.download", "moment = " << moment); DEBUG("commodity.download", "slip.moment = " << seconds_diff); } else { seconds_diff = (TRUE_CURRENT_TIME() - point->when).total_seconds(); @@ -209,7 +207,7 @@ commodity_t::check_for_updated_price(const optional& point, pool().get_commodity_quote(*this, in_terms_of)) { if (! in_terms_of || (quote->price.has_commodity() && - quote->price.commodity() == *in_terms_of)) + quote->price.commodity_ptr() == in_terms_of)) return quote; } } diff --git a/src/commodity.h b/src/commodity.h index 1358966e..bd1aedb9 100644 --- a/src/commodity.h +++ b/src/commodity.h @@ -117,12 +117,12 @@ protected: optional larger; optional value_expr; - typedef tuple, - optional, commodity_t *> memoized_price_entry; + typedef tuple memoized_price_entry; typedef std::map > memoized_price_map; - static const std::size_t max_price_map_size = 16; + static const std::size_t max_price_map_size = 8; mutable memoized_price_map price_map; public: @@ -272,22 +272,22 @@ public: void remove_price(const datetime_t& date, commodity_t& commodity); void map_prices(function fn, - const optional& moment = none, - const optional& _oldest = none); + const datetime_t& moment = datetime_t(), + const datetime_t& _oldest = datetime_t()); optional - find_price_from_expr(expr_t& expr, const optional& commodity, + find_price_from_expr(expr_t& expr, const commodity_t * commodity, const datetime_t& moment) const; optional - virtual find_price(const optional& commodity = none, - const optional& moment = none, - const optional& oldest = none) const; + virtual find_price(const commodity_t * commodity = NULL, + const datetime_t& moment = datetime_t(), + const datetime_t& oldest = datetime_t()) const; optional check_for_updated_price(const optional& point, - const optional& moment, - const optional& in_terms_of); + const datetime_t& moment, + const commodity_t * in_terms_of); commodity_t& nail_down(const expr_t& expr); diff --git a/src/history.cc b/src/history.cc index 83326728..22ac4494 100644 --- a/src/history.cc +++ b/src/history.cc @@ -52,15 +52,15 @@ public: PricePointMap price_point; PriceRatioMap ratios; - datetime_t reftime; - optional oldest; + datetime_t reftime; + datetime_t oldest; recent_edge_weight() { } - recent_edge_weight(EdgeWeightMap _weight, - PricePointMap _price_point, - PriceRatioMap _ratios, - datetime_t _reftime, - const optional& _oldest = none) + recent_edge_weight(EdgeWeightMap _weight, + PricePointMap _price_point, + PriceRatioMap _ratios, + const datetime_t& _reftime, + const datetime_t& _oldest = datetime_t()) : weight(_weight), price_point(_price_point), ratios(_ratios), reftime(_reftime), oldest(_oldest) { } @@ -69,8 +69,8 @@ public: { #if defined(DEBUG_ON) DEBUG("history.find", " reftime = " << reftime); - if (oldest) { - DEBUG("history.find", " oldest = " << *oldest); + if (! oldest.is_not_a_date_time()) { + DEBUG("history.find", " oldest = " << oldest); } #endif @@ -88,7 +88,7 @@ public: --low; assert(((*low).first <= reftime)); - if (oldest && (*low).first < *oldest) { + if (! oldest.is_not_a_date_time() && (*low).first < oldest) { DEBUG("history.find", " edge is out of range"); return false; } @@ -170,9 +170,9 @@ void commodity_history_t::remove_price(const commodity_t& source, void commodity_history_t::map_prices(function fn, - const commodity_t& source, - const datetime_t& moment, - const optional& oldest) + const commodity_t& source, + const datetime_t& moment, + const datetime_t& oldest) { vertex_descriptor sv = vertex(*source.graph_index(), price_graph); @@ -193,7 +193,7 @@ void commodity_history_t::map_prices(function= *oldest) && when <= moment) { + if ((oldest.is_not_a_date_time() || when >= oldest) && when <= moment) { if (pair.second.commodity() == source) { amount_t price(pair.second); price.in_place_invert(); @@ -209,9 +209,9 @@ void commodity_history_t::map_prices(function -commodity_history_t::find_price(const commodity_t& source, - const datetime_t& moment, - const optional& oldest) +commodity_history_t::find_price(const commodity_t& source, + const datetime_t& moment, + const datetime_t& oldest) { vertex_descriptor sv = vertex(*source.graph_index(), price_graph); @@ -270,10 +270,10 @@ commodity_history_t::find_price(const commodity_t& source, } optional -commodity_history_t::find_price(const commodity_t& source, - const commodity_t& target, - const datetime_t& moment, - const optional& oldest) +commodity_history_t::find_price(const commodity_t& source, + const commodity_t& target, + const datetime_t& moment, + const datetime_t& oldest) { vertex_descriptor sv = vertex(*source.graph_index(), price_graph); vertex_descriptor tv = vertex(*target.graph_index(), price_graph); @@ -402,17 +402,16 @@ private: Name name; }; -void commodity_history_t::print_map(std::ostream& out, - const optional& moment) +void commodity_history_t::print_map(std::ostream& out, const datetime_t& moment) { - if (moment) { + if (moment.is_not_a_date_time()) { + write_graphviz(out, price_graph, + label_writer(get(vertex_name, price_graph))); + } else { FGraph fg(price_graph, recent_edge_weight - (get(edge_weight, price_graph), pricemap, ratiomap, *moment)); + (get(edge_weight, price_graph), pricemap, ratiomap, moment)); write_graphviz(out, fg, label_writer(get(vertex_name, fg))); - } else { - write_graphviz(out, price_graph, - label_writer(get(vertex_name, price_graph))); } } diff --git a/src/history.h b/src/history.h index 920feec6..71cbad0c 100644 --- a/src/history.h +++ b/src/history.h @@ -111,23 +111,22 @@ public: const datetime_t& date); void map_prices(function fn, - const commodity_t& source, - const datetime_t& moment, - const optional& _oldest = none); + const commodity_t& source, + const datetime_t& moment, + const datetime_t& _oldest = datetime_t()); optional - find_price(const commodity_t& source, - const datetime_t& moment, - const optional& oldest = none); + find_price(const commodity_t& source, + const datetime_t& moment, + const datetime_t& oldest = datetime_t()); optional - find_price(const commodity_t& source, - const commodity_t& target, - const datetime_t& moment, - const optional& oldest = none); + find_price(const commodity_t& source, + const commodity_t& target, + const datetime_t& moment, + const datetime_t& oldest = datetime_t()); - void print_map(std::ostream& out, - const optional& moment = none); + void print_map(std::ostream& out, const datetime_t& moment = datetime_t()); }; } // namespace ledger diff --git a/src/pool.h b/src/pool.h index b7921f59..eb630781 100644 --- a/src/pool.h +++ b/src/pool.h @@ -83,13 +83,12 @@ public: bool get_quotes; // --download function - (commodity_t& commodity, const optional& in_terms_of)> + (commodity_t& commodity, const commodity_t * in_terms_of)> get_commodity_quote; static shared_ptr current_pool; explicit commodity_pool_t(); - virtual ~commodity_pool_t() { TRACE_DTOR(commodity_pool_t); } diff --git a/src/py_amount.cc b/src/py_amount.cc index 25ec8e26..ea69dec5 100644 --- a/src/py_amount.cc +++ b/src/py_amount.cc @@ -48,12 +48,12 @@ namespace { return amount.value(CURRENT_TIME()); } boost::optional py_value_1(const amount_t& amount, - commodity_t& in_terms_of) { + const commodity_t * in_terms_of) { return amount.value(CURRENT_TIME(), in_terms_of); } boost::optional py_value_2(const amount_t& amount, - commodity_t& in_terms_of, - datetime_t& moment) { + const commodity_t * in_terms_of, + const datetime_t& moment) { return amount.value(moment, in_terms_of); } diff --git a/src/py_balance.cc b/src/py_balance.cc index 38941832..2ae546f1 100644 --- a/src/py_balance.cc +++ b/src/py_balance.cc @@ -48,12 +48,12 @@ namespace { return balance.value(CURRENT_TIME()); } boost::optional py_value_1(const balance_t& balance, - commodity_t& in_terms_of) { + const commodity_t * in_terms_of) { return balance.value(CURRENT_TIME(), in_terms_of); } boost::optional py_value_2(const balance_t& balance, - commodity_t& in_terms_of, - datetime_t& moment) { + const commodity_t * in_terms_of, + const datetime_t& moment) { return balance.value(moment, in_terms_of); } diff --git a/src/py_value.cc b/src/py_value.cc index 78301acd..efeb4340 100644 --- a/src/py_value.cc +++ b/src/py_value.cc @@ -51,12 +51,12 @@ namespace { return value.value(CURRENT_TIME()); } boost::optional py_value_1(const value_t& value, - commodity_t& in_terms_of) { + const commodity_t * in_terms_of) { return value.value(CURRENT_TIME(), in_terms_of); } boost::optional py_value_2(const value_t& value, - commodity_t& in_terms_of, - datetime_t& moment) { + const commodity_t * in_terms_of, + const datetime_t& moment) { return value.value(moment, in_terms_of); } diff --git a/src/quotes.cc b/src/quotes.cc index b29eb8bd..c33e0826 100644 --- a/src/quotes.cc +++ b/src/quotes.cc @@ -40,7 +40,7 @@ namespace ledger { optional commodity_quote_from_script(commodity_t& commodity, - const optional& exchange_commodity) + const commodity_t * exchange_commodity) { DEBUG("commodity.download", "downloading quote for symbol " << commodity.symbol()); #if defined(DEBUG_ON) diff --git a/src/quotes.h b/src/quotes.h index 52092fbc..56740e47 100644 --- a/src/quotes.h +++ b/src/quotes.h @@ -46,7 +46,7 @@ namespace ledger { optional commodity_quote_from_script(commodity_t& commodity, - const optional& exchange_commodity); + const commodity_t * exchange_commodity); } // namespace ledger diff --git a/src/report.cc b/src/report.cc index 8205c1dd..a3abcb98 100644 --- a/src/report.cc +++ b/src/report.cc @@ -532,12 +532,13 @@ value_t report_t::fn_should_bold(call_scope_t& scope) value_t report_t::fn_market(call_scope_t& args) { - optional moment = (args.has(1) ? - args.get(1) : - optional()); value_t result; value_t arg0 = args[0]; + datetime_t moment; + if (args.has(1)) + moment = args.get(1); + if (arg0.is_string()) { amount_t tmp(1L); commodity_t * commodity = @@ -962,7 +963,7 @@ value_t report_t::pricemap_command(call_scope_t& args) std::ostream& out(output_stream); commodity_pool_t::current_pool->commodity_price_history.print_map (out, args.has(0) ? - optional(datetime_t(parse_date(args.get(0)))) : none); + datetime_t(parse_date(args.get(0))) : datetime_t()); return true; } diff --git a/src/value.cc b/src/value.cc index c4e7170d..cae2a356 100644 --- a/src/value.cc +++ b/src/value.cc @@ -1399,8 +1399,8 @@ bool value_t::is_zero() const return false; } -value_t value_t::value(const optional& moment, - const optional& in_terms_of) const +value_t value_t::value(const datetime_t& moment, + const commodity_t * in_terms_of) const { switch (type()) { case INTEGER: @@ -1432,9 +1432,9 @@ value_t value_t::value(const optional& moment, return NULL_VALUE; } -value_t value_t::exchange_commodities(const std::string& commodities, - const bool add_prices, - const optional& moment) +value_t value_t::exchange_commodities(const std::string& commodities, + const bool add_prices, + const datetime_t& moment) { if (type() == SEQUENCE) { value_t temp; @@ -1447,7 +1447,7 @@ value_t value_t::exchange_commodities(const std::string& commodities, // expression, skip the expensive logic below. if (commodities.find(',') == string::npos && commodities.find('=') == string::npos) - return value(moment, *commodity_pool_t::current_pool->find_or_create(commodities)); + return value(moment, commodity_pool_t::current_pool->find_or_create(commodities)); std::vector comms; std::vector force; @@ -1479,7 +1479,7 @@ value_t value_t::exchange_commodities(const std::string& commodities, break; DEBUG("commodity.exchange", "Referent doesn't match, pricing..."); - if (optional val = as_amount_lval().value(moment, *comm)) { + if (optional val = as_amount_lval().value(moment, comm)) { DEBUG("commodity.exchange", "Re-priced amount is: " << *val); return *val; } @@ -1502,7 +1502,7 @@ value_t value_t::exchange_commodities(const std::string& commodities, temp += pair.second; } else { DEBUG("commodity.exchange", "Referent doesn't match, pricing..."); - if (optional val = pair.second.value(moment, *comm)) { + if (optional val = pair.second.value(moment, comm)) { DEBUG("commodity.exchange", "Re-priced member amount is: " << *val); temp += *val; repriced = true; diff --git a/src/value.h b/src/value.h index df075843..a95968c2 100644 --- a/src/value.h +++ b/src/value.h @@ -477,12 +477,12 @@ public: void in_place_unreduce(); // exists for efficiency's sake // Return the "market value" of a given value at a specific time. - value_t value(const optional& moment = none, - const optional& in_terms_of = none) const; + value_t value(const datetime_t& moment = datetime_t(), + const commodity_t * in_terms_of = NULL) const; - value_t exchange_commodities(const std::string& commodities, - const bool add_prices = false, - const optional& moment = none); + value_t exchange_commodities(const std::string& commodities, + const bool add_prices = false, + const datetime_t& moment = datetime_t()); /** * Truth tests. diff --git a/test/regress/25A099C9.test b/test/regress/25A099C9.test index c43deb21..418b77c8 100644 --- a/test/regress/25A099C9.test +++ b/test/regress/25A099C9.test @@ -2,16 +2,16 @@ test -f $sourcepath/src/amount.h reg -> 7 __ERROR__ While parsing file "$sourcepath/src/amount.h", line 66: Error: No quantity specified for amount -While parsing file "$sourcepath/src/amount.h", line 732: +While parsing file "$sourcepath/src/amount.h", line 734: Error: Invalid date/time: line amount_t amoun -While parsing file "$sourcepath/src/amount.h", line 738: +While parsing file "$sourcepath/src/amount.h", line 740: Error: Invalid date/time: line string amount_ -While parsing file "$sourcepath/src/amount.h", line 744: +While parsing file "$sourcepath/src/amount.h", line 746: Error: Invalid date/time: line string amount_ -While parsing file "$sourcepath/src/amount.h", line 750: +While parsing file "$sourcepath/src/amount.h", line 752: Error: Invalid date/time: line string amount_ -While parsing file "$sourcepath/src/amount.h", line 756: +While parsing file "$sourcepath/src/amount.h", line 758: Error: Invalid date/time: line std::ostream& -While parsing file "$sourcepath/src/amount.h", line 763: +While parsing file "$sourcepath/src/amount.h", line 765: Error: Invalid date/time: line std::istream& end test diff --git a/test/unit/t_commodity.cc b/test/unit/t_commodity.cc index 6a6f27aa..8caeb694 100644 --- a/test/unit/t_commodity.cc +++ b/test/unit/t_commodity.cc @@ -92,18 +92,18 @@ BOOST_AUTO_TEST_CASE(testPriceHistory) BOOST_CHECK_EQUAL(string("$2124.122"), amt->to_fullstring()); #endif - amt = x1.value(CURRENT_TIME(), euro); + amt = x1.value(CURRENT_TIME(), &euro); BOOST_CHECK(amt); BOOST_CHECK_EQUAL(string("EUR 1787.50"), amt->rounded().to_string()); // Add a newer Euro pricing aapl.add_price(jan17_07, amount_t("EUR 23.00")); - amt = x1.value(CURRENT_TIME(), euro); + amt = x1.value(CURRENT_TIME(), &euro); BOOST_CHECK(amt); BOOST_CHECK_EQUAL(string("EUR 2302.30"), amt->to_string()); - amt = x1.value(CURRENT_TIME(), cad); + amt = x1.value(CURRENT_TIME(), &cad); BOOST_CHECK(amt); BOOST_CHECK_EQUAL(string("CAD 3223.22"), amt->to_string()); #endif // NOT_FOR_PYTHON -- 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/amount.h') 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 From 8e8c2904f55eb9a43b3eb8057e9f11767a624dff Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Fri, 30 Mar 2012 00:38:29 -0500 Subject: Never price commodities using annotated commodities --- src/amount.cc | 6 +++--- src/amount.h | 9 +++++++++ src/annotate.cc | 2 +- src/commodity.cc | 17 ++++++++--------- src/commodity.h | 3 +++ test/regress/25A099C9.test | 20 ++++++++++---------- 6 files changed, 34 insertions(+), 23 deletions(-) (limited to 'src/amount.h') diff --git a/src/amount.cc b/src/amount.cc index 2f7b434e..50496f2d 100644 --- a/src/amount.cc +++ b/src/amount.cc @@ -757,10 +757,10 @@ amount_t::value(const datetime_t& moment, } } - if (! point) { - if (comm && commodity().referent() == comm->referent()) - return *this; + if (comm && commodity().referent() == comm->referent()) + return with_commodity(comm->referent()); + if (! point) { point = commodity().find_price(comm, moment); // Whether a price was found or not, check whether we should attempt diff --git a/src/amount.h b/src/amount.h index 10e83552..cd77a79a 100644 --- a/src/amount.h +++ b/src/amount.h @@ -544,6 +544,15 @@ public: *this = 0L; commodity_ = &comm; } + amount_t with_commodity(const commodity_t& comm) const { + if (commodity_ == &comm) { + return *this; + } else { + amount_t tmp(*this); + tmp.set_commodity(const_cast(comm)); + return tmp; + } + } void clear_commodity() { commodity_ = NULL; } diff --git a/src/annotate.cc b/src/annotate.cc index c9fd6d3f..41e7a752 100644 --- a/src/annotate.cc +++ b/src/annotate.cc @@ -288,7 +288,7 @@ annotated_commodity_t::find_price(const commodity_t * commodity, return find_price_from_expr(const_cast(*details.value_expr), commodity, when); - return commodity_t::find_price(target, moment, oldest); + return commodity_t::find_price(target, when, oldest); } commodity_t& diff --git a/src/commodity.cc b/src/commodity.cc index bc04c3db..a72d85c8 100644 --- a/src/commodity.cc +++ b/src/commodity.cc @@ -56,14 +56,14 @@ void commodity_t::add_price(const datetime_t& date, const amount_t& price, DEBUG("history.find", "Adding price: " << symbol() << " for " << price << " on " << date); - pool().commodity_price_history.add_price(*this, date, price); + pool().commodity_price_history.add_price(referent(), date, price); base->price_map.clear(); // a price was added, invalid the map } void commodity_t::remove_price(const datetime_t& date, commodity_t& commodity) { - pool().commodity_price_history.remove_price(*this, commodity, date); + pool().commodity_price_history.remove_price(referent(), commodity, date); DEBUG("history.find", "Removing price: " << symbol() << " on " << date); @@ -83,7 +83,7 @@ void commodity_t::map_prices(function fn, else when = CURRENT_TIME(); - pool().commodity_price_history.map_prices(fn, *this, when, _oldest, + pool().commodity_price_history.map_prices(fn, referent(), when, _oldest, bidirectionally); } @@ -159,9 +159,9 @@ commodity_t::find_price(const commodity_t * commodity, optional point(target ? - pool().commodity_price_history.find_price(*this, *target, + pool().commodity_price_history.find_price(referent(), *target, when, oldest) : - pool().commodity_price_history.find_price(*this, when, oldest)); + pool().commodity_price_history.find_price(referent(), when, oldest)); // Record this price point in the memoization map if (base->price_map.size() > base_t::max_price_map_size) { @@ -206,7 +206,7 @@ commodity_t::check_for_updated_price(const optional& point, DEBUG("commodity.download", "attempting to download a more current quote..."); if (optional quote = - pool().get_commodity_quote(*this, in_terms_of)) { + pool().get_commodity_quote(referent(), in_terms_of)) { if (! in_terms_of || (quote->price.has_commodity() && quote->price.commodity_ptr() == in_terms_of)) @@ -220,12 +220,11 @@ commodity_t::check_for_updated_price(const optional& point, commodity_t& commodity_t::nail_down(const expr_t& expr) { annotation_t new_details; + new_details.value_expr = expr; new_details.add_flags(ANNOTATION_VALUE_EXPR_CALCULATED); - commodity_t * new_comm = - commodity_pool_t::current_pool->find_or_create(symbol(), new_details); - return *new_comm; + return *pool().find_or_create(symbol(), new_details); } commodity_t::operator bool() const diff --git a/src/commodity.h b/src/commodity.h index d6885ee9..bfbabe6b 100644 --- a/src/commodity.h +++ b/src/commodity.h @@ -188,6 +188,9 @@ public: return comm == *this; return base.get() == comm.base.get(); } + bool operator==(const string& name) const { + return base_symbol() == name; + } static bool symbol_needs_quotes(const string& symbol); diff --git a/test/regress/25A099C9.test b/test/regress/25A099C9.test index a8a93832..1ef5ebef 100644 --- a/test/regress/25A099C9.test +++ b/test/regress/25A099C9.test @@ -20,24 +20,24 @@ While parsing file "src/amount.h", line 121: Error: Unexpected whitespace at beginning of line While parsing file "src/amount.h", line 132: Error: Unexpected whitespace at beginning of line -While parsing file "src/amount.h", line 693: +While parsing file "src/amount.h", line 702: Error: Unexpected whitespace at beginning of line -While parsing file "src/amount.h", line 723: +While parsing file "src/amount.h", line 732: Error: Unexpected whitespace at beginning of line -While parsing file "src/amount.h", line 731: +While parsing file "src/amount.h", line 740: Error: Unexpected whitespace at beginning of line -While parsing file "src/amount.h", line 734: +While parsing file "src/amount.h", line 743: Error: Invalid date/time: line amount_t amoun -While parsing file "src/amount.h", line 740: +While parsing file "src/amount.h", line 749: Error: Invalid date/time: line string amount_ -While parsing file "src/amount.h", line 746: +While parsing file "src/amount.h", line 755: Error: Invalid date/time: line string amount_ -While parsing file "src/amount.h", line 752: +While parsing file "src/amount.h", line 761: Error: Invalid date/time: line string amount_ -While parsing file "src/amount.h", line 758: +While parsing file "src/amount.h", line 767: Error: Invalid date/time: line std::ostream& -While parsing file "src/amount.h", line 765: +While parsing file "src/amount.h", line 774: Error: Invalid date/time: line std::istream& -While parsing file "src/amount.h", line 771: +While parsing file "src/amount.h", line 780: Error: Unexpected whitespace at beginning of line end test -- cgit v1.2.3