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'
This commit is contained in:
John Wiegley 2009-06-18 18:50:49 +01:00
parent 1dc21c2d34
commit 86dfc1e0be
7 changed files with 70 additions and 41 deletions

View file

@ -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;
scoped_array<char> buf(new char[str.length() + 1]);
optarg = skip_ws(optarg);
while (equals > optarg && std::isspace(*(equals - 1)))
equals--;
std::strcpy(buf.get(), str.c_str());
std::string symbol(optarg, 0, equals - optarg);
amount_t price(equals + 1);
char * price = std::strchr(buf.get(), '=');
if (price)
*price++ = '\0';
if (commodity_t * commodity = find_or_create(symbol))
commodity->add_price(CURRENT_TIME(), price);
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

View file

@ -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

View file

@ -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();

View file

@ -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_);

View file

@ -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]);

View file

@ -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()) {

View file

@ -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.
*/