From ea75613760440604ba5bdc2ab7f89892dc28c079 Mon Sep 17 00:00:00 2001 From: John Wiegley Date: Sun, 22 Feb 2009 17:51:11 -0400 Subject: --exchange option now accepts multiple commodities They must be separated by a comma, and all whitespace is ignored. --- src/commodity.cc | 39 --------------------------------------- src/commodity.h | 29 ----------------------------- src/interactive.h | 2 +- src/option.h | 2 +- src/report.cc | 44 ++++++++++++++++++++++++++++---------------- src/report.h | 4 ++-- src/utils.h | 8 ++++++++ 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 return none; } -optional - commodity_t::base_t::varied_history_t:: - find_price(const commodity_t& source, - const std::vector& commodities, - const optional& moment, - const optional& oldest -#if defined(DEBUG_ON) - , const int indent -#endif - ) const -{ - foreach (commodity_t * commodity, commodities) { - if (optional point = find_price(source, *commodity, - moment, oldest -#if defined(DEBUG_ON) - , indent -#endif - )) - return point; - } - return none; -} - optional commodity_t::base_t::varied_history_t:: history(const optional& commodity) @@ -400,22 +377,6 @@ optional return none; } -optional -commodity_t::base_t::varied_history_t::history - (const std::vector& 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 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 @@ -124,22 +124,11 @@ public: const optional& oldest = none #if defined(DEBUG_ON) , const int indent = 0 -#endif - ) const; - optional - find_price(const commodity_t& source, - const std::vector& commodities, - const optional& moment = none, - const optional& oldest = none -#if defined(DEBUG_ON) - , const int indent = 0 #endif ) const; optional history(const optional& commodity = none); - optional - history(const std::vector& commodities); }; #define COMMODITY_STYLE_DEFAULTS 0x000 @@ -283,7 +272,6 @@ public: } optional history(const optional& commodity); - optional history(const std::vector& commodities); public: // These methods provide a transparent pass-through to the underlying @@ -324,23 +312,6 @@ public: return none; } - optional - find_price(const std::vector& commodities, - const optional& moment = none, - const optional& 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(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(1) : optional(), - commodity ? - optional(*commodity) : - optional()); - - DEBUG("report.market", "result is: " << result); - return result; + if (args.has(2)) { + scoped_array buf(new char[args.get(2).length() + 1]); + std::strcpy(buf.get(), args.get(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(1) : + optional(), *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(1) : + optional()); + 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 val = as_amount().value(primary_only, moment, in_terms_of)) return *val; - return *this; + return NULL_VALUE; case BALANCE: if (optional bal = as_balance().value(primary_only, moment, in_terms_of)) return *bal; - return *this; + return NULL_VALUE; default: break; -- cgit v1.2.3