summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--entry.cc29
-rw-r--r--format.cc13
-rw-r--r--main.cc12
-rw-r--r--report.cc10
-rw-r--r--report.h8
-rw-r--r--scope.h16
-rw-r--r--session.cc6
-rw-r--r--session.h9
-rw-r--r--value.cc4
-rw-r--r--xact.cc25
10 files changed, 82 insertions, 50 deletions
diff --git a/entry.cc b/entry.cc
index e9b932fe..799de841 100644
--- a/entry.cc
+++ b/entry.cc
@@ -32,6 +32,8 @@
#include "entry.h"
#include "journal.h"
#include "format.h"
+#include "session.h"
+#include "report.h"
namespace ledger {
@@ -361,18 +363,13 @@ namespace {
return entry.date();
}
- value_t get_payee(entry_t& entry)
- {
+ value_t get_payee(entry_t& entry) {
return string_value(entry.payee);
}
- typedef value_t (*entry_func_t)(entry_t&);
-
- template <entry_func_t Func>
- value_t get_wrapper(call_scope_t& scope)
- {
- xact_t& xact(downcast<xact_t>(*scope.parent));
- return (*Func)(*xact.entry);
+ template <value_t (*Func)(entry_t&)>
+ value_t get_wrapper(call_scope_t& scope) {
+ return (*Func)(find_scope<entry_t>(scope));
}
}
@@ -383,12 +380,24 @@ expr_t::ptr_op_t entry_t::lookup(const string& name)
if (name[1] == '\0' || name == "date")
return WRAP_FUNCTOR(get_wrapper<&get_date>);
break;
+
+ case 'f':
+ if (name.find("fmt_") == 0) {
+ switch (name[4]) {
+ case 'D':
+ return WRAP_FUNCTOR(get_wrapper<&get_date>);
+ case 'P':
+ return WRAP_FUNCTOR(get_wrapper<&get_payee>);
+ }
+ }
+ break;
+
case 'p':
if (name[1] == '\0' || name == "payee")
return WRAP_FUNCTOR(get_wrapper<&get_payee>);
break;
}
- return expr_t::ptr_op_t();
+ return journal->owner->current_report->lookup(name);
}
bool entry_t::valid() const
diff --git a/format.cc b/format.cc
index 772fa0bc..b1cc0bd8 100644
--- a/format.cc
+++ b/format.cc
@@ -247,18 +247,9 @@ void format_t::format(std::ostream& out_str, scope_t& scope)
if (elem->expr.is_function()) {
call_scope_t args(scope);
args.push_back(long(elem->max_width));
-
- if (elem->max_width == 0)
- elem->expr.get_function()(args).dump(out, elem->min_width);
- else
- out << truncate(elem->expr.get_function()(args).as_string(),
- elem->max_width);
+ elem->expr.get_function()(args).dump(out, elem->min_width);
} else {
- if (elem->max_width == 0)
- elem->expr.calc(scope).dump(out, elem->min_width);
- else
- out << truncate(elem->expr.calc(scope).as_string(),
- elem->max_width);
+ elem->expr.calc(scope).dump(out, elem->min_width);
}
}
catch (const calc_error&) {
diff --git a/main.cc b/main.cc
index 78a9433b..1a6f0ea2 100644
--- a/main.cc
+++ b/main.cc
@@ -462,16 +462,14 @@ int main(int argc, char * argv[], char * envp[])
session->register_parser(new ledger::qif_parser_t);
session->register_parser(new ledger::textual_parser_t);
- std::auto_ptr<ledger::report_t> report(new ledger::report_t(*session.get()));
+ session->current_report.reset(new ledger::report_t(*session.get()));
- status = read_and_report(*report.get(), argc, argv, envp);
+ status = read_and_report(*session->current_report.get(), argc, argv, envp);
- if (DO_VERIFY()) {
+ if (DO_VERIFY())
ledger::set_session_context();
- } else {
- report.release();
- session.release();
- }
+ else
+ session.release(); // don't free anything!
}
catch (const std::exception& err) {
std::cout.flush();
diff --git a/report.cc b/report.cc
index fe1cdb8f..d6aea4fa 100644
--- a/report.cc
+++ b/report.cc
@@ -521,6 +521,16 @@ expr_t::ptr_op_t report_t::lookup(const string& name)
case 'f':
if (std::strcmp(p, "format") == 0)
return MAKE_FUNCTOR(report_t::option_format);
+ else if (name.find("fmt_") == 0) {
+ switch (name[4]) {
+ case 't':
+ return MAKE_FUNCTOR(report_t::get_amount_expr);
+#if 0
+ case 'T':
+ return MAKE_FUNCTOR(report_t::get_total_expr);
+#endif
+ }
+ }
break;
case 't':
diff --git a/report.h b/report.h
index 0881ace1..a2bbe8e6 100644
--- a/report.h
+++ b/report.h
@@ -243,6 +243,14 @@ public:
}
//
+ // Formatting functions
+ //
+
+ value_t get_amount_expr(call_scope_t&) {
+ return NULL_VALUE;
+ }
+
+ //
// Scope members
//
diff --git a/scope.h b/scope.h
index be60fb85..88b45d84 100644
--- a/scope.h
+++ b/scope.h
@@ -66,14 +66,14 @@ template <typename T>
inline T& find_scope(scope_t& scope, bool skip_this = true) {
optional<scope_t&> found = scope.find_scope(typeid(T), skip_this);
assert(found);
- return downcast<T>(*found);
+ return static_cast<T&>(*found);
}
template <typename T>
inline optional<T&> maybe_find_scope(scope_t& scope, bool skip_this = true) {
optional<scope_t&> found = scope.find_scope(typeid(T), skip_this);
if (found)
- return optional<T&>(downcast<T>(*found));
+ return optional<T&>(static_cast<T&>(*found));
else
return none;
}
@@ -102,12 +102,14 @@ public:
virtual optional<scope_t&> find_scope(const std::type_info& type,
bool skip_this = true) {
- for (scope_t * ptr = (skip_this ? parent : this);
- ptr;
- ptr = polymorphic_downcast<child_scope_t *>(ptr)->parent)
- if (typeid(ptr) == type)
+ for (scope_t * ptr = (skip_this ? parent : this); ptr; ) {
+ if (typeid(*ptr) == type)
return *ptr;
-
+ if (child_scope_t * scope = dynamic_cast<child_scope_t *>(ptr))
+ ptr = scope->parent;
+ else
+ ptr = NULL;
+ }
return none;
}
};
diff --git a/session.cc b/session.cc
index 68db4fd0..3bafd43c 100644
--- a/session.cc
+++ b/session.cc
@@ -30,6 +30,7 @@
*/
#include "session.h"
+#include "report.h"
#include "walk.h"
namespace ledger {
@@ -113,6 +114,11 @@ session_t::session_t()
TRACE_CTOR(session_t, "");
}
+session_t::~session_t()
+{
+ TRACE_DTOR(session_t);
+}
+
std::size_t session_t::read_journal(journal_t& journal,
std::istream& in,
const path& pathname,
diff --git a/session.h b/session.h
index f35accb2..dc78d6f5 100644
--- a/session.h
+++ b/session.h
@@ -39,6 +39,8 @@
namespace ledger {
+class report_t;
+
class session_t : public noncopyable, public scope_t
{
static void initialize();
@@ -50,6 +52,8 @@ class session_t : public noncopyable, public scope_t
public:
static session_t * current;
+ scoped_ptr<report_t> current_report;
+
path data_file;
optional<path> init_file;
optional<path> cache_file;
@@ -89,10 +93,7 @@ public:
mutable accounts_map accounts_cache;
session_t();
-
- virtual ~session_t() {
- TRACE_DTOR(session_t);
- }
+ virtual ~session_t();
journal_t * create_journal() {
journal_t * journal = new journal_t(this);
diff --git a/value.cc b/value.cc
index 797f3e55..2569c237 100644
--- a/value.cc
+++ b/value.cc
@@ -1574,11 +1574,11 @@ void value_t::dump(std::ostream& out, const int first_width,
break;
case DATETIME:
- out << as_datetime();
+ out << format_datetime(as_datetime());
break;
case DATE:
- out << as_date();
+ out << format_date(as_date());
break;
case INTEGER:
diff --git a/xact.cc b/xact.cc
index c6f76ebe..d9886752 100644
--- a/xact.cc
+++ b/xact.cc
@@ -78,6 +78,10 @@ namespace {
return xact.date();
}
+ value_t get_payee(xact_t& xact) {
+ return string_value(xact.entry->payee);
+ }
+
value_t get_amount(xact_t& xact) {
return xact.amount;
}
@@ -90,19 +94,16 @@ namespace {
return string_value(xact.note ? *xact.note : ":NOTELESS:");
}
- value_t get_account(call_scope_t& scope) {
+ value_t get_account(call_scope_t& scope)
+ {
xact_t& xact(downcast<xact_t>(*scope.parent));
- long width = 0;
- if (scope.size() == 1)
- width = var_t<long>(scope, 0);
+ var_t<long> width(scope, 0);
- // jww (2008-08-02): Accept a width here so that we can abbreviate the
- // string.
string name = xact.reported_account()->fullname();
- if (width > 2)
- name = format_t::truncate(name, width - 2, true);
+ if (width && *width > 2)
+ name = format_t::truncate(name, *width - 2, true);
if (xact.has_flags(XACT_VIRTUAL)) {
if (xact.must_balance())
@@ -172,8 +173,14 @@ expr_t::ptr_op_t xact_t::lookup(const string& name)
case 'f':
if (name.find("fmt_") == 0) {
- if (name == "fmt_A")
+ switch (name[4]) {
+ case 'A':
return WRAP_FUNCTOR(get_account);
+ case 'D':
+ return WRAP_FUNCTOR(get_wrapper<&get_date>);
+ case 'P':
+ return WRAP_FUNCTOR(get_wrapper<&get_payee>);
+ }
}
break;