Added the var_t helper class, which can be seen in the beginning
implementation of register_command in main.cc.
This commit is contained in:
parent
8601a2a8bf
commit
aa4f0d4364
7 changed files with 86 additions and 99 deletions
23
main.cc
23
main.cc
|
|
@ -45,6 +45,17 @@
|
||||||
#include <fdstream.hpp>
|
#include <fdstream.hpp>
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
namespace ledger {
|
||||||
|
value_t register_command(expr::call_scope_t& args)
|
||||||
|
{
|
||||||
|
expr::var_t<std::ostream> ostream(args, "ostream");
|
||||||
|
|
||||||
|
*ostream << "This (will be) the register command.\n";
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
static int read_and_report(ledger::report_t& report, int argc, char * argv[],
|
static int read_and_report(ledger::report_t& report, int argc, char * argv[],
|
||||||
char * envp[])
|
char * envp[])
|
||||||
{
|
{
|
||||||
|
|
@ -109,9 +120,9 @@ static int read_and_report(ledger::report_t& report, int argc, char * argv[],
|
||||||
|
|
||||||
expr::function_t command;
|
expr::function_t command;
|
||||||
|
|
||||||
#if 0
|
|
||||||
if (verb == "register" || verb == "reg" || verb == "r")
|
if (verb == "register" || verb == "reg" || verb == "r")
|
||||||
command = register_command();
|
command = register_command;
|
||||||
|
#if 0
|
||||||
else if (verb == "balance" || verb == "bal" || verb == "b")
|
else if (verb == "balance" || verb == "bal" || verb == "b")
|
||||||
command = balance_command();
|
command = balance_command();
|
||||||
else if (verb == "print" || verb == "p")
|
else if (verb == "print" || verb == "p")
|
||||||
|
|
@ -132,12 +143,8 @@ static int read_and_report(ledger::report_t& report, int argc, char * argv[],
|
||||||
command = csv_command();
|
command = csv_command();
|
||||||
else if (verb == "emacs" || verb == "lisp")
|
else if (verb == "emacs" || verb == "lisp")
|
||||||
command = emacs_command();
|
command = emacs_command();
|
||||||
else
|
else if (verb == "xml")
|
||||||
#endif
|
|
||||||
if (verb == "xml")
|
|
||||||
#if 0
|
|
||||||
command = bind(xml_command, _1);
|
command = bind(xml_command, _1);
|
||||||
#else
|
|
||||||
;
|
;
|
||||||
#endif
|
#endif
|
||||||
else if (verb == "expr")
|
else if (verb == "expr")
|
||||||
|
|
@ -297,7 +304,7 @@ static int read_and_report(ledger::report_t& report, int argc, char * argv[],
|
||||||
// Create an argument scope containing the report command's
|
// Create an argument scope containing the report command's
|
||||||
// arguments, and then invoke the command.
|
// arguments, and then invoke the command.
|
||||||
|
|
||||||
expr::call_scope_t command_args(*expr::global_scope);
|
expr::call_scope_t command_args(report);
|
||||||
|
|
||||||
for (strings_list::iterator i = arg; i != args.end(); i++)
|
for (strings_list::iterator i = arg; i != args.end(); i++)
|
||||||
command_args.push_back(value_t(*i, true));
|
command_args.push_back(value_t(*i, true));
|
||||||
|
|
|
||||||
36
option.cc
36
option.cc
|
|
@ -215,32 +215,12 @@ void process_arguments(int argc, char ** argv, const bool anywhere,
|
||||||
process_option(o.get<0>()->as_function(), scope, value);
|
process_option(o.get<0>()->as_function(), scope, value);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace ledger
|
||||||
|
|
||||||
#if 0
|
#if 0
|
||||||
}
|
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
|
||||||
|
|
||||||
namespace ledger {
|
|
||||||
|
|
||||||
config_t * config = NULL;
|
|
||||||
report_t * report = NULL;
|
|
||||||
|
|
||||||
static void show_version(std::ostream& out)
|
|
||||||
{
|
|
||||||
out << "Ledger " << ledger::version << ", the command-line accounting tool";
|
|
||||||
out << "\n\nCopyright (c) 2003-2008, John Wiegley. All rights reserved.\n\n\
|
|
||||||
This program is made available under the terms of the BSD Public License.\n\
|
|
||||||
See LICENSE file included with the distribution for details and disclaimer.\n";
|
|
||||||
out << "\n(modules: gmp, pcre";
|
|
||||||
#if defined(HAVE_EXPAT) || defined(HAVE_XMLPARSE)
|
|
||||||
out << ", xml";
|
|
||||||
#endif
|
|
||||||
#ifdef HAVE_LIBOFX
|
|
||||||
out << ", ofx";
|
|
||||||
#endif
|
|
||||||
out << ")\n";
|
|
||||||
}
|
|
||||||
|
|
||||||
void option_full_help(std::ostream& out)
|
void option_full_help(std::ostream& out)
|
||||||
{
|
{
|
||||||
out << "usage: ledger [options] COMMAND [ACCT REGEX]... [-- [PAYEE REGEX]...]\n\n\
|
out << "usage: ledger [options] COMMAND [ACCT REGEX]... [-- [PAYEE REGEX]...]\n\n\
|
||||||
|
|
@ -948,8 +928,6 @@ namespace {
|
||||||
commodity->add_price(datetime_t::now, price);
|
commodity->add_price(datetime_t::now, price);
|
||||||
commodity->history()->bogus_time = datetime_t::now;
|
commodity->history()->bogus_time = datetime_t::now;
|
||||||
}
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace ledger
|
|
||||||
|
|
|
||||||
|
|
@ -57,9 +57,9 @@ value_t report_t::abbrev(expr::call_scope_t& args)
|
||||||
throw_(std::logic_error, "usage: abbrev(STRING, WIDTH [, STYLE, ABBREV_LEN])");
|
throw_(std::logic_error, "usage: abbrev(STRING, WIDTH [, STYLE, ABBREV_LEN])");
|
||||||
|
|
||||||
string str = args[0].as_string();
|
string str = args[0].as_string();
|
||||||
|
#if 0
|
||||||
long wid = args[1];
|
long wid = args[1];
|
||||||
|
|
||||||
#if 0
|
|
||||||
elision_style_t style = session.elision_style;
|
elision_style_t style = session.elision_style;
|
||||||
if (args.size() == 3)
|
if (args.size() == 3)
|
||||||
style = static_cast<elision_style_t>(args[2].as_long());
|
style = static_cast<elision_style_t>(args[2].as_long());
|
||||||
|
|
|
||||||
32
valexpr.cc
32
valexpr.cc
|
|
@ -77,6 +77,14 @@ void scope_t::define(const string& name, const value_t& val) {
|
||||||
define(name, op_t::wrap_value(val));
|
define(name, op_t::wrap_value(val));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
value_t scope_t::resolve(const string& name) {
|
||||||
|
ptr_op_t definition = lookup(name);
|
||||||
|
if (definition)
|
||||||
|
return definition->calc(*this);
|
||||||
|
else
|
||||||
|
return value_t();
|
||||||
|
}
|
||||||
|
|
||||||
void symbol_scope_t::define(const string& name, ptr_op_t def)
|
void symbol_scope_t::define(const string& name, ptr_op_t def)
|
||||||
{
|
{
|
||||||
DEBUG("ledger.xpath.syms", "Defining '" << name << "' = " << def);
|
DEBUG("ledger.xpath.syms", "Defining '" << name << "' = " << def);
|
||||||
|
|
@ -817,10 +825,10 @@ void valexpr_context::describe(std::ostream& out) const throw()
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
ptr_op_t op_t::compile(scope_t& scope)
|
||||||
xpath_t::ptr_op_t xpath_t::op_t::compile(scope_t& scope)
|
|
||||||
{
|
{
|
||||||
switch (kind) {
|
switch (kind) {
|
||||||
|
#if 0
|
||||||
case VAR_NAME:
|
case VAR_NAME:
|
||||||
case FUNC_NAME:
|
case FUNC_NAME:
|
||||||
if (ptr_op_t def = scope.lookup(as_string())) {
|
if (ptr_op_t def = scope.lookup(as_string())) {
|
||||||
|
|
@ -833,6 +841,7 @@ xpath_t::ptr_op_t xpath_t::op_t::compile(scope_t& scope)
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
return this;
|
return this;
|
||||||
|
#endif
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
|
|
@ -856,14 +865,17 @@ xpath_t::ptr_op_t xpath_t::op_t::compile(scope_t& scope)
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
||||||
value_t xpath_t::op_t::calc(scope_t& scope)
|
value_t op_t::calc(scope_t& scope)
|
||||||
{
|
{
|
||||||
|
#if 0
|
||||||
bool find_all_nodes = false;
|
bool find_all_nodes = false;
|
||||||
|
#endif
|
||||||
|
|
||||||
switch (kind) {
|
switch (kind) {
|
||||||
case VALUE:
|
case VALUE:
|
||||||
return as_value();
|
return as_value();
|
||||||
|
|
||||||
|
#if 0
|
||||||
case VAR_NAME:
|
case VAR_NAME:
|
||||||
case FUNC_NAME:
|
case FUNC_NAME:
|
||||||
if (ptr_op_t reference = compile(scope)) {
|
if (ptr_op_t reference = compile(scope)) {
|
||||||
|
|
@ -873,6 +885,7 @@ value_t xpath_t::op_t::calc(scope_t& scope)
|
||||||
<< " named '" << as_string() << "'");
|
<< " named '" << as_string() << "'");
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
case FUNCTION:
|
case FUNCTION:
|
||||||
// This should never be evaluated directly; it only appears as the
|
// This should never be evaluated directly; it only appears as the
|
||||||
|
|
@ -880,6 +893,7 @@ value_t xpath_t::op_t::calc(scope_t& scope)
|
||||||
assert(false);
|
assert(false);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
#if 0
|
||||||
case O_CALL: {
|
case O_CALL: {
|
||||||
call_scope_t call_args(scope);
|
call_scope_t call_args(scope);
|
||||||
|
|
||||||
|
|
@ -901,6 +915,7 @@ value_t xpath_t::op_t::calc(scope_t& scope)
|
||||||
|
|
||||||
return func->as_function()(call_args);
|
return func->as_function()(call_args);
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
case ARG_INDEX: {
|
case ARG_INDEX: {
|
||||||
call_scope_t& args(CALL_SCOPE(scope));
|
call_scope_t& args(CALL_SCOPE(scope));
|
||||||
|
|
@ -912,6 +927,7 @@ value_t xpath_t::op_t::calc(scope_t& scope)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
case O_FIND:
|
case O_FIND:
|
||||||
case O_RFIND:
|
case O_RFIND:
|
||||||
return select_nodes(scope, left()->calc(scope), right(), kind == O_RFIND);
|
return select_nodes(scope, left()->calc(scope), right(), kind == O_RFIND);
|
||||||
|
|
@ -997,6 +1013,7 @@ value_t xpath_t::op_t::calc(scope_t& scope)
|
||||||
return *value;
|
return *value;
|
||||||
|
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
case O_NEQ:
|
case O_NEQ:
|
||||||
return left()->calc(scope) != right()->calc(scope);
|
return left()->calc(scope) != right()->calc(scope);
|
||||||
|
|
@ -1033,14 +1050,16 @@ value_t xpath_t::op_t::calc(scope_t& scope)
|
||||||
case O_OR:
|
case O_OR:
|
||||||
return left()->calc(scope) || right()->calc(scope);
|
return left()->calc(scope) || right()->calc(scope);
|
||||||
|
|
||||||
case O_COMMA:
|
#if 0
|
||||||
case O_UNION: {
|
case O_UNION:
|
||||||
|
#endif
|
||||||
|
case O_COMMA: {
|
||||||
value_t result(left()->calc(scope));
|
value_t result(left()->calc(scope));
|
||||||
|
|
||||||
ptr_op_t next = right();
|
ptr_op_t next = right();
|
||||||
while (next) {
|
while (next) {
|
||||||
ptr_op_t value_op;
|
ptr_op_t value_op;
|
||||||
if (next->kind == O_COMMA || next->kind == O_UNION) {
|
if (next->kind == O_COMMA /* || next->kind == O_UNION */) {
|
||||||
value_op = next->left();
|
value_op = next->left();
|
||||||
next = next->right();
|
next = next->right();
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -1061,7 +1080,6 @@ value_t xpath_t::op_t::calc(scope_t& scope)
|
||||||
|
|
||||||
return NULL_VALUE;
|
return NULL_VALUE;
|
||||||
}
|
}
|
||||||
#endif
|
|
||||||
|
|
||||||
} // namespace expr
|
} // namespace expr
|
||||||
|
|
||||||
|
|
|
||||||
68
valexpr.h
68
valexpr.h
|
|
@ -152,13 +152,7 @@ public:
|
||||||
virtual void define(const string& name, ptr_op_t def) = 0;
|
virtual void define(const string& name, ptr_op_t def) = 0;
|
||||||
void define(const string& name, const value_t& val);
|
void define(const string& name, const value_t& val);
|
||||||
virtual ptr_op_t lookup(const string& name) = 0;
|
virtual ptr_op_t lookup(const string& name) = 0;
|
||||||
value_t resolve(const string& name) {
|
value_t resolve(const string& name);
|
||||||
#if 0
|
|
||||||
return lookup(name)->calc(*this);
|
|
||||||
#else
|
|
||||||
return value_t();
|
|
||||||
#endif
|
|
||||||
}
|
|
||||||
|
|
||||||
virtual optional<scope_t&> find_scope(const type_t _type,
|
virtual optional<scope_t&> find_scope(const type_t _type,
|
||||||
bool skip_this = false) = 0;
|
bool skip_this = false) = 0;
|
||||||
|
|
@ -273,10 +267,12 @@ public:
|
||||||
return args;
|
return args;
|
||||||
}
|
}
|
||||||
|
|
||||||
value_t& operator[](const int index) {
|
value_t& operator[](const unsigned int index) {
|
||||||
|
// jww (2008-07-21): exception here if it's out of bounds
|
||||||
return args[index];
|
return args[index];
|
||||||
}
|
}
|
||||||
const value_t& operator[](const int index) const {
|
const value_t& operator[](const unsigned int index) const {
|
||||||
|
// jww (2008-07-21): exception here if it's out of bounds
|
||||||
return args[index];
|
return args[index];
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -292,6 +288,21 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
struct var_t
|
||||||
|
{
|
||||||
|
T * value;
|
||||||
|
|
||||||
|
// jww (2008-07-21): Give a good exception here if we can't find "name"
|
||||||
|
var_t(scope_t& scope, const string& name)
|
||||||
|
: value(scope.resolve(name).template as_pointer<T>()) {}
|
||||||
|
var_t(call_scope_t& scope, const unsigned int idx)
|
||||||
|
: value(scope[idx].template as_pointer<T>()) {}
|
||||||
|
|
||||||
|
T& operator *() { return *value; }
|
||||||
|
T * operator->() { return value; }
|
||||||
|
};
|
||||||
|
|
||||||
class context_scope_t : public child_scope_t
|
class context_scope_t : public child_scope_t
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
@ -748,40 +759,6 @@ inline ptr_op_t op_t::wrap_functor(const function_t& fobj) {
|
||||||
return temp;
|
return temp;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
class xpath_t
|
|
||||||
{
|
|
||||||
public:
|
|
||||||
public:
|
|
||||||
void parse(const string& _expr, flags_t _flags = XPATH_PARSE_RELAXED) {
|
|
||||||
expr = _expr;
|
|
||||||
flags = _flags;
|
|
||||||
ptr = parse_expr(_expr, _flags);
|
|
||||||
}
|
|
||||||
void parse(std::istream& in, flags_t _flags = XPATH_PARSE_RELAXED) {
|
|
||||||
expr = "";
|
|
||||||
flags = _flags;
|
|
||||||
ptr = parse_expr(in, _flags);
|
|
||||||
}
|
|
||||||
|
|
||||||
void compile(scope_t& scope) {
|
|
||||||
if (ptr.get())
|
|
||||||
ptr = ptr->compile(scope);
|
|
||||||
}
|
|
||||||
|
|
||||||
value_t calc(scope_t& scope) const {
|
|
||||||
if (ptr.get())
|
|
||||||
return ptr->calc(scope);
|
|
||||||
return NULL_VALUE;
|
|
||||||
}
|
|
||||||
|
|
||||||
static value_t eval(const string& _expr, scope_t& scope) {
|
|
||||||
return xpath_t(_expr).calc(scope);
|
|
||||||
}
|
|
||||||
|
|
||||||
};
|
|
||||||
#endif
|
|
||||||
|
|
||||||
} // namespace expr
|
} // namespace expr
|
||||||
|
|
||||||
//////////////////////////////////////////////////////////////////////
|
//////////////////////////////////////////////////////////////////////
|
||||||
|
|
@ -826,11 +803,6 @@ public:
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
||||||
#if 0
|
|
||||||
const expr::op_t& operator*() const throw() {
|
|
||||||
return *ptr;
|
|
||||||
}
|
|
||||||
#endif
|
|
||||||
const expr::ptr_op_t operator->() const throw() {
|
const expr::ptr_op_t operator->() const throw() {
|
||||||
return ptr;
|
return ptr;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
22
value.cc
22
value.cc
|
|
@ -1413,19 +1413,31 @@ void value_t::print(std::ostream& out, const int first_width,
|
||||||
{
|
{
|
||||||
switch (type()) {
|
switch (type()) {
|
||||||
case VOID:
|
case VOID:
|
||||||
out << "NULL";
|
out << "VOID";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case BOOLEAN:
|
case BOOLEAN:
|
||||||
|
out << const_cast<value_t&>(*this).as_boolean_lval();
|
||||||
|
break;
|
||||||
|
|
||||||
case DATETIME:
|
case DATETIME:
|
||||||
|
out << const_cast<value_t&>(*this).as_datetime_lval();
|
||||||
|
break;
|
||||||
|
|
||||||
case INTEGER:
|
case INTEGER:
|
||||||
|
out << const_cast<value_t&>(*this).as_long_lval();
|
||||||
|
break;
|
||||||
|
|
||||||
case AMOUNT:
|
case AMOUNT:
|
||||||
|
out << const_cast<value_t&>(*this).as_amount_lval();
|
||||||
|
break;
|
||||||
|
|
||||||
case STRING:
|
case STRING:
|
||||||
|
out << const_cast<value_t&>(*this).as_string_lval();
|
||||||
|
break;
|
||||||
|
|
||||||
case POINTER:
|
case POINTER:
|
||||||
// jww (2007-05-14): I need a version of this print just for XPath
|
out << boost::unsafe_any_cast<void *>(&const_cast<value_t&>(*this).as_any_pointer_lval());
|
||||||
// expression, since amounts and strings need to be output with
|
|
||||||
// special syntax.
|
|
||||||
out << *this;
|
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SEQUENCE: {
|
case SEQUENCE: {
|
||||||
|
|
|
||||||
2
value.h
2
value.h
|
|
@ -610,7 +610,7 @@ public:
|
||||||
return *(boost::any *) storage->data;
|
return *(boost::any *) storage->data;
|
||||||
}
|
}
|
||||||
template <typename T>
|
template <typename T>
|
||||||
T *& as_pointer_lval() {
|
T * as_pointer_lval() {
|
||||||
assert(is_pointer());
|
assert(is_pointer());
|
||||||
_dup();
|
_dup();
|
||||||
return any_cast<T *>(*(boost::any *) storage->data);
|
return any_cast<T *>(*(boost::any *) storage->data);
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue