Changed all uses of scope_t * to scope_t&

This commit is contained in:
John Wiegley 2007-05-16 10:46:05 +00:00
parent 1134fc7eff
commit 2d8512af88
16 changed files with 269 additions and 251 deletions

View file

@ -1,3 +1,6 @@
- What does SEQUENCE + VALUE mean in XPath? Does it add VALUE to
every member of SEQUENCE?
- Add tracing code for functions that records call count and total
time spent, as well as average time per call. This would implement
selective profiling.

View file

@ -177,11 +177,11 @@ public:
amount_t(const unsigned long val);
amount_t(const long val);
amount_t(const string& val) : quantity(NULL) {
explicit amount_t(const string& val) : quantity(NULL) {
TRACE_CTOR(amount_t, "const string&");
parse(val);
}
amount_t(const char * val) : quantity(NULL) {
explicit amount_t(const char * val) : quantity(NULL) {
TRACE_CTOR(amount_t, "const char *");
parse(val);
}
@ -216,7 +216,7 @@ public:
* causing the result to compare equal to the reference amount.
*
* Note: `quantity' must be initialized to NULL first, otherwise the
* `_copy' function will attempt to release the unitialized pointer.
* `_copy' function will attempt to release the uninitialized pointer.
*/
amount_t(const amount_t& amt) : quantity(NULL) {
TRACE_CTOR(amount_t, "copy");
@ -227,6 +227,13 @@ public:
}
amount_t& operator=(const amount_t& amt);
amount_t& operator=(const string& str) {
return *this = amount_t(str);
}
amount_t& operator=(const char * str) {
return *this = amount_t(str);
}
/**
* Comparison operators. The fundamental comparison operation for
* amounts is `compare', which returns a value less than, greater

View file

@ -46,12 +46,12 @@
#include <fdstream.hpp>
#endif
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[])
{
using namespace ledger;
session_t& session(*report->session);
session_t& session(report.session);
// Handle the command-line arguments
@ -164,7 +164,7 @@ static int read_and_report(ledger::report_t * report, int argc, char * argv[],
std::strcpy(buf, "command_");
std::strcat(buf, verb.c_str());
if (xml::xpath_t::ptr_op_t def = report->lookup(buf))
if (xml::xpath_t::ptr_op_t def = report.lookup(buf))
command = def->as_function();
if (! command)
@ -182,7 +182,7 @@ static int read_and_report(ledger::report_t * report, int argc, char * argv[],
journal_t * journal = session.create_journal();
xml::document_builder_t builder(xml_document);
if (! session.read_data(builder, journal, report->account))
if (! session.read_data(builder, journal, report.account))
throw_(parse_error, "Failed to locate any journal entries; "
"did you specify a valid file with -f?");
@ -202,11 +202,11 @@ static int read_and_report(ledger::report_t * report, int argc, char * argv[],
#endif
std::ostream * out = &std::cout;
if (report->output_file) {
out = new ofstream(*report->output_file);
if (report.output_file) {
out = new ofstream(*report.output_file);
}
#ifdef HAVE_UNIX_PIPES
else if (report->pager) {
else if (report.pager) {
status = pipe(pfd);
if (status == -1)
throw_(std::logic_error, "Failed to create pipe");
@ -230,8 +230,8 @@ static int read_and_report(ledger::report_t * report, int argc, char * argv[],
// Find command name: its the substring starting right of the
// rightmost '/' character in the pager pathname. See manpage
// for strrchr.
execlp(report->pager->native_file_string().c_str(),
basename(*report->pager).c_str(), (char *)0);
execlp(report.pager->native_file_string().c_str(),
basename(*report.pager).c_str(), (char *)0);
perror("execl");
exit(1);
}
@ -282,28 +282,25 @@ static int read_and_report(ledger::report_t * report, int argc, char * argv[],
// Apply transforms to the hierarchical document structure
INFO_START(transforms, "Applied transforms");
report->apply_transforms(xml_document);
report.apply_transforms(xml_document);
INFO_FINISH(transforms);
// Create an argument scope containing the report command's
// arguments, and then invoke the command.
scoped_ptr<xml::xpath_t::scope_t> locals
(new xml::xpath_t::scope_t(report, xml::xpath_t::scope_t::ARGUMENT));
xml::xpath_t::scope_t locals(report, xml::xpath_t::scope_t::ARGUMENT);
locals->args = value_t::sequence_t();
locals->args.push_back(out);
locals->args.push_back(&xml_document);
locals.args.push_back(out);
locals.args.push_back(&xml_document);
value_t::sequence_t args_list;
foreach (string& i, args)
args_list.push_back(value_t(i, true));
locals->args.push_back(args_list);
locals.args.push_back(args_list);
INFO_START(command, "Did user command '" << verb << "'");
command(locals.get());
command(locals);
INFO_FINISH(command);
@ -323,7 +320,7 @@ static int read_and_report(ledger::report_t * report, int argc, char * argv[],
// If the user specified a pager, wait for it to exit now
#ifdef HAVE_UNIX_PIPES
if (! report->output_file && report->pager) {
if (! report.output_file && report.pager) {
checked_delete(out);
close(pfd[1]);
@ -333,7 +330,7 @@ static int read_and_report(ledger::report_t * report, int argc, char * argv[],
throw_(std::logic_error, "Something went wrong in the pager");
}
#endif
else if (DO_VERIFY() && report->output_file) {
else if (DO_VERIFY() && report.output_file) {
checked_delete(out);
}
@ -401,9 +398,9 @@ int main(int argc, char * argv[], char * envp[])
#endif
session->register_parser(new ledger::textual_parser_t);
std::auto_ptr<ledger::report_t> report(new ledger::report_t(session.get()));
std::auto_ptr<ledger::report_t> report(new ledger::report_t(*session.get()));
status = read_and_report(report.get(), argc, argv, envp);
status = read_and_report(*report.get(), argc, argv, envp);
if (DO_VERIFY()) {
ledger::set_session_context();

View file

@ -36,7 +36,7 @@ namespace ledger {
namespace {
typedef tuple<xml::xpath_t::ptr_op_t, bool> op_bool_tuple;
op_bool_tuple find_option(xml::xpath_t::scope_t * scope, const string& name)
op_bool_tuple find_option(xml::xpath_t::scope_t& scope, const string& name)
{
char buf[128];
std::strcpy(buf, "option_");
@ -49,46 +49,44 @@ namespace {
}
*p = '\0';
xml::xpath_t::ptr_op_t op = scope->lookup(buf);
xml::xpath_t::ptr_op_t op = scope.lookup(buf);
if (op)
return op_bool_tuple(op, false);
*p++ = '_';
*p = '\0';
return op_bool_tuple(scope->lookup(buf), true);
return op_bool_tuple(scope.lookup(buf), true);
}
op_bool_tuple find_option(xml::xpath_t::scope_t * scope, const char letter)
op_bool_tuple find_option(xml::xpath_t::scope_t& scope, const char letter)
{
char buf[10];
std::strcpy(buf, "option_");
buf[7] = letter;
buf[8] = '\0';
xml::xpath_t::ptr_op_t op = scope->lookup(buf);
xml::xpath_t::ptr_op_t op = scope.lookup(buf);
if (op)
return op_bool_tuple(op, false);
buf[8] = '_';
buf[9] = '\0';
return op_bool_tuple(scope->lookup(buf), true);
return op_bool_tuple(scope.lookup(buf), true);
}
void process_option(const xml::xpath_t::function_t& opt,
xml::xpath_t::scope_t * scope, const char * arg)
xml::xpath_t::scope_t& scope, const char * arg)
{
#if 0
try {
#endif
scoped_ptr<xml::xpath_t::scope_t> args;
if (arg) {
args.reset(new xml::xpath_t::scope_t
(scope, xml::xpath_t::scope_t::ARGUMENT));
args->args.push_back(value_t(arg, true));
}
opt(args.get());
xml::xpath_t::scope_t arguments(scope, xml::xpath_t::scope_t::ARGUMENT);
if (arg)
arguments.args.push_back(value_t(arg, true));
opt(arguments);
#if 0
}
catch (error * err) {
@ -103,7 +101,7 @@ namespace {
}
}
void process_option(const string& name, xml::xpath_t::scope_t * scope,
void process_option(const string& name, xml::xpath_t::scope_t& scope,
const char * arg)
{
op_bool_tuple opt(find_option(scope, name));
@ -112,7 +110,7 @@ void process_option(const string& name, xml::xpath_t::scope_t * scope,
}
void process_environment(const char ** envp, const string& tag,
xml::xpath_t::scope_t * scope)
xml::xpath_t::scope_t& scope)
{
const char * tag_p = tag.c_str();
unsigned int tag_len = tag.length();
@ -151,7 +149,7 @@ void process_environment(const char ** envp, const string& tag,
}
void process_arguments(int argc, char ** argv, const bool anywhere,
xml::xpath_t::scope_t * scope,
xml::xpath_t::scope_t& scope,
std::list<string>& args)
{
for (char ** i = argv; *i; i++) {

View file

@ -36,14 +36,14 @@
namespace ledger {
void process_option(const string& name, xml::xpath_t::scope_t * scope,
void process_option(const string& name, xml::xpath_t::scope_t& scope,
const char * arg = NULL);
void process_environment(const char ** envp, const string& tag,
xml::xpath_t::scope_t * scope);
xml::xpath_t::scope_t& scope);
void process_arguments(int argc, char ** argv, const bool anywhere,
xml::xpath_t::scope_t * scope,
xml::xpath_t::scope_t& scope,
std::list<string>& args);
DECLARE_EXCEPTION(option_error);

View file

@ -86,7 +86,7 @@ struct python_run
}
};
python_interpreter_t::python_interpreter_t(xml::xpath_t::scope_t * parent)
python_interpreter_t::python_interpreter_t(xml::xpath_t::scope_t& parent)
: xml::xpath_t::scope_t(parent),
mmodule(borrowed(PyImport_AddModule("__main__"))),
nspace(handle<>(borrowed(PyModule_GetDict(mmodule.get()))))
@ -176,15 +176,15 @@ object python_interpreter_t::eval(const string& str, py_eval_mode_t mode)
return object();
}
value_t python_interpreter_t::functor_t::operator()(xml::xpath_t::scope_t * locals)
value_t python_interpreter_t::functor_t::operator()(xml::xpath_t::scope_t& locals)
{
try {
if (! PyCallable_Check(func.ptr())) {
return extract<value_t>(func.ptr());
} else {
if (locals->args.size() > 0) {
if (locals.args.size() > 0) {
list arglist;
foreach (const value_t& value, locals->args)
foreach (const value_t& value, locals.args)
arglist.append(value);
if (PyObject * val =
@ -215,11 +215,11 @@ value_t python_interpreter_t::functor_t::operator()(xml::xpath_t::scope_t * loca
}
value_t python_interpreter_t::lambda_t::operator()
(xml::xpath_t::scope_t * locals)
(xml::xpath_t::scope_t& locals)
{
try {
assert(locals->args.size() == 1);
value_t item = locals->args[0];
assert(locals.args.size() == 1);
value_t item = locals.args[0];
assert(item.is_xml_node());
return call<value_t>(func.ptr(), item.as_xml_node());
}

View file

@ -46,7 +46,7 @@ class python_interpreter_t : public xml::xpath_t::scope_t
public:
boost::python::dict nspace;
python_interpreter_t(xml::xpath_t::scope_t * parent);
python_interpreter_t(xml::xpath_t::scope_t& parent);
virtual ~python_interpreter_t() {
Py_Finalize();
@ -76,7 +76,7 @@ class python_interpreter_t : public xml::xpath_t::scope_t
public:
functor_t(const string& name, boost::python::object _func) : func(_func) {}
virtual ~functor_t() {}
virtual value_t operator()(xml::xpath_t::scope_t * locals);
virtual value_t operator()(xml::xpath_t::scope_t& locals);
};
virtual void define(const string& name, xml::xpath_t::ptr_op_t def) {
@ -94,7 +94,7 @@ class python_interpreter_t : public xml::xpath_t::scope_t
class lambda_t : public functor_t {
public:
lambda_t(boost::python::object code) : functor_t("<lambda>", code) {}
virtual value_t operator()(xml::xpath_t::scope_t * locals);
virtual value_t operator()(xml::xpath_t::scope_t& locals);
};
};

View file

@ -44,35 +44,35 @@ void report_t::apply_transforms(xml::document_t& document)
transform.execute(document);
}
value_t report_t::abbrev(xml::xpath_t::scope_t * locals)
value_t report_t::abbrev(xml::xpath_t::scope_t& locals)
{
if (locals->args.size() < 2)
if (locals.args.size() < 2)
throw_(std::logic_error, "usage: abbrev(STRING, WIDTH [, STYLE, ABBREV_LEN])");
string str = locals->args[0].as_string();
long wid = locals->args[1];
string str = locals.args[0].as_string();
long wid = locals.args[1];
elision_style_t style = session->elision_style;
if (locals->args.size() == 3)
style = (elision_style_t)locals->args[2].as_long();
elision_style_t style = session.elision_style;
if (locals.args.size() == 3)
style = (elision_style_t)locals.args[2].as_long();
long abbrev_len = session->abbrev_length;
if (locals->args.size() == 4)
abbrev_len = locals->args[3].as_long();
long abbrev_len = session.abbrev_length;
if (locals.args.size() == 4)
abbrev_len = locals.args[3].as_long();
return value_t(abbreviate(str, wid, style, true, (int)abbrev_len), true);
}
value_t report_t::ftime(xml::xpath_t::scope_t * locals)
value_t report_t::ftime(xml::xpath_t::scope_t& locals)
{
if (locals->args.size() < 1)
if (locals.args.size() < 1)
throw_(std::logic_error, "usage: ftime(DATE [, DATE_FORMAT])");
moment_t date = locals->args[0].as_datetime();
moment_t date = locals.args[0].as_datetime();
string date_format;
if (locals->args.size() == 2)
date_format = locals->args[1].as_string();
if (locals.args.size() == 2)
date_format = locals.args[1].as_string();
#if 0
// jww (2007-04-18): Need to setup an output facet here
else
@ -85,7 +85,7 @@ value_t report_t::ftime(xml::xpath_t::scope_t * locals)
}
optional<value_t>
report_t::resolve(const string& name, xml::xpath_t::scope_t * locals)
report_t::resolve(const string& name, xml::xpath_t::scope_t& locals)
{
const char * p = name.c_str();
switch (*p) {

View file

@ -48,28 +48,30 @@ class report_t : public xml::xpath_t::scope_t
string total_expr;
string date_output_format;
unsigned long budget_flags;
unsigned long budget_flags;
string account;
string account;
optional<path> pager;
bool show_totals;
bool raw_mode;
bool show_totals;
bool raw_mode;
session_t * session;
transform_t * last_transform;
session_t& session;
transform_t * last_transform;
ptr_list<transform_t> transforms;
report_t(session_t * _session)
explicit report_t(session_t& _session)
: xml::xpath_t::scope_t(_session),
show_totals(false),
raw_mode(false),
session(_session),
last_transform(NULL)
{
TRACE_CTOR(report_t, "session_t *");
TRACE_CTOR(report_t, "session_t&");
#if 0
eval("t=total,TOT=0,T()=(TOT=TOT+t,TOT)");
#endif
}
virtual ~report_t();
@ -80,8 +82,8 @@ class report_t : public xml::xpath_t::scope_t
// Utility functions for value expressions
//
value_t ftime(xml::xpath_t::scope_t * locals);
value_t abbrev(xml::xpath_t::scope_t * locals);
value_t ftime(xml::xpath_t::scope_t& locals);
value_t abbrev(xml::xpath_t::scope_t& locals);
//
// Config options
@ -92,36 +94,36 @@ class report_t : public xml::xpath_t::scope_t
xml::xpath_t(expr).compile((xml::document_t *)NULL, this);
#endif
}
value_t option_eval(xml::xpath_t::scope_t * locals) {
eval(locals->args[0].as_string());
value_t option_eval(xml::xpath_t::scope_t& locals) {
eval(locals.args[0].as_string());
return NULL_VALUE;
}
value_t option_amount(xml::xpath_t::scope_t * locals) {
eval(string("t=") + locals->args[0].as_string());
value_t option_amount(xml::xpath_t::scope_t& locals) {
eval(string("t=") + locals.args[0].as_string());
return NULL_VALUE;
}
value_t option_total(xml::xpath_t::scope_t * locals) {
eval(string("T()=") + locals->args[0].as_string());
value_t option_total(xml::xpath_t::scope_t& locals) {
eval(string("T()=") + locals.args[0].as_string());
return NULL_VALUE;
}
value_t option_format(xml::xpath_t::scope_t * locals) {
format_string = locals->args[0].as_string();
value_t option_format(xml::xpath_t::scope_t& locals) {
format_string = locals.args[0].as_string();
return NULL_VALUE;
}
value_t option_raw(xml::xpath_t::scope_t * locals) {
value_t option_raw(xml::xpath_t::scope_t& locals) {
raw_mode = true;
return NULL_VALUE;
}
value_t option_foo(xml::xpath_t::scope_t * locals) {
value_t option_foo(xml::xpath_t::scope_t& locals) {
std::cout << "This is foo" << std::endl;
return NULL_VALUE;
}
value_t option_bar(xml::xpath_t::scope_t * locals) {
std::cout << "This is bar: " << locals->args[0] << std::endl;
value_t option_bar(xml::xpath_t::scope_t& locals) {
std::cout << "This is bar: " << locals.args[0] << std::endl;
return NULL_VALUE;
}
@ -130,44 +132,44 @@ class report_t : public xml::xpath_t::scope_t
//
#if 0
value_t option_select(xml::xpath_t::scope_t * locals) {
transforms.push_back(new select_transform(locals->args[0].as_string()));
value_t option_select(xml::xpath_t::scope_t& locals) {
transforms.push_back(new select_transform(locals.args[0].as_string()));
return NULL_VALUE;
}
value_t option_limit(xml::xpath_t::scope_t * locals) {
value_t option_limit(xml::xpath_t::scope_t& locals) {
string expr = (string("//xact[") +
locals->args[0].as_string() + "]");
locals.args[0].as_string() + "]");
transforms.push_back(new select_transform(expr));
return NULL_VALUE;
}
value_t option_remove(xml::xpath_t::scope_t * locals) {
transforms.push_back(new remove_transform(locals->args[0].as_string()));
value_t option_remove(xml::xpath_t::scope_t& locals) {
transforms.push_back(new remove_transform(locals.args[0].as_string()));
return NULL_VALUE;
}
value_t option_accounts(xml::xpath_t::scope_t * locals) {
value_t option_accounts(xml::xpath_t::scope_t& locals) {
transforms.push_back(new accounts_transform);
return NULL_VALUE;
}
value_t option_compact(xml::xpath_t::scope_t * locals) {
value_t option_compact(xml::xpath_t::scope_t& locals) {
transforms.push_back(new compact_transform);
return NULL_VALUE;
}
value_t option_clean(xml::xpath_t::scope_t * locals) {
value_t option_clean(xml::xpath_t::scope_t& locals) {
transforms.push_back(new clean_transform);
return NULL_VALUE;
}
value_t option_entries(xml::xpath_t::scope_t * locals) {
value_t option_entries(xml::xpath_t::scope_t& locals) {
transforms.push_back(new entries_transform);
return NULL_VALUE;
}
value_t option_split(xml::xpath_t::scope_t * locals) {
value_t option_split(xml::xpath_t::scope_t& locals) {
transforms.push_back(new split_transform);
return NULL_VALUE;
}
value_t option_merge(xml::xpath_t::scope_t * locals) {
value_t option_merge(xml::xpath_t::scope_t& locals) {
transforms.push_back(new merge_transform);
return NULL_VALUE;
}
@ -178,7 +180,7 @@ class report_t : public xml::xpath_t::scope_t
//
virtual optional<value_t> resolve(const string& name,
xml::xpath_t::scope_t * locals);
xml::xpath_t::scope_t& locals);
virtual xml::xpath_t::ptr_op_t lookup(const string& name);
};

View file

@ -174,7 +174,7 @@ std::size_t session_t::read_data(xml::builder_t& builder,
}
optional<value_t>
session_t::resolve(const string& name, xml::xpath_t::scope_t * locals)
session_t::resolve(const string& name, xml::xpath_t::scope_t& locals)
{
const char * p = name.c_str();
switch (*p) {

View file

@ -79,9 +79,7 @@ class session_t : public xml::xpath_t::scope_t
ptr_list<journal_t> journals;
ptr_list<parser_t> parsers;
session_t(xml::xpath_t::scope_t * _parent = NULL) :
xml::xpath_t::scope_t(_parent),
session_t() :
register_format
("%((//entry)%{date} %-.20{payee}"
"%((./xact)%32|%-22{abbrev(account, 22)} %12.67t %12.80T\n))"),
@ -125,7 +123,7 @@ class session_t : public xml::xpath_t::scope_t
ansi_codes(false),
ansi_invert(false) {
TRACE_CTOR(session_t, "xml::xpath_t::scope_t *");
TRACE_CTOR(session_t, "xml::xpath_t::scope_t&");
}
virtual ~session_t() {
@ -181,24 +179,24 @@ class session_t : public xml::xpath_t::scope_t
//
virtual optional<value_t> resolve(const string& name,
xml::xpath_t::scope_t * locals = NULL);
xml::xpath_t::scope_t& locals = NULL);
virtual xml::xpath_t::ptr_op_t lookup(const string& name);
//
// Debug options
//
value_t option_trace_(xml::xpath_t::scope_t * locals) {
value_t option_trace_(xml::xpath_t::scope_t& locals) {
return NULL_VALUE;
}
value_t option_debug_(xml::xpath_t::scope_t * locals) {
value_t option_debug_(xml::xpath_t::scope_t& locals) {
return NULL_VALUE;
}
value_t option_verify(xml::xpath_t::scope_t *) {
value_t option_verify(xml::xpath_t::scope_t&) {
return NULL_VALUE;
}
value_t option_verbose(xml::xpath_t::scope_t *) {
value_t option_verbose(xml::xpath_t::scope_t&) {
#if defined(LOGGING_ON)
if (_log_level < LOG_INFO)
_log_level = LOG_INFO;
@ -210,19 +208,19 @@ class session_t : public xml::xpath_t::scope_t
// Option handlers
//
value_t option_file_(xml::xpath_t::scope_t * locals) {
assert(locals->args.size() == 1);
data_file = locals->args[0].as_string();
value_t option_file_(xml::xpath_t::scope_t& locals) {
assert(locals.args.size() == 1);
data_file = locals.args[0].as_string();
return NULL_VALUE;
}
#if 0
#if defined(USE_BOOST_PYTHON)
value_t option_import_(xml::xpath_t::scope_t * locals) {
value_t option_import_(xml::xpath_t::scope_t& locals) {
python_import(optarg);
return NULL_VALUE;
}
value_t option_import_stdin(xml::xpath_t::scope_t * locals) {
value_t option_import_stdin(xml::xpath_t::scope_t& locals) {
python_eval(std::cin, PY_EVAL_MULTI);
return NULL_VALUE;
}

View file

@ -1053,7 +1053,7 @@ void value_t::in_place_cast(type_t cast_type)
break;
}
case AMOUNT:
set_amount(as_string());
set_amount(amount_t(as_string()));
return;
default:
break;
@ -1340,7 +1340,7 @@ value_t value_t::annotated_tag() const
optional<string> temp = as_amount().annotation_details().tag;
if (! temp)
return false;
return *temp;
return value_t(*temp, true);
}
case BALANCE:

View file

@ -183,19 +183,19 @@ public:
TRACE_CTOR(value_t, "const unsigned long");
set_amount(val);
}
value_t(const string& val, bool literal = false) {
explicit value_t(const string& val, bool literal = false) {
TRACE_CTOR(value_t, "const string&, bool");
if (literal)
set_string(val);
else
set_amount(val);
set_amount(amount_t(val));
}
value_t(const char * val, bool literal = false) {
explicit value_t(const char * val, bool literal = false) {
TRACE_CTOR(value_t, "const char *");
if (literal)
set_string(val);
else
set_amount(val);
set_amount(amount_t(val));
}
value_t(const amount_t& val) {
TRACE_CTOR(value_t, "const amount_t&");

View file

@ -484,7 +484,7 @@ void xpath_t::scope_t::define(const string& name, const function_t& def) {
}
optional<value_t>
xpath_t::function_scope_t::resolve(const string& name, scope_t * locals)
xpath_t::function_scope_t::resolve(const string& name, scope_t& locals)
{
switch (name[0]) {
case 'l':
@ -1092,7 +1092,7 @@ void xpath_t::op_t::append_value(value_t::sequence_t& result_seq, value_t& val)
}
xpath_t::ptr_op_t
xpath_t::op_t::compile(const node_t& context, scope_t * scope, bool resolve)
xpath_t::op_t::compile(const node_t& context, scope_t& scope, bool resolve)
{
#if 0
try {
@ -1103,33 +1103,32 @@ xpath_t::op_t::compile(const node_t& context, scope_t * scope, bool resolve)
case ATTR_ID:
if (optional<const string&> value = context.get_attr(as_long()))
return wrap_value(*value);
return wrap_value(value_t(*value, true));
return this;
case ATTR_NAME:
if (optional<node_t::nameid_t> id =
context.document().lookup_name_id(as_string())) {
if (optional<const string&> value = context.get_attr(*id))
return wrap_value(*value);
return wrap_value(value_t(*value, true));
}
return this;
case VAR_NAME:
case FUNC_NAME:
if (scope) {
if (resolve) {
if (optional<value_t> temp = scope->resolve(as_string()))
return wrap_value(*temp);
}
if (ptr_op_t def = scope->lookup(as_string()))
return def->compile(context, scope, resolve);
if (resolve) {
scope_t null_scope;
if (optional<value_t> temp = scope.resolve(as_string(), null_scope))
return wrap_value(*temp);
}
if (ptr_op_t def = scope.lookup(as_string()))
return def->compile(context, scope, resolve);
return this;
case ARG_INDEX:
if (scope && scope->kind == scope_t::ARGUMENT) {
if (as_long() < scope->args.size())
return wrap_value(scope->args[as_long()]);
if (scope.kind == scope_t::ARGUMENT) {
if (as_long() < scope.args.size())
return wrap_value(scope.args[as_long()]);
else
throw_(compile_error, "Reference to non-existing argument");
} else {
@ -1389,14 +1388,17 @@ xpath_t::op_t::compile(const node_t& context, scope_t * scope, bool resolve)
case O_DEFINE:
if (left()->kind == VAR_NAME || left()->kind == FUNC_NAME) {
xpath_t rexpr(right()->compile(context, scope, resolve));
if (scope)
scope->define(left()->as_string(), rexpr.ptr);
scope.define(left()->as_string(), rexpr.ptr);
return rexpr.ptr;
} else {
assert(left()->kind == O_EVAL);
assert(left()->left()->kind == FUNC_NAME);
std::auto_ptr<scope_t> arg_scope(new scope_t(scope));
#if 0
// jww (2006-09-16): If I compile the definition of a function,
// I eliminate the possibility of future lookups
scope_t arg_scope(scope);
unsigned int index = 0;
ptr_op_t args = left()->right();
@ -1415,24 +1417,18 @@ xpath_t::op_t::compile(const node_t& context, scope_t * scope, bool resolve)
ref->set_long(index++);
assert(arg->kind == NODE_NAME);
arg_scope->define(arg->as_string(), ref);
arg_scope.define(arg->as_string(), ref);
}
// jww (2006-09-16): If I compile the definition of a function,
// I eliminate the possibility of future lookups
//xpath_t rexpr(right->compile(arg_scope.get(), resolve));
if (scope)
scope->define(left()->left()->as_string(), right());
xpath_t rexpr(right->compile(arg_scope, resolve));
#endif
scope.define(left()->left()->as_string(), right());
return right();
}
case O_EVAL: {
std::auto_ptr<scope_t> call_args(new scope_t(scope));
call_args->kind = scope_t::ARGUMENT;
value_t::sequence_t call_seq;
scope_t call_args(scope, scope_t::ARGUMENT);
ptr_op_t args = right();
while (args) {
@ -1446,25 +1442,23 @@ xpath_t::op_t::compile(const node_t& context, scope_t * scope, bool resolve)
// jww (2006-09-15): Need to return a reference to these, if
// there are undetermined arguments!
call_seq.push_back(arg->compile(context, scope, resolve)->as_value());
call_args.args.push_back(arg->compile(context, scope, resolve)->as_value());
}
call_args->args = call_seq;
if (left()->kind == FUNC_NAME) {
if (resolve && scope)
if (resolve)
if (optional<value_t> temp =
scope->resolve(left()->as_string(), call_args.get()))
scope.resolve(left()->as_string(), call_args))
return wrap_value(*temp);
// Don't compile to the left, otherwise the function name may
// get resolved before we have a chance to call it
xpath_t func(left()->compile(context, scope, false));
if (func.ptr->kind == FUNCTION) {
return wrap_value(func.ptr->as_function()(call_args.get()));
return wrap_value(func.ptr->as_function()(call_args));
}
else if (! resolve) {
return func.ptr->compile(context, call_args.get(), resolve);
return func.ptr->compile(context, call_args, resolve);
}
else {
throw_(calc_error,
@ -1472,7 +1466,7 @@ xpath_t::op_t::compile(const node_t& context, scope_t * scope, bool resolve)
}
}
else if (left()->kind == FUNCTION) {
return wrap_value(left()->as_function()(call_args.get()));
return wrap_value(left()->as_function()(call_args));
}
else {
assert(false);
@ -1515,7 +1509,7 @@ xpath_t::op_t::compile(const node_t& context, scope_t * scope, bool resolve)
return NULL;
}
value_t xpath_t::calc(const node_t& context, scope_t * scope) const
value_t xpath_t::calc(const node_t& context, scope_t& scope) const
{
#if 0
try {
@ -1987,7 +1981,7 @@ void xpath_t::op_t::dump(std::ostream& out, const int depth) const
template <typename NodeType>
void xpath_t::path_t::check_element(NodeType& start,
const ptr_op_t& element,
scope_t * scope,
scope_t& scope,
std::size_t index,
std::size_t size,
const visitor_t& func)
@ -1995,7 +1989,7 @@ void xpath_t::path_t::check_element(NodeType& start,
if (element->kind > op_t::TERMINALS &&
element->left()->kind == op_t::O_PRED) {
function_scope_t xpath_fscope(start, index, size, scope);
if (! op_predicate(element->left()->right())(start, &xpath_fscope))
if (! op_predicate(element->left()->right())(start, xpath_fscope))
return;
}
@ -2013,7 +2007,7 @@ template <typename NodeType>
void xpath_t::path_t::walk_elements(NodeType& start,
const ptr_op_t& element,
const bool recurse,
scope_t * scope,
scope_t& scope,
const visitor_t& func)
{
ptr_op_t name(element);
@ -2078,7 +2072,7 @@ void xpath_t::path_t::walk_elements(NodeType& start,
default: {
function_scope_t xpath_fscope(start, 0, 1, scope);
xpath_t final(name->compile(start, &xpath_fscope, true));
xpath_t final(name->compile(start, xpath_fscope, true));
if (final.ptr->is_value()) {
value_t& result(final.ptr->as_value());
@ -2131,14 +2125,14 @@ void xpath_t::path_t::walk_elements<node_t>
(node_t& start,
const ptr_op_t& element,
const bool recurse,
scope_t * scope,
scope_t& scope,
const visitor_t& func);
template
void xpath_t::path_t::check_element<const node_t>
(const node_t& start,
const ptr_op_t& element,
scope_t * scope,
scope_t& scope,
std::size_t index,
std::size_t size,
const visitor_t& func);

View file

@ -53,7 +53,7 @@ public:
public:
class scope_t;
typedef function<value_t (scope_t *)> function_t;
typedef function<value_t (scope_t&)> function_t;
#define MAKE_FUNCTOR(x) \
xml::xpath_t::wrap_functor(bind(&x, this, _1))
@ -68,31 +68,34 @@ public:
symbol_map symbols;
public:
scope_t * parent;
optional<scope_t&> parent;
value_t::sequence_t args;
enum kind_t { NORMAL, STATIC, ARGUMENT } kind;
scope_t(scope_t * _parent = NULL, kind_t _kind = NORMAL)
explicit scope_t(const optional<scope_t&>& _parent = none,
kind_t _kind = NORMAL)
: parent(_parent), kind(_kind) {
TRACE_CTOR(xpath_t::scope_t, "scope *, kind_t");
TRACE_CTOR(xpath_t::scope_t, "kind_t, const optional<scope_t&>&");
}
explicit scope_t(scope_t& _parent, kind_t _kind = NORMAL)
: parent(_parent), kind(_kind) {
TRACE_CTOR(xpath_t::scope_t, "scope_t&, kind_t");
}
virtual ~scope_t() {
TRACE_DTOR(xpath_t::scope_t);
}
public:
virtual void define(const string& name, ptr_op_t def);
virtual optional<value_t> resolve(const string& name,
scope_t * locals = NULL) {
virtual void define(const string& name, ptr_op_t def);
void define(const string& name, const function_t& def);
virtual ptr_op_t lookup(const string& name);
virtual optional<value_t> resolve(const string& name, scope_t& locals) {
if (parent)
return parent->resolve(name, locals);
return none;
}
virtual ptr_op_t lookup(const string& name);
void define(const string& name, const function_t& def);
friend struct op_t;
};
@ -105,18 +108,20 @@ public:
public:
function_scope_t(const value_t::sequence_t& _sequence,
const node_t& _node, std::size_t _index,
scope_t * _parent = NULL)
const node_t& _node,
std::size_t _index,
const optional<scope_t&>& _parent = none)
: scope_t(_parent, STATIC), node(_node), index(_index),
size(_sequence.size()) {}
function_scope_t(const node_t& _node, std::size_t _index,
std::size_t _size, scope_t * _parent = NULL)
function_scope_t(const node_t& _node,
std::size_t _index,
std::size_t _size,
const optional<scope_t&>& _parent = none)
: scope_t(_parent, STATIC), node(_node), index(_index),
size(_size) {}
virtual optional<value_t> resolve(const string& name,
scope_t * locals = NULL);
virtual optional<value_t> resolve(const string& name, scope_t& locals);
};
#define XPATH_PARSE_NORMAL 0x00
@ -218,7 +223,7 @@ public:
{
public:
typedef function<void (const value_t&)> visitor_t;
typedef function<bool (const node_t&, scope_t *)> predicate_t;
typedef function<bool (const node_t&, scope_t&)> predicate_t;
private:
struct value_appender_t {
@ -236,13 +241,13 @@ public:
void walk_elements(NodeType& start,
const ptr_op_t& element,
const bool recurse,
scope_t * scope,
scope_t& scope,
const visitor_t& func);
template <typename NodeType>
void check_element(NodeType& start,
const ptr_op_t& element,
scope_t * scope,
scope_t& scope,
std::size_t index,
std::size_t size,
const visitor_t& func);
@ -251,22 +256,22 @@ public:
path_t(const xpath_t& xpath) : path_expr(xpath.ptr) {}
path_t(const ptr_op_t& _path_expr) : path_expr(_path_expr) {}
value_t find_all(node_t& start, scope_t * scope) {
value_t find_all(node_t& start, scope_t& scope) {
value_t result = value_t::sequence_t();
visit(start, scope, value_appender_t(result.as_sequence_lval()));
return result;
}
value_t find_all(const node_t& start, scope_t * scope) {
value_t find_all(const node_t& start, scope_t& scope) {
value_t result = value_t::sequence_t();
visit(start, scope, value_appender_t(result.as_sequence_lval()));
return result;
}
void visit(node_t& start, scope_t * scope, const visitor_t& func) {
void visit(node_t& start, scope_t& scope, const visitor_t& func) {
if (path_expr)
walk_elements<node_t>(start, path_expr, false, scope, func);
}
void visit(const node_t& start, scope_t * scope, const visitor_t& func) {
void visit(const node_t& start, scope_t& scope, const visitor_t& func) {
if (path_expr)
walk_elements<const node_t>(start, path_expr, false, scope, func);
}
@ -280,7 +285,7 @@ public:
path_t path;
reference start;
scope_t * scope;
scope_t& scope;
mutable value_t::sequence_t sequence;
mutable bool searched;
@ -299,7 +304,7 @@ public:
typedef value_t::sequence_t::const_iterator const_iterator;
path_iterator_t(const xpath_t& path_expr,
reference _start, scope_t * _scope)
reference _start, scope_t& _scope)
: path(path_expr), start(_start), scope(_scope),
searched(false) {
}
@ -537,7 +542,7 @@ public:
ptr_op_t right = NULL);
ptr_op_t copy(ptr_op_t left = NULL, ptr_op_t right = NULL) const;
ptr_op_t compile(const node_t& context, scope_t * scope, bool resolve = false);
ptr_op_t compile(const node_t& context, scope_t& scope, bool resolve = false);
void append_value(value_t::sequence_t& result_seq, value_t& value);
@ -560,13 +565,13 @@ public:
}
};
class op_predicate
class op_predicate : public noncopyable
{
ptr_op_t op;
public:
op_predicate(ptr_op_t _op) : op(_op) {}
explicit op_predicate(ptr_op_t _op) : op(_op) {}
bool operator()(const node_t& node, scope_t * scope) {
bool operator()(const node_t& node, scope_t& scope) {
xpath_t result(op->compile(node, scope, true));
return result.ptr->as_value().to_boolean();
}
@ -732,31 +737,31 @@ public:
ptr = parse_expr(in, _flags);
}
void compile(const node_t& context, scope_t * scope = NULL) {
void compile(const node_t& context, scope_t& scope) {
if (ptr.get())
ptr = ptr->compile(context, scope);
}
virtual value_t calc(const node_t& context, scope_t * scope = NULL) const;
virtual value_t calc(const node_t& context, scope_t& scope) const;
static value_t eval(const string& _expr, const node_t& context,
scope_t * scope = NULL) {
scope_t& scope) {
return xpath_t(_expr).calc(context, scope);
}
path_iterator_t<node_t>
find_all(node_t& start, scope_t * scope) {
find_all(node_t& start, scope_t& scope) {
return path_iterator_t<node_t>(*this, start, scope);
}
path_iterator_t<const node_t>
find_all(const node_t& start, scope_t * scope) {
find_all(const node_t& start, scope_t& scope) {
return path_iterator_t<const node_t>(*this, start, scope);
}
void visit(node_t& start, scope_t * scope, const path_t::visitor_t& func) {
void visit(node_t& start, scope_t& scope, const path_t::visitor_t& func) {
path_t(*this).visit(start, scope, func);
}
void visit(const node_t& start, scope_t * scope, const
void visit(const node_t& start, scope_t& scope, const
path_t::visitor_t& func) {
path_t(*this).visit(start, scope, func);
}
@ -776,17 +781,17 @@ public:
} // namespace xml
template <typename T>
inline T * get_ptr(xml::xpath_t::scope_t * locals, unsigned int idx) {
assert(locals->args.size() > idx);
T * ptr = locals->args[idx].as_pointer<T>();
inline T * get_ptr(xml::xpath_t::scope_t& locals, unsigned int idx) {
assert(locals.args.size() > idx);
T * ptr = locals.args[idx].as_pointer<T>();
assert(ptr);
return ptr;
}
template <typename T>
inline T * get_node_ptr(xml::xpath_t::scope_t * locals, unsigned int idx) {
assert(locals->args.size() > idx);
T * ptr = polymorphic_downcast<T *>(locals->args[idx].as_xml_node_mutable());
inline T * get_node_ptr(xml::xpath_t::scope_t& locals, unsigned int idx) {
assert(locals.args.size() > idx);
T * ptr = polymorphic_downcast<T *>(locals.args[idx].as_xml_node_mutable());
assert(ptr);
return ptr;
}
@ -794,7 +799,7 @@ inline T * get_node_ptr(xml::xpath_t::scope_t * locals, unsigned int idx) {
class xml_command
{
public:
value_t operator()(xml::xpath_t::scope_t * locals) {
value_t operator()(xml::xpath_t::scope_t& locals) {
std::ostream * out = get_ptr<std::ostream>(locals, 0);
xml::document_t * doc = get_node_ptr<xml::document_t>(locals, 1);
doc->print(*out);

View file

@ -209,23 +209,15 @@ void AmountTestCase::testCommodityConstructors()
void AmountTestCase::testAssignment()
{
amount_t x0;
amount_t x1 = 123456L;
amount_t x2 = 123456UL;
amount_t x3 = 123.456;
amount_t x5 = "123456";
amount_t x6 = "123.456";
amount_t x7 = string("123456");
amount_t x8 = string("123.456");
amount_t x9 = x3;
amount_t x10 = amount_t(x6);
assertEqual(x2, x1);
assertEqual(x5, x1);
assertEqual(x7, x1);
assertEqual(x6, x3);
assertEqual(x8, x3);
assertEqual(x10, x3);
assertEqual(x10, x9);
amount_t x1;
amount_t x2;
amount_t x3;
amount_t x5;
amount_t x6;
amount_t x7;
amount_t x8;
amount_t x9;
amount_t x10;
x1 = 123456L;
x2 = 123456UL;
@ -264,16 +256,27 @@ void AmountTestCase::testAssignment()
void AmountTestCase::testCommodityAssignment()
{
amount_t x1 = "$123.45";
amount_t x2 = "-$123.45";
amount_t x3 = "$-123.45";
amount_t x4 = "DM 123.45";
amount_t x5 = "-DM 123.45";
amount_t x6 = "DM -123.45";
amount_t x7 = "123.45 euro";
amount_t x8 = "-123.45 euro";
amount_t x9 = "123.45€";
amount_t x10 = "-123.45€";
amount_t x1;
amount_t x2;
amount_t x3;
amount_t x4;
amount_t x5;
amount_t x6;
amount_t x7;
amount_t x8;
amount_t x9;
amount_t x10;
x1 = "$123.45";
x2 = "-$123.45";
x3 = "$-123.45";
x4 = "DM 123.45";
x5 = "-DM 123.45";
x6 = "DM -123.45";
x7 = "123.45 euro";
x8 = "-123.45 euro";
x9 = "123.45€";
x10 = "-123.45€";
assertEqual(amount_t("$123.45"), x1);
assertEqual(amount_t("-$123.45"), x2);
@ -343,16 +346,27 @@ void AmountTestCase::testEquality()
void AmountTestCase::testCommodityEquality()
{
amount_t x0;
amount_t x1 = "$123.45";
amount_t x2 = "-$123.45";
amount_t x3 = "$-123.45";
amount_t x4 = "DM 123.45";
amount_t x5 = "-DM 123.45";
amount_t x6 = "DM -123.45";
amount_t x7 = "123.45 euro";
amount_t x8 = "-123.45 euro";
amount_t x9 = "123.45€";
amount_t x10 = "-123.45€";
amount_t x1;
amount_t x2;
amount_t x3;
amount_t x4;
amount_t x5;
amount_t x6;
amount_t x7;
amount_t x8;
amount_t x9;
amount_t x10;
x1 = "$123.45";
x2 = "-$123.45";
x3 = "$-123.45";
x4 = "DM 123.45";
x5 = "-DM 123.45";
x6 = "DM -123.45";
x7 = "123.45 euro";
x8 = "-123.45 euro";
x9 = "123.45€";
x10 = "-123.45€";
assertTrue(x0.is_null());
assertThrow(x0.is_zero(), amount_error);