diff options
-rw-r--r-- | src/format.cc | 26 | ||||
-rw-r--r-- | src/format.h | 12 | ||||
-rw-r--r-- | src/report.cc | 20 | ||||
-rw-r--r-- | src/scope.h | 20 | ||||
-rw-r--r-- | src/session.cc | 6 |
5 files changed, 55 insertions, 29 deletions
diff --git a/src/format.cc b/src/format.cc index 81aa5c26..fc588c9b 100644 --- a/src/format.cc +++ b/src/format.cc @@ -31,6 +31,7 @@ #include "format.h" #include "account.h" +#include "parser.h" namespace ledger { @@ -50,7 +51,7 @@ void format_t::element_t::dump(std::ostream& out) const case EXPR: out << " EXPR"; break; } - out << " flags: " << int(flags); + out << " flags: " << flags(); out << " min: "; out << std::right; out.width(2); @@ -166,10 +167,10 @@ format_t::element_t * format_t::parse_elements(const string& fmt) while (*p == '!' || *p == '-') { switch (*p) { case '-': - current->flags |= ELEMENT_ALIGN_LEFT; + current->add_flags(ELEMENT_ALIGN_LEFT); break; case '!': - current->flags |= ELEMENT_HIGHLIGHT; + current->add_flags(ELEMENT_FORMATTED); break; } ++p; @@ -209,9 +210,14 @@ format_t::element_t * format_t::parse_elements(const string& fmt) case '[': { std::istringstream str(p); current->type = element_t::EXPR; - current->expr.parse(str); - current->expr.set_text(string(p, p + long(str.tellg()))); - p += long(str.tellg()); + current->expr.parse(str, EXPR_PARSE_PARTIAL); + istream_pos_type pos = str.tellg(); + current->expr.set_text(string(p, p + long(pos))); + p += long(pos) - 1; + // Don't gobble up any whitespace + const char * base = p; + while (p >= base && std::isspace(*p)) + p--; break; } @@ -253,9 +259,8 @@ void format_t::format(std::ostream& out_str, scope_t& scope) for (element_t * elem = elements.get(); elem; elem = elem->next.get()) { std::ostringstream out; string name; - bool ignore_max_width = false; - if (elem->flags & ELEMENT_ALIGN_LEFT) + if (elem->has_flags(ELEMENT_ALIGN_LEFT)) out << std::left; else out << std::right; @@ -280,6 +285,7 @@ void format_t::format(std::ostream& out_str, scope_t& scope) } else { value = elem->expr.calc(scope); } + DEBUG("format.expr", "value = (" << value << ")"); value.strip_annotations().dump(out, elem->min_width); } catch (const calc_error&) { @@ -294,7 +300,9 @@ void format_t::format(std::ostream& out_str, scope_t& scope) string temp = out.str(); - if (! ignore_max_width && + DEBUG("format.expr", "output = \"" << temp << "\""); + + if (! elem->has_flags(ELEMENT_FORMATTED) && elem->max_width > 0 && elem->max_width < temp.length()) out_str << truncate(temp, elem->max_width); else diff --git a/src/format.h b/src/format.h index 31f2bb1d..ff33e2d7 100644 --- a/src/format.h +++ b/src/format.h @@ -41,21 +41,17 @@ DECLARE_EXCEPTION(format_error, std::runtime_error); class format_t : public noncopyable { - struct element_t : public noncopyable + struct element_t : public supports_flags<>, public noncopyable { #define ELEMENT_ALIGN_LEFT 0x01 -#define ELEMENT_HIGHLIGHT 0x02 +#define ELEMENT_FORMATTED 0x02 enum kind_t { STRING, EXPR, -#if 0 - DEPTH_SPACER -#endif }; kind_t type; - unsigned char flags; unsigned char min_width; unsigned char max_width; string chars; @@ -64,7 +60,7 @@ class format_t : public noncopyable scoped_ptr<struct element_t> next; element_t() throw() - : type(STRING), flags(false), min_width(0), max_width(0) { + : supports_flags<>(), type(STRING), min_width(0), max_width(0) { TRACE_CTOR(element_t, ""); } ~element_t() throw() { @@ -76,7 +72,7 @@ class format_t : public noncopyable out.width(0); out << "\e[31m"; - if (elem->flags & ELEMENT_ALIGN_LEFT) + if (elem->has_flags(ELEMENT_ALIGN_LEFT)) out << std::left; else out << std::right; diff --git a/src/report.cc b/src/report.cc index 360b7685..42a9b186 100644 --- a/src/report.cc +++ b/src/report.cc @@ -363,6 +363,21 @@ value_t report_t::get_total_expr(call_scope_t& scope) return total_expr.calc(scope); } +namespace { + value_t print_balance(call_scope_t& args) + { + var_t<long> first_width(args, 1); + var_t<long> latter_width(args, 2); +#if 0 + var_t<bool> bold_negative(args, 3); +#endif + + std::ostringstream out; + args[0].dump(out, *first_width, *latter_width); + return string_value(out.str()); + } +} + expr_t::ptr_op_t report_t::lookup(const string& name) { const char * p = name.c_str(); @@ -423,6 +438,11 @@ expr_t::ptr_op_t report_t::lookup(const string& name) } } break; + + case 'p': + if (name == "print_balance") + return WRAP_FUNCTOR(print_balance); + break; } return session.lookup(name); diff --git a/src/scope.h b/src/scope.h index 8c98bb3d..2f33a442 100644 --- a/src/scope.h +++ b/src/scope.h @@ -247,8 +247,8 @@ public: operator bool() { return value; } - T& operator *(); - const T& operator *() const; + T operator *(); + const T operator *() const; T * operator->() { return &**this; @@ -259,21 +259,21 @@ public: }; template <> -inline long& var_t<long>::operator *() { - return value->as_long_lval(); +inline long var_t<long>::operator *() { + return value->to_long(); } template <> -inline const long& var_t<long>::operator *() const { - return value->as_long(); +inline const long var_t<long>::operator *() const { + return value->to_long(); } template <> -inline string& var_t<string>::operator *() { - return value->as_string_lval(); +inline string var_t<string>::operator *() { + return value->to_string(); } template <> -inline const string& var_t<string>::operator *() const { - return value->as_string(); +inline const string var_t<string>::operator *() const { + return value->to_string(); } } // namespace ledger diff --git a/src/session.cc b/src/session.cc index f634c855..fea379d6 100644 --- a/src/session.cc +++ b/src/session.cc @@ -71,8 +71,10 @@ void release_session_context() session_t::session_t() : register_format - ("%-.10D %-.20P %-.22A %12.67t %!12.80T\n%/" - "%32|%-.22A %12.67t %!12.80T\n"), + ("%-.10D %-.20P %-.22A %!12(print_balance(fmt_t, 12, 67)) " + "%!12(print_balance(fmt_T, 12, 80, true))\n%/" + "%32|%-.22A %!12(print_balance(fmt_t, 12, 67)) " + "%!12(print_balance(fmt_T, 12, 80, true))\n"), wide_register_format ("%-.10D %-.35P %-.38A %22.108t %!22.132T\n%/" "%48|%-.38A %22.108t %!22.132T\n"), |