Node compilation is beginning to work.

This commit is contained in:
John Wiegley 2007-05-19 03:11:00 +00:00
parent cdea8aa18c
commit 5a72d17d02
7 changed files with 117 additions and 18 deletions

View file

@ -34,5 +34,29 @@
namespace ledger {
namespace xml {
void entry_node_t::compile()
{
typedef std::list<attributes_t::iterator> iterator_list;
iterator_list to_update;
for (attributes_t::iterator i = attributes->begin();
i != attributes->end();
i++)
if (i->first == DATE_ATTR && i->second.is_string())
//i->second = parse_datetime(i->second.as_string().c_str());
to_update.push_back(i);
for (iterator_list::iterator i = to_update.begin();
i != to_update.end();
i++) {
attr_pair attr_def = **i;
attributes->erase(*i);
attr_def.second = parse_datetime(attr_def.second.as_string().c_str());
attributes->push_back(attr_def);
}
}
} // namespace xml
} // namespace ledger

View file

@ -82,6 +82,26 @@ public:
};
#endif
class entry_node_t : public parent_node_t
{
public:
shared_ptr<entry_t> entry;
entry_node_t(nameid_t _name_id,
document_t& _document,
const optional<parent_node_t&>& _parent = none,
entry_t * _entry = NULL)
: parent_node_t(_name_id, _document, _parent), entry(_entry) {
TRACE_CTOR(entry_node_t, "document_t&, parent_node_t, entry_t *");
assert(_name_id == ENTRY_NODE);
}
virtual ~entry_node_t() {
TRACE_DTOR(entry_node_t);
}
virtual void compile();
};
class transaction_node_t : public parent_node_t
{
public:

View file

@ -286,12 +286,27 @@ static int read_and_report(ledger::report_t& report, int argc, char * argv[],
xpath.print(*out, doc_scope);
*out << std::endl;
foreach (const value_t& value, xpath.find_all(doc_scope)) {
if (value.is_xml_node()) {
value.as_xml_node()->print(std::cout);
} else {
std::cout << value;
IF_INFO() {
*out << "Raw results:" << std::endl;
foreach (const value_t& value, xpath.find_all(doc_scope)) {
if (value.is_xml_node())
value.as_xml_node()->print(std::cout);
else
std::cout << value;
std::cout << std::endl;
}
*out << "Compiled results:" << std::endl;
}
xml_document.compile();
foreach (const value_t& value, xpath.find_all(doc_scope)) {
if (value.is_xml_node())
value.as_xml_node()->print(std::cout);
else
std::cout << value;
std::cout << std::endl;
}
return 0;

View file

@ -40,7 +40,7 @@ const char * node_t::name() const
return *document().lookup_name(name_id());
}
optional<const string&> node_t::get_attr(const string& _name) const
optional<value_t> node_t::get_attr(const string& _name) const
{
optional<nameid_t> name_id = document().lookup_name_id(_name);
if (name_id)
@ -71,12 +71,11 @@ void output_xml_string(std::ostream& out, const string& str)
void node_t::print_attributes(std::ostream& out) const
{
if (attributes) {
typedef attributes_t::nth_index<0>::type attributes_by_order;
if (attributes)
foreach (const attr_pair& attr, attributes->get<0>())
out << ' ' << *document().lookup_name(attr.first)
<< "=\"" << attr.second << "\"";
}
IF_VERIFY()
out << " type=\"parent_node_t\"";
}

View file

@ -50,13 +50,15 @@ class node_t : public supports_flags<>, public noncopyable
public:
typedef uint_fast16_t nameid_t;
// This has to be public so that multi_index_container can reference
// it in parent_node_t.
nameid_t name_id_;
protected:
document_t& document_;
optional<parent_node_t&> parent_;
typedef std::pair<nameid_t, string> attr_pair;
typedef std::pair<nameid_t, value_t> attr_pair;
typedef multi_index_container<
attr_pair,
@ -69,6 +71,11 @@ protected:
optional<attributes_t> attributes;
typedef attributes_t::nth_index<0>::type attributes_by_order;
typedef attributes_t::nth_index<1>::type attributes_hashed;
bool compiled;
public:
node_t(nameid_t _name_id, document_t& _document,
const optional<parent_node_t&>& _parent = none, flags_t _flags = 0)
@ -81,6 +88,11 @@ public:
TRACE_DTOR(node_t);
}
bool is_compiled() const {
return compiled;
}
virtual void compile() {}
bool is_parent_node() const {
return has_flags(XML_NODE_IS_PARENT);
}
@ -112,12 +124,18 @@ public:
}
void set_attr(const nameid_t _name_id, const char * value) {
if (! attributes)
attributes = attributes_t();
attributes->push_back(attr_pair(_name_id, string_value(value)));
}
void set_attr(const nameid_t _name_id, const value_t& value) {
if (! attributes)
attributes = attributes_t();
attributes->push_back(attr_pair(_name_id, value));
}
optional<const string&> get_attr(const string& _name) const;
optional<const string&> get_attr(const nameid_t _name_id) const {
optional<value_t> get_attr(const string& _name) const;
optional<value_t> get_attr(const nameid_t _name_id) const {
if (attributes) {
typedef attributes_t::nth_index<1>::type attributes_by_name;
@ -159,6 +177,11 @@ public:
clear_children();
}
virtual void compile() {
foreach (node_t * child, *this)
child->compile();
}
template <typename T>
T * create_child(nameid_t _name_id) {
T * child = new T(_name_id, document(), *this);

View file

@ -676,6 +676,10 @@ public:
#define NULL_VALUE (value_t())
inline value_t string_value(const string& str) {
return value_t(str, true);
}
std::ostream& operator<<(std::ostream& out, const value_t& val);
DECLARE_EXCEPTION(value_error);

View file

@ -433,23 +433,35 @@ namespace {
value_t xpath_fn_last(xpath_t::call_scope_t& scope)
{
xpath_t::context_scope_t& context(CONTEXT_SCOPE(scope));
return context.size();
}
value_t xpath_fn_position(xpath_t::call_scope_t& scope)
{
xpath_t::context_scope_t& context(CONTEXT_SCOPE(scope));
return context.index() + 1;
}
value_t xpath_fn_text(xpath_t::call_scope_t& scope)
{
xpath_t::context_scope_t& context(CONTEXT_SCOPE(scope));
return value_t(context.xml_node().to_value().to_string(), true);
}
value_t xpath_fn_type(xpath_t::call_scope_t& scope)
{
if (scope.size() == 0) {
xpath_t::context_scope_t& context(CONTEXT_SCOPE(scope));
return string_value(context.value().label());
}
else if (scope.size() == 1) {
return string_value(scope[0].label());
}
else {
assert(false);
return string_value("INVALID");
}
}
}
xpath_t::ptr_op_t
@ -469,6 +481,8 @@ xpath_t::symbol_scope_t::lookup(const string& name)
case 't':
if (name == "text")
return WRAP_FUNCTOR(bind(xpath_fn_text, _1));
else if (name == "type")
return WRAP_FUNCTOR(bind(xpath_fn_type, _1));
break;
}
@ -1194,10 +1208,10 @@ value_t xpath_t::op_t::calc(scope_t& scope)
case ATTR_ID:
case ATTR_NAME:
if (optional<const string&> value =
kind == ATTR_ID ? current_xml_node(scope).get_attr(as_long()) :
if (optional<value_t> value =
kind == ATTR_ID ? current_xml_node(scope).get_attr(as_name()) :
current_xml_node(scope).get_attr(as_string()))
return value_t(*value, true);
return *value;
else
throw_(calc_error, "Attribute '"
<< (kind == ATTR_ID ?