diff options
author | John Wiegley <johnw@newartisans.com> | 2009-02-22 17:51:11 -0400 |
---|---|---|
committer | John Wiegley <johnw@newartisans.com> | 2009-02-22 17:51:11 -0400 |
commit | ea75613760440604ba5bdc2ab7f89892dc28c079 (patch) | |
tree | c6cd3ec4871f9598dfe2191f0cb7e2933da8b920 /src | |
parent | f2e4f4c6d1f20949232ab776cb24bfbd2db2797b (diff) | |
download | fork-ledger-ea75613760440604ba5bdc2ab7f89892dc28c079.tar.gz fork-ledger-ea75613760440604ba5bdc2ab7f89892dc28c079.tar.bz2 fork-ledger-ea75613760440604ba5bdc2ab7f89892dc28c079.zip |
--exchange option now accepts multiple commodities
They must be separated by a comma, and all whitespace is ignored.
Diffstat (limited to 'src')
-rw-r--r-- | src/commodity.cc | 39 | ||||
-rw-r--r-- | src/commodity.h | 29 | ||||
-rw-r--r-- | src/interactive.h | 2 | ||||
-rw-r--r-- | src/option.h | 2 | ||||
-rw-r--r-- | src/report.cc | 44 | ||||
-rw-r--r-- | src/report.h | 4 | ||||
-rw-r--r-- | src/utils.h | 8 | ||||
-rw-r--r-- | src/value.cc | 6 |
8 files changed, 43 insertions, 91 deletions
diff --git a/src/commodity.cc b/src/commodity.cc index 57e20891..f758d3b4 100644 --- a/src/commodity.cc +++ b/src/commodity.cc @@ -352,29 +352,6 @@ optional<price_point_t> return none; } -optional<price_point_t> - commodity_t::base_t::varied_history_t:: - find_price(const commodity_t& source, - const std::vector<commodity_t *>& commodities, - const optional<datetime_t>& moment, - const optional<datetime_t>& oldest -#if defined(DEBUG_ON) - , const int indent -#endif - ) const -{ - foreach (commodity_t * commodity, commodities) { - if (optional<price_point_t> point = find_price(source, *commodity, - moment, oldest -#if defined(DEBUG_ON) - , indent -#endif - )) - return point; - } - return none; -} - optional<commodity_t::base_t::history_t&> commodity_t::base_t::varied_history_t:: history(const optional<commodity_t&>& commodity) @@ -400,22 +377,6 @@ optional<commodity_t::base_t::history_t&> return none; } -optional<commodity_t::history_t&> -commodity_t::base_t::varied_history_t::history - (const std::vector<commodity_t *>& commodities) -{ - // This function differs from the single commodity case avoid in that - // 'commodities' represents a list of preferred valuation commodities. - // If no price can be located in terms of the first commodity, then - // the second is chosen, etc. - - foreach (commodity_t * commodity, commodities) { - if (optional<history_t&> hist = history(*commodity)) - return hist; - } - return none; -} - void commodity_t::exchange(commodity_t& commodity, const amount_t& per_unit_cost, const datetime_t& moment) diff --git a/src/commodity.h b/src/commodity.h index 4e57ec6f..2962152a 100644 --- a/src/commodity.h +++ b/src/commodity.h @@ -126,20 +126,9 @@ public: , const int indent = 0 #endif ) const; - optional<price_point_t> - find_price(const commodity_t& source, - const std::vector<commodity_t *>& commodities, - const optional<datetime_t>& moment = none, - const optional<datetime_t>& oldest = none -#if defined(DEBUG_ON) - , const int indent = 0 -#endif - ) const; optional<history_t&> history(const optional<commodity_t&>& commodity = none); - optional<history_t&> - history(const std::vector<commodity_t *>& commodities); }; #define COMMODITY_STYLE_DEFAULTS 0x000 @@ -283,7 +272,6 @@ public: } optional<history_t&> history(const optional<commodity_t&>& commodity); - optional<history_t&> history(const std::vector<commodity_t *>& commodities); public: // These methods provide a transparent pass-through to the underlying @@ -324,23 +312,6 @@ public: return none; } - optional<price_point_t> - find_price(const std::vector<commodity_t *>& commodities, - const optional<datetime_t>& moment = none, - const optional<datetime_t>& oldest = none -#if defined(DEBUG_ON) - , const int indent = 0 -#endif - ) const { - if (base->varied_history) - return base->varied_history->find_price(*this, commodities, moment, oldest -#if defined(DEBUG_ON) - , indent -#endif - ); - return none; - } - // Methods to exchange one commodity for another, while recording the // factored price. diff --git a/src/interactive.h b/src/interactive.h index 766953ec..a2c64ffb 100644 --- a/src/interactive.h +++ b/src/interactive.h @@ -73,7 +73,7 @@ public: void verify_arguments() const; bool has(std::size_t index) const { - if (index < args.size()) + if (index < args.size() && ! args[index].is_null()) return true; return false; } diff --git a/src/option.h b/src/option.h index d7aeba1b..538de60a 100644 --- a/src/option.h +++ b/src/option.h @@ -162,7 +162,7 @@ public: if (handled) return value; else - return false; + return NULL_VALUE; } else { return handled; diff --git a/src/report.cc b/src/report.cc index 62fbe503..03b35b71 100644 --- a/src/report.cc +++ b/src/report.cc @@ -124,22 +124,34 @@ value_t report_t::fn_market_value(call_scope_t& scope) { interactive_t args(scope, "a&ts"); - commodity_t * commodity = NULL; - if (args.has(2)) - commodity = amount_t::current_pool->find_or_create(args.get<string>(2)); - - DEBUG("report.market", "getting market value of: " << args.value_at(0)); - - value_t result = - args.value_at(0).value(! args.has(2), - args.has(1) ? - args.get<datetime_t>(1) : optional<datetime_t>(), - commodity ? - optional<commodity_t&>(*commodity) : - optional<commodity_t&>()); - - DEBUG("report.market", "result is: " << result); - return result; + if (args.has(2)) { + scoped_array<char> buf(new char[args.get<string>(2).length() + 1]); + std::strcpy(buf.get(), args.get<string>(2).c_str()); + + bool primary_only = false; + for (char * p = std::strtok(buf.get(), ","); + p; + p = std::strtok(NULL, ",")) { + if (commodity_t * commodity = amount_t::current_pool->find(trim_ws(p))) { + value_t result = + args.value_at(0).value(primary_only, args.has(1) ? + args.get<datetime_t>(1) : + optional<datetime_t>(), *commodity); + if (! result.is_null()) + return result; + } + // For subsequent, secondary commodities, don't convert primaries + primary_only = true; + } + } else { + value_t result = + args.value_at(0).value(! args.has(2), args.has(1) ? + args.get<datetime_t>(1) : + optional<datetime_t>()); + if (! result.is_null()) + return result; + } + return args.value_at(0); } value_t report_t::fn_strip(call_scope_t& args) diff --git a/src/report.h b/src/report.h index 02993727..29f37e9d 100644 --- a/src/report.h +++ b/src/report.h @@ -411,9 +411,9 @@ public: OPTION_(report_t, market, DO() { // -V parent->HANDLER(revalued).on_only(); parent->HANDLER(display_amount_) - .set_expr("exchange ? market(amount_expr, now, exchange) : market(amount_expr)"); + .set_expr("market(amount_expr, now, exchange)"); parent->HANDLER(display_total_) - .set_expr("exchange ? market(total_expr, now, exchange) : market(total_expr)"); + .set_expr("market(total_expr, now, exchange)"); }); OPTION_(report_t, monthly, DO() { // -M diff --git a/src/utils.h b/src/utils.h index 4beff305..38fd2439 100644 --- a/src/utils.h +++ b/src/utils.h @@ -522,6 +522,14 @@ inline char * skip_ws(char * ptr) { return ptr; } +inline char * trim_ws(char * ptr) { + std::size_t len = std::strlen(ptr); + int i = int(len) - 1; + while (i >= 0 && ptr[i] == ' ' || ptr[i] == '\t' || ptr[i] == '\n') + ptr[i--] = '\0'; + return skip_ws(ptr); +} + inline char * next_element(char * buf, bool variable = false) { for (char * p = buf; *p; p++) { if (! (*p == ' ' || *p == '\t')) diff --git a/src/value.cc b/src/value.cc index 5c05c437..d39597bd 100644 --- a/src/value.cc +++ b/src/value.cc @@ -1143,19 +1143,19 @@ value_t value_t::value(const bool primary_only, { switch (type()) { case INTEGER: - return *this; + return NULL_VALUE; case AMOUNT: if (optional<amount_t> val = as_amount().value(primary_only, moment, in_terms_of)) return *val; - return *this; + return NULL_VALUE; case BALANCE: if (optional<balance_t> bal = as_balance().value(primary_only, moment, in_terms_of)) return *bal; - return *this; + return NULL_VALUE; default: break; |