summaryrefslogtreecommitdiff
path: root/src/data
diff options
context:
space:
mode:
Diffstat (limited to 'src/data')
-rw-r--r--src/data/builder.h256
-rw-r--r--src/data/compile.cc235
-rw-r--r--src/data/compile.h206
-rw-r--r--src/data/document.cc181
-rw-r--r--src/data/document.h152
-rw-r--r--src/data/jbuilder.cc67
-rw-r--r--src/data/jbuilder.h81
-rw-r--r--src/data/journal.cc702
-rw-r--r--src/data/journal.h439
-rw-r--r--src/data/node.cc130
-rw-r--r--src/data/node.h352
-rw-r--r--src/data/parser.h138
-rw-r--r--src/data/textual.cc480
-rw-r--r--src/data/textual.h51
14 files changed, 0 insertions, 3470 deletions
diff --git a/src/data/builder.h b/src/data/builder.h
deleted file mode 100644
index a193879e..00000000
--- a/src/data/builder.h
+++ /dev/null
@@ -1,256 +0,0 @@
-/*
- * Copyright (c) 2003-2007, John Wiegley. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * - Neither the name of New Artisans LLC nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _BUILDER_H
-#define _BUILDER_H
-
-#include "document.h"
-
-namespace ledger {
-namespace xml {
-
-/**
- * @class builder_t
- *
- * @brief Represents an interface for building a data hierarchy.
- *
- * This interface is much like .NET's XmlWriter facility. It
- * abstracts the kind of hierarchy we're building, instead focusing
- * only on the relationships.
- */
-class builder_t
-{
-public:
- struct position_t
- {
- typedef uint_least32_t file_pos_t;
- typedef uint_least32_t file_line_t;
-
- file_pos_t offset;
- file_line_t linenum;
-
- position_t() : offset(0), linenum(0) {}
-
- explicit position_t(file_pos_t _offset,
- file_line_t _linenum)
- : offset(_offset), linenum(_linenum) {}
- };
-
-protected:
- position_t current_position;
-
-public:
- virtual ~builder_t() {}
-
- virtual void set_start_position(std::istream& in) {}
- virtual void set_position(const position_t& position) {}
- virtual position_t& position() { return current_position; }
-
- virtual void push_attr(const string& name,
- const string& value) = 0;
- virtual void push_attr(const node_t::nameid_t name_id,
- const string& value) = 0;
-
- virtual void begin_node(const string& name, bool terminal = false) = 0;
- virtual void begin_node(const node_t::nameid_t name_id, bool terminal = false) = 0;
-
- virtual void push_node(const string& name,
- const optional<position_t>& end_pos = none) = 0;
- virtual void push_node(const node_t::nameid_t name_id,
- const optional<position_t>& end_pos = none) = 0;
-
- virtual node_t * current_node() = 0;
-
- virtual void append_text(const string& text) = 0;
-
- virtual node_t * end_node(const string& name,
- const optional<position_t>& end_pos = none) = 0;
- virtual node_t * end_node(const node_t::nameid_t name_id,
- const optional<position_t>& end_pos = none) = 0;
-};
-
-/**
- * @class xml_builder_t
- *
- * @brief Build a generic node_t hierarchy.
- *
- * This builder can be used to parse ordinary XML into a document
- * object structure which can then be traversed in memory.
- */
-class document_builder_t : public builder_t
-{
-protected:
- typedef std::list<std::pair<node_t::nameid_t, string> > attrs_list;
-
- document_t& document_;
- attrs_list current_attrs;
- node_t * current;
- string current_text;
-
-public:
- document_builder_t(document_t& _document)
- : document_(_document), current(&document_) {}
-
- virtual void push_attr(const string& name,
- const string& value) {
- push_attr(document().register_name(name), value);
- }
- virtual void push_attr(const node_t::nameid_t name_id,
- const string& value) {
- current_attrs.push_back(attrs_list::value_type(name_id, value.c_str()));
- }
-
- virtual void begin_node(const string& name, bool terminal = false) {
- begin_node(document().register_name(name), terminal);
- }
- virtual void begin_node(const node_t::nameid_t name_id,
- bool terminal = false) {
- if (terminal)
- current = current->as_parent_node().create_child<terminal_node_t>(name_id);
- else
- current = current->as_parent_node().create_child<parent_node_t>(name_id);
-
- foreach (const attrs_list::value_type& pair, current_attrs)
- current->set_attr(pair.first, pair.second.c_str());
- current_attrs.clear();
- }
-
- virtual void push_node(const string& name,
- const optional<position_t>& end_pos = none) {
- begin_node(name, true);
- end_node(name, end_pos);
- }
- virtual void push_node(const node_t::nameid_t name_id,
- const optional<position_t>& end_pos = none) {
- begin_node(name_id, true);
- end_node(name_id, end_pos);
- }
-
- virtual document_t& document() {
- return document_;
- }
- virtual node_t * current_node() {
- return current;
- }
-
- virtual void append_text(const string& text) {
- assert(! current->is_parent_node());
- polymorphic_downcast<terminal_node_t *>(current)->set_text(text);
- }
-
- virtual node_t * end_node(const string& name,
- const optional<position_t>& end_pos = none) {
- return current = &*current->parent();
- }
- virtual node_t * end_node(const node_t::nameid_t name_id,
- const optional<position_t>& end_pos = none) {
- return current = &*current->parent();
- }
-};
-
-/**
- * @class xml_writer_t
- *
- * @brief Create textual XML on the given output stream.
- *
- * This builder, rather than manipulating data structures in memory,
- * simply streams its contents on the fly to the given output stream.
- * It uses only enough memory to remember the currently push
- * attributes and text.
- */
-class xml_writer_t : public builder_t
-{
- typedef std::list<std::pair<string, string> > attrs_list;
-
- attrs_list current_attrs;
- std::ostream& outs;
-
-public:
- xml_writer_t(std::ostream& _outs) : outs(_outs) {
- outs << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
- begin_node("ledger");
- }
- ~xml_writer_t() {
- end_node("ledger");
- }
-
- virtual void push_attr(const string& name,
- const string& value) {
- current_attrs.push_back(attrs_list::value_type(name, value));
- }
- virtual void push_attr(const node_t::nameid_t name_id,
- const string& value) {
- push_attr("hello", value);
- }
-
- virtual void begin_node(const string& name, bool terminal = false) {
- outs << '<' << name;
- foreach (const attrs_list::value_type& attr, current_attrs)
- outs << ' ' << attr.first << "=\"" << attr.second << "\"";
- current_attrs.clear();
- outs << '>';
- }
- virtual void begin_node(const node_t::nameid_t name_id, bool terminal = false) {
- begin_node("hello");
- }
-
- virtual void push_node(const string& name,
- const optional<position_t>& end_pos = none) {
- begin_node(name, true);
- end_node(name, end_pos);
- }
- virtual void push_node(const node_t::nameid_t name_id,
- const optional<position_t>& end_pos = none) {
- push_node("hello", end_pos);
- }
-
- virtual node_t * current_node() { return NULL; }
-
- virtual void append_text(const string& text) {
- outs << text;
- }
-
- virtual node_t * end_node(const string& name,
- const optional<position_t>& end_pos = none) {
- outs << "</" << name << '>';
- return NULL;
- }
- virtual node_t * end_node(const node_t::nameid_t name_id,
- const optional<position_t>& end_pos = none) {
- end_node("hello", end_pos);
- return NULL;
- }
-};
-
-} // namespace xml
-} // namespace ledger
-
-#endif // _BUILDER_H
diff --git a/src/data/compile.cc b/src/data/compile.cc
deleted file mode 100644
index 07ce9394..00000000
--- a/src/data/compile.cc
+++ /dev/null
@@ -1,235 +0,0 @@
-/*
- * Copyright (c) 2003-2007, John Wiegley. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * - Neither the name of New Artisans LLC nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "compile.h"
-#include "parser.h"
-
-namespace ledger {
-namespace xml {
-
-void compile_node(node_t& node, xpath_t::scope_t& scope)
-{
- switch (node.name_id()) {
- case JOURNAL_NODE:
- downcast<journal_node_t>(node).compile(scope);
- break;
- case ENTRY_NODE:
- downcast<entry_node_t>(node).compile(scope);
- break;
- case TRANSACTION_NODE:
- downcast<transaction_node_t>(node).compile(scope);
- break;
-
- default:
- break;
- }
-
- node.compiled = true;
-
- if (node.is_parent_node())
- foreach (node_t * child, node.as_parent_node())
- compile_node(*child, scope);
-}
-
-void journal_node_t::compile(xpath_t::scope_t& scope)
-{
- if (! journal.get())
- journal.reset(new journal_t);
-}
-
-void entry_node_t::compile(xpath_t::scope_t& scope)
-{
- parent_node_t& parent_node(*parent());
-
- assert(parent_node.name_id() == JOURNAL_NODE);
- assert(parent_node.is_compiled());
-
- journal_t * journal = downcast<journal_node_t>(parent_node).journal.get();
-
- if (! entry.get()) {
- entry.reset(new entry_t);
-#if 0
- journal->add_entry(entry.get());
-#endif
- }
- entry->journal = journal;
-
- foreach (attr_pair& attr, *attributes) {
- if (attr.first == DATE_ATTR && attr.second.is_string())
- entry->_date = parse_datetime(attr.second.as_string().c_str());
- else if (attr.first == EFF_DATE_ATTR && attr.second.is_string())
- entry->_date_eff = parse_datetime(attr.second.as_string().c_str());
- else if (attr.first == CODE_ATTR)
- entry->code = attr.second.as_string();
- }
-}
-
-void transaction_node_t::parse_amount_expr(xpath_t::scope_t& scope,
- const char * amount_expr)
-{
- value_t * amount;
-
- std::istringstream in(amount_expr);
-
- PUSH_CONTEXT();
-
- // jww (2006-09-15): Make sure it doesn't gobble up the upcoming @ symbol
-
- unsigned long beg = (long)in.tellg();
-
- amount_t temp;
- temp.parse(in, AMOUNT_PARSE_NO_REDUCE);
-
- char c;
- if (! in.eof() && (c = peek_next_nonws(in)) != '@' &&
- c != ';' && ! in.eof()) {
- in.seekg(beg, std::ios::beg);
-
- xpath_t xpath(in, (XPATH_PARSE_NO_REDUCE | XPATH_PARSE_RELAXED |
- XPATH_PARSE_PARTIAL));
-
- xpath_t::context_scope_t node_scope(scope, this);
- amount = &set_attr(AMOUNT_ATTR, xpath.calc(node_scope));
-
- //unsigned long end = (long)in.tellg();
- } else {
- amount = &set_attr(AMOUNT_ATTR, temp);
- }
-
- // jww (2007-04-30): This should be a string context, or perhaps a
- // file context
- POP_CONTEXT(context("While parsing transaction amount"));
-
- // Parse the optional cost (@ PER-UNIT-COST, @@ TOTAL-COST)
-
- if (in.good() && ! in.eof()) {
- char c = peek_next_nonws(in);
- if (c == '@') {
- DEBUG("ledger.textual.parse", "Found a price indicator");
- bool per_unit = true;
- in.get(c);
- if (in.peek() == '@') {
- in.get(c);
- per_unit = false;
- DEBUG("ledger.textual.parse", "And it's for a total price");
- }
-
- if (in.good() && ! in.eof()) {
- amount_t temp;
-
- PUSH_CONTEXT();
-
- //unsigned long beg = (long)in.tellg();
-
- temp.parse(in);
-
- if (temp.sign() < 0)
- throw_(parse_error, "A transaction's cost may not be negative");
-
- //unsigned long end = (long)in.tellg();
-
- POP_CONTEXT(context("While parsing transaction cost"));
-
- amount_t per_unit_cost(temp);
- amount_t& base_amount(amount->as_amount_lval());
- if (per_unit)
- temp *= base_amount.number();
- else
- per_unit_cost /= base_amount.number();
-
- value_t& cost = set_attr(COST_ATTR, temp);
-
- if (base_amount.commodity() && ! base_amount.commodity().annotated) {
- assert(transaction);
- assert(transaction->entry);
- base_amount.annotate_commodity
- (annotation_t(per_unit_cost, transaction->entry->actual_date(),
- transaction->entry->code));
- }
-
- DEBUG("ledger.textual.parse", "Total cost is " << cost);
- DEBUG("ledger.textual.parse", "Per-unit cost is " << per_unit_cost);
- DEBUG("ledger.textual.parse", "Annotated amount is " << base_amount);
- DEBUG("ledger.textual.parse", "Bare amount is " << base_amount.number());
- }
- }
- }
-
- amount->in_place_reduce();
-
- DEBUG("ledger.textual.parse", "Reduced amount is " << *amount);
-}
-
-void transaction_node_t::compile(xpath_t::scope_t& scope)
-{
- parent_node_t& parent_node(*parent());
-
- assert(parent_node.name_id() == ENTRY_NODE);
- assert(parent_node.is_compiled());
-
- entry_t * entry = downcast<entry_node_t>(parent_node).entry.get();
-
- if (! transaction.get()) {
- transaction.reset(new transaction_t);
-#if 0
- entry->add_transaction(transaction.get());
-#endif
- }
- transaction->entry = entry;
-
- foreach (node_t * child, *this) {
- switch (child->name_id()) {
- case AMOUNT_EXPR_NODE:
- parse_amount_expr(scope, child->as_terminal_node().text());
- break;
-
- case ACCOUNT_PATH_NODE: {
- assert(entry);
-
- journal_t * journal = entry->journal;
- assert(journal);
-
- transaction->account =
- journal->find_account(child->as_terminal_node().text());
-
- // jww (2007-05-18): Need to set an attribute that refers to the
- // unique id of the account
- break;
- }
-
- default:
- break;
- }
- }
-}
-
-} // namespace xml
-} // namespace ledger
diff --git a/src/data/compile.h b/src/data/compile.h
deleted file mode 100644
index d8b9f536..00000000
--- a/src/data/compile.h
+++ /dev/null
@@ -1,206 +0,0 @@
-/*
- * Copyright (c) 2003-2007, John Wiegley. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * - Neither the name of New Artisans LLC nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _COMPILE_H
-#define _COMPILE_H
-
-#include "node.h"
-#include "journal.h"
-
-namespace ledger {
-namespace xml {
-
-void compile_node(node_t& node, xml::xpath_t::scope_t& scope);
-
-#if 0
-class commodity_node_t : public parent_node_t
-{
-public:
- commodity_t * commodity;
-
- commodity_node_t(document_t * _document,
- commodity_t * _commodity,
- parent_node_t * _parent = NULL)
- : parent_node_t(_document, _parent), commodity(_commodity) {
- TRACE_CTOR(commodity_node_t, "document_t *, commodity_t *, parent_node_t *");
- set_name(document_t::COMMODITY);
- }
- virtual ~commodity_node_t() {
- TRACE_DTOR(commodity_node_t);
- }
-
- virtual node_t * children() const;
-};
-
-class amount_node_t : public parent_node_t
-{
-public:
- amount_t * amount;
-
- amount_node_t(document_t * _document,
- amount_t * _amount,
- parent_node_t * _parent = NULL)
- : parent_node_t(_document, _parent), amount(_amount) {
- TRACE_CTOR(amount_node_t, "document_t *, amount_t *, parent_node_t *");
- set_name(document_t::AMOUNT);
- }
- virtual ~amount_node_t() {
- TRACE_DTOR(amount_node_t);
- }
-
- virtual node_t * children() const;
-
- virtual value_t to_value() const {
- return *amount;
- }
-};
-#endif
-
-class journal_node_t : public parent_node_t
-{
-public:
- shared_ptr<journal_t> journal;
-
- journal_node_t(nameid_t _name_id,
- document_t& _document,
- const optional<parent_node_t&>& _parent = none,
- journal_t * _journal = NULL)
- : parent_node_t(_name_id, _document, _parent), journal(_journal) {
- TRACE_CTOR(journal_node_t, "document_t *, journal_t *, parent_node_t *");
- }
- virtual ~journal_node_t() {
- TRACE_DTOR(journal_node_t);
- }
-
- void compile(xpath_t::scope_t& scope);
-};
-
-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);
- }
-
- void compile(xpath_t::scope_t& scope);
-};
-
-class transaction_node_t : public parent_node_t
-{
-public:
- shared_ptr<transaction_t> transaction;
-
- transaction_node_t(nameid_t _name_id,
- document_t& _document,
- const optional<parent_node_t&>& _parent = none,
- transaction_t * _transaction = NULL)
- : parent_node_t(_name_id, _document, _parent),
- transaction(_transaction) {
- TRACE_CTOR(transaction_node_t,
- "document_t&, parent_node_t, transaction_t *");
- assert(_name_id == TRANSACTION_NODE);
- }
- virtual ~transaction_node_t() {
- TRACE_DTOR(transaction_node_t);
- }
-
- void compile(xpath_t::scope_t& scope);
-
-private:
- void parse_amount_expr(xpath_t::scope_t& scope,
- const char * amount_expr);
-};
-
-#if 0
-class account_node_t : public parent_node_t
-{
- account_t * account;
-
-public:
- account_node_t(document_t * _document, account_t * _account,
- parent_node_t * _parent = NULL)
- : parent_node_t(_document, _parent), account(_account) {
- TRACE_CTOR(account_node_t, "document_t *, account_t *, parent_node_t *");
- set_name(document_t::ACCOUNT);
- }
- virtual ~account_node_t() {
- TRACE_DTOR(account_node_t);
- }
-
- virtual node_t * children() const;
-};
-
-template <typename T>
-inline typename T::node_type *
-wrap_node(document_t * doc, T * item, void * parent_node = NULL) {
- assert(false);
- return NULL;
-}
-
-template <>
-inline transaction_t::node_type *
-wrap_node(document_t * doc, transaction_t * xact, void * parent_node) {
- return new transaction_node_t(doc, xact, (parent_node_t *)parent_node);
-}
-
-template <>
-inline entry_t::node_type *
-wrap_node(document_t * doc, entry_t * entry, void * parent_node) {
- return new entry_node_t(doc, entry, (parent_node_t *)parent_node);
-}
-
-template <>
-inline account_t::node_type *
-wrap_node(document_t * doc, account_t * account, void * parent_node) {
- return new account_node_t(doc, account, (parent_node_t *)parent_node);
-}
-
-template <>
-inline journal_t::node_type *
-wrap_node(document_t * doc, journal_t * journal, void * parent_node) {
- return new journal_node_t(doc, journal, (parent_node_t *)parent_node);
-}
-#endif
-
-} // namespace xml
-} // namespace ledger
-
-#endif // _COMPILE_H
diff --git a/src/data/document.cc b/src/data/document.cc
deleted file mode 100644
index 41bf77a3..00000000
--- a/src/data/document.cc
+++ /dev/null
@@ -1,181 +0,0 @@
-/*
- * Copyright (c) 2003-2007, John Wiegley. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * - Neither the name of New Artisans LLC nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "document.h"
-
-namespace ledger {
-namespace xml {
-
-namespace {
- const std::size_t ledger_builtins_size = 39;
- const char * ledger_builtins[] = {
- "account",
- "account-path",
- "amount",
- "amount",
- "amount-expr",
- "arg",
- "auto-entry",
- "balance",
- "checkin",
- "cleared",
- "code",
- "commodity",
- "commodity-conversion",
- "commodity-nomarket",
- "commodity-template",
- "cost",
- "current-year",
- "date",
- "default-account",
- "directive",
- "effective",
- "entries",
- "entry",
- "from",
- "journal",
- "ledger",
- "name",
- "note",
- "payee",
- "pending",
- "period",
- "period-entry",
- "price",
- "price-history",
- "rule",
- "symbol",
- "template",
- "time",
- "to",
- "transaction",
- "virtual",
- "year"
- };
-}
-
-node_t::nameid_t document_t::register_name(const string& name)
-{
- optional<nameid_t> index = lookup_name_id(name);
- if (index)
- return *index;
-
- if (! names)
- names = names_t();
-
- nameid_t real_index = names->size() + 1000;
- names->push_back(name_pair(name, real_index));
- DEBUG("xml.lookup", this << " Inserted name: " << name);
-
- return real_index;
-}
-
-optional<node_t::nameid_t> document_t::lookup_name_id(const string& name) const
-{
- if (optional<node_t::nameid_t> id = lookup_builtin_id(name))
- return id;
-
- if (! names)
- return none;
-
- DEBUG("xml.lookup", this << " Finding name: " << name);
-
- typedef names_t::nth_index<1>::type names_by_name;
-
- const names_by_name& name_index = names->get<1>();
- names_by_name::const_iterator i = name_index.find(name);
- if (i != name_index.end())
- return (*i).second;
-
- return none;
-}
-
-optional<node_t::nameid_t> document_t::lookup_builtin_id(const string& name)
-{
- int first = 0;
- int last = static_cast<int>(ledger_builtins_size);
-
- while (first <= last) {
- int mid = (first + last) / 2; // compute mid point.
-
- int result;
- if ((result = (static_cast<int>(name[0]) -
- static_cast<int>(ledger_builtins[mid][0]))) == 0)
- result = std::strcmp(name.c_str(), ledger_builtins[mid]);
-
- if (result > 0)
- first = mid + 1; // repeat search in top half.
- else if (result < 0)
- last = mid - 1; // repeat search in bottom half.
- else
- return nameid_t(mid + 10);
- }
-
- return none;
-}
-
-optional<const char *> document_t::lookup_name(nameid_t id) const
-{
- if (id < 1000) {
- switch (id) {
- case CURRENT:
- return ".";
- case PARENT:
- return "..";
- case ROOT:
- return "";
- case ALL:
- return "*";
-
- default:
- assert(id >= 10);
- return ledger_builtins[id - 10];
- }
- }
- else if (names) {
- assert(id >= 1000);
- std::size_t index = id - 1000;
- typedef names_t::nth_index<0>::type names_by_random_access;
- const names_by_random_access& random_access = names->get<0>();
- if (index < random_access.size())
- return random_access[index].first.c_str();
- }
- return none;
-}
-
-void document_t::print(std::ostream& out) const
-{
- out << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
- parent_node_t::print(out);
-}
-
-} // namespace xml
-} // namespace ledger
diff --git a/src/data/document.h b/src/data/document.h
deleted file mode 100644
index 2eac4043..00000000
--- a/src/data/document.h
+++ /dev/null
@@ -1,152 +0,0 @@
-/*
- * Copyright (c) 2003-2007, John Wiegley. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * - Neither the name of New Artisans LLC nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _DOCUMENT_H
-#define _DOCUMENT_H
-
-#include "node.h"
-#include "value.h"
-
-namespace ledger {
-namespace xml {
-
-enum ledger_builtins_t {
- ACCOUNT_ATTR = 10,
- ACCOUNT_PATH_NODE,
- AMOUNT_ATTR,
- AMOUNT_NODE,
- AMOUNT_EXPR_NODE,
- ARG_ATTR,
- AUTO_ENTRY_NODE,
- BALANCE_ATTR,
- CHECKIN_NODE,
- CLEARED_ATTR,
- CODE_ATTR,
- COMMODITY_NODE,
- COMMODITY_CONVERSION_NODE,
- COMMODITY_NOMARKET_NODE,
- COMMODITY_TEMPLATE_NODE,
- COST_ATTR,
- CURRENT_YEAR_NODE,
- DATE_ATTR,
- DEFAULT_ACCOUNT_NODE,
- DIRECTIVE_NODE,
- EFF_DATE_ATTR,
- ENTRIES_NODE,
- ENTRY_NODE,
- FROM_ATTR,
- JOURNAL_NODE,
- LEDGER_NODE,
- NAME_ATTR,
- NOTE_NODE,
- PAYEE_NODE,
- PENDING_ATTR,
- PERIOD_NODE,
- PERIOD_ENTRY_NODE,
- PRICE_ATTR,
- PRICE_HISTORY_NODE,
- RULE_NODE,
- SYMBOL_ATTR,
- TEMPLATE_ATTR,
- TIME_ATTR,
- TO_ATTR,
- TRANSACTION_NODE,
- VIRTUAL_ATTR,
- YEAR_ATTR
-};
-
-class document_t : public parent_node_t
-{
- typedef std::pair<string, nameid_t> name_pair;
-
- typedef multi_index_container<
- name_pair,
- multi_index::indexed_by<
- multi_index::random_access<>,
- multi_index::hashed_unique<
- multi_index::member<name_pair, string, &name_pair::first> >
- >
- > names_t;
-
- optional<names_t> names;
-
-public:
- // Ids 0-9 are reserved. 10-999 are for "builtin" names. 1000+ are
- // for dynamically registered names.
- enum special_names_t {
- CURRENT, PARENT, ROOT, ALL, LAST_BUILTIN = 10
- };
-
- document_t(node_t::nameid_t _name_id)
- : parent_node_t(_name_id, *this) {
- TRACE_CTOR(xml::document_t, "node_t::nameid_t");
- }
- ~document_t() {
- TRACE_DTOR(xml::document_t);
- }
-
- nameid_t register_name(const string& name);
-
- optional<nameid_t> lookup_name_id(const string& name) const;
- static optional<nameid_t> lookup_builtin_id(const string& name);
- optional<const char *> lookup_name(nameid_t id) const;
-
- void print(std::ostream& out) const;
-
-#if 0
-#if defined(HAVE_EXPAT) || defined(HAVE_XMLPARSE)
- class parser_t
- {
- public:
- document_t * document;
- XML_Parser parser;
- string have_error;
- const char * pending;
- node_t::attrs_map * pending_attrs;
- bool handled_data;
-
- std::list<parent_node_t *> node_stack;
-
- parser_t() : document(NULL), pending(NULL), pending_attrs(NULL),
- handled_data(false) {}
- virtual ~parser_t() {}
-
- virtual bool test(std::istream& in) const;
- virtual document_t * parse(std::istream& in);
- };
-#endif
-#endif
-};
-
-} // namespace xml
-} // namespace ledger
-
-#endif // _DOCUMENT_H
diff --git a/src/data/jbuilder.cc b/src/data/jbuilder.cc
deleted file mode 100644
index f37abca5..00000000
--- a/src/data/jbuilder.cc
+++ /dev/null
@@ -1,67 +0,0 @@
-/*
- * Copyright (c) 2003-2007, John Wiegley. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * - Neither the name of New Artisans LLC nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "jbuilder.h"
-#include "compile.h"
-
-namespace ledger {
-namespace xml {
-
-void journal_builder_t::begin_node(const node_t::nameid_t name_id,
- bool terminal)
-{
- switch (name_id) {
- case JOURNAL_NODE:
- current = current->as_parent_node().create_child<journal_node_t>(name_id);
- break;
- case ENTRY_NODE:
- current = current->as_parent_node().create_child<entry_node_t>(name_id);
- break;
- case TRANSACTION_NODE:
- current = current->as_parent_node().create_child<transaction_node_t>(name_id);
- break;
-
- default:
- if (terminal)
- current = current->as_parent_node().create_child<terminal_node_t>(name_id);
- else
- current = current->as_parent_node().create_child<parent_node_t>(name_id);
- break;
- }
-
- foreach (const attrs_list::value_type& pair, current_attrs)
- current->set_attr(pair.first, pair.second.c_str());
-
- current_attrs.clear();
-}
-
-} // namespace xml
-} // namespace ledger
diff --git a/src/data/jbuilder.h b/src/data/jbuilder.h
deleted file mode 100644
index 4e109a35..00000000
--- a/src/data/jbuilder.h
+++ /dev/null
@@ -1,81 +0,0 @@
-/*
- * Copyright (c) 2003-2007, John Wiegley. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * - Neither the name of New Artisans LLC nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _JBUILDER_H
-#define _JBUILDER_H
-
-#include "builder.h"
-#include "journal.h"
-
-namespace ledger {
-namespace xml {
-
-/**
- * @class journal_builder_t
- *
- * @brief This custom builder creates an XML-mirrored Ledger journal.
- *
- * Rather than simply creating a node_t hierarchy, as xml_builder_t
- * does, this code creates the associated journal elements referred to
- * by those nodes, and then refers to those elements via minimalist
- * "shadow nodes".
- *
- * Thus, after building a <transaction> element, the element itself
- * will have no children, but instead will point to a transaction_t
- * object. If later an XPath expression desires to traverse the
- * <transaction> element, all of the appropriate child nodes will be
- * constructed on the fly, as if they'd been created in the first
- * place by a regular xml_builder_t.
- */
-class journal_builder_t : public document_builder_t
-{
-public:
- journal_t * journal;
-
- journal_builder_t(document_t& _document, journal_t * _journal)
- : document_builder_t(_document), journal(_journal) {}
-
- virtual void set_start_position(std::istream& in) {
- set_position(position_t(in.tellg(), 1));
- }
-
- virtual void set_position(const position_t& position) {
- current_position = position;
- }
-
- virtual void begin_node(const node_t::nameid_t name_id,
- bool terminal = false);
-};
-
-} // namespace xml
-} // namespace ledger
-
-#endif // _JBUILDER_H
diff --git a/src/data/journal.cc b/src/data/journal.cc
deleted file mode 100644
index bb33f4dc..00000000
--- a/src/data/journal.cc
+++ /dev/null
@@ -1,702 +0,0 @@
-/*
- * Copyright (c) 2003-2007, John Wiegley. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * - Neither the name of New Artisans LLC nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "journal.h"
-#include "xpath.h"
-#include "mask.h"
-
-namespace ledger {
-
-const string version = PACKAGE_VERSION;
-
-bool transaction_t::use_effective_date = false;
-
-transaction_t::~transaction_t()
-{
- TRACE_DTOR(transaction_t);
-}
-
-moment_t transaction_t::actual_date() const
-{
- if (! _date && entry)
- return entry->actual_date();
- return *_date;
-}
-
-moment_t transaction_t::effective_date() const
-{
- if (! _date_eff && entry)
- return entry->effective_date();
- return *_date_eff;
-}
-
-bool transaction_t::valid() const
-{
- if (! entry) {
- DEBUG("ledger.validate", "transaction_t: ! entry");
- return false;
- }
-
- if (state != UNCLEARED && state != CLEARED && state != PENDING) {
- DEBUG("ledger.validate", "transaction_t: state is bad");
- return false;
- }
-
- transactions_list::const_iterator i =
- std::find(entry->transactions.begin(),
- entry->transactions.end(), this);
- if (i == entry->transactions.end()) {
- DEBUG("ledger.validate", "transaction_t: ! found");
- return false;
- }
-
- if (! account) {
- DEBUG("ledger.validate", "transaction_t: ! account");
- return false;
- }
-
- if (! amount.valid()) {
- DEBUG("ledger.validate", "transaction_t: ! amount.valid()");
- return false;
- }
-
- if (cost && ! cost->valid()) {
- DEBUG("ledger.validate", "transaction_t: cost && ! cost->valid()");
- return false;
- }
-
- return true;
-}
-
-void entry_base_t::add_transaction(transaction_t * xact)
-{
- transactions.push_back(xact);
-}
-
-bool entry_base_t::remove_transaction(transaction_t * xact)
-{
- transactions.remove(xact);
- return true;
-}
-
-bool entry_base_t::finalize()
-{
- // Scan through and compute the total balance for the entry. This
- // is used for auto-calculating the value of entries with no cost,
- // and the per-unit price of unpriced commodities.
-
- value_t balance;
- bool no_amounts = true;
- bool saw_null = false;
-
- for (transactions_list::const_iterator x = transactions.begin();
- x != transactions.end();
- x++)
- if (! (*x)->has_flags(TRANSACTION_VIRTUAL) ||
- (*x)->has_flags(TRANSACTION_BALANCE)) {
- amount_t& p((*x)->cost ? *(*x)->cost : (*x)->amount);
- if (p) {
- if (no_amounts) {
- balance = p;
- no_amounts = false;
- } else {
- balance += p;
- }
-
- assert((*x)->amount);
- if ((*x)->cost && (*x)->amount.commodity().annotated) {
- annotated_commodity_t&
- ann_comm(static_cast<annotated_commodity_t&>
- ((*x)->amount.commodity()));
- if (ann_comm.details.price)
- balance += (*ann_comm.details.price * (*x)->amount.number() -
- *((*x)->cost));
- }
- } else {
- saw_null = true;
- }
- }
-
- // If it's a null entry, then let the user have their fun
- if (no_amounts)
- return true;
-
- // If there is only one transaction, balance against the basket
- // account if one has been set.
-
- if (journal && journal->basket && transactions.size() == 1) {
- assert(balance.is_amount());
- transaction_t * nxact = new transaction_t(journal->basket);
- // The amount doesn't need to be set because the code below will
- // balance this transaction against the other.
- add_transaction(nxact);
- nxact->add_flags(TRANSACTION_CALCULATED);
- }
-
- // If the first transaction of a two-transaction entry is of a
- // different commodity than the other, and it has no per-unit price,
- // determine its price by dividing the unit count into the value of
- // the balance. This is done for the last eligible commodity.
-
- if (! saw_null && balance && balance.is_balance() &&
- balance.as_balance().amounts.size() == 2) {
- transactions_list::const_iterator x = transactions.begin();
- assert((*x)->amount);
- commodity_t& this_comm = (*x)->amount.commodity();
-
- balance_t::amounts_map::const_iterator this_bal =
- balance.as_balance().amounts.find(&this_comm);
- balance_t::amounts_map::const_iterator other_bal =
- balance.as_balance().amounts.begin();
- if (this_bal == other_bal)
- other_bal++;
-
- amount_t per_unit_cost =
- amount_t((*other_bal).second / (*this_bal).second.number()).unround();
-
- for (; x != transactions.end(); x++) {
- if ((*x)->cost || (*x)->has_flags(TRANSACTION_VIRTUAL) ||
- (*x)->amount.commodity() != this_comm)
- continue;
-
- balance -= (*x)->amount;
-
- entry_t * entry = dynamic_cast<entry_t *>(this);
-
- if ((*x)->amount.commodity() &&
- ! (*x)->amount.commodity().annotated)
- (*x)->amount.annotate_commodity
- (annotation_t(per_unit_cost.abs(),
- entry ? entry->actual_date() : optional<moment_t>(),
- entry ? entry->code : optional<string>()));
-
- (*x)->cost = - (per_unit_cost * (*x)->amount.number());
- balance += *(*x)->cost;
- }
- }
-
- // Walk through each of the transactions, fixing up any that we
- // can, and performing any on-the-fly calculations.
-
- bool empty_allowed = true;
-
- for (transactions_list::const_iterator x = transactions.begin();
- x != transactions.end();
- x++) {
- if ((*x)->amount ||
- ((*x)->has_flags(TRANSACTION_VIRTUAL) &&
- ! (*x)->has_flags(TRANSACTION_BALANCE)))
- continue;
-
- if (! empty_allowed)
- throw_(std::logic_error,
- "Only one transaction with null amount allowed per entry");
- empty_allowed = false;
-
- // If one transaction gives no value at all, its value will become
- // the inverse of the value of the others. If multiple
- // commodities are involved, multiple transactions will be
- // generated to balance them all.
-
- const balance_t * bal = NULL;
- switch (balance.type()) {
- case value_t::BALANCE_PAIR:
- bal = &balance.as_balance_pair().quantity();
- // fall through...
-
- case value_t::BALANCE:
- if (! bal)
- bal = &balance.as_balance();
-
- if (bal->amounts.size() < 2) {
- balance.cast(value_t::AMOUNT);
- } else {
- bool first = true;
- for (balance_t::amounts_map::const_iterator
- i = bal->amounts.begin();
- i != bal->amounts.end();
- i++) {
- amount_t amt = (*i).second.negate();
-
- if (first) {
- (*x)->amount = amt;
- first = false;
- } else {
- transaction_t * nxact = new transaction_t((*x)->account);
- add_transaction(nxact);
- nxact->add_flags(TRANSACTION_CALCULATED);
- nxact->amount = amt;
- }
-
- balance += amt;
- }
- break;
- }
- // fall through...
-
- case value_t::AMOUNT:
- (*x)->amount = balance.as_amount().negate();
- (*x)->add_flags(TRANSACTION_CALCULATED);
-
- balance += (*x)->amount;
- break;
-
- default:
- break;
- }
- }
-
- if (balance) {
-#if 1
- throw_(balance_error, "Entry does not balance");
-#else
- error * err =
- new balance_error("Entry does not balance",
- new entry_context(*this, "While balancing entry:"));
- err->context.push_front
- (new value_context(balance, "Unbalanced remainder is:"));
- throw err;
-#endif
- }
-
- return true;
-}
-
-entry_t::entry_t(const entry_t& e)
- : entry_base_t(e), _date(e._date), _date_eff(e._date_eff),
- code(e.code), payee(e.payee)
-{
- TRACE_CTOR(entry_t, "copy");
- for (transactions_list::const_iterator i = transactions.begin();
- i != transactions.end();
- i++)
- (*i)->entry = this;
-}
-
-bool entry_t::get_state(transaction_t::state_t * state) const
-{
- bool first = true;
- bool hetero = false;
-
- for (transactions_list::const_iterator i = transactions.begin();
- i != transactions.end();
- i++) {
- if (first) {
- *state = (*i)->state;
- first = false;
- }
- else if (*state != (*i)->state) {
- hetero = true;
- break;
- }
- }
-
- return ! hetero;
-}
-
-void entry_t::add_transaction(transaction_t * xact)
-{
- xact->entry = this;
- entry_base_t::add_transaction(xact);
-}
-
-bool entry_t::valid() const
-{
- if (! is_valid_moment(_date) || ! journal) {
- DEBUG("ledger.validate", "entry_t: ! _date || ! journal");
- return false;
- }
-
- for (transactions_list::const_iterator i = transactions.begin();
- i != transactions.end();
- i++)
- if ((*i)->entry != this || ! (*i)->valid()) {
- DEBUG("ledger.validate", "entry_t: transaction not valid");
- return false;
- }
-
- return true;
-}
-
-auto_entry_t::auto_entry_t()
-{
- TRACE_CTOR(auto_entry_t, "");
-}
-
-auto_entry_t::auto_entry_t(const string& _predicate)
- : predicate(new xml::xpath_t(_predicate))
-{
- TRACE_CTOR(auto_entry_t, "const string&");
-}
-
-auto_entry_t::~auto_entry_t() {
- TRACE_DTOR(auto_entry_t);
-}
-
-void auto_entry_t::extend_entry(entry_base_t& entry, bool post)
-{
-#if 0
- transactions_list initial_xacts(entry.transactions.begin(),
- entry.transactions.end());
-
- for (transactions_list::iterator i = initial_xacts.begin();
- i != initial_xacts.end();
- i++) {
- // jww (2006-09-10): Create a scope here based on entry
- if (predicate->calc((xml::node_t *) NULL)) {
- for (transactions_list::iterator t = transactions.begin();
- t != transactions.end();
- t++) {
- amount_t amt;
- assert((*t)->amount);
- if (! (*t)->amount.commodity()) {
- if (! post)
- continue;
- assert((*i)->amount);
- amt = *(*i)->amount * *(*t)->amount;
- } else {
- if (post)
- continue;
- amt = *(*t)->amount;
- }
-
- account_t * account = (*t)->account;
- string fullname = account->fullname();
- assert(! fullname.empty());
- if (fullname == "$account" || fullname == "@account")
- account = (*i)->account;
-
- transaction_t * xact
- = new transaction_t(account, amt, (*t)->flags() | TRANSACTION_AUTO);
- entry.add_transaction(xact);
- }
- }
- }
-#endif
-}
-
-account_t::~account_t()
-{
- TRACE_DTOR(account_t);
-
- for (accounts_map::iterator i = accounts.begin();
- i != accounts.end();
- i++)
- checked_delete((*i).second);
-}
-
-account_t * account_t::find_account(const string& name,
- const bool auto_create)
-{
- accounts_map::const_iterator i = accounts.find(name);
- if (i != accounts.end())
- return (*i).second;
-
- char buf[256];
-
- string::size_type sep = name.find(':');
- assert(sep < 256|| sep == string::npos);
-
- const char * first, * rest;
- if (sep == string::npos) {
- first = name.c_str();
- rest = NULL;
- } else {
- std::strncpy(buf, name.c_str(), sep);
- buf[sep] = '\0';
-
- first = buf;
- rest = name.c_str() + sep + 1;
- }
-
- account_t * account;
-
- i = accounts.find(first);
- if (i == accounts.end()) {
- if (! auto_create)
- return NULL;
-
- account = new account_t(this, first);
- account->journal = journal;
-
- std::pair<accounts_map::iterator, bool> result
- = accounts.insert(accounts_map::value_type(first, account));
- assert(result.second);
- } else {
- account = (*i).second;
- }
-
- if (rest)
- account = account->find_account(rest, auto_create);
-
- return account;
-}
-
-static inline
-account_t * find_account_re_(account_t * account, const mask_t& regexp)
-{
- if (regexp.match(account->fullname()))
- return account;
-
- for (accounts_map::iterator i = account->accounts.begin();
- i != account->accounts.end();
- i++)
- if (account_t * a = find_account_re_((*i).second, regexp))
- return a;
-
- return NULL;
-}
-
-account_t * journal_t::find_account_re(const string& regexp)
-{
- return find_account_re_(master, mask_t(regexp));
-}
-
-string account_t::fullname() const
-{
- if (! _fullname.empty()) {
- return _fullname;
- } else {
- const account_t * first = this;
- string fullname = name;
-
- while (first->parent) {
- first = first->parent;
- if (! first->name.empty())
- fullname = first->name + ":" + fullname;
- }
-
- _fullname = fullname;
-
- return fullname;
- }
-}
-
-std::ostream& operator<<(std::ostream& out, const account_t& account)
-{
- out << account.fullname();
- return out;
-}
-
-bool account_t::valid() const
-{
- if (depth > 256 || ! journal) {
- DEBUG("ledger.validate", "account_t: depth > 256 || ! journal");
- return false;
- }
-
- for (accounts_map::const_iterator i = accounts.begin();
- i != accounts.end();
- i++) {
- if (this == (*i).second) {
- DEBUG("ledger.validate", "account_t: parent refers to itself!");
- return false;
- }
-
- if (! (*i).second->valid()) {
- DEBUG("ledger.validate", "account_t: child not valid");
- return false;
- }
- }
-
- return true;
-}
-
-journal_t::~journal_t()
-{
- TRACE_DTOR(journal_t);
-
- assert(master);
- checked_delete(master);
-
- // Don't bother unhooking each entry's transactions from the
- // accounts they refer to, because all accounts are about to
- // be deleted.
- for (entries_list::iterator i = entries.begin();
- i != entries.end();
- i++) {
- if (! item_pool ||
- reinterpret_cast<char *>(*i) < item_pool ||
- reinterpret_cast<char *>(*i) >= item_pool_end) {
- checked_delete(*i);
- } else {
- (*i)->~entry_t();
- }
- }
-
- for (auto_entries_list::iterator i = auto_entries.begin();
- i != auto_entries.end();
- i++)
- if (! item_pool ||
- reinterpret_cast<char *>(*i) < item_pool ||
- reinterpret_cast<char *>(*i) >= item_pool_end)
- checked_delete(*i);
- else
- (*i)->~auto_entry_t();
-
- for (period_entries_list::iterator i = period_entries.begin();
- i != period_entries.end();
- i++)
- if (! item_pool ||
- reinterpret_cast<char *>(*i) < item_pool ||
- reinterpret_cast<char *>(*i) >= item_pool_end)
- checked_delete(*i);
- else
- (*i)->~period_entry_t();
-
- if (item_pool)
- checked_array_delete(item_pool);
-}
-
-bool journal_t::add_entry(entry_t * entry)
-{
- entry->journal = this;
-
- if (! run_hooks(entry_finalize_hooks, *entry, false) ||
- ! entry->finalize() ||
- ! run_hooks(entry_finalize_hooks, *entry, true)) {
- entry->journal = NULL;
- return false;
- }
-
- entries.push_back(entry);
-
- for (transactions_list::const_iterator i = entry->transactions.begin();
- i != entry->transactions.end();
- i++)
- if ((*i)->cost) {
- assert((*i)->amount);
- (*i)->amount.commodity().add_price(entry->date(),
- *(*i)->cost / (*i)->amount.number());
- }
-
- return true;
-}
-
-bool journal_t::remove_entry(entry_t * entry)
-{
- bool found = false;
- entries_list::iterator i;
- for (i = entries.begin(); i != entries.end(); i++)
- if (*i == entry) {
- found = true;
- break;
- }
- if (! found)
- return false;
-
- entries.erase(i);
- entry->journal = NULL;
-
- return true;
-}
-
-bool journal_t::valid() const
-{
- if (! master->valid()) {
- DEBUG("ledger.validate", "journal_t: master not valid");
- return false;
- }
-
- for (entries_list::const_iterator i = entries.begin();
- i != entries.end();
- i++)
- if (! (*i)->valid()) {
- DEBUG("ledger.validate", "journal_t: entry not valid");
- return false;
- }
-
- return true;
-}
-
-void print_entry(std::ostream& out, const entry_base_t& entry_base,
- const string& prefix)
-{
- string print_format;
-
- if (dynamic_cast<const entry_t *>(&entry_base)) {
- print_format = (prefix + "%D %X%C%P\n" +
- prefix + " %-34A %12o\n%/" +
- prefix + " %-34A %12o\n");
- }
- else if (const auto_entry_t * entry =
- dynamic_cast<const auto_entry_t *>(&entry_base)) {
- out << "= " << entry->predicate->expr << '\n';
- print_format = prefix + " %-34A %12o\n";
- }
- else if (const period_entry_t * entry =
- dynamic_cast<const period_entry_t *>(&entry_base)) {
- out << "~ " << entry->period_string << '\n';
- print_format = prefix + " %-34A %12o\n";
- }
- else {
- assert(false);
- }
-
-#if 0
- format_entries formatter(out, print_format);
- walk_transactions(const_cast<transactions_list&>(entry_base.transactions),
- formatter);
- formatter.flush();
-
- clear_transaction_xdata cleaner;
- walk_transactions(const_cast<transactions_list&>(entry_base.transactions),
- cleaner);
-#endif
-}
-
-#if 0
-void entry_context::describe(std::ostream& out) const throw()
-{
- if (! desc.empty())
- out << desc << std::endl;
-
- print_entry(out, entry, " ");
-}
-
-xact_context::xact_context(const ledger::transaction_t& _xact,
- const string& desc) throw()
- : file_context("", 0, desc), xact(_xact)
-{
- const ledger::strings_list& sources(xact.entry->journal->sources);
- unsigned int x = 0;
- for (ledger::strings_list::const_iterator i = sources.begin();
- i != sources.end();
- i++, x++)
- if (x == xact.entry->src_idx) {
- file = *i;
- break;
- }
- line = xact.beg_line;
-}
-#endif
-
-} // namespace ledger
diff --git a/src/data/journal.h b/src/data/journal.h
deleted file mode 100644
index 821f6910..00000000
--- a/src/data/journal.h
+++ /dev/null
@@ -1,439 +0,0 @@
-/*
- * Copyright (c) 2003-2007, John Wiegley. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * - Neither the name of New Artisans LLC nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _JOURNAL_H
-#define _JOURNAL_H
-
-#include "amount.h"
-#include "xpath.h"
-
-namespace ledger {
-
-// These flags persist with the object
-#define TRANSACTION_NORMAL 0x0000
-#define TRANSACTION_VIRTUAL 0x0001
-#define TRANSACTION_BALANCE 0x0002
-#define TRANSACTION_AUTO 0x0004
-#define TRANSACTION_BULK_ALLOC 0x0008
-#define TRANSACTION_CALCULATED 0x0010
-
-class entry_t;
-class account_t;
-
-class transaction_t : public supports_flags<>
-{
- public:
- enum state_t { UNCLEARED, CLEARED, PENDING };
-
- entry_t * entry;
- state_t state;
- account_t * account;
- optional<moment_t> _date;
- optional<moment_t> _date_eff;
- amount_t amount;
- optional<amount_t> cost;
- optional<string> note;
-
- static bool use_effective_date;
-
- explicit transaction_t(account_t * _account = NULL)
- : supports_flags<>(TRANSACTION_NORMAL), entry(NULL),
- state(UNCLEARED), account(_account) {
- TRACE_CTOR(transaction_t, "account_t *");
- }
- explicit transaction_t(account_t * _account,
- const amount_t& _amount,
- unsigned int _flags = TRANSACTION_NORMAL,
- const optional<string> _note = none)
- : supports_flags<>(_flags), entry(NULL), state(UNCLEARED),
- account(_account), amount(_amount), note(_note) {
- TRACE_CTOR(transaction_t,
- "account_t *, const amount_t&, unsigned int, const string&");
- }
- explicit transaction_t(const transaction_t& xact)
- : supports_flags<>(xact),
- entry(xact.entry),
- state(xact.state),
- account(xact.account),
- _date(xact._date),
- _date_eff(xact._date_eff),
- amount(xact.amount),
- cost(xact.cost),
- note(xact.note) {
- TRACE_CTOR(transaction_t, "copy");
- }
- ~transaction_t();
-
- moment_t actual_date() const;
- moment_t effective_date() const;
- moment_t date() const {
- if (use_effective_date)
- return effective_date();
- else
- return actual_date();
- }
-
- bool valid() const;
-};
-
-#if 0
-class xact_context : public file_context {
- public:
- const transaction_t& xact;
-
- xact_context(const transaction_t& _xact,
- const string& desc = "") throw();
- virtual ~xact_context() throw() {}
-};
-#endif
-
-class journal_t;
-
-typedef std::list<transaction_t *> transactions_list;
-
-class entry_base_t
-{
- public:
- journal_t * journal;
- transactions_list transactions;
-
- entry_base_t() : journal(NULL) {
- TRACE_CTOR(entry_base_t, "");
- }
- entry_base_t(const entry_base_t& e) : journal(NULL)
- {
- TRACE_CTOR(entry_base_t, "copy");
- for (transactions_list::const_iterator i = e.transactions.begin();
- i != e.transactions.end();
- i++)
- transactions.push_back(new transaction_t(**i));
- }
- virtual ~entry_base_t() {
- TRACE_DTOR(entry_base_t);
- for (transactions_list::iterator i = transactions.begin();
- i != transactions.end();
- i++)
- if (! (*i)->has_flags(TRANSACTION_BULK_ALLOC))
- checked_delete(*i);
- else
- (*i)->~transaction_t();
- }
-
- bool operator==(const entry_base_t& entry) {
- return this == &entry;
- }
- bool operator!=(const entry_base_t& entry) {
- return ! (*this == entry);
- }
-
- virtual void add_transaction(transaction_t * xact);
- virtual bool remove_transaction(transaction_t * xact);
-
- virtual bool finalize();
- virtual bool valid() const = 0;
-};
-
-class entry_t : public entry_base_t
-{
-public:
- moment_t _date;
- optional<moment_t> _date_eff;
- optional<string> code;
- string payee;
-
- entry_t() {
- TRACE_CTOR(entry_t, "");
- }
- entry_t(const entry_t& e);
-
- virtual ~entry_t() {
- TRACE_DTOR(entry_t);
- }
-
- moment_t actual_date() const {
- return _date;
- }
- moment_t effective_date() const {
- return _date_eff ? *_date_eff : _date;
- }
- moment_t date() const {
- if (transaction_t::use_effective_date)
- return effective_date();
- else
- return actual_date();
- }
-
- virtual void add_transaction(transaction_t * xact);
- virtual bool valid() const;
-
- bool get_state(transaction_t::state_t * state) const;
-};
-
-struct entry_finalizer_t {
- virtual ~entry_finalizer_t() {}
- virtual bool operator()(entry_t& entry, bool post) = 0;
-};
-
-void print_entry(std::ostream& out, const entry_base_t& entry,
- const string& prefix = "");
-
-#if 0
-class entry_context : public error_context {
- public:
- const entry_base_t& entry;
-
- entry_context(const entry_base_t& _entry,
- const string& _desc = "") throw()
- : error_context(_desc), entry(_entry) {}
- virtual ~entry_context() throw() {}
-
- virtual void describe(std::ostream& out) const throw();
-};
-#endif
-
-class auto_entry_t : public entry_base_t
-{
-public:
- scoped_ptr<xml::xpath_t> predicate;
-
- auto_entry_t();
- auto_entry_t(const string& _predicate);
- virtual ~auto_entry_t();
-
- virtual void extend_entry(entry_base_t& entry, bool post);
- virtual bool valid() const {
- return true;
- }
-};
-
-struct auto_entry_finalizer_t : public entry_finalizer_t {
- journal_t * journal;
- auto_entry_finalizer_t(journal_t * _journal) : journal(_journal) {}
- virtual bool operator()(entry_t& entry, bool post);
-};
-
-
-class period_entry_t : public entry_base_t
-{
- public:
- interval_t period;
- string period_string;
-
- period_entry_t() {
- TRACE_CTOR(period_entry_t, "");
- }
- period_entry_t(const string& _period)
- : period(_period), period_string(_period) {
- TRACE_CTOR(period_entry_t, "const string&");
- }
- period_entry_t(const period_entry_t& e)
- : entry_base_t(e), period(e.period), period_string(e.period_string) {
- TRACE_CTOR(period_entry_t, "copy");
- }
-
- virtual ~period_entry_t() {
- TRACE_DTOR(period_entry_t);
- }
-
- virtual bool valid() const {
- return period;
- }
-};
-
-
-typedef std::map<const string, account_t *> accounts_map;
-
-class account_t
-{
- public:
- typedef unsigned long ident_t;
-
- journal_t * journal;
- account_t * parent;
- string name;
- optional<string> note;
- unsigned short depth;
- accounts_map accounts;
-
- mutable ident_t ident;
- mutable string _fullname;
-
- account_t(account_t * _parent = NULL,
- const string& _name = "",
- const optional<string> _note = none)
- : parent(_parent), name(_name), note(_note),
- depth(parent ? parent->depth + 1 : 0), ident(0) {
- TRACE_CTOR(account_t, "account_t *, const string&, const string&");
- }
- ~account_t();
-
- operator string() const {
- return fullname();
- }
- string fullname() const;
-
- void add_account(account_t * acct) {
- accounts.insert(accounts_map::value_type(acct->name, acct));
- acct->journal = journal;
- }
- bool remove_account(account_t * acct) {
- accounts_map::size_type n = accounts.erase(acct->name);
- acct->journal = NULL;
- return n > 0;
- }
-
- account_t * find_account(const string& name, bool auto_create = true);
-
- bool valid() const;
-
- friend class journal_t;
-};
-
-std::ostream& operator<<(std::ostream& out, const account_t& account);
-
-
-struct func_finalizer_t : public entry_finalizer_t {
- typedef bool (*func_t)(entry_t& entry, bool post);
- func_t func;
- func_finalizer_t(func_t _func) : func(_func) {}
- func_finalizer_t(const func_finalizer_t& other) :
- entry_finalizer_t(), func(other.func) {}
- virtual bool operator()(entry_t& entry, bool post) {
- return func(entry, post);
- }
-};
-
-template <typename T>
-void add_hook(std::list<T>& list, T obj, const bool prepend = false) {
- if (prepend)
- list.push_front(obj);
- else
- list.push_back(obj);
-}
-
-template <typename T>
-void remove_hook(std::list<T>& list, T obj) {
- list.remove(obj);
-}
-
-template <typename T, typename Data>
-bool run_hooks(std::list<T>& list, Data& item, bool post) {
- for (typename std::list<T>::const_iterator i = list.begin();
- i != list.end();
- i++)
- if (! (*(*i))(item, post))
- return false;
- return true;
-}
-
-
-typedef std::list<entry_t *> entries_list;
-typedef std::list<auto_entry_t *> auto_entries_list;
-typedef std::list<period_entry_t *> period_entries_list;
-typedef std::list<path> path_list;
-typedef std::list<string> strings_list;
-
-class journal_t
-{
- public:
- account_t * master;
- account_t * basket;
- entries_list entries;
- path_list sources;
- optional<path> price_db;
- char * item_pool;
- char * item_pool_end;
-
- auto_entries_list auto_entries;
- period_entries_list period_entries;
- mutable accounts_map accounts_cache;
-
- std::list<entry_finalizer_t *> entry_finalize_hooks;
-
- journal_t() : basket(NULL), item_pool(NULL), item_pool_end(NULL) {
- TRACE_CTOR(journal_t, "");
- master = new account_t(NULL, "");
- master->journal = this;
- }
- ~journal_t();
-
- void add_account(account_t * acct) {
- master->add_account(acct);
- acct->journal = this;
- }
- bool remove_account(account_t * acct) {
- return master->remove_account(acct);
- acct->journal = NULL;
- }
-
- account_t * find_account(const string& name, bool auto_create = true) {
- accounts_map::iterator c = accounts_cache.find(name);
- if (c != accounts_cache.end())
- return (*c).second;
-
- account_t * account = master->find_account(name, auto_create);
- accounts_cache.insert(accounts_map::value_type(name, account));
- account->journal = this;
- return account;
- }
- account_t * find_account_re(const string& regexp);
-
- bool add_entry(entry_t * entry);
- bool remove_entry(entry_t * entry);
-
- void add_entry_finalizer(entry_finalizer_t * finalizer) {
- add_hook<entry_finalizer_t *>(entry_finalize_hooks, finalizer);
- }
- void remove_entry_finalizer(entry_finalizer_t * finalizer) {
- remove_hook<entry_finalizer_t *>(entry_finalize_hooks, finalizer);
- }
-
- bool valid() const;
-};
-
-inline void extend_entry_base(journal_t * journal, entry_base_t& entry,
- bool post) {
- for (auto_entries_list::iterator i = journal->auto_entries.begin();
- i != journal->auto_entries.end();
- i++)
- (*i)->extend_entry(entry, post);
-}
-
-inline bool auto_entry_finalizer_t::operator()(entry_t& entry, bool post) {
- extend_entry_base(journal, entry, post);
- return true;
-}
-
-extern const string version;
-
-} // namespace ledger
-
-#endif // _JOURNAL_H
diff --git a/src/data/node.cc b/src/data/node.cc
deleted file mode 100644
index 0ca0a04c..00000000
--- a/src/data/node.cc
+++ /dev/null
@@ -1,130 +0,0 @@
-/*
- * Copyright (c) 2003-2007, John Wiegley. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * - Neither the name of New Artisans LLC nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "node.h"
-#include "document.h"
-
-namespace ledger {
-namespace xml {
-
-const char * node_t::name() const
-{
- return *document().lookup_name(name_id());
-}
-
-value_t& node_t::set_attr(const string& _name, const char * value)
-{
- nameid_t name_id = document().register_name(_name);
- return set_attr(name_id, value);
-}
-
-value_t& node_t::set_attr(const string& _name, const value_t& value)
-{
- nameid_t name_id = document().register_name(_name);
- return set_attr(name_id, value);
-}
-
-optional<value_t&> node_t::get_attr(const string& _name)
-{
- optional<nameid_t> name_id = document().lookup_name_id(_name);
- if (name_id)
- return get_attr(*name_id);
- else
- return none;
-}
-
-void output_xml_string(std::ostream& out, const string& str)
-{
- for (const char * s = str.c_str(); *s; s++) {
- switch (*s) {
- case '<':
- out << "&lt;";
- break;
- case '>':
- out << "&gt;";
- break;
- case '&':
- out << "&amp;";
- break;
- default:
- out << *s;
- break;
- }
- }
-}
-
-void node_t::print_attributes(std::ostream& out) const
-{
- if (attributes) {
-#if 1
- foreach (const attr_pair& attr, *attributes)
- out << ' ' << *document().lookup_name(attr.first)
- << "=\"" << attr.second << "\"";
-#else
- foreach (const attr_pair& attr, attributes->get<0>())
- out << ' ' << *document().lookup_name(attr.first)
- << "=\"" << attr.second << "\"";
-#endif
- }
-
- IF_VERIFY()
- out << " type=\"parent_node_t\"";
-}
-
-void parent_node_t::print(std::ostream& out) const
-{
- out << '<' << name();
- print_attributes(out);
- out << '>';
-
- foreach (node_t * child, *this)
- child->print(out);
-
- out << "</" << name() << '>';
-}
-
-void terminal_node_t::print(std::ostream& out) const
-{
- if (data.empty()) {
- out << '<' << name();
- print_attributes(out);
- out << " />";
- } else {
- out << '<' << name();
- print_attributes(out);
- out << '>';
- output_xml_string(out, text());
- out << "</" << name() << '>';
- }
-}
-
-} // namespace xml
-} // namespace ledger
diff --git a/src/data/node.h b/src/data/node.h
deleted file mode 100644
index 36964bdf..00000000
--- a/src/data/node.h
+++ /dev/null
@@ -1,352 +0,0 @@
-/*
- * Copyright (c) 2003-2007, John Wiegley. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * - Neither the name of New Artisans LLC nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _NODE_H
-#define _NODE_H
-
-#include "value.h"
-
-namespace ledger {
-namespace xml {
-
-#define XML_NODE_IS_PARENT 0x1
-
-DECLARE_EXCEPTION(conversion_error);
-
-class document_t;
-class parent_node_t;
-class terminal_node_t;
-
-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_;
-
-#if 1
- typedef std::map<const nameid_t, value_t> attributes_t;
- typedef std::pair<const nameid_t, value_t> attr_pair;
-#else
- typedef std::pair<nameid_t, value_t> attr_pair;
-
- typedef multi_index_container<
- attr_pair,
- multi_index::indexed_by<
- multi_index::sequenced<>,
- multi_index::hashed_unique<
- multi_index::member<attr_pair, nameid_t, &attr_pair::first> >
- >
- > attributes_t;
-
- typedef attributes_t::nth_index<0>::type attributes_by_order;
- typedef attributes_t::nth_index<1>::type attributes_hashed;
-#endif
-
- optional<attributes_t> attributes;
-
-public:
- bool compiled; // so that compile_node() can access it
-
- node_t(nameid_t _name_id, document_t& _document,
- const optional<parent_node_t&>& _parent = none, flags_t _flags = 0)
- : supports_flags<>(_flags), name_id_(_name_id),
- document_(_document), parent_(_parent) {
- TRACE_CTOR(node_t, "document_t&, parent_node_t&, nameid_t, flags_t");
- }
-
- virtual ~node_t() {
- TRACE_DTOR(node_t);
- }
-
- void extract();
-
- bool is_compiled() const {
- return compiled;
- }
-
- bool is_parent_node() const {
- return has_flags(XML_NODE_IS_PARENT);
- }
- parent_node_t& as_parent_node() {
- if (! is_parent_node())
- throw_(std::logic_error, "Request to cast leaf node to a parent node");
- return downcast<parent_node_t>(*this);
- }
- const parent_node_t& as_parent_node() const {
- return const_cast<node_t *>(this)->as_parent_node();
- }
-
- bool is_terminal_node() const {
- return ! has_flags(XML_NODE_IS_PARENT);
- }
- terminal_node_t& as_terminal_node() {
- if (! is_terminal_node())
- throw_(std::logic_error, "Request to cast parent node to a leaf node");
- return downcast<terminal_node_t>(*this);
- }
- const terminal_node_t& as_terminal_node() const {
- return const_cast<node_t *>(this)->as_terminal_node();
- }
-
- virtual value_t to_value() const = 0;
- virtual void print(std::ostream& out) const = 0;
- virtual void print_attributes(std::ostream& out) const;
-
- const char * name() const;
- nameid_t name_id() const {
- return name_id_;
- }
-
- document_t& document() const {
- return document_;
- }
- optional<parent_node_t&> parent() const {
- return parent_;
- }
-
- value_t& set_attr(const string& _name, const char * value);
- value_t& set_attr(const string& _name, const value_t& value);
-
- value_t& set_attr(const nameid_t _name_id, const char * value) {
- return set_attr(_name_id, string_value(value));
- }
- value_t& set_attr(const nameid_t _name_id, const value_t& value) {
- if (! attributes)
- attributes = attributes_t();
-
- attributes_t::iterator i = attributes->find(_name_id);
- if (i == attributes->end()) {
- std::pair<attributes_t::iterator, bool> result =
- attributes->insert(attr_pair(_name_id, value));
- assert(result.second);
- return (*result.first).second;
- } else {
- i->second = value;
- return i->second;
- }
- }
-
- optional<value_t&> get_attr(const string& _name);
- optional<value_t&> get_attr(const nameid_t _name_id) {
- if (attributes) {
-#if 1
- attributes_t::iterator i = attributes->find(_name_id);
- if (i != attributes->end())
- return (*i).second;
-#else
- typedef attributes_t::nth_index<1>::type attributes_by_name;
-
- const attributes_by_name& name_index = attributes->get<1>();
- attributes_by_name::iterator i = name_index.find(_name_id);
- if (i != name_index.end())
- return (*i).second;
-#endif
- }
- return none;
- }
-
- optional<const value_t&> get_attr(const string& _name) const {
- if (optional<value_t&> value =
- const_cast<node_t *>(this)->get_attr(_name))
- return *value;
- else
- return none;
- }
- optional<const value_t&> get_attr(const nameid_t _name_id) const {
- if (optional<value_t&> value =
- const_cast<node_t *>(this)->get_attr(_name_id))
- return *value;
- else
- return none;
- }
-};
-
-class parent_node_t : public node_t
-{
- typedef multi_index_container<
- node_t *,
- multi_index::indexed_by<
- multi_index::sequenced<>,
- multi_index::hashed_non_unique<
- multi_index::member<node_t, nameid_t, &node_t::name_id_> >,
- multi_index::hashed_unique<multi_index::identity<node_t *> >
- >
- > children_t;
-
- children_t children;
-
-public:
- typedef children_t::nth_index<0>::type children_by_order;
- typedef children_t::nth_index<1>::type children_by_nameid;
- typedef children_t::nth_index<2>::type children_by_ptr;
-
- parent_node_t(nameid_t _name_id, document_t& _document,
- const optional<parent_node_t&>& _parent = none)
- : node_t(_name_id, _document, _parent, XML_NODE_IS_PARENT) {
- TRACE_CTOR(parent_node_t, "document_t *, parent_node_t *");
- }
- virtual ~parent_node_t() {
- TRACE_DTOR(parent_node_t);
- clear_children();
- }
-
- template <typename T>
- T * create_child(nameid_t _name_id) {
- T * child = new T(_name_id, document(), *this);
- children.push_back(child);
- return child;
- }
-
- void remove_child(node_t * child) {
- children_by_ptr& ptr_index = children.get<2>();
- children_by_ptr::iterator i = ptr_index.find(child);
- if (i == ptr_index.end())
- throw_(std::logic_error, "Request to delete node which is not a child");
- ptr_index.erase(i);
- }
-
- void delete_child(node_t * child) {
- remove_child(child);
- checked_delete(child);
- }
-
- struct match_nameid {
- nameid_t nameid;
- match_nameid(nameid_t _nameid) : nameid(_nameid) {}
- bool operator()(const node_t * node) const {
- return node->name_id() == nameid;
- }
- };
-
- typedef children_by_order::iterator iterator;
- typedef children_by_order::iterator const_iterator;
-
- children_by_order::iterator begin() {
- return children.get<0>().begin();
- }
- children_by_order::const_iterator begin() const {
- return children.get<0>().begin();
- }
- children_by_order::iterator end() {
- return children.get<0>().end();
- }
- children_by_order::const_iterator end() const {
- return children.get<0>().end();
- }
-
- std::size_t size() const {
- return children.get<0>().size();
- }
-
- children_by_nameid::iterator begin(nameid_t _name_id) {
- return std::find_if(children.get<1>().begin(),
- children.get<1>().end(), match_nameid(_name_id));
- }
- children_by_nameid::const_iterator begin(nameid_t _name_id) const {
- return std::find_if(children.get<1>().begin(),
- children.get<1>().end(), match_nameid(_name_id));
- }
- children_by_nameid::iterator end(nameid_t) {
- return children.get<1>().end();
- }
- children_by_nameid::const_iterator end(nameid_t) const {
- return children.get<1>().end();
- }
-
- void clear_children() {
- typedef children_t::nth_index<0>::type children_by_index;
-
- children_by_index& child_index = children.get<0>();
- for (children_by_index::iterator i = child_index.begin();
- i != child_index.end();
- i++)
- checked_delete(*i);
-
- children.clear();
- }
-
- virtual value_t to_value() const {
- throw_(std::logic_error, "Cannot convert parent node to a value");
- return NULL_VALUE;
- }
-
- void print(std::ostream& out) const;
-};
-
-inline void node_t::extract()
-{
- if (parent_)
- parent_->remove_child(this);
-}
-
-class terminal_node_t : public node_t
-{
- string data;
-
-public:
- terminal_node_t(nameid_t _name_id, document_t& _document,
- const optional<parent_node_t&>& _parent = none)
- : node_t(_name_id, _document, _parent)
- {
- TRACE_CTOR(terminal_node_t, "document_t *, parent_node_t *");
- }
- virtual ~terminal_node_t() {
- TRACE_DTOR(terminal_node_t);
- }
-
- const char * text() const {
- return data.c_str();
- }
- void set_text(const string& _data) {
- data = _data;
- }
- void set_text(const char * _data) {
- data = _data;
- }
-
- virtual value_t to_value() const {
- return value_t(text(), true);
- }
-
- void print(std::ostream& out) const;
-};
-
-} // namespace xml
-} // namespace ledger
-
-#endif // _NODE_H
diff --git a/src/data/parser.h b/src/data/parser.h
deleted file mode 100644
index ecc73a6f..00000000
--- a/src/data/parser.h
+++ /dev/null
@@ -1,138 +0,0 @@
-/*
- * Copyright (c) 2003-2007, John Wiegley. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * - Neither the name of New Artisans LLC nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _PARSER_H
-#define _PARSER_H
-
-#include "utils.h"
-#include "builder.h"
-
-namespace ledger {
-
-class account_t;
-class journal_t;
-
-class parser_t
-{
- public:
- virtual ~parser_t() {}
-
- virtual bool test(std::istream& in) const = 0;
-
- virtual std::size_t parse(std::istream& in,
- const path& pathname,
- xml::builder_t& builder) = 0;
-};
-
-DECLARE_EXCEPTION(parse_error);
-
-/************************************************************************
- *
- * General utility parsing functions
- */
-
-inline char * skip_ws(char * ptr) {
- while (*ptr == ' ' || *ptr == '\t' || *ptr == '\n')
- ptr++;
- return ptr;
-}
-
-inline char * next_element(char * buf, bool variable = false) {
- for (char * p = buf; *p; p++) {
- if (! (*p == ' ' || *p == '\t'))
- continue;
-
- if (! variable) {
- *p = '\0';
- return skip_ws(p + 1);
- }
- else if (*p == '\t') {
- *p = '\0';
- return skip_ws(p + 1);
- }
- else if (*(p + 1) == ' ') {
- *p = '\0';
- return skip_ws(p + 2);
- }
- }
- return NULL;
-}
-
-inline char peek_next_nonws(std::istream& in) {
- char c = in.peek();
- while (! in.eof() && std::isspace(c)) {
- in.get(c);
- c = in.peek();
- }
- return c;
-}
-
-#define READ_INTO(str, targ, size, var, cond) { \
- char * _p = targ; \
- var = str.peek(); \
- while (! str.eof() && var != '\n' && (cond) && _p - targ < size) { \
- str.get(var); \
- if (str.eof()) \
- break; \
- if (var == '\\') { \
- str.get(var); \
- if (in.eof()) \
- break; \
- } \
- *_p++ = var; \
- var = str.peek(); \
- } \
- *_p = '\0'; \
-}
-
-#define READ_INTO_(str, targ, size, var, idx, cond) { \
- char * _p = targ; \
- var = str.peek(); \
- while (! str.eof() && var != '\n' && (cond) && _p - targ < size) { \
- str.get(var); \
- if (str.eof()) \
- break; \
- idx++; \
- if (var == '\\') { \
- str.get(var); \
- if (in.eof()) \
- break; \
- idx++; \
- } \
- *_p++ = var; \
- var = str.peek(); \
- } \
- *_p = '\0'; \
-}
-
-} // namespace ledger
-
-#endif // _PARSER_H
diff --git a/src/data/textual.cc b/src/data/textual.cc
deleted file mode 100644
index 9bee6c39..00000000
--- a/src/data/textual.cc
+++ /dev/null
@@ -1,480 +0,0 @@
-/*
- * Copyright (c) 2003-2007, John Wiegley. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * - Neither the name of New Artisans LLC nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#include "textual.h"
-
-namespace ledger {
-
-using namespace xml;
-
-#define MAX_LINE 1024
-
-typedef builder_t::position_t position_t;
-
-void parse_transaction(builder_t& builder,
- char * line,
- position_t& end_of_line)
-{
- // First cut up the input line into its various parts.
-
- char * state = NULL;
- char * account_path = NULL;
- char * amount = NULL;
- char * note = NULL;
-
- char * p = line;
-
- if (*p == '*' || *p == '!')
- state = p++;
-
- account_path = skip_ws(p);
-
- amount = next_element(account_path, true);
- if (amount) {
- char * p = amount;
- while (*p && *p != ';')
- p++;
-
- if (*p == ';') {
- *p++ = '\0';
- note = skip_ws(p);
- }
-
- p = amount + (std::strlen(amount) - 1);
- while (p > amount && std::isspace(*p))
- p--;
-
- if (std::isspace(*(p + 1)))
- *++p = '\0';
- }
-
- // Setup the details for this node
-
- if (state) {
- switch (*state) {
- case '*':
- builder.push_attr(CLEARED_ATTR, "yes");
- break;
- case '!':
- builder.push_attr(PENDING_ATTR, "yes");
- break;
- }
- }
-
- builder.begin_node(TRANSACTION_NODE);
-
- // Parse the account name
-
- char * b = &account_path[0];
- char * e = &account_path[std::strlen(account_path) - 1];
- if ((*b == '[' && *e == ']') ||
- (*b == '(' && *e == ')')) {
- builder.push_attr(VIRTUAL_ATTR, "yes");
- if (*b == '[')
- builder.push_attr(BALANCE_ATTR, "yes");
- *account_path++ = '\0';
- *e = '\0';
- }
-
- builder.begin_node(ACCOUNT_PATH_NODE, true);
- builder.append_text(account_path);
- builder.end_node(ACCOUNT_PATH_NODE);
-
- // Parse the optional amount
-
- if (amount) {
- builder.begin_node(AMOUNT_EXPR_NODE, true);
- builder.append_text(amount);
- builder.end_node(AMOUNT_EXPR_NODE);
- }
-
- // Parse the optional note
-
- if (note) {
- builder.begin_node(NOTE_NODE, true);
- builder.append_text(note);
- builder.end_node(NOTE_NODE);
- }
-
- builder.end_node(TRANSACTION_NODE, end_of_line);
-}
-
-bool parse_transactions(std::istream& in, builder_t& builder)
-{
- TRACE_START(entry_xacts, 1, "Time spent parsing transactions:");
-
- bool added = false;
-
- while (! in.eof() && (in.peek() == ' ' || in.peek() == '\t')) {
- static char line[MAX_LINE + 1];
- line[0] = '\0';
- in.getline(line, MAX_LINE);
- if (in.eof() || line[0] == '\0')
- break;
-
- position_t end_of_line(builder.position());
- end_of_line.offset += std::strlen(line) + 1;
- end_of_line.linenum++;
-
- char * p = skip_ws(line);
- if (! *p || *p == '\r' || *p == '\n')
- break;
-
- parse_transaction(builder, line, end_of_line);
- added = true;
- }
-
- TRACE_STOP(entry_xacts, 1);
-
- return added;
-}
-
-void parse_entry(std::istream& in,
- builder_t& builder,
- char * line,
- position_t& end_of_line)
-{
- TRACE_START(entry_text, 1, "Time spent preparing entry text:");
-
- // First cut up the input line into its various parts
-
- char * date = NULL;
- char * date_eff = NULL;
- char * statep = NULL;
- char * code = NULL;
- char * payee = NULL;
-
- date = line;
-
- char * p = line;
-
- while (*p && (std::isdigit(*p) || *p == '/' || *p == '.' || *p == '-'))
- p++;
- assert(*p);
-
- if (*p == '=') {
- *p++ = '\0';
- date_eff = p;
-
- while (*p && (std::isdigit(*p) || *p == '/' || *p == '.' || *p == '-'))
- p++;
- assert(*p);
- } else {
- *p++ = '\0';
- }
-
- p = skip_ws(p);
-
- if (*p == '*' || *p == '!') {
- statep = p;
- p++; *p++ = '\0';
-
- p = skip_ws(p);
- }
-
- if (*p == '(') {
- code = ++p;
- while (*p && *p != ')')
- p++;
- assert(*p);
- *p++ = '\0';
-
- p = skip_ws(p);
- }
-
- payee = p;
-
- p = payee + (std::strlen(payee) - 1);
- while (p > payee && std::isspace(*p))
- p--;
-
- if (std::isspace(*(p + 1)))
- *++p = '\0';
-
- TRACE_STOP(entry_text, 1);
-
- // Setup the details for this node
-
- TRACE_START(entry_details, 1, "Time spent parsing entry details:");
-
- builder.push_attr(DATE_ATTR, date);
-
- if (date_eff)
- builder.push_attr(EFF_DATE_ATTR, date_eff);
-
- if (statep) {
- switch (*statep) {
- case '*':
- builder.push_attr(CLEARED_ATTR, "yes");
- break;
- case '!':
- builder.push_attr(PENDING_ATTR, "yes");
- break;
- }
- }
-
- if (code)
- builder.push_attr(CODE_ATTR, code);
-
- builder.begin_node(ENTRY_NODE);
-
- builder.begin_node(PAYEE_NODE, true);
- assert(payee);
- builder.append_text(*payee != '\0' ? payee : "<Unspecified payee>");
- builder.end_node(PAYEE_NODE, end_of_line);
-
- TRACE_STOP(entry_details, 1);
-
- // Parse all the transactions associated with this entry
-
- if (! parse_transactions(in, builder))
- throw_(parse_error, "Entry has no transactions");
-
- builder.end_node(ENTRY_NODE);
-}
-
-bool textual_parser_t::test(std::istream& in) const
-{
- char buf[5];
-
- in.read(buf, 5);
- if (std::strncmp(buf, "<?xml", 5) == 0)
- throw_(parse_error, "Ledger file contains XML data, but format was not recognized");
-
- in.clear();
- in.seekg(0, std::ios::beg);
- assert(in.good());
- return true;
-}
-
-std::size_t textual_parser_t::parse(std::istream& in,
- const path& pathname,
- builder_t& builder)
-{
- TRACE_START(parsing_total, 1, "Total time spent parsing text:");
-
- INFO("Parsing file '" << pathname.string() << "'");
-
- builder.begin_node(JOURNAL_NODE);
-
- std::size_t count = 0;
-
- while (in.good() && ! in.eof()) {
- static char line[MAX_LINE + 1];
- in.getline(line, MAX_LINE);
- if (in.eof())
- break;
-
- position_t end_of_line(builder.position());
- end_of_line.offset += std::strlen(line) + 1;
- end_of_line.linenum++;
-
- //PUSH_CONTEXT();
-
- switch (line[0]) {
- case '\0':
- case '\r':
- break;
-
- case ' ':
- case '\t': {
- char * p = skip_ws(line);
- if (*p && *p != '\r')
- throw_(parse_error, "Line begins with whitespace");
- break;
- }
-
- case 'i':
- case 'I': {
- string date(line, 2, 19);
-
- char * p = skip_ws(line + 22);
- char * n = next_element(p, true);
-
- builder.push_attr(TIME_ATTR, date);
- builder.push_attr(ACCOUNT_ATTR, p);
- builder.begin_node(CHECKIN_NODE, true);
- builder.append_text(n);
- builder.end_node(CHECKIN_NODE, end_of_line);
- break;
- }
-
- case 'o':
- case 'O': {
- string date(line, 2, 19);
-
- char * p = skip_ws(line + 22);
- char * n = next_element(p, true);
-
- builder.push_attr(TIME_ATTR, date);
- builder.push_attr(ACCOUNT_ATTR, p);
- builder.begin_node(CHECKIN_NODE, true);
- builder.append_text(n);
- builder.end_node(CHECKIN_NODE, end_of_line);
- break;
- }
-
- case 'D': { // specifies default commodity flags
- builder.push_attr(TEMPLATE_ATTR, skip_ws(line + 1));
- builder.push_node(COMMODITY_TEMPLATE_NODE, end_of_line);
- break;
- }
-
- case 'A': // a default account for unbalanced xacts
- builder.push_attr(NAME_ATTR, skip_ws(line + 1));
- builder.push_node(DEFAULT_ACCOUNT_NODE, end_of_line);
- break;
-
- case 'C': // a set of conversions
- if (char * p = std::strchr(line + 1, '=')) {
- *p++ = '\0';
- builder.push_attr(FROM_ATTR, skip_ws(line + 1));
- builder.push_attr(TO_ATTR, p);
- builder.push_node(COMMODITY_CONVERSION_NODE, end_of_line);
- } else {
- throw_(parse_error, "Conversion entry (code C) must follow the format X=Y");
- }
- break;
-
- case 'P': { // a pricing entry
- char * date_field_ptr = skip_ws(line + 1);
- char * time_field_ptr = next_element(date_field_ptr);
- if (! time_field_ptr)
- throw_(parse_error, "Pricing entry (code P) is missing arguments");
- string date_field = date_field_ptr;
-
- char * symbol_and_price;
- moment_t datetime;
-
- if (std::isdigit(time_field_ptr[0])) {
- symbol_and_price = next_element(time_field_ptr);
- if (! symbol_and_price)
- throw_(parse_error, "Pricing entry (code P) is missing a symbol name");
- } else {
- symbol_and_price = time_field_ptr;
- }
-
- builder.push_attr(DATE_ATTR, date_field_ptr);
- builder.push_attr(TIME_ATTR, time_field_ptr);
-
- string symbol;
- commodity_t::parse_symbol(symbol_and_price, symbol);
-
- builder.push_attr(SYMBOL_ATTR, symbol);
- builder.push_attr(PRICE_ATTR, skip_ws(symbol_and_price));
- builder.push_node(PRICE_HISTORY_NODE, end_of_line);
- break;
- }
-
- case 'N': { // don't download prices
- char * p = skip_ws(line + 1);
-
- string symbol;
- commodity_t::parse_symbol(p, symbol);
-
- builder.push_attr(SYMBOL_ATTR, symbol);
- builder.push_node(COMMODITY_NOMARKET_NODE, end_of_line);
- break;
- }
-
- case 'Y': // set current year
- builder.push_attr(YEAR_ATTR, skip_ws(line + 1));
- builder.push_node(CURRENT_YEAR_NODE, end_of_line);
- break;
-
- case 'h':
- case 'b':
- case ';': // comment
- // jww (2007-05-12): Read in the comment and save it
- break;
-
- case '@':
- case '!': { // directive
- char * p = next_element(line);
- string word(line + 1);
-
- builder.push_attr(NAME_ATTR, word);
- builder.push_attr(ARG_ATTR, p);
- builder.push_node(DIRECTIVE_NODE, end_of_line);
- break;
- }
-
- case '-': // option setting
- throw_(parse_error, "Option settings are not allowed in journal files");
-
- case '=': { // automated entry
- builder.begin_node(AUTO_ENTRY_NODE);
- builder.begin_node(RULE_NODE, true);
- builder.append_text(skip_ws(line + 1));
- builder.end_node(RULE_NODE);
-
- builder.set_position(end_of_line);
-
- if (! parse_transactions(in, builder))
- throw_(parse_error, "Automated entry has no transactions");
-
- builder.end_node(AUTO_ENTRY_NODE);
- break;
- }
-
- case '~': // period entry
- builder.begin_node(PERIOD_ENTRY_NODE);
- builder.begin_node(PERIOD_NODE, true);
- builder.append_text(skip_ws(line + 1));
- builder.end_node(PERIOD_NODE);
-
- builder.set_position(end_of_line);
-
- if (! parse_transactions(in, builder))
- throw_(parse_error, "Repeating entry has no transactions");
-
- builder.end_node(PERIOD_ENTRY_NODE);
- break;
-
- default:
- TRACE_START(entries, 1, "Time spent handling entries:");
- parse_entry(in, builder, line, end_of_line);
- count++;
- TRACE_STOP(entries, 1);
- break;
- }
-
- //POP_CONTEXT(builder_context(builder));
- }
-
- builder.end_node(JOURNAL_NODE);
-
- TRACE_STOP(parsing_total, 1);
-
- return count;
-}
-
-} // namespace ledger
diff --git a/src/data/textual.h b/src/data/textual.h
deleted file mode 100644
index f4d81f19..00000000
--- a/src/data/textual.h
+++ /dev/null
@@ -1,51 +0,0 @@
-/*
- * Copyright (c) 2003-2007, John Wiegley. All rights reserved.
- *
- * Redistribution and use in source and binary forms, with or without
- * modification, are permitted provided that the following conditions are
- * met:
- *
- * - Redistributions of source code must retain the above copyright
- * notice, this list of conditions and the following disclaimer.
- *
- * - Redistributions in binary form must reproduce the above copyright
- * notice, this list of conditions and the following disclaimer in the
- * documentation and/or other materials provided with the distribution.
- *
- * - Neither the name of New Artisans LLC nor the names of its
- * contributors may be used to endorse or promote products derived from
- * this software without specific prior written permission.
- *
- * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
- * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
- * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
- * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
- * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
- * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
- * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
- * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
- * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
- * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
- * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
- */
-
-#ifndef _TEXTUAL_H
-#define _TEXTUAL_H
-
-#include "parser.h"
-
-namespace ledger {
-
-class textual_parser_t : public parser_t
-{
- public:
- virtual bool test(std::istream& in) const;
-
- virtual std::size_t parse(std::istream& in,
- const path& pathname,
- xml::builder_t& builder);
-};
-
-} // namespace ledger
-
-#endif // _TEXTUAL_H