The next value expression scheme is working, but the individual accessor
functions for each of the journal objects has yet to be ported.
This commit is contained in:
parent
ea27d1b45a
commit
42e1d725aa
9 changed files with 127 additions and 41 deletions
36
entry.cc
36
entry.cc
|
|
@ -363,6 +363,42 @@ void entry_t::add_xact(xact_t * xact)
|
||||||
entry_base_t::add_xact(xact);
|
entry_base_t::add_xact(xact);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
value_t get_date(call_scope_t& scope)
|
||||||
|
{
|
||||||
|
entry_t& entry(downcast<entry_t>(*scope.parent));
|
||||||
|
return entry.date();
|
||||||
|
}
|
||||||
|
|
||||||
|
value_t get_payee(call_scope_t& scope)
|
||||||
|
{
|
||||||
|
entry_t& entry(downcast<entry_t>(*scope.parent));
|
||||||
|
return value_t(entry.payee, true);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
expr_t::ptr_op_t entry_t::lookup(const string& name)
|
||||||
|
{
|
||||||
|
switch (name[0]) {
|
||||||
|
case 'd':
|
||||||
|
if (name[1] == '\0' || name == "date")
|
||||||
|
return WRAP_FUNCTOR(bind(get_date, _1));
|
||||||
|
break;
|
||||||
|
case 'p':
|
||||||
|
if (name[1] == '\0' || name == "payee")
|
||||||
|
return WRAP_FUNCTOR(bind(get_payee, _1));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
// jww (2008-07-29): Should it go to the containing journal next, or to the
|
||||||
|
// session?
|
||||||
|
return entry->lookup(name);
|
||||||
|
#else
|
||||||
|
return expr_t::ptr_op_t();
|
||||||
|
#endif
|
||||||
|
}
|
||||||
|
|
||||||
bool entry_t::valid() const
|
bool entry_t::valid() const
|
||||||
{
|
{
|
||||||
if (! is_valid(_date) || ! journal) {
|
if (! is_valid(_date) || ! journal) {
|
||||||
|
|
|
||||||
8
entry.h
8
entry.h
|
|
@ -76,7 +76,7 @@ class entry_base_t
|
||||||
virtual bool valid() const = 0;
|
virtual bool valid() const = 0;
|
||||||
};
|
};
|
||||||
|
|
||||||
class entry_t : public entry_base_t
|
class entry_t : public entry_base_t, public scope_t
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
datetime_t _date;
|
datetime_t _date;
|
||||||
|
|
@ -108,11 +108,13 @@ public:
|
||||||
return actual_date();
|
return actual_date();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
bool get_state(xact_t::state_t * state) const;
|
||||||
|
|
||||||
virtual void add_xact(xact_t * xact);
|
virtual void add_xact(xact_t * xact);
|
||||||
|
|
||||||
virtual bool valid() const;
|
virtual expr_t::ptr_op_t lookup(const string& name);
|
||||||
|
|
||||||
bool get_state(xact_t::state_t * state) const;
|
virtual bool valid() const;
|
||||||
};
|
};
|
||||||
|
|
||||||
struct entry_finalizer_t {
|
struct entry_finalizer_t {
|
||||||
|
|
|
||||||
51
format.cc
51
format.cc
|
|
@ -320,7 +320,7 @@ namespace {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void format_t::format(std::ostream& out_str, const scope_t& scope) const
|
void format_t::format(std::ostream& out_str, scope_t& scope) const
|
||||||
{
|
{
|
||||||
for (const element_t * elem = elements; elem; elem = elem->next) {
|
for (const element_t * elem = elements; elem; elem = elem->next) {
|
||||||
std::ostringstream out;
|
std::ostringstream out;
|
||||||
|
|
@ -340,9 +340,23 @@ void format_t::format(std::ostream& out_str, const scope_t& scope) const
|
||||||
out << elem->chars;
|
out << elem->chars;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
#if 0
|
|
||||||
case element_t::AMOUNT:
|
case element_t::AMOUNT:
|
||||||
|
out << scope.resolve("amount");
|
||||||
|
break;
|
||||||
|
|
||||||
|
case element_t::ACCOUNT_FULLNAME:
|
||||||
|
scope.resolve("account").dump(out, elem->min_width);
|
||||||
|
break;
|
||||||
|
case element_t::ACCOUNT_NAME:
|
||||||
|
scope.resolve("account_base").dump(out, elem->min_width);
|
||||||
|
break;
|
||||||
|
|
||||||
case element_t::TOTAL:
|
case element_t::TOTAL:
|
||||||
|
out << "T";
|
||||||
|
//out << scope.resolve("total");
|
||||||
|
break;
|
||||||
|
|
||||||
|
#if 0
|
||||||
case element_t::VALUE_EXPR: {
|
case element_t::VALUE_EXPR: {
|
||||||
expr_t * calc;
|
expr_t * calc;
|
||||||
switch (elem->type) {
|
switch (elem->type) {
|
||||||
|
|
@ -569,23 +583,13 @@ void format_t::format(std::ostream& out_str, const scope_t& scope) const
|
||||||
if (details.xact)
|
if (details.xact)
|
||||||
out << details.xact->end_line;
|
out << details.xact->end_line;
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
case element_t::DATE_STRING: {
|
case element_t::DATE_STRING:
|
||||||
datetime_t date;
|
out << format_datetime(scope.resolve("date").as_datetime());
|
||||||
if (details.xact)
|
break;
|
||||||
date = details.xact->date();
|
|
||||||
else if (details.entry)
|
|
||||||
date = details.entry->date();
|
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
// jww (2008-04-20): This needs to be rewritten
|
|
||||||
char buf[256];
|
|
||||||
std::strftime(buf, 255, elem->chars.c_str(), date.localtime());
|
|
||||||
out << (elem->max_width == 0 ? buf : truncate(buf, elem->max_width));
|
|
||||||
#endif
|
|
||||||
break;
|
|
||||||
}
|
|
||||||
|
|
||||||
case element_t::COMPLETE_DATE_STRING: {
|
case element_t::COMPLETE_DATE_STRING: {
|
||||||
datetime_t actual_date;
|
datetime_t actual_date;
|
||||||
datetime_t effective_date;
|
datetime_t effective_date;
|
||||||
|
|
@ -670,14 +674,13 @@ void format_t::format(std::ostream& out_str, const scope_t& scope) const
|
||||||
out << temp;
|
out << temp;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
case element_t::PAYEE:
|
case element_t::PAYEE:
|
||||||
if (details.entry)
|
scope.resolve("payee").dump(out, elem->min_width);
|
||||||
out << (elem->max_width == 0 ?
|
|
||||||
details.entry->payee : truncate(details.entry->payee,
|
|
||||||
elem->max_width));
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
#if 0
|
||||||
case element_t::OPT_NOTE:
|
case element_t::OPT_NOTE:
|
||||||
if (details.xact && details.xact->note)
|
if (details.xact && details.xact->note)
|
||||||
out << " ; ";
|
out << " ; ";
|
||||||
|
|
@ -781,24 +784,22 @@ format_xacts::format_xacts(std::ostream& _output_stream,
|
||||||
|
|
||||||
void format_xacts::operator()(xact_t& xact)
|
void format_xacts::operator()(xact_t& xact)
|
||||||
{
|
{
|
||||||
#if 0
|
|
||||||
if (! xact_has_xdata(xact) ||
|
if (! xact_has_xdata(xact) ||
|
||||||
! (xact_xdata_(xact).dflags & XACT_DISPLAYED)) {
|
! (xact_xdata_(xact).dflags & XACT_DISPLAYED)) {
|
||||||
if (last_entry != xact.entry) {
|
if (last_entry != xact.entry) {
|
||||||
first_line_format.format(output_stream, details_t(xact));
|
first_line_format.format(output_stream, xact);
|
||||||
last_entry = xact.entry;
|
last_entry = xact.entry;
|
||||||
}
|
}
|
||||||
else if (last_xact && last_xact->date() != xact.date()) {
|
else if (last_xact && last_xact->date() != xact.date()) {
|
||||||
first_line_format.format(output_stream, details_t(xact));
|
first_line_format.format(output_stream, xact);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
next_lines_format.format(output_stream, details_t(xact));
|
next_lines_format.format(output_stream, xact);
|
||||||
}
|
}
|
||||||
|
|
||||||
xact_xdata(xact).dflags |= XACT_DISPLAYED;
|
xact_xdata(xact).dflags |= XACT_DISPLAYED;
|
||||||
last_xact = &xact;
|
last_xact = &xact;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void format_entries::format_last_entry()
|
void format_entries::format_last_entry()
|
||||||
|
|
|
||||||
2
format.h
2
format.h
|
|
@ -110,7 +110,7 @@ struct format_t : public noncopyable
|
||||||
static string truncate(const string& str, unsigned int width,
|
static string truncate(const string& str, unsigned int width,
|
||||||
const bool is_account = false);
|
const bool is_account = false);
|
||||||
|
|
||||||
void format(std::ostream& out, const scope_t& scope) const;
|
void format(std::ostream& out, scope_t& scope) const;
|
||||||
};
|
};
|
||||||
|
|
||||||
class format_xacts : public item_handler<xact_t>
|
class format_xacts : public item_handler<xact_t>
|
||||||
|
|
|
||||||
2
main.cc
2
main.cc
|
|
@ -51,6 +51,8 @@ namespace ledger {
|
||||||
var_t<report_t> report(args, 0);
|
var_t<report_t> report(args, 0);
|
||||||
var_t<std::ostream> ostream(args, 1);
|
var_t<std::ostream> ostream(args, 1);
|
||||||
|
|
||||||
|
std::cout << "Hello, world!" << std::endl;
|
||||||
|
|
||||||
report->xacts_report
|
report->xacts_report
|
||||||
(xact_handler_ptr(new format_xacts
|
(xact_handler_ptr(new format_xacts
|
||||||
(*ostream, report->session.register_format)));
|
(*ostream, report->session.register_format)));
|
||||||
|
|
|
||||||
12
op.cc
12
op.cc
|
|
@ -682,11 +682,13 @@ value_t expr_t::op_t::calc(scope_t& scope)
|
||||||
}
|
}
|
||||||
throw_(calc_error, "Unknown identifier '" << as_ident() << "'");
|
throw_(calc_error, "Unknown identifier '" << as_ident() << "'");
|
||||||
|
|
||||||
case FUNCTION:
|
case FUNCTION: {
|
||||||
// This should never be evaluated directly; it only appears as the
|
// Evaluating a FUNCTION is the same as calling it directly; this happens
|
||||||
// left node of an O_CALL operator.
|
// when certain functions-that-look-like-variables (such as "amount") are
|
||||||
assert(false);
|
// resolved.
|
||||||
break;
|
call_scope_t call_args(scope);
|
||||||
|
return as_function()(call_args);
|
||||||
|
}
|
||||||
|
|
||||||
case O_CALL: {
|
case O_CALL: {
|
||||||
call_scope_t call_args(scope);
|
call_scope_t call_args(scope);
|
||||||
|
|
|
||||||
|
|
@ -291,7 +291,10 @@ xact_t * parse_xact(char * line, account_t * account,
|
||||||
account_xdata_t& xdata(account_xdata(*xact->account));
|
account_xdata_t& xdata(account_xdata(*xact->account));
|
||||||
|
|
||||||
if (xact->amount) {
|
if (xact->amount) {
|
||||||
xdata.value += xact->amount;
|
if (xdata.value.is_null())
|
||||||
|
xdata.value = xact->amount;
|
||||||
|
else
|
||||||
|
xdata.value += xact->amount;
|
||||||
DEBUG("ledger.textual.parse", "line " << linenum << ": " <<
|
DEBUG("ledger.textual.parse", "line " << linenum << ": " <<
|
||||||
"XACT assign: account total = " << xdata.value);
|
"XACT assign: account total = " << xdata.value);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
1
value.cc
1
value.cc
|
|
@ -448,7 +448,6 @@ value_t& value_t::operator+=(const value_t& val)
|
||||||
}
|
}
|
||||||
|
|
||||||
throw_(value_error, "Cannot add " << val.label() << " to " << label());
|
throw_(value_error, "Cannot add " << val.label() << " to " << label());
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
51
xact.cc
51
xact.cc
|
|
@ -31,6 +31,7 @@
|
||||||
|
|
||||||
#include "xact.h"
|
#include "xact.h"
|
||||||
#include "journal.h"
|
#include "journal.h"
|
||||||
|
#include "account.h"
|
||||||
|
|
||||||
namespace ledger {
|
namespace ledger {
|
||||||
|
|
||||||
|
|
@ -61,6 +62,39 @@ namespace {
|
||||||
xact_t& xact(downcast<xact_t>(*scope.parent));
|
xact_t& xact(downcast<xact_t>(*scope.parent));
|
||||||
return xact.amount;
|
return xact.amount;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
value_t get_date(call_scope_t& scope)
|
||||||
|
{
|
||||||
|
xact_t& xact(downcast<xact_t>(*scope.parent));
|
||||||
|
return xact.entry->date();
|
||||||
|
}
|
||||||
|
|
||||||
|
value_t get_payee(call_scope_t& scope)
|
||||||
|
{
|
||||||
|
xact_t& xact(downcast<xact_t>(*scope.parent));
|
||||||
|
return value_t(xact.entry->payee, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
value_t get_account(call_scope_t& scope)
|
||||||
|
{
|
||||||
|
xact_t& xact(downcast<xact_t>(*scope.parent));
|
||||||
|
|
||||||
|
string name = xact.account->fullname();
|
||||||
|
|
||||||
|
if (xact.has_flags(XACT_VIRTUAL)) {
|
||||||
|
if (xact.must_balance())
|
||||||
|
name = string("[") + name + "]";
|
||||||
|
else
|
||||||
|
name = string("(") + name + ")";
|
||||||
|
}
|
||||||
|
return value_t(name, true);
|
||||||
|
}
|
||||||
|
|
||||||
|
value_t get_account_base(call_scope_t& scope)
|
||||||
|
{
|
||||||
|
assert(false);
|
||||||
|
return NULL_VALUE;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
expr_t::ptr_op_t xact_t::lookup(const string& name)
|
expr_t::ptr_op_t xact_t::lookup(const string& name)
|
||||||
|
|
@ -69,14 +103,21 @@ expr_t::ptr_op_t xact_t::lookup(const string& name)
|
||||||
case 'a':
|
case 'a':
|
||||||
if (name[1] == '\0' || name == "amount")
|
if (name[1] == '\0' || name == "amount")
|
||||||
return WRAP_FUNCTOR(bind(get_amount, _1));
|
return WRAP_FUNCTOR(bind(get_amount, _1));
|
||||||
|
else if (name == "account")
|
||||||
|
return WRAP_FUNCTOR(bind(get_account, _1));
|
||||||
|
else if (name == "account_base")
|
||||||
|
return WRAP_FUNCTOR(bind(get_account_base, _1));
|
||||||
|
break;
|
||||||
|
case 'd':
|
||||||
|
if (name[1] == '\0' || name == "date")
|
||||||
|
return WRAP_FUNCTOR(bind(get_date, _1));
|
||||||
|
break;
|
||||||
|
case 'p':
|
||||||
|
if (name[1] == '\0' || name == "payee")
|
||||||
|
return WRAP_FUNCTOR(bind(get_payee, _1));
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
return entry->lookup(name);
|
return entry->lookup(name);
|
||||||
#else
|
|
||||||
return expr_t::ptr_op_t();
|
|
||||||
#endif
|
|
||||||
}
|
}
|
||||||
|
|
||||||
bool xact_t::valid() const
|
bool xact_t::valid() const
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue