summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJohn Wiegley <johnw@newartisans.com>2009-02-22 17:51:11 -0400
committerJohn Wiegley <johnw@newartisans.com>2009-02-22 17:51:11 -0400
commitea75613760440604ba5bdc2ab7f89892dc28c079 (patch)
treec6cd3ec4871f9598dfe2191f0cb7e2933da8b920
parentf2e4f4c6d1f20949232ab776cb24bfbd2db2797b (diff)
downloadfork-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.
-rw-r--r--src/commodity.cc39
-rw-r--r--src/commodity.h29
-rw-r--r--src/interactive.h2
-rw-r--r--src/option.h2
-rw-r--r--src/report.cc44
-rw-r--r--src/report.h4
-rw-r--r--src/utils.h8
-rw-r--r--src/value.cc6
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;