diff options
author | John Wiegley <johnw@newartisans.com> | 2009-06-18 18:50:49 +0100 |
---|---|---|
committer | John Wiegley <johnw@newartisans.com> | 2009-06-18 18:50:49 +0100 |
commit | 86dfc1e0be5dbfab195cba8a8be31d3dbf0f68c9 (patch) | |
tree | 55965512c0a1abf8f4bbb1519817c7b96fdcab12 | |
parent | 1dc21c2d344aa52833e516fea831ff45d8bf7aa1 (diff) | |
download | fork-ledger-86dfc1e0be5dbfab195cba8a8be31d3dbf0f68c9.tar.gz fork-ledger-86dfc1e0be5dbfab195cba8a8be31d3dbf0f68c9.tar.bz2 fork-ledger-86dfc1e0be5dbfab195cba8a8be31d3dbf0f68c9.zip |
The -X option now accepts price settings
For example, if you had 100 AU (onces of gold) and wanted to report it
in dollars, but at a price of $997 per ounce, you could now easily say:
ledger bal -X '$,AU=$997'
-rw-r--r-- | src/commodity.cc | 33 | ||||
-rw-r--r-- | src/commodity.h | 4 | ||||
-rw-r--r-- | src/global.cc | 8 | ||||
-rw-r--r-- | src/report.cc | 41 | ||||
-rw-r--r-- | src/report.h | 2 | ||||
-rw-r--r-- | src/value.cc | 21 | ||||
-rw-r--r-- | src/value.h | 4 |
7 files changed, 71 insertions, 42 deletions
diff --git a/src/commodity.cc b/src/commodity.cc index d826feb6..e69758f0 100644 --- a/src/commodity.cc +++ b/src/commodity.cc @@ -1026,21 +1026,30 @@ commodity_t * commodity_pool_t::find_or_create(commodity_t& comm, return create(comm, details, name); } -void commodity_pool_t::parse_commodity_price(char * optarg) +commodity_t * +commodity_pool_t::parse_commodity_prices(const std::string& str, + const bool add_prices, + const optional<datetime_t>& moment) { - char * equals = std::strchr(optarg, '='); - if (! equals) - return; - - optarg = skip_ws(optarg); - while (equals > optarg && std::isspace(*(equals - 1))) - equals--; + scoped_array<char> buf(new char[str.length() + 1]); - std::string symbol(optarg, 0, equals - optarg); - amount_t price(equals + 1); + std::strcpy(buf.get(), str.c_str()); - if (commodity_t * commodity = find_or_create(symbol)) - commodity->add_price(CURRENT_TIME(), price); + char * price = std::strchr(buf.get(), '='); + if (price) + *price++ = '\0'; + + if (commodity_t * commodity = find_or_create(trim_ws(buf.get()))) { + if (price && add_prices) { + for (char * p = std::strtok(price, ";"); + p; + p = std::strtok(NULL, ";")) { + commodity->add_price(moment ? *moment : CURRENT_TIME(), amount_t(p)); + } + } + return commodity; + } + return NULL; } } // namespace ledger diff --git a/src/commodity.h b/src/commodity.h index 8121199a..c15a32f0 100644 --- a/src/commodity.h +++ b/src/commodity.h @@ -567,7 +567,9 @@ public: commodity_t * find_or_create(commodity_t& comm, const annotation_t& details); - void parse_commodity_price(char * optarg); + commodity_t * parse_commodity_prices(const std::string& str, + const bool add_prices = true, + const optional<datetime_t>& moment = none); }; } // namespace ledger diff --git a/src/global.cc b/src/global.cc index b0b08930..461c6985 100644 --- a/src/global.cc +++ b/src/global.cc @@ -487,6 +487,14 @@ void global_scope_t::normalize_report_options(const string& verb) .on_with(string("?normalize"), rep.HANDLER(plot_total_format_).value); } + // If the --exchange (-X) option was used, parse out any final price + // settings that may be there. + if (rep.HANDLED(exchange_) && + rep.HANDLER(exchange_).str().find('=') != string::npos) { + value_t(0L).exchange_commodities(rep.HANDLER(exchange_).str(), + true, datetime_t(rep.terminus)); + } + long cols = 0; if (rep.HANDLED(columns_)) cols = rep.HANDLER(columns_).value.to_long(); diff --git a/src/report.cc b/src/report.cc index fde3365b..6c7a9f39 100644 --- a/src/report.cc +++ b/src/report.cc @@ -129,33 +129,21 @@ value_t report_t::fn_market(call_scope_t& scope) { interactive_t args(scope, "a&ts"); - 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()); - - for (char * p = std::strtok(buf.get(), ","); - p; - p = std::strtok(NULL, ",")) { - if (commodity_t * commodity = amount_t::current_pool->find(trim_ws(p))) { - DEBUG("report.market", "Searching for value of " << args.value_at(0) - << " in terms of commodity " << commodity->symbol()); - value_t result = - args.value_at(0).value(false, args.has(1) ? + value_t result; + optional<datetime_t> moment = (args.has(1) ? args.get<datetime_t>(1) : - optional<datetime_t>(), *commodity); - if (! result.is_null()) { - DEBUG("report.market", "Market value is = " << result); - return result; - } - } - } - } else { - value_t result = - args.value_at(0).value(true, args.has(1) ? - args.get<datetime_t>(1) : optional<datetime_t>()); - if (! result.is_null()) - return result; - } + optional<datetime_t>()); + + if (args.has(2)) + result = args.value_at(0).exchange_commodities(args.get<string>(2), + /* add_prices= */ false, + moment); + else + result = args.value_at(0).value(true, moment); + + if (! result.is_null()) + return result; + return args.value_at(0); } @@ -608,7 +596,6 @@ option_t<report_t> * report_t::lookup_option(const char * p) case 's': OPT(set_account_); else OPT(set_payee_); - else OPT(set_price_); else OPT(sort_); else OPT(sort_all_); else OPT(sort_xacts_); diff --git a/src/report.h b/src/report.h index 0f01345c..cad4b5ba 100644 --- a/src/report.h +++ b/src/report.h @@ -271,7 +271,6 @@ public: HANDLER(seed_).report(out); HANDLER(set_account_).report(out); HANDLER(set_payee_).report(out); - HANDLER(set_price_).report(out); HANDLER(sort_).report(out); HANDLER(sort_all_).report(out); HANDLER(sort_xacts_).report(out); @@ -714,7 +713,6 @@ public: OPTION(report_t, seed_); OPTION(report_t, set_account_); OPTION(report_t, set_payee_); - OPTION(report_t, set_price_); OPTION_(report_t, sort_, DO_(args) { // -S on_with(args[0].as_string(), args[1]); diff --git a/src/value.cc b/src/value.cc index 6f6e665d..7fa9866f 100644 --- a/src/value.cc +++ b/src/value.cc @@ -1228,6 +1228,27 @@ value_t value_t::value(const bool primary_only, return NULL_VALUE; } +value_t value_t::exchange_commodities(const std::string& commodities, + const bool add_prices, + const optional<datetime_t>& moment) +{ + scoped_array<char> buf(new char[commodities.length() + 1]); + + std::strcpy(buf.get(), commodities.c_str()); + + for (char * p = std::strtok(buf.get(), ","); + p; + p = std::strtok(NULL, ",")) { + if (commodity_t * commodity = + amount_t::current_pool->parse_commodity_prices(p, add_prices, moment)) { + value_t result = value(false, moment, *commodity); + if (! result.is_null()) + return result; + } + } + return *this; +} + void value_t::in_place_reduce() { switch (type()) { diff --git a/src/value.h b/src/value.h index a2b9c07f..31ed1d58 100644 --- a/src/value.h +++ b/src/value.h @@ -449,6 +449,10 @@ public: const optional<datetime_t>& moment = none, const optional<commodity_t&>& in_terms_of = none) const; + value_t exchange_commodities(const std::string& commodities, + const bool add_prices = false, + const optional<datetime_t>& moment = none); + /** * Truth tests. */ |