diff options
Diffstat (limited to 'src/value.cc')
-rw-r--r-- | src/value.cc | 76 |
1 files changed, 66 insertions, 10 deletions
diff --git a/src/value.cc b/src/value.cc index 53e2bdeb..702b889e 100644 --- a/src/value.cc +++ b/src/value.cc @@ -33,6 +33,8 @@ #include "value.h" #include "commodity.h" +#include "annotate.h" +#include "pool.h" #include "unistring.h" namespace ledger { @@ -573,6 +575,7 @@ value_t& value_t::operator*=(const value_t& val) return *this; case AMOUNT: if (as_amount().commodity() == val.as_amount().commodity() || + ! as_amount().has_commodity() || ! val.as_amount().has_commodity()) { as_amount_lval() *= val.as_amount(); return *this; @@ -1227,6 +1230,39 @@ value_t value_t::value(const bool primary_only, return NULL_VALUE; } +value_t value_t::price() const +{ + switch (type()) { + case AMOUNT: + return as_amount().price(); + case BALANCE: + return as_balance().price(); + default: + return *this; + } +} + +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_price_expression(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()) { @@ -1336,10 +1372,10 @@ void value_t::in_place_unround() case INTEGER: return; case AMOUNT: - as_amount_lval().unrounded(); + as_amount_lval().in_place_unround(); return; case BALANCE: - as_balance_lval().unrounded(); + as_balance_lval().in_place_unround(); return; case SEQUENCE: { value_t temp; @@ -1423,10 +1459,12 @@ void value_t::print(std::ostream& out, const int first_width, const int latter_width, const bool right_justify, + const bool colorize, const optional<string>& date_format) const { if (first_width > 0 && - ! is_amount() && ! is_balance() && ! is_string()) { + (! is_amount() || as_amount().is_zero()) && + ! is_balance() && ! is_string()) { out.width(first_width); if (right_justify) @@ -1459,17 +1497,20 @@ void value_t::print(std::ostream& out, break; case INTEGER: - out << std::right << as_long(); + if (colorize && as_long() < 0) + justify(out, to_string(), first_width, right_justify, true); + else + out << as_long(); break; case AMOUNT: { if (as_amount().is_zero()) { - out.width(first_width); - out << (right_justify ? std::right : std::left) << 0; + out << 0; } else { std::ostringstream buf; buf << as_amount(); - justify(out, buf.str(), first_width, right_justify); + justify(out, buf.str(), first_width, right_justify, + colorize && as_amount().sign() < 0); } break; } @@ -1492,14 +1533,15 @@ void value_t::print(std::ostream& out, out << ", "; value.print(out, first_width, latter_width, right_justify, - date_format); + colorize, date_format); } out << ')'; break; } case BALANCE: - as_balance().print(out, first_width, latter_width, right_justify); + as_balance().print(out, first_width, latter_width, right_justify, + colorize); break; case POINTER: @@ -1549,7 +1591,21 @@ void value_t::dump(std::ostream& out, const bool relaxed) const break; case STRING: - out << '"' << as_string() << '"'; + out << '"'; + foreach (const char& ch, as_string()) { + switch (ch) { + case '"': + out << "\\\""; + break; + case '\\': + out << "\\\\"; + break; + default: + out << ch; + break; + } + } + out << '"'; break; case MASK: |