summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Wiegley <johnw@newartisans.com>2009-06-18 18:50:49 +0100
committerJohn Wiegley <johnw@newartisans.com>2009-06-18 18:50:49 +0100
commit86dfc1e0be5dbfab195cba8a8be31d3dbf0f68c9 (patch)
tree55965512c0a1abf8f4bbb1519817c7b96fdcab12
parent1dc21c2d344aa52833e516fea831ff45d8bf7aa1 (diff)
downloadfork-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.cc33
-rw-r--r--src/commodity.h4
-rw-r--r--src/global.cc8
-rw-r--r--src/report.cc41
-rw-r--r--src/report.h2
-rw-r--r--src/value.cc21
-rw-r--r--src/value.h4
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.
*/