summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/format.cc26
-rw-r--r--src/format.h12
-rw-r--r--src/report.cc20
-rw-r--r--src/scope.h20
-rw-r--r--src/session.cc6
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"),