summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorJohn Wiegley <johnw@newartisans.com>2007-05-14 11:09:28 +0000
committerJohn Wiegley <johnw@newartisans.com>2008-04-13 03:38:50 -0400
commit59fc3d1bdb01b7195a0f9745fe9914ac31b8a3a5 (patch)
treeb925cd5f52bed29606364c76a08c0b7795ebcedd /src
parent77db7eb92f730af315d4bcdf831cc67acb386b58 (diff)
downloadfork-ledger-59fc3d1bdb01b7195a0f9745fe9914ac31b8a3a5.tar.gz
fork-ledger-59fc3d1bdb01b7195a0f9745fe9914ac31b8a3a5.tar.bz2
fork-ledger-59fc3d1bdb01b7195a0f9745fe9914ac31b8a3a5.zip
Initial implementation of document_builder_t.
Diffstat (limited to 'src')
-rw-r--r--src/builder.h79
-rw-r--r--src/commodity.cc26
-rw-r--r--src/commodity.h4
-rw-r--r--src/compile.h (renamed from src/xml.h)6
-rw-r--r--src/csv.cc31
-rw-r--r--src/csv.h31
-rw-r--r--src/derive.cc209
-rw-r--r--src/derive.h49
-rw-r--r--src/document.cc177
-rw-r--r--src/document.h150
-rw-r--r--src/emacs.cc31
-rw-r--r--src/emacs.h31
-rw-r--r--src/gnucash.cc397
-rw-r--r--src/gnucash.h103
-rw-r--r--src/journal.cc2
-rw-r--r--src/ledger.h3
-rw-r--r--src/main.cc16
-rw-r--r--src/node.cc (renamed from src/quotes.h)89
-rw-r--r--src/node.h276
-rw-r--r--src/ofx.cc246
-rw-r--r--src/ofx.h52
-rw-r--r--src/py_balance.cc233
-rw-r--r--src/py_format.cc42
-rw-r--r--src/py_journal.cc404
-rw-r--r--src/py_option.cc103
-rw-r--r--src/py_parser.cc79
-rw-r--r--src/py_report.cc44
-rw-r--r--src/py_session.cc67
-rw-r--r--src/py_transform.cc39
-rw-r--r--src/py_value.cc368
-rw-r--r--src/py_xpath.cc110
-rw-r--r--src/qif.cc274
-rw-r--r--src/qif.h52
-rw-r--r--src/quotes.cc117
-rw-r--r--src/reconcile.cc31
-rw-r--r--src/reconcile.h31
-rw-r--r--src/register.cc12
-rw-r--r--src/report.h2
-rw-r--r--src/system.hh2
-rw-r--r--src/textual.cc28
-rw-r--r--src/value.cc4
-rw-r--r--src/xml.cc584
-rw-r--r--src/xpath.cc83
-rw-r--r--src/xpath.h55
44 files changed, 832 insertions, 3940 deletions
diff --git a/src/builder.h b/src/builder.h
index 69fec3d9..ea340242 100644
--- a/src/builder.h
+++ b/src/builder.h
@@ -1,7 +1,7 @@
#ifndef _BUILDER_H
#define _BUILDER_H
-#include "xml.h"
+#include "document.h"
namespace ledger {
namespace xml {
@@ -44,8 +44,8 @@ public:
virtual void push_attr(const node_t::nameid_t name_id,
const string& value) = 0;
- virtual void begin_node(const string& name) = 0;
- virtual void begin_node(const node_t::nameid_t name_id) = 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;
@@ -70,8 +70,71 @@ public:
* This builder can be used to parse ordinary XML into a document
* object structure which can then be traversed in memory.
*/
-class xml_builder_t : public builder_t
+class document_builder_t : public builder_t
{
+public:
+ 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;
+
+ 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 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) {
+ current = &*current->parent();
+ }
+ virtual node_t * end_node(const node_t::nameid_t name_id,
+ const optional<position_t>& end_pos = none) {
+ current = &*current->parent();
+ }
};
/**
@@ -91,7 +154,7 @@ class xml_builder_t : public builder_t
* 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 xml_builder_t
+class journal_builder_t : public document_builder_t
{
public:
virtual void set_start_position(std::istream& in) {
@@ -138,20 +201,20 @@ public:
push_attr("hello", value);
}
- virtual void begin_node(const string& name) {
+ 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) {
+ 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);
+ begin_node(name, true);
end_node(name, end_pos);
}
virtual void push_node(const node_t::nameid_t name_id,
diff --git a/src/commodity.cc b/src/commodity.cc
index 4cc38e06..48609577 100644
--- a/src/commodity.cc
+++ b/src/commodity.cc
@@ -455,14 +455,8 @@ commodity_t * commodity_pool_t::create(const string& symbol)
commodity->ident = commodities.size();
- std::pair<commodities_t::iterator, bool> result =
- commodities.insert(commodity.get());
- if (! result.second) {
- assert(false);
- return NULL;
- } else {
- return commodity.release();
- }
+ commodities.push_back(commodity.get());
+ return commodity.release();
}
commodity_t * commodity_pool_t::find_or_create(const string& symbol)
@@ -498,11 +492,7 @@ commodity_t * commodity_pool_t::find(const commodity_t::ident_t ident)
commodities_by_ident;
commodities_by_ident& ident_index = commodities.get<0>();
- commodities_by_ident::iterator i = ident_index.find(ident);
- if (i != ident_index.end())
- return *i;
- else
- return NULL;
+ return ident_index[ident];
}
commodity_t *
@@ -598,14 +588,8 @@ commodity_pool_t::create(commodity_t& comm,
commodity->ident = commodities.size();
commodity->mapping_key_ = mapping_key;
- std::pair<commodities_t::iterator, bool> result
- = commodities.insert(commodity.get());
- if (! result.second) {
- assert(false);
- return NULL;
- } else {
- return commodity.release();
- }
+ commodities.push_back(commodity.get());
+ return commodity.release();
}
commodity_t * commodity_pool_t::find_or_create(commodity_t& comm,
diff --git a/src/commodity.h b/src/commodity.h
index 84ca5fff..6212e743 100644
--- a/src/commodity.h
+++ b/src/commodity.h
@@ -318,9 +318,7 @@ class commodity_pool_t : public noncopyable
typedef multi_index_container<
commodity_t *,
multi_index::indexed_by<
- multi_index::ordered_unique<
- multi_index::member<commodity_t,
- commodity_t::ident_t, &commodity_t::ident> >,
+ multi_index::random_access<>,
multi_index::hashed_unique<
multi_index::const_mem_fun<commodity_t,
string, &commodity_t::mapping_key> >
diff --git a/src/xml.h b/src/compile.h
index a247260b..25e12183 100644
--- a/src/xml.h
+++ b/src/compile.h
@@ -29,8 +29,8 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef _XML_H
-#define _XML_H
+#ifndef _NODE_H
+#define _NODE_H
#include "journal.h"
#include "value.h"
@@ -507,4 +507,4 @@ wrap_node(document_t * doc, journal_t * journal, void * parent_node) {
} // namespace xml
} // namespace ledger
-#endif // _XML_H
+#endif // _NODE_H
diff --git a/src/csv.cc b/src/csv.cc
deleted file mode 100644
index 0b623407..00000000
--- a/src/csv.cc
+++ /dev/null
@@ -1,31 +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.
- */
-
diff --git a/src/csv.h b/src/csv.h
deleted file mode 100644
index 0b623407..00000000
--- a/src/csv.h
+++ /dev/null
@@ -1,31 +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.
- */
-
diff --git a/src/derive.cc b/src/derive.cc
deleted file mode 100644
index 73c4cdf0..00000000
--- a/src/derive.cc
+++ /dev/null
@@ -1,209 +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 "derive.h"
-#include "mask.h"
-
-namespace ledger {
-
-void derive_command::operator()
- (value_t& result, xml::xpath_t::scope_t * locals)
-{
-#if 0
- std::ostream& out = *get_ptr<std::ostream>(locals, 0);
- repitem_t * items = get_ptr<repitem_t>(locals, 1);
- strings_list& args = *get_ptr<strings_list *>(locals, 2);
-
- std::auto_ptr<entry_t> added(new entry_t);
-
- entry_t * matching = NULL;
-
- strings_list::iterator i = args.begin();
-
- added->_date = *i++;
- if (i == args.end())
- throw new error("Too few arguments to 'entry'");
-
- mask_t regexp(*i++);
-
- entries_list::reverse_iterator j;
- for (j = journal.entries.rbegin();
- j != journal.entries.rend();
- j++)
- if (regexp.match((*j)->payee)) {
- matching = *j;
- break;
- }
-
- added->payee = matching ? matching->payee : regexp.pattern;
-
- if (! matching) {
- account_t * acct;
- if (i == args.end() || ((*i)[0] == '-' || std::isdigit((*i)[0]))) {
- acct = journal.find_account("Expenses");
- }
- else if (i != args.end()) {
- acct = journal.find_account_re(*i);
- if (! acct)
- acct = journal.find_account(*i);
- assert(acct);
- i++;
- }
-
- if (i == args.end()) {
- added->add_transaction(new transaction_t(acct));
- } else {
- transaction_t * xact = new transaction_t(acct, amount_t(*i++));
- added->add_transaction(xact);
-
- if (! xact->amount.commodity()) {
- // If the amount has no commodity, we can determine it given
- // the account by creating a final for the account and then
- // checking if it contains only a single commodity. An
- // account to which only dollars are applied would imply that
- // dollars are wanted now too.
-
- std::auto_ptr<item_handler<transaction_t> > formatter;
- formatter.reset(new set_account_value);
- walk_entries(journal.entries, *formatter.get());
- formatter->flush();
-
- sum_accounts(*journal.master);
-
- value_t total = account_xdata(*acct).total;
- if (total.type == value_t::AMOUNT)
- xact->amount.set_commodity(((amount_t *) total.data)->commodity());
- }
- }
-
- if (journal.basket)
- acct = journal.basket;
- else
- acct = journal.find_account("Equity");
-
- added->add_transaction(new transaction_t(acct));
- }
- else if (i == args.end()) {
- // If no argument were given but the payee, assume the user wants
- // to see the same transaction as last time.
- added->code = matching->code;
-
- for (transactions_list::iterator k = matching->transactions.begin();
- k != matching->transactions.end();
- k++)
- added->add_transaction(new transaction_t(**k));
- }
- else if ((*i)[0] == '-' || std::isdigit((*i)[0])) {
- transaction_t * m_xact, * xact, * first;
- m_xact = matching->transactions.front();
-
- first = xact = new transaction_t(m_xact->account, amount_t(*i++));
- added->add_transaction(xact);
-
- if (! xact->amount.commodity())
- xact->amount.set_commodity(m_xact->amount.commodity());
-
- m_xact = matching->transactions.back();
-
- xact = new transaction_t(m_xact->account, - first->amount);
- added->add_transaction(xact);
-
- if (i != args.end()) {
- account_t * acct = journal.find_account_re(*i);
- if (! acct)
- acct = journal.find_account(*i);
- assert(acct);
- added->transactions.back()->account = acct;
- }
- }
- else {
- while (i != args.end()) {
- string& re_pat(*i++);
- account_t * acct = NULL;
- amount_t * amt = NULL;
-
- mask_t acct_regex(re_pat);
-
- for (; j != journal.entries.rend(); j++)
- if (regexp.match((*j)->payee)) {
- entry_t * entry = *j;
- for (transactions_list::const_iterator x =
- entry->transactions.begin();
- x != entry->transactions.end();
- x++)
- if (acct_regex.match((*x)->account->fullname())) {
- acct = (*x)->account;
- amt = &(*x)->amount;
- matching = entry;
- goto found;
- }
- }
-
- found:
- if (! acct)
- acct = journal.find_account_re(re_pat);
- if (! acct)
- acct = journal.find_account(re_pat);
-
- transaction_t * xact;
- if (i == args.end()) {
- if (amt)
- xact = new transaction_t(acct, *amt);
- else
- xact = new transaction_t(acct);
- } else {
- xact = new transaction_t(acct, amount_t(*i++));
- if (! xact->amount.commodity()) {
- if (amt)
- xact->amount.set_commodity(amt->commodity());
- else if (commodity_t::default_commodity)
- xact->amount.set_commodity(*commodity_t::default_commodity);
- }
- }
- added->add_transaction(xact);
- }
-
- assert(matching->transactions.back()->account);
- if (account_t * draw_acct = matching->transactions.back()->account)
- added->add_transaction(new transaction_t(draw_acct));
- }
-
- done:
- if (! run_hooks(journal.entry_finalize_hooks, *added, false) ||
- ! added->finalize() ||
- ! run_hooks(journal.entry_finalize_hooks, *added, true))
- throw new error("Failed to finalize derived entry (check commodities)");
-
- return added.release();
-#endif
-}
-
-} // namespace ledger
diff --git a/src/derive.h b/src/derive.h
deleted file mode 100644
index 422248d8..00000000
--- a/src/derive.h
+++ /dev/null
@@ -1,49 +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 _DERIVE_H
-#define _DERIVE_H
-
-#include "xpath.h"
-
-namespace ledger {
-
-class derive_command : public xml::xpath_t::functor_t
-{
- public:
- derive_command() : xml::xpath_t::functor_t("entry", true) {}
-
- virtual void operator()(value_t& result, xml::xpath_t::scope_t * locals);
-};
-
-} // namespace ledger
-
-#endif // _DERIVE_H
diff --git a/src/document.cc b/src/document.cc
new file mode 100644
index 00000000..e48462da
--- /dev/null
+++ b/src/document.cc
@@ -0,0 +1,177 @@
+/*
+ * 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-expr",
+ "arg",
+ "auto-entry",
+ "balance",
+ "checkin",
+ "cleared",
+ "code",
+ "commodity",
+ "commodity-conversion",
+ "commodity-nomarket",
+ "commodity-template",
+ "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 = (int)ledger_builtins_size;
+
+ while (first <= last) {
+ int mid = (first + last) / 2; // compute mid point.
+
+ int result;
+ if ((result = (int)name[0] - (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 "CURRENT";
+ case PARENT:
+ return "PARENT";
+ case ROOT:
+ return "ROOT";
+ case ALL:
+ return "ALL";
+
+ default:
+ assert(id >= 10);
+ return ledger_builtins[id - 10];
+ }
+ }
+ else if (names) {
+ int 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/document.h b/src/document.h
new file mode 100644
index 00000000..1b6f0924
--- /dev/null
+++ b/src/document.h
@@ -0,0 +1,150 @@
+/*
+ * 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_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,
+ 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
+ };
+
+ 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/emacs.cc b/src/emacs.cc
deleted file mode 100644
index 0b623407..00000000
--- a/src/emacs.cc
+++ /dev/null
@@ -1,31 +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.
- */
-
diff --git a/src/emacs.h b/src/emacs.h
deleted file mode 100644
index 0b623407..00000000
--- a/src/emacs.h
+++ /dev/null
@@ -1,31 +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.
- */
-
diff --git a/src/gnucash.cc b/src/gnucash.cc
deleted file mode 100644
index 8fa5a524..00000000
--- a/src/gnucash.cc
+++ /dev/null
@@ -1,397 +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 "gnucash.h"
-
-namespace ledger {
-
-void startElement(void *userData, const char *name, const char ** /* attrs */)
-{
- gnucash_parser_t * parser = static_cast<gnucash_parser_t *>(userData);
-
- if (std::strcmp(name, "gnc:account") == 0) {
- parser->curr_account = new account_t(parser->master_account);
- }
- else if (std::strcmp(name, "act:name") == 0)
- parser->action = gnucash_parser_t::ACCOUNT_NAME;
- else if (std::strcmp(name, "act:id") == 0)
- parser->action = gnucash_parser_t::ACCOUNT_ID;
- else if (std::strcmp(name, "act:parent") == 0)
- parser->action = gnucash_parser_t::ACCOUNT_PARENT;
- else if (std::strcmp(name, "gnc:commodity") == 0)
- parser->curr_comm = NULL;
- else if (std::strcmp(name, "cmdty:id") == 0)
- parser->action = gnucash_parser_t::COMM_SYM;
- else if (std::strcmp(name, "cmdty:name") == 0)
- parser->action = gnucash_parser_t::COMM_NAME;
- else if (std::strcmp(name, "cmdty:fraction") == 0)
- parser->action = gnucash_parser_t::COMM_PREC;
- else if (std::strcmp(name, "gnc:transaction") == 0) {
- assert(! parser->curr_entry);
- parser->curr_entry = new entry_t;
- }
- else if (std::strcmp(name, "trn:num") == 0)
- parser->action = gnucash_parser_t::ENTRY_NUM;
- else if (std::strcmp(name, "trn:date-posted") == 0)
- parser->action = gnucash_parser_t::ALMOST_ENTRY_DATE;
- else if (parser->action == gnucash_parser_t::ALMOST_ENTRY_DATE &&
- std::strcmp(name, "ts:date") == 0)
- parser->action = gnucash_parser_t::ENTRY_DATE;
- else if (std::strcmp(name, "trn:description") == 0)
- parser->action = gnucash_parser_t::ENTRY_DESC;
- else if (std::strcmp(name, "trn:split") == 0) {
- assert(parser->curr_entry);
- parser->curr_entry->add_transaction(new transaction_t(parser->curr_account));
- }
- else if (std::strcmp(name, "split:reconciled-state") == 0)
- parser->action = gnucash_parser_t::XACT_STATE;
- else if (std::strcmp(name, "split:amount") == 0)
- parser->action = gnucash_parser_t::XACT_AMOUNT;
- else if (std::strcmp(name, "split:value") == 0)
- parser->action = gnucash_parser_t::XACT_VALUE;
- else if (std::strcmp(name, "split:quantity") == 0)
- parser->action = gnucash_parser_t::XACT_QUANTITY;
- else if (std::strcmp(name, "split:account") == 0)
- parser->action = gnucash_parser_t::XACT_ACCOUNT;
- else if (std::strcmp(name, "split:memo") == 0)
- parser->action = gnucash_parser_t::XACT_NOTE;
-}
-
-void endElement(void *userData, const char *name)
-{
- gnucash_parser_t * parser = static_cast<gnucash_parser_t *>(userData);
-
- if (std::strcmp(name, "gnc:account") == 0) {
- assert(parser->curr_account);
- if (parser->curr_account->parent == parser->master_account)
- parser->curr_journal->add_account(parser->curr_account);
- parser->accounts_by_id.insert
- (accounts_map::value_type(parser->curr_account_id, parser->curr_account));
- parser->curr_account = NULL;
- }
- else if (std::strcmp(name, "gnc:commodity") == 0) {
- parser->curr_comm = NULL;
- }
- else if (std::strcmp(name, "gnc:transaction") == 0) {
- assert(parser->curr_entry);
-
- // Add the new entry (what gnucash calls a 'transaction') to the
- // journal
- if (! parser->curr_journal->add_entry(parser->curr_entry)) {
- print_entry(std::cerr, *parser->curr_entry);
- parser->have_error = "The above entry does not balance";
- checked_delete(parser->curr_entry);
- } else {
- parser->curr_entry->src_idx = parser->src_idx;
- parser->curr_entry->beg_pos = parser->beg_pos;
- parser->curr_entry->beg_line = parser->beg_line;
- parser->curr_entry->end_pos = parser->instreamp->tellg();
- parser->curr_entry->end_line =
- XML_GetCurrentLineNumber(parser->expat_parser) - parser->offset;
- parser->count++;
- }
-
- // Clear the relevant variables for the next run
- parser->curr_entry = NULL;
- parser->entry_comm = NULL;
- }
- else if (std::strcmp(name, "trn:split") == 0) {
- transaction_t * xact = parser->curr_entry->transactions.back();
-
- // Identify the commodity to use for the value of this
- // transaction. The quantity indicates how many times that value
- // the transaction is worth.
- amount_t value;
- commodity_t * default_commodity = NULL;
- if (parser->entry_comm) {
- default_commodity = parser->entry_comm;
- } else {
- gnucash_parser_t::account_comm_map::iterator ac =
- parser->account_comms.find(xact->account);
- if (ac != parser->account_comms.end())
- default_commodity = (*ac).second;
- }
-
- if (default_commodity) {
- parser->curr_quant.set_commodity(*default_commodity);
- value = parser->curr_quant.round();
-
- if (parser->curr_value.commodity() == *default_commodity)
- parser->curr_value = value;
- } else {
- value = parser->curr_quant;
- }
-
- xact->state = parser->curr_state;
- xact->amount = value;
- if (value != parser->curr_value)
- xact->cost = amount_t(parser->curr_value);
-
- xact->beg_pos = parser->beg_pos;
- xact->beg_line = parser->beg_line;
- xact->end_pos = parser->instreamp->tellg();
- xact->end_line =
- XML_GetCurrentLineNumber(parser->expat_parser) - parser->offset;
-
- // Clear the relevant variables for the next run
- parser->curr_state = transaction_t::UNCLEARED;
- parser->curr_value = amount_t();
- parser->curr_quant = amount_t();
- }
-
- parser->action = gnucash_parser_t::NO_ACTION;
-}
-
-amount_t gnucash_parser_t::convert_number(const string& number,
- int * precision)
-{
- const char * num = number.c_str();
-
- if (char * p = std::strchr(num, '/')) {
- string numer_str(num, p - num);
- string denom_str(p + 1);
-
- amount_t amt(numer_str);
- amount_t den(denom_str);
-
- if (precision)
- *precision = denom_str.length() - 1;
-
- if (! den) {
- have_error = "Denominator in entry is zero!";
- return amt;
- } else {
- return amt / den;
- }
- } else {
- return amount_t(number);
- }
-}
-
-void dataHandler(void *userData, const char *s, int len)
-{
- gnucash_parser_t * parser = static_cast<gnucash_parser_t *>(userData);
-
- switch (parser->action) {
- case gnucash_parser_t::ACCOUNT_NAME:
- parser->curr_account->name = string(s, len);
- break;
-
- case gnucash_parser_t::ACCOUNT_ID:
- parser->curr_account_id = string(s, len);
- break;
-
- case gnucash_parser_t::ACCOUNT_PARENT: {
- accounts_map::iterator i = parser->accounts_by_id.find(string(s, len));
- assert(i != parser->accounts_by_id.end());
- parser->curr_account->parent = (*i).second;
- parser->curr_account->depth = parser->curr_account->parent->depth + 1;
- (*i).second->add_account(parser->curr_account);
- break;
- }
-
- case gnucash_parser_t::COMM_SYM: {
- string symbol(s, len);
- if (symbol == "USD") symbol = "$";
-
- parser->curr_comm = amount_t::current_pool->find_or_create(symbol);
- assert(parser->curr_comm);
-
- if (symbol != "$")
- parser->curr_comm->add_flags(COMMODITY_STYLE_SEPARATED);
-
- if (parser->curr_account)
- parser->account_comms.insert
- (gnucash_parser_t::account_comm_map::value_type
- (parser->curr_account, parser->curr_comm));
- else if (parser->curr_entry)
- parser->entry_comm = parser->curr_comm;
- break;
- }
-
- case gnucash_parser_t::COMM_NAME:
- parser->curr_comm->set_name(string(s, len));
- break;
-
- case gnucash_parser_t::COMM_PREC:
- parser->curr_comm->set_precision(len - 1);
- break;
-
- case gnucash_parser_t::ENTRY_NUM:
- parser->curr_entry->code = string(s, len);
- break;
-
- case gnucash_parser_t::ENTRY_DATE:
- parser->curr_entry->_date = parse_datetime(string(s, len));
- break;
-
- case gnucash_parser_t::ENTRY_DESC:
- parser->curr_entry->payee = string(s, len);
- break;
-
- case gnucash_parser_t::XACT_STATE:
- if (*s == 'y')
- parser->curr_state = transaction_t::CLEARED;
- else if (*s == 'n')
- parser->curr_state = transaction_t::UNCLEARED;
- else
- parser->curr_state = transaction_t::PENDING;
- break;
-
- case gnucash_parser_t::XACT_VALUE: {
- int precision;
- assert(parser->entry_comm);
- parser->curr_value = parser->convert_number(string(s, len), &precision);
- parser->curr_value.set_commodity(*parser->entry_comm);
-
- if (precision > parser->entry_comm->precision())
- parser->entry_comm->set_precision(precision);
- break;
- }
-
- case gnucash_parser_t::XACT_QUANTITY:
- parser->curr_quant = parser->convert_number(string(s, len));
- break;
-
- case gnucash_parser_t::XACT_ACCOUNT: {
- transaction_t * xact = parser->curr_entry->transactions.back();
-
- accounts_map::iterator i =
- parser->accounts_by_id.find(string(s, len));
- if (i != parser->accounts_by_id.end()) {
- xact->account = (*i).second;
- } else {
- xact->account = parser->curr_journal->find_account("<Unknown>");
-
- parser->have_error = (string("Could not find account ") +
- string(s, len));
- }
- break;
- }
-
- case gnucash_parser_t::XACT_NOTE:
- parser->curr_entry->transactions.back()->note = string(s, len);
- break;
-
- case gnucash_parser_t::NO_ACTION:
- case gnucash_parser_t::ALMOST_ENTRY_DATE:
- case gnucash_parser_t::XACT_AMOUNT:
- break;
-
- default:
- assert(false);
- break;
- }
-}
-
-bool gnucash_parser_t::test(std::istream& in) const
-{
- char buf[5];
- in.read(buf, 5);
- in.clear();
- in.seekg(0, std::ios::beg);
-
- return std::strncmp(buf, "<?xml", 5) == 0;
-}
-
-unsigned int gnucash_parser_t::parse(std::istream& in,
- journal_t * journal,
- account_t * master,
- const optional<path>& original_file)
-{
- char buf[BUFSIZ];
-
- // This is the date format used by Gnucash, so override whatever the
- // user specified.
- //
- // jww (2006-09-13): Make this parser local somehow.
- //date_t::input_format = "%Y-%m-%d %H:%M:%S %z";
-
- count = 0;
- action = NO_ACTION;
- curr_journal = journal;
- master_account = master ? master : journal->master;
- curr_account = NULL;
- curr_entry = NULL;
- curr_comm = NULL;
- entry_comm = NULL;
- curr_state = transaction_t::UNCLEARED;
-
- instreamp = &in;
- pathname = original_file ? *original_file : "<gnucash>";
- src_idx = journal->sources.size() - 1;
-
- // GnuCash uses the USD commodity without defining it, which really
- // means $.
- commodity_t * usd = amount_t::current_pool->find_or_create("$");
- usd->set_precision(2);
- usd->add_flags(COMMODITY_STYLE_THOUSANDS);
-
- offset = 2;
- expat_parser = XML_ParserCreate(NULL);
-
- XML_SetElementHandler(parser, startElement, endElement);
- XML_SetCharacterDataHandler(parser, dataHandler);
- XML_SetUserData(parser, this);
-
- while (in.good() && ! in.eof()) {
- beg_pos = in.tellg();
- beg_line = (XML_GetCurrentLineNumber(parser) - offset) + 1;
-
- in.getline(buf, BUFSIZ - 1);
- std::strcat(buf, "\n");
- if (! XML_Parse(parser, buf, std::strlen(buf), in.eof())) {
- //unsigned long line = XML_GetCurrentLineNumber(parser) - offset++;
- const char * msg = XML_ErrorString(XML_GetErrorCode(parser));
- XML_ParserFree(parser);
- throw_(parse_error, msg);
- }
-
- if (! have_error.empty()) {
- //unsigned long line = XML_GetCurrentLineNumber(parser) - offset++;
-#if 0
- // jww (2007-04-26): What is this doing?
- parse_error err(have_error);
- std::cerr << "Error: " << err.what() << std::endl;
-#endif
- have_error = "";
- }
- }
-
- XML_ParserFree(parser);
-
- accounts_by_id.clear();
- curr_account_id.clear();
-
- return count;
-}
-
-} // namespace ledger
diff --git a/src/gnucash.h b/src/gnucash.h
deleted file mode 100644
index ce46eec7..00000000
--- a/src/gnucash.h
+++ /dev/null
@@ -1,103 +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 _GNUCASH_H
-#define _GNUCASH_H
-
-#include "parser.h"
-#include "journal.h"
-
-namespace ledger {
-
-struct gnucash_parser_t : public parser_t
-{
- typedef std::map<const string, account_t *> accounts_map;
- typedef std::map<account_t *, commodity_t *> account_comm_map;
-
- journal_t * curr_journal;
- account_t * master_account;
- account_t * curr_account;
- string curr_account_id;
- entry_t * curr_entry;
- commodity_t * entry_comm;
- commodity_t * curr_comm;
- amount_t curr_value;
- amount_t curr_quant;
- XML_Parser expat_parser;
- accounts_map accounts_by_id;
- account_comm_map account_comms;
- unsigned int count;
- string have_error;
-
- std::istream * instreamp;
- unsigned int offset;
- XML_Parser parser;
- path pathname;
- unsigned int src_idx;
- unsigned long beg_pos;
- unsigned long beg_line;
-
- transaction_t::state_t curr_state;
-
- enum action_t {
- NO_ACTION,
- ACCOUNT_NAME,
- ACCOUNT_ID,
- ACCOUNT_PARENT,
- COMM_SYM,
- COMM_NAME,
- COMM_PREC,
- ENTRY_NUM,
- ALMOST_ENTRY_DATE,
- ENTRY_DATE,
- ENTRY_DESC,
- XACT_STATE,
- XACT_AMOUNT,
- XACT_VALUE,
- XACT_QUANTITY,
- XACT_ACCOUNT,
- XACT_NOTE
- } action;
-
- public:
- virtual bool test(std::istream& in) const;
-
- virtual unsigned int parse(std::istream& in,
- journal_t * journal,
- account_t * master = NULL,
- const optional<path>& original = none);
-
- amount_t convert_number(const string& number, int * precision = NULL);
-};
-
-} // namespace ledger
-
-#endif // _GNUCASH_H
diff --git a/src/journal.cc b/src/journal.cc
index 7a6f3354..7fe6b285 100644
--- a/src/journal.cc
+++ b/src/journal.cc
@@ -364,6 +364,7 @@ auto_entry_t::~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());
@@ -400,6 +401,7 @@ void auto_entry_t::extend_entry(entry_base_t& entry, bool post)
}
}
}
+#endif
}
account_t::~account_t()
diff --git a/src/ledger.h b/src/ledger.h
index d4bdcabe..c9f0f9c4 100644
--- a/src/ledger.h
+++ b/src/ledger.h
@@ -44,10 +44,9 @@
#include <amount.h>
#include <balance.h>
#include <value.h>
-#include <xml.h>
#include <xpath.h>
#include <format.h>
-#include <quotes.h>
+//#include <quotes.h>
#include <session.h>
#include <journal.h>
diff --git a/src/main.cc b/src/main.cc
index 010abd3c..945587b1 100644
--- a/src/main.cc
+++ b/src/main.cc
@@ -186,8 +186,8 @@ static int read_and_report(report_t * report, int argc, char * argv[],
std::cout << "Result of calculation: ";
}
- std::cout << expr.calc((xml::document_t *)NULL, report).
- strip_annotations() << std::endl;
+ xml::document_t temp(xml::LEDGER_NODE);
+ std::cout << expr.calc(temp, report).strip_annotations() << std::endl;
return 0;
}
@@ -215,8 +215,16 @@ static int read_and_report(report_t * report, int argc, char * argv[],
{
textual_parser_t text_parser;
ifstream input(session.data_file);
+
+#if 1
+ xml::document_t temp(xml::LEDGER_NODE);
+ xml::document_builder_t builder(temp);
+ text_parser.parse(input, session.data_file, builder);
+ temp.print(std::cout);
+#else
xml::xml_writer_t writer(std::cout);
text_parser.parse(input, session.data_file, writer);
+#endif
}
INFO_FINISH(journal);
return 0;
@@ -292,8 +300,8 @@ static int read_and_report(report_t * report, int argc, char * argv[],
*out << "Result of calculation: ";
}
- *out << expr.calc((xml::document_t *)NULL, report).
- strip_annotations() << std::endl;
+ xml::document_t temp(xml::LEDGER_NODE);
+ *out << expr.calc(temp, report).strip_annotations() << std::endl;
return 0;
}
diff --git a/src/quotes.h b/src/node.cc
index c94b405b..390ef988 100644
--- a/src/quotes.h
+++ b/src/node.cc
@@ -29,35 +29,72 @@
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
*/
-#ifndef _QUOTES_H
-#define _QUOTES_H
-
-#include "amount.h"
+#include "node.h"
+#include "document.h"
namespace ledger {
+namespace xml {
-class quotes_by_script
+const char * node_t::name() const
{
- path price_db;
- time_duration pricing_leeway;
- bool& cache_dirty;
-
- public:
- quotes_by_script(path _price_db,
- time_duration _pricing_leeway,
- bool& _cache_dirty)
- : price_db(_price_db), pricing_leeway(_pricing_leeway),
- cache_dirty(_cache_dirty) {}
-
- virtual optional<amount_t>
- operator()(commodity_t& commodity,
- const optional<moment_t>& date,
- const optional<moment_t>& moment,
- const optional<moment_t>& last);
-};
-
-DECLARE_EXCEPTION(download_error);
+ return *document().lookup_name(name_id());
+}
-} // namespace ledger
+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 parent_node_t::print(std::ostream& out) const
+{
+ out << '<' << name();
+ if (attributes) {
+ typedef attributes_t::nth_index<0>::type attributes_by_order;
+ foreach (const attr_pair& attr, attributes->get<0>())
+ out << ' ' << document().lookup_name(attr.first)
+ << "=\"" << attr.second << "\"";
+ }
+ IF_VERIFY()
+ out << " type=\"parent_node_t\"";
+ out << '>';
-#endif // _QUOTES_H
+ foreach (node_t * child, *this)
+ child->print(out);
+
+ out << "</" << name() << '>';
+}
+
+void terminal_node_t::print(std::ostream& out) const
+{
+ if (data.empty()) {
+ out << '<' << name();
+ IF_VERIFY()
+ out << " type=\"terminal_node_t\"";
+ out << " />";
+ } else {
+ out << '<' << name();
+ IF_VERIFY()
+ out << " type=\"terminal_node_t\"";
+ out << '>';
+ output_xml_string(out, text());
+ out << "</" << name() << '>';
+ }
+}
+
+} // namespace xml
+} // namespace ledger
diff --git a/src/node.h b/src/node.h
new file mode 100644
index 00000000..86b468e8
--- /dev/null
+++ b/src/node.h
@@ -0,0 +1,276 @@
+/*
+ * 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 "journal.h"
+#include "value.h"
+//#include "parser.h"
+
+namespace ledger {
+
+class transaction_t;
+class entry_t;
+class account_t;
+class journal_t;
+
+namespace xml {
+
+#define XML_NODE_IS_PARENT 0x1
+
+DECLARE_EXCEPTION(conversion_error);
+
+class parent_node_t;
+class document_t;
+
+class node_t : public supports_flags<>, public noncopyable
+{
+public:
+ typedef uint_fast16_t nameid_t;
+
+ nameid_t name_id_;
+
+protected:
+ document_t& document_;
+ optional<parent_node_t&> parent_;
+
+ typedef std::pair<nameid_t, string> 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;
+
+ optional<attributes_t> attributes;
+
+public:
+ 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);
+ }
+
+ 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 *polymorphic_downcast<parent_node_t *>(this);
+ }
+ const parent_node_t& as_parent_node() const {
+ if (! is_parent_node())
+ throw_(std::logic_error, "Request to cast leaf node to a parent node");
+ return *polymorphic_downcast<const parent_node_t *>(this);
+ }
+
+ virtual value_t to_value() const = 0;
+ virtual void print(std::ostream& out) const = 0;
+
+ 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_;
+ }
+
+ void set_attr(const nameid_t _name_id, const char * value) {
+ if (! attributes)
+ attributes = attributes_t();
+ attributes->push_back(attr_pair(_name_id, value));
+ }
+ optional<const string&> get_attr(const nameid_t _name_id) {
+ if (attributes) {
+ typedef attributes_t::nth_index<1>::type attributes_by_name;
+
+ 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;
+ }
+ 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);
+ }
+
+ void delete_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");
+ node_t * ptr = *i;
+ ptr_index.erase(i);
+ checked_delete(ptr);
+ }
+
+ 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();
+ }
+
+ 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");
+ }
+
+ void print(std::ostream& out) const;
+};
+
+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 text();
+ }
+
+ void print(std::ostream& out) const;
+};
+
+} // namespace xml
+} // namespace ledger
+
+#endif // _NODE_H
diff --git a/src/ofx.cc b/src/ofx.cc
deleted file mode 100644
index 24be9409..00000000
--- a/src/ofx.cc
+++ /dev/null
@@ -1,246 +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 "ofx.h"
-
-namespace ledger {
-
-typedef std::map<const string, account_t *> accounts_map;
-typedef std::map<const string, commodity_t *> commodities_map;
-
-journal_t * curr_journal;
-accounts_map ofx_accounts;
-commodities_map ofx_account_currencies;
-commodities_map ofx_securities;
-account_t * master_account;
-
-int ofx_proc_statement_cb(struct OfxStatementData data, void * statement_data)
-{
-}
-
-int ofx_proc_account_cb(struct OfxAccountData data, void * account_data)
-{
- if (! data.account_id_valid)
- return -1;
-
- DEBUG("ledger.ofx.parse", "account " << data.account_name);
- account_t * account = new account_t(master_account, data.account_name);
- curr_journal->add_account(account);
- ofx_accounts.insert(accounts_pair(data.account_id, account));
-
- if (data.currency_valid) {
- commodity_t * commodity = commodity_t::find_or_create(data.currency);
- commodity->add_flags(COMMODITY_STYLE_SUFFIXED | COMMODITY_STYLE_SEPARATED);
-
- commodities_map::iterator i = ofx_account_currencies.find(data.account_id);
- if (i == ofx_account_currencies.end())
- ofx_account_currencies.insert(commodities_pair(data.account_id,
- commodity));
- }
-
- return 0;
-}
-
-int ofx_proc_transaction_cb(struct OfxTransactionData data,
- void * transaction_data)
-{
- if (! data.account_id_valid || ! data.units_valid)
- return -1;
-
- accounts_map::iterator i = ofx_accounts.find(data.account_id);
- assert(i != ofx_accounts.end());
- account_t * account = (*i).second;
-
- entry_t * entry = new entry_t;
-
- entry->add_transaction(new transaction_t(account));
- transaction_t * xact = entry->transactions.back();
-
- // get the account's default currency
- commodities_map::iterator ac = ofx_account_currencies.find(data.account_id);
- assert(ac != ofx_account_currencies.end());
- commodity_t * default_commodity = (*ac).second;
-
- std::ostringstream stream;
- stream << - data.units;
-
- // jww (2005-02-09): what if the amount contains fees?
-
- if (data.unique_id_valid) {
- commodities_map::iterator s = ofx_securities.find(data.unique_id);
- assert(s != ofx_securities.end());
- xact->amount = stream.str() + " " + (*s).second->base_symbol();
- } else {
- xact->amount = stream.str() + " " + default_commodity->base_symbol();
- }
-
- if (data.unitprice_valid && data.unitprice != 1.0) {
- std::ostringstream cstream;
- stream << - data.unitprice << " " << default_commodity->base_symbol();
- xact->cost = new amount_t(stream.str());
- }
-
- DEBUG("ofx.parse", "xact " << xact->amount << " from " << *xact->account);
-
- if (data.date_initiated_valid)
- entry->_date = data.date_initiated;
- else if (data.date_posted_valid)
- entry->_date = data.date_posted;
-
- if (data.check_number_valid)
- entry->code = data.check_number;
- else if (data.reference_number_valid)
- entry->code = data.reference_number;
-
- if (data.name_valid)
- entry->payee = data.name;
-
- if (data.memo_valid)
- xact->note = data.memo;
-
- // jww (2005-02-09): check for fi_id_corrected? or is this handled
- // by the library?
-
- // Balance all entries into <Unknown>, since it is not specified.
- account = curr_journal->find_account("<Unknown>");
- entry->add_transaction(new transaction_t(account));
-
- if (! curr_journal->add_entry(entry)) {
- print_entry(std::cerr, *entry);
-#if 0
- // jww (2005-02-09): uncomment
- have_error = "The above entry does not balance";
-#endif
- checked_delete(entry);
- return -1;
- }
- return 0;
-}
-
-int ofx_proc_security_cb(struct OfxSecurityData data, void * security_data)
-{
- if (! data.unique_id_valid)
- return -1;
-
- string symbol;
- if (data.ticker_valid)
- symbol = data.ticker;
- else if (data.currency_valid)
- symbol = data.currency;
- else
- return -1;
-
- commodity_t * commodity = commodity_t::find_or_create(symbol);
- commodity->add_flags(COMMODITY_STYLE_SUFFIXED | COMMODITY_STYLE_SEPARATED);
-
- if (data.secname_valid)
- commodity->set_name(data.secname);
-
- if (data.memo_valid)
- commodity->set_note(data.memo);
-
- commodities_map::iterator i = ofx_securities.find(data.unique_id);
- if (i == ofx_securities.end()) {
- DEBUG("ledger.ofx.parse", "security " << symbol);
- ofx_securities.insert(commodities_pair(data.unique_id, commodity));
- }
-
- // jww (2005-02-09): What is the commodity for data.unitprice?
- if (data.date_unitprice_valid && data.unitprice_valid) {
- DEBUG("ledger.ofx.parse", " price " << data.unitprice);
- commodity->add_price(data.date_unitprice, amount_t(data.unitprice));
- }
-
- return 0;
-}
-
-int ofx_proc_status_cb(struct OfxStatusData data, void * status_data)
-{
-}
-
-bool ofx_parser_t::test(std::istream& in) const
-{
- char buf[80];
-
- in.getline(buf, 79);
- if (std::strncmp(buf, "OFXHEADER", 9) == 0) {
- in.clear();
- in.seekg(0, std::ios::beg);
- return true;
- }
- else if (std::strncmp(buf, "<?xml", 5) != 0) {
- in.clear();
- in.seekg(0, std::ios::beg);
- return false;
- }
-
- in.getline(buf, 79);
- if (std::strncmp(buf, "<?OFX", 5) != 0 &&
- std::strncmp(buf, "<?ofx", 5) != 0) {
- in.clear();
- in.seekg(0, std::ios::beg);
- return false;
- }
-
- in.clear();
- in.seekg(0, std::ios::beg);
- return true;
-}
-
-unsigned int ofx_parser_t::parse(std::istream& in,
- journal_t * journal,
- account_t * master,
- const string * original_file)
-{
- if (! original_file)
- return 0;
-
- curr_journal = journal;
- master_account = master ? master : journal->master;
-
- LibofxContextPtr libofx_context = libofx_get_new_context();
-
- ofx_set_statement_cb (libofx_context, ofx_proc_statement_cb, 0);
- ofx_set_account_cb (libofx_context, ofx_proc_account_cb, 0);
- ofx_set_transaction_cb(libofx_context, ofx_proc_transaction_cb, 0);
- ofx_set_security_cb (libofx_context, ofx_proc_security_cb, 0);
- ofx_set_status_cb (libofx_context, ofx_proc_status_cb, 0);
-
- // The processing is done by way of callbacks, which are all defined
- // above.
- libofx_proc_file(libofx_context, original_file->c_str(), AUTODETECT);
-
- libofx_free_context(libofx_context);
-
- return 1; // jww (2005-02-09): count;
-}
-
-} // namespace ledger
diff --git a/src/ofx.h b/src/ofx.h
deleted file mode 100644
index 5a55d75c..00000000
--- a/src/ofx.h
+++ /dev/null
@@ -1,52 +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 _OFX_H
-#define _OFX_H
-
-#include "parser.h"
-
-namespace ledger {
-
-class ofx_parser_t : public parser_t
-{
- public:
- virtual bool test(std::istream& in) const;
-
- virtual unsigned int parse(std::istream& in,
- journal_t * journal,
- account_t * master = NULL,
- const optional<path>& original = none);
-};
-
-} // namespace ledger
-
-#endif // _OFX_H
diff --git a/src/py_balance.cc b/src/py_balance.cc
deleted file mode 100644
index 90712d12..00000000
--- a/src/py_balance.cc
+++ /dev/null
@@ -1,233 +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.
- */
-
-using namespace boost::python;
-using namespace ledger;
-
-unsigned int balance_len(balance_t& bal)
-{
- return bal.amounts.size();
-}
-
-amount_t balance_getitem(balance_t& bal, int i)
-{
- std::size_t len = bal.amounts.size();
-
- if (abs(i) >= len) {
- PyErr_SetString(PyExc_IndexError, "Index out of range");
- throw_error_already_set();
- }
-
- int x = i < 0 ? len + i : i;
- balance_t::amounts_map::iterator elem = bal.amounts.begin();
- while (--x >= 0)
- elem++;
-
- return (*elem).second;
-}
-
-unsigned int balance_pair_len(balance_pair_t& bal_pair)
-{
- return balance_len(bal_pair.quantity);
-}
-
-amount_t balance_pair_getitem(balance_pair_t& bal_pair, int i)
-{
- return balance_getitem(bal_pair.quantity, i);
-}
-
-void export_balance()
-{
- class_< balance_t > ("Balance")
- .def(init<balance_t>())
- .def(init<amount_t>())
- .def(init<long>())
- .def(init<unsigned long>())
- .def(init<double>())
-
- .def(self += self)
- .def(self += other<amount_t>())
- .def(self += long())
- .def(self + self)
- .def(self + other<amount_t>())
- .def(self + long())
- .def(self -= self)
- .def(self -= other<amount_t>())
- .def(self -= long())
- .def(self - self)
- .def(self - other<amount_t>())
- .def(self - long())
- .def(self *= self)
- .def(self *= other<amount_t>())
- .def(self *= long())
- .def(self * self)
- .def(self * other<amount_t>())
- .def(self * long())
- .def(self /= self)
- .def(self /= other<amount_t>())
- .def(self /= long())
- .def(self / self)
- .def(self / other<amount_t>())
- .def(self / long())
- .def(- self)
-
- .def(self < self)
- .def(self < other<amount_t>())
- .def(self < long())
- .def(self <= self)
- .def(self <= other<amount_t>())
- .def(self <= long())
- .def(self > self)
- .def(self > other<amount_t>())
- .def(self > long())
- .def(self >= self)
- .def(self >= other<amount_t>())
- .def(self >= long())
- .def(self == self)
- .def(self == other<amount_t>())
- .def(self == long())
- .def(self != self)
- .def(self != other<amount_t>())
- .def(self != long())
- .def(! self)
-
- .def(self_ns::str(self))
-
- .def("__abs__", &balance_t::abs)
- .def("__len__", balance_len)
- .def("__getitem__", balance_getitem)
-
- .def("valid", &balance_t::valid)
-
- .def("realzero", &balance_t::realzero)
- .def("amount", &balance_t::amount)
- .def("value", &balance_t::value)
- .def("price", &balance_t::price)
- .def("date", &balance_t::date)
- .def("strip_annotations", &balance_t::strip_annotations)
- .def("write", &balance_t::write)
- .def("round", &balance_t::round)
- .def("negate", &balance_t::negate)
- .def("negated", &balance_t::negated)
- ;
-
- class_< balance_pair_t > ("BalancePair")
- .def(init<balance_pair_t>())
- .def(init<balance_t>())
- .def(init<amount_t>())
- .def(init<long>())
- .def(init<unsigned long>())
- .def(init<double>())
-
- .def(self += self)
- .def(self += other<balance_t>())
- .def(self += other<amount_t>())
- .def(self += long())
- .def(self + self)
- .def(self + other<balance_t>())
- .def(self + other<amount_t>())
- .def(self + long())
- .def(self -= self)
- .def(self -= other<balance_t>())
- .def(self -= other<amount_t>())
- .def(self -= long())
- .def(self - self)
- .def(self - other<balance_t>())
- .def(self - other<amount_t>())
- .def(self - long())
- .def(self *= self)
- .def(self *= other<balance_t>())
- .def(self *= other<amount_t>())
- .def(self *= long())
- .def(self * self)
- .def(self * other<balance_t>())
- .def(self * other<amount_t>())
- .def(self * long())
- .def(self /= self)
- .def(self /= other<balance_t>())
- .def(self /= other<amount_t>())
- .def(self /= long())
- .def(self / self)
- .def(self / other<balance_t>())
- .def(self / other<amount_t>())
- .def(self / long())
- .def(- self)
-
- .def(self < self)
- .def(self < other<balance_t>())
- .def(self < other<amount_t>())
- .def(self < long())
- .def(self <= self)
- .def(self <= other<balance_t>())
- .def(self <= other<amount_t>())
- .def(self <= long())
- .def(self > self)
- .def(self > other<balance_t>())
- .def(self > other<amount_t>())
- .def(self > long())
- .def(self >= self)
- .def(self >= other<balance_t>())
- .def(self >= other<amount_t>())
- .def(self >= long())
- .def(self == self)
- .def(self == other<balance_t>())
- .def(self == other<amount_t>())
- .def(self == long())
- .def(self != self)
- .def(self != other<balance_t>())
- .def(self != other<amount_t>())
- .def(self != long())
- .def(! self)
-
- .def(self_ns::str(self))
-
- .def("__abs__", &balance_pair_t::abs)
- .def("__len__", balance_pair_len)
- .def("__getitem__", balance_pair_getitem)
-
- .def("valid", &balance_pair_t::valid)
-
- .def("realzero", &balance_pair_t::realzero)
- .def("amount", &balance_pair_t::amount)
- .def("value", &balance_pair_t::value)
- .def("price", &balance_pair_t::price)
- .def("date", &balance_pair_t::date)
- .def("strip_annotations", &balance_pair_t::strip_annotations)
- .def("write", &balance_pair_t::write)
- .def("round", &balance_pair_t::round)
- .def("negate", &balance_pair_t::negate)
- .def("negated", &balance_pair_t::negated)
-
- .add_property("cost",
- make_getter(&balance_pair_t::cost,
- return_value_policy<reference_existing_object>()))
- ;
-}
diff --git a/src/py_format.cc b/src/py_format.cc
deleted file mode 100644
index 819a0ac7..00000000
--- a/src/py_format.cc
+++ /dev/null
@@ -1,42 +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.
- */
-
-using namespace boost::python;
-using namespace ledger;
-
-void export_format()
-{
- class_< format_t > ("Format")
- .def(init<string>())
- .def("parse", &format_t::parse)
- .def("format", &format_t::format)
- ;
-}
diff --git a/src/py_journal.cc b/src/py_journal.cc
deleted file mode 100644
index e7cd600a..00000000
--- a/src/py_journal.cc
+++ /dev/null
@@ -1,404 +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.
- */
-
-using namespace boost::python;
-using namespace ledger;
-
-entry_t& transaction_entry(const transaction_t& xact)
-{
- return *xact.entry;
-}
-
-unsigned int transactions_len(entry_base_t& entry)
-{
- return entry.transactions.size();
-}
-
-transaction_t& transactions_getitem(entry_base_t& entry, int i)
-{
- static int last_index = 0;
- static entry_base_t * last_entry = NULL;
- static transactions_list::iterator elem;
-
- std::size_t len = entry.transactions.size();
-
- if (abs(i) >= len) {
- PyErr_SetString(PyExc_IndexError, "Index out of range");
- throw_error_already_set();
- }
-
- if (&entry == last_entry && i == last_index + 1) {
- last_index = i;
- return **++elem;
- }
-
- int x = i < 0 ? len + i : i;
- elem = entry.transactions.begin();
- while (--x >= 0)
- elem++;
-
- last_entry = &entry;
- last_index = i;
-
- return **elem;
-}
-
-unsigned int entries_len(journal_t& journal)
-{
- return journal.entries.size();
-}
-
-entry_t& entries_getitem(journal_t& journal, int i)
-{
- static int last_index = 0;
- static journal_t * last_journal = NULL;
- static entries_list::iterator elem;
-
- std::size_t len = journal.entries.size();
-
- if (abs(i) >= len) {
- PyErr_SetString(PyExc_IndexError, "Index out of range");
- throw_error_already_set();
- }
-
- if (&journal == last_journal && i == last_index + 1) {
- last_index = i;
- return **++elem;
- }
-
- int x = i < 0 ? len + i : i;
- elem = journal.entries.begin();
- while (--x >= 0)
- elem++;
-
- last_journal = &journal;
- last_index = i;
-
- return **elem;
-}
-
-unsigned int accounts_len(account_t& account)
-{
- return account.accounts.size();
-}
-
-account_t& accounts_getitem(account_t& account, int i)
-{
- static int last_index = 0;
- static account_t * last_account = NULL;
- static accounts_map::iterator elem;
-
- std::size_t len = account.accounts.size();
-
- if (abs(i) >= len) {
- PyErr_SetString(PyExc_IndexError, "Index out of range");
- throw_error_already_set();
- }
-
- if (&account == last_account && i == last_index + 1) {
- last_index = i;
- return *(*++elem).second;
- }
-
- int x = i < 0 ? len + i : i;
- elem = account.accounts.begin();
- while (--x >= 0)
- elem++;
-
- last_account = &account;
- last_index = i;
-
- return *(*elem).second;
-}
-
-PyObject * py_account_get_data(account_t& account)
-{
- return (PyObject *) account.data;
-}
-
-void py_account_set_data(account_t& account, PyObject * obj)
-{
- account.data = obj;
-}
-
-account_t * py_find_account_1(journal_t& journal, const string& name)
-{
- return journal.find_account(name);
-}
-
-account_t * py_find_account_2(journal_t& journal, const string& name,
- const bool auto_create)
-{
- return journal.find_account(name, auto_create);
-}
-
-bool py_add_entry(journal_t& journal, entry_t * entry) {
- return journal.add_entry(new entry_t(*entry));
-}
-
-void py_add_transaction(entry_base_t& entry, transaction_t * xact) {
- return entry.add_transaction(new transaction_t(*xact));
-}
-
-struct entry_base_wrap : public entry_base_t
-{
- PyObject * self;
- entry_base_wrap(PyObject * self_) : self(self_) {}
-
- virtual bool valid() const {
- return call_method<bool>(self, "valid");
- }
-};
-
-struct py_entry_finalizer_t : public entry_finalizer_t {
- object pyobj;
- py_entry_finalizer_t() {}
- py_entry_finalizer_t(object obj) : pyobj(obj) {}
- py_entry_finalizer_t(const py_entry_finalizer_t& other)
- : pyobj(other.pyobj) {}
- virtual bool operator()(entry_t& entry, bool post) {
- return call<bool>(pyobj.ptr(), entry, post);
- }
-};
-
-std::list<py_entry_finalizer_t> py_finalizers;
-
-void py_add_entry_finalizer(journal_t& journal, object x)
-{
- py_finalizers.push_back(py_entry_finalizer_t(x));
- journal.add_entry_finalizer(&py_finalizers.back());
-}
-
-void py_remove_entry_finalizer(journal_t& journal, object x)
-{
- for (std::list<py_entry_finalizer_t>::iterator i = py_finalizers.begin();
- i != py_finalizers.end();
- i++)
- if ((*i).pyobj == x) {
- journal.remove_entry_finalizer(&(*i));
- py_finalizers.erase(i);
- return;
- }
-}
-
-void py_run_entry_finalizers(journal_t& journal, entry_t& entry, bool post)
-{
- run_hooks(journal.entry_finalize_hooks, entry, post);
-}
-
-#define EXC_TRANSLATOR(type) \
- void exc_translate_ ## type(const type& err) { \
- PyErr_SetString(PyExc_RuntimeError, err.what()); \
- }
-
-EXC_TRANSLATOR(balance_error)
-EXC_TRANSLATOR(interval_expr_error)
-EXC_TRANSLATOR(format_error)
-EXC_TRANSLATOR(parse_error)
-
-value_t py_transaction_amount(transaction_t * xact) {
- return value_t(xact->amount);
-}
-
-transaction_t::state_t py_entry_state(entry_t * entry) {
- transaction_t::state_t state;
- if (entry->get_state(&state))
- return state;
- else
- return transaction_t::UNCLEARED;
-}
-
-void export_journal()
-{
- scope().attr("TRANSACTION_NORMAL") = TRANSACTION_NORMAL;
- scope().attr("TRANSACTION_VIRTUAL") = TRANSACTION_VIRTUAL;
- scope().attr("TRANSACTION_BALANCE") = TRANSACTION_BALANCE;
- scope().attr("TRANSACTION_AUTO") = TRANSACTION_AUTO;
- scope().attr("TRANSACTION_BULK_ALLOC") = TRANSACTION_BULK_ALLOC;
- scope().attr("TRANSACTION_CALCULATED") = TRANSACTION_CALCULATED;
-
- enum_< transaction_t::state_t > ("State")
- .value("Uncleared", transaction_t::UNCLEARED)
- .value("Cleared", transaction_t::CLEARED)
- .value("Pending", transaction_t::PENDING)
- ;
-
- class_< transaction_t > ("Transaction")
- .def(init<optional<account_t *> >())
- .def(init<account_t *, amount_t, optional<unsigned int, const string&> >())
-
- .def(self == self)
- .def(self != self)
-
- .add_property("entry",
- make_getter(&transaction_t::entry,
- return_value_policy<reference_existing_object>()))
- .add_property("account",
- make_getter(&transaction_t::account,
- return_value_policy<reference_existing_object>()))
-
- .add_property("amount", &py_transaction_amount)
- .def_readonly("amount_expr", &transaction_t::amount_expr)
- .add_property("cost",
- make_getter(&transaction_t::cost,
- return_internal_reference<1>()))
- .def_readonly("cost_expr", &transaction_t::cost_expr)
-
- .def_readwrite("state", &transaction_t::state)
- .def_readwrite("flags", &transaction_t::flags)
- .def_readwrite("note", &transaction_t::note)
-
- .def_readonly("beg_pos", &transaction_t::beg_pos)
- .def_readonly("beg_line", &transaction_t::beg_line)
- .def_readonly("end_pos", &transaction_t::end_pos)
- .def_readonly("end_line", &transaction_t::end_line)
-
- .def("actual_date", &transaction_t::actual_date)
- .def("effective_date", &transaction_t::effective_date)
- .def("date", &transaction_t::date)
-
- .def("use_effective_date", &transaction_t::use_effective_date)
-
- .def("valid", &transaction_t::valid)
- ;
-
- class_< account_t >
- ("Account", init<optional<account_t *, string, string> >()
- [with_custodian_and_ward<1, 2>()])
- .def(self == self)
- .def(self != self)
-
- .def(self_ns::str(self))
-
- .def("__len__", accounts_len)
- .def("__getitem__", accounts_getitem, return_internal_reference<1>())
-
- .add_property("journal",
- make_getter(&account_t::journal,
- return_value_policy<reference_existing_object>()))
- .add_property("parent",
- make_getter(&account_t::parent,
- return_value_policy<reference_existing_object>()))
- .def_readwrite("name", &account_t::name)
- .def_readwrite("note", &account_t::note)
- .def_readonly("depth", &account_t::depth)
- .add_property("data", py_account_get_data, py_account_set_data)
- .def_readonly("ident", &account_t::ident)
-
- .def("fullname", &account_t::fullname)
-
- .def("add_account", &account_t::add_account)
- .def("remove_account", &account_t::remove_account)
-
- .def("find_account", &account_t::find_account,
- return_value_policy<reference_existing_object>())
-
- .def("valid", &account_t::valid)
- ;
-
- class_< journal_t > ("Journal")
- .def(self == self)
- .def(self != self)
-
- .def("__len__", entries_len)
- .def("__getitem__", entries_getitem, return_internal_reference<1>())
-
- .add_property("master", make_getter(&journal_t::master,
- return_internal_reference<1>()))
- .add_property("basket", make_getter(&journal_t::basket,
- return_internal_reference<1>()))
-
- .def_readonly("sources", &journal_t::sources)
-
- .def_readwrite("price_db", &journal_t::price_db)
-
- .def("add_account", &journal_t::add_account)
- .def("remove_account", &journal_t::remove_account)
-
- .def("find_account", py_find_account_1, return_internal_reference<1>())
- .def("find_account", py_find_account_2, return_internal_reference<1>())
- .def("find_account_re", &journal_t::find_account_re,
- return_internal_reference<1>())
-
- .def("add_entry", py_add_entry)
- .def("remove_entry", &journal_t::remove_entry)
-
- .def("add_entry_finalizer", py_add_entry_finalizer)
- .def("remove_entry_finalizer", py_remove_entry_finalizer)
- .def("run_entry_finalizers", py_run_entry_finalizers)
-
- .def("valid", &journal_t::valid)
- ;
-
- class_< entry_base_t, entry_base_wrap, boost::noncopyable > ("EntryBase")
- .def("__len__", transactions_len)
- .def("__getitem__", transactions_getitem,
- return_internal_reference<1>())
-
- .def_readonly("journal", &entry_base_t::journal)
-
- .def_readonly("src_idx", &entry_base_t::src_idx)
- .def_readonly("beg_pos", &entry_base_t::beg_pos)
- .def_readonly("beg_line", &entry_base_t::beg_line)
- .def_readonly("end_pos", &entry_base_t::end_pos)
- .def_readonly("end_line", &entry_base_t::end_line)
-
- .def("add_transaction", py_add_transaction)
- .def("remove_transaction", &entry_base_t::remove_transaction)
-
- .def(self == self)
- .def(self != self)
-
- .def("finalize", &entry_base_t::finalize)
- .def("valid", &entry_base_t::valid)
- ;
-
- class_< entry_t, bases<entry_base_t> > ("Entry")
- .add_property("date", &entry_t::date)
- .add_property("effective_date", &entry_t::effective_date)
- .add_property("actual_date", &entry_t::actual_date)
-
- .def_readwrite("code", &entry_t::code)
- .def_readwrite("payee", &entry_t::payee)
-
- .add_property("state", &py_entry_state)
-
- .def("valid", &entry_t::valid)
- ;
-
-#define EXC_TRANSLATE(type) \
- register_error_translator<type>(&exc_translate_ ## type);
-
- EXC_TRANSLATE(balance_error);
- EXC_TRANSLATE(interval_expr_error);
- EXC_TRANSLATE(format_error);
- EXC_TRANSLATE(parse_error);
-}
diff --git a/src/py_option.cc b/src/py_option.cc
deleted file mode 100644
index 2e298272..00000000
--- a/src/py_option.cc
+++ /dev/null
@@ -1,103 +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.
- */
-
-using namespace boost::python;
-using namespace ledger;
-
-struct py_option_t : public option_t
-{
- PyObject * self;
-
- py_option_t(PyObject * self_,
- const string& long_opt,
- const bool wants_arg)
- : self(self_), option_t(long_opt, wants_arg) {}
-
- virtual ~py_option_t() {}
-
- virtual bool check(option_source_t source) {
- return call_method<bool>(self, "check", source);
- }
-
- virtual void select(report_t * report, const char * optarg = NULL) {
- if (optarg)
- return call_method<void>(self, "select", report, optarg);
- else
- return call_method<void>(self, "select", report);
- }
-};
-
-BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(option_select_overloads,
- py_option_t::select, 1, 2)
-
-typedef std::map<const string, object> options_map;
-
-options_map options;
-
-static option_t * find_option(const string& name)
-{
- options_map::const_iterator i = options.find(name);
- if (i != options.end())
- return extract<py_option_t *>((*i).second.ptr());
-
- return NULL;
-}
-
-void shutdown_option()
-{
- options.clear();
-}
-
-void export_option()
-{
- class_< option_t, py_option_t, boost::noncopyable >
- ("Option", init<const string&, bool>())
- .def_readonly("long_opt", &py_option_t::long_opt)
- .def_readonly("short_opt", &py_option_t::short_opt)
- .def_readonly("wants_arg", &py_option_t::wants_arg)
- .def_readwrite("handled", &py_option_t::handled)
- .def("check", &py_option_t::check)
- .def("select", &py_option_t::select, option_select_overloads())
- ;
-
- enum_< option_t::option_source_t > ("OptionSource")
- .value("InitFile", option_t::INIT_FILE)
- .value("Environment", option_t::ENVIRONMENT)
- .value("DataFile", option_t::DATA_FILE)
- .value("CommandLine", option_t::COMMAND_LINE)
- ;
-
- class_< options_map > ("OptionsMap")
- .def(map_indexing_suite<options_map>())
- ;
-
- scope().attr("options") = ptr(&options);
-}
diff --git a/src/py_parser.cc b/src/py_parser.cc
deleted file mode 100644
index df3f8209..00000000
--- a/src/py_parser.cc
+++ /dev/null
@@ -1,79 +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 "parser.h"
-
-#if 0
-#ifdef USE_BOOST_PYTHON
-
-using namespace boost::python;
-using namespace ledger;
-
-struct py_parser_t : public parser_t
-{
- PyObject * self;
- py_parser_t(PyObject * self_) : self(self_) {}
-
- virtual bool test(std::istream& in) const {
- return call_method<bool>(self, "test", in);
- }
-
- virtual repitem_t * parse(std::istream& in,
- journal_t * journal,
- account_t * master = NULL,
- const string * original_file = NULL) {
- return call_method<unsigned int>(self, "parse", in, journal, master,
- original_file);
- }
-};
-
-BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(parser_parse_overloads,
- py_parser_t::parse, 2, 4)
-
-BOOST_PYTHON_FUNCTION_OVERLOADS(parse_journal_overloads, parse_journal, 2, 4)
-BOOST_PYTHON_FUNCTION_OVERLOADS(parse_journal_file_overloads,
- parse_journal_file, 2, 4)
-
-void export_parser() {
- class_< parser_t, py_parser_t, boost::noncopyable > ("Parser")
- .def("test", &py_parser_t::test)
- .def("parse", &py_parser_t::parse, parser_parse_overloads())
- ;
-
- def("register_parser", register_parser);
- def("unregister_parser", unregister_parser);
-
- def("parse_journal", parse_journal, parse_journal_overloads());
- def("parse_journal_file", parse_journal_file, parse_journal_file_overloads());
-}
-
-#endif // USE_BOOST_PYTHON
-#endif
diff --git a/src/py_report.cc b/src/py_report.cc
deleted file mode 100644
index 5816b398..00000000
--- a/src/py_report.cc
+++ /dev/null
@@ -1,44 +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.
- */
-
-using namespace boost::python;
-using namespace ledger;
-
-void export_report()
-{
- class_< report_t > ("Report")
- .add_property("session",
- make_getter(&report_t::session,
- return_value_policy<reference_existing_object>()))
-
- .def("apply_transforms", &report_t::apply_transforms)
- ;
-}
diff --git a/src/py_session.cc b/src/py_session.cc
deleted file mode 100644
index eb0e1b7d..00000000
--- a/src/py_session.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.
- */
-
-using namespace boost::python;
-using namespace ledger;
-
-void export_session()
-{
- class_< session_t > ("Session")
- .def_readwrite("init_file", &session_t::init_file)
- .def_readwrite("data_file", &session_t::data_file)
- .def_readwrite("cache_file", &session_t::cache_file)
- .def_readwrite("price_db", &session_t::price_db)
-
- .def_readwrite("balance_format", &session_t::balance_format)
- .def_readwrite("register_format", &session_t::register_format)
- .def_readwrite("wide_register_format", &session_t::wide_register_format)
- .def_readwrite("plot_amount_format", &session_t::plot_amount_format)
- .def_readwrite("plot_total_format", &session_t::plot_total_format)
- .def_readwrite("print_format", &session_t::print_format)
- .def_readwrite("write_hdr_format", &session_t::write_hdr_format)
- .def_readwrite("write_xact_format", &session_t::write_xact_format)
- .def_readwrite("equity_format", &session_t::equity_format)
- .def_readwrite("prices_format", &session_t::prices_format)
- .def_readwrite("pricesdb_format", &session_t::pricesdb_format)
-
- .def_readwrite("pricing_leeway", &session_t::pricing_leeway)
-
- .def_readwrite("download_quotes", &session_t::download_quotes)
- .def_readwrite("use_cache", &session_t::use_cache)
- .def_readwrite("cache_dirty", &session_t::cache_dirty)
- .def_readwrite("debug_mode", &session_t::debug_mode)
- .def_readwrite("verbose_mode", &session_t::verbose_mode)
- .def_readwrite("trace_alloc_mode", &session_t::trace_alloc_mode)
- .def_readwrite("trace_class_mode", &session_t::trace_class_mode)
-
- .def_readwrite("journals", &session_t::journals)
- ;
-}
diff --git a/src/py_transform.cc b/src/py_transform.cc
deleted file mode 100644
index 4ab2e9f6..00000000
--- a/src/py_transform.cc
+++ /dev/null
@@ -1,39 +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.
- */
-
-using namespace boost::python;
-using namespace ledger;
-
-void export_transform()
-{
- class_< repitem_t > ("Transform")
- ;
-}
diff --git a/src/py_value.cc b/src/py_value.cc
deleted file mode 100644
index f85eef1e..00000000
--- a/src/py_value.cc
+++ /dev/null
@@ -1,368 +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.
- */
-
-using namespace boost::python;
-using namespace ledger;
-
-long balance_len(balance_t& bal);
-amount_t balance_getitem(balance_t& bal, int i);
-long balance_pair_len(balance_pair_t& bal_pair);
-amount_t balance_pair_getitem(balance_pair_t& bal_pair, int i);
-
-long value_len(value_t& val)
-{
- switch (val.type) {
- case value_t::BOOLEAN:
- case value_t::INTEGER:
- case value_t::DATETIME:
- case value_t::AMOUNT:
- return 1;
-
- case value_t::BALANCE:
- return balance_len(*((balance_t *) val.data));
-
- case value_t::BALANCE_PAIR:
- return balance_pair_len(*((balance_pair_t *) val.data));
-
- case value_t::STRING:
- case value_t::XML_NODE:
- case value_t::POINTER:
- return 1;
-
- case value_t::SEQUENCE:
- return (*(value_t::sequence_t **) val.data)->size();
-
- default:
- assert(false);
- break;
- }
- assert(false);
- return 0;
-}
-
-amount_t value_getitem(value_t& val, int i)
-{
- std::size_t len = value_len(val);
-
- if (abs(i) >= len) {
- PyErr_SetString(PyExc_IndexError, "Index out of range");
- throw_error_already_set();
- }
-
- switch (val.type) {
- case value_t::BOOLEAN:
- throw_(value_error, "Cannot cast a boolean to an amount");
-
- case value_t::INTEGER:
- return long(val);
-
- case value_t::DATETIME:
- throw_(value_error, "Cannot cast a date/time to an amount");
-
- case value_t::AMOUNT:
- return *((amount_t *) val.data);
-
- case value_t::BALANCE:
- return balance_getitem(*((balance_t *) val.data), i);
-
- case value_t::BALANCE_PAIR:
- return balance_pair_getitem(*((balance_pair_t *) val.data), i);
-
- case value_t::STRING:
- throw_(value_error, "Cannot cast a string to an amount");
-
- case value_t::XML_NODE:
- return (*(xml::node_t **) data)->to_value();
-
- case value_t::POINTER:
- throw_(value_error, "Cannot cast a pointer to an amount");
-
- case value_t::SEQUENCE:
- return (*(value_t::sequence_t **) val.data)[i];
-
- default:
- assert(false);
- break;
- }
- assert(false);
- return 0L;
-}
-
-double py_to_float(value_t& val)
-{
- return double(val);
-}
-
-void export_value()
-{
- class_< value_t > ("value")
- .def(init<value_t>())
- .def(init<balance_pair_t>())
- .def(init<balance_t>())
- .def(init<amount_t>())
- .def(init<string>())
- .def(init<double>())
- .def(init<long>())
- .def(initmoment_t())
-
- .def(self + self)
- .def(self + other<string>())
- .def(self + other<balance_pair_t>())
- .def(self + other<balance_t>())
- .def(self + other<amount_t>())
- .def(self + long())
- .def(self + double())
-
- .def(other<string>() + self)
- .def(other<balance_pair_t>() + self)
- .def(other<balance_t>() + self)
- .def(other<amount_t>() + self)
- .def(long() + self)
- .def(double() + self)
-
- .def(self - self)
- .def(self - other<string>())
- .def(self - other<balance_pair_t>())
- .def(self - other<balance_t>())
- .def(self - other<amount_t>())
- .def(self - long())
- .def(self - double())
-
- .def(other<string>() - self)
- .def(other<balance_pair_t>() - self)
- .def(other<balance_t>() - self)
- .def(other<amount_t>() - self)
- .def(long() - self)
- .def(double() - self)
-
- .def(self * self)
- .def(self * other<string>())
- .def(self * other<balance_pair_t>())
- .def(self * other<balance_t>())
- .def(self * other<amount_t>())
- .def(self * long())
- .def(self * double())
-
- .def(other<string>() * self)
- .def(other<balance_pair_t>() * self)
- .def(other<balance_t>() * self)
- .def(other<amount_t>() * self)
- .def(long() * self)
- .def(double() * self)
-
- .def(self / self)
- .def(self / other<string>())
- .def(self / other<balance_pair_t>())
- .def(self / other<balance_t>())
- .def(self / other<amount_t>())
- .def(self / long())
- .def(self / double())
-
- .def(other<string>() / self)
- .def(other<balance_pair_t>() / self)
- .def(other<balance_t>() / self)
- .def(other<amount_t>() / self)
- .def(long() / self)
- .def(double() / self)
-
- .def(- self)
-
- .def(self += self)
- .def(self += other<string>())
- .def(self += other<balance_pair_t>())
- .def(self += other<balance_t>())
- .def(self += other<amount_t>())
- .def(self += long())
- .def(self += double())
-
- .def(self -= self)
- .def(self -= other<string>())
- .def(self -= other<balance_pair_t>())
- .def(self -= other<balance_t>())
- .def(self -= other<amount_t>())
- .def(self -= long())
- .def(self -= double())
-
- .def(self *= self)
- .def(self *= other<string>())
- .def(self *= other<balance_pair_t>())
- .def(self *= other<balance_t>())
- .def(self *= other<amount_t>())
- .def(self *= long())
- .def(self *= double())
-
- .def(self /= self)
- .def(self /= other<string>())
- .def(self /= other<balance_pair_t>())
- .def(self /= other<balance_t>())
- .def(self /= other<amount_t>())
- .def(self /= long())
- .def(self /= double())
-
- .def(self < self)
- .def(self < other<string>())
- .def(self < other<balance_pair_t>())
- .def(self < other<balance_t>())
- .def(self < other<amount_t>())
- .def(self < long())
- .def(self < othermoment_t())
- .def(self < double())
-
- .def(other<string>() < self)
- .def(other<balance_pair_t>() < self)
- .def(other<balance_t>() < self)
- .def(other<amount_t>() < self)
- .def(long() < self)
- .def(othermoment_t() < self)
- .def(double() < self)
-
- .def(self <= self)
- .def(self <= other<string>())
- .def(self <= other<balance_pair_t>())
- .def(self <= other<balance_t>())
- .def(self <= other<amount_t>())
- .def(self <= long())
- .def(self <= othermoment_t())
- .def(self <= double())
-
- .def(other<string>() <= self)
- .def(other<balance_pair_t>() <= self)
- .def(other<balance_t>() <= self)
- .def(other<amount_t>() <= self)
- .def(long() <= self)
- .def(othermoment_t() <= self)
- .def(double() <= self)
-
- .def(self > self)
- .def(self > other<string>())
- .def(self > other<balance_pair_t>())
- .def(self > other<balance_t>())
- .def(self > other<amount_t>())
- .def(self > long())
- .def(self > othermoment_t())
- .def(self > double())
-
- .def(other<string>() > self)
- .def(other<balance_pair_t>() > self)
- .def(other<balance_t>() > self)
- .def(other<amount_t>() > self)
- .def(long() > self)
- .def(othermoment_t() > self)
- .def(double() > self)
-
- .def(self >= self)
- .def(self >= other<string>())
- .def(self >= other<balance_pair_t>())
- .def(self >= other<balance_t>())
- .def(self >= other<amount_t>())
- .def(self >= long())
- .def(self >= othermoment_t())
- .def(self >= double())
-
- .def(other<string>() >= self)
- .def(other<balance_pair_t>() >= self)
- .def(other<balance_t>() >= self)
- .def(other<amount_t>() >= self)
- .def(long() >= self)
- .def(othermoment_t() >= self)
- .def(double() >= self)
-
- .def(self == self)
- .def(self == other<string>())
- .def(self == other<balance_pair_t>())
- .def(self == other<balance_t>())
- .def(self == other<amount_t>())
- .def(self == long())
- .def(self == othermoment_t())
- .def(self == double())
-
- .def(other<string>() == self)
- .def(other<balance_pair_t>() == self)
- .def(other<balance_t>() == self)
- .def(other<amount_t>() == self)
- .def(long() == self)
- .def(othermoment_t() == self)
- .def(double() == self)
-
- .def(self != self)
- .def(self != other<string>())
- .def(self != other<balance_pair_t>())
- .def(self != other<balance_t>())
- .def(self != other<amount_t>())
- .def(self != long())
- .def(self != othermoment_t())
- .def(self != double())
-
- .def(other<string>() != self)
- .def(other<balance_pair_t>() != self)
- .def(other<balance_t>() != self)
- .def(other<amount_t>() != self)
- .def(long() != self)
- .def(othermoment_t() != self)
- .def(double() != self)
-
- .def(! self)
-
- .def(self_ns::int_(self))
- .def(self_ns::float_(self))
- .def(self_ns::str(self))
-
- .def_readonly("type", &value_t::type)
-
- .def("__abs__", &value_t::abs)
- .def("__len__", value_len)
- .def("__getitem__", value_getitem)
-
- .def("cast", &value_t::cast)
- .def("cost", &value_t::cost)
- .def("price", &value_t::price)
- .def("date", &value_t::date)
- .def("strip_annotations", &value_t::strip_annotations)
- .def("add", &value_t::add, return_internal_reference<>())
- .def("value", &value_t::value)
- .def("round", &value_t::round)
- .def("negate", &value_t::negate)
- .def("write", &value_t::write)
- ;
-
- enum_< value_t::type_t > ("ValueType")
- .value("Boolean", value_t::BOOLEAN)
- .value("Integer", value_t::INTEGER)
- .value("DateTime", value_t::DATETIME)
- .value("Amount", value_t::AMOUNT)
- .value("Balance", value_t::BALANCE)
- .value("BalancePair", value_t::BALANCE_PAIR)
- .value("String", value_t::STRING)
- .value("XmlNode", value_t::XML_NODE)
- .value("Pointer", value_t::POINTER)
- .value("Sequence", value_t::SEQUENCE)
- ;
-}
diff --git a/src/py_xpath.cc b/src/py_xpath.cc
deleted file mode 100644
index 55a68b12..00000000
--- a/src/py_xpath.cc
+++ /dev/null
@@ -1,110 +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.
- */
-
-using namespace boost::python;
-using namespace ledger;
-
-value_t py_calc_1(xpath_t::op_t& xpath_t, const details_t& item)
-{
- value_t result;
- xpath_t.calc(result, item);
- return result;
-}
-
-template <typename T>
-value_t py_calc(xpath_t::op_t& xpath_t, const T& item)
-{
- value_t result;
- xpath_t.calc(result, details_t(item));
- return result;
-}
-
-xpath_t::op_t * py_parse_xpath_t_1(const string& str)
-{
- return parse_xpath_t(str);
-}
-
-#define EXC_TRANSLATOR(type) \
- void exc_translate_ ## type(const type& err) { \
- PyErr_SetString(PyExc_RuntimeError, err.what()); \
- }
-
-EXC_TRANSLATOR(xpath_t_error)
-EXC_TRANSLATOR(calc_error)
-#if 0
-EXC_TRANSLATOR(mask_error)
-#endif
-
-void export_xpath()
-{
- class_< details_t > ("Details", init<const entry_t&>())
- .def(init<const transaction_t&>())
- .def(init<const account_t&>())
- .add_property("entry",
- make_getter(&details_t::entry,
- return_value_policy<reference_existing_object>()))
- .add_property("xact",
- make_getter(&details_t::xact,
- return_value_policy<reference_existing_object>()))
- .add_property("account",
- make_getter(&details_t::account,
- return_value_policy<reference_existing_object>()))
- ;
-
- class_< xpath_t::op_t > ("ValueExpr", init<xpath_t::op_t::kind_t>())
- .def("calc", py_calc_1)
- .def("calc", py_calc<account_t>)
- .def("calc", py_calc<entry_t>)
- .def("calc", py_calc<transaction_t>)
- ;
-
- def("parse_xpath_t", py_parse_xpath_t_1,
- return_value_policy<manage_new_object>());
-
- class_< item_predicate<transaction_t> >
- ("TransactionPredicate", init<string>())
- .def("__call__", &item_predicate<transaction_t>::operator())
- ;
-
- class_< item_predicate<account_t> >
- ("AccountPredicate", init<string>())
- .def("__call__", &item_predicate<account_t>::operator())
- ;
-
-#define EXC_TRANSLATE(type) \
- register_error_translator<type>(&exc_translate_ ## type);
-
- EXC_TRANSLATE(xpath_t_error);
- EXC_TRANSLATE(calc_error);
-#if 0
- EXC_TRANSLATE(mask_error);
-#endif
-}
diff --git a/src/qif.cc b/src/qif.cc
deleted file mode 100644
index 20d7d2e1..00000000
--- a/src/qif.cc
+++ /dev/null
@@ -1,274 +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 "qif.h"
-#include "journal.h"
-
-namespace ledger {
-
-#define MAX_LINE 1024
-
-static char line[MAX_LINE + 1];
-static path pathname;
-static unsigned int src_idx;
-static unsigned int linenum;
-
-static inline char * get_line(std::istream& in) {
- in.getline(line, MAX_LINE);
- int len = std::strlen(line);
- if (line[len - 1] == '\r')
- line[len - 1] = '\0';
- linenum++;
- return line;
-}
-
-bool qif_parser_t::test(std::istream& in) const
-{
- char magic[sizeof(unsigned int) + 1];
- in.read(magic, sizeof(unsigned int));
- magic[sizeof(unsigned int)] = '\0';
- in.clear();
- in.seekg(0, std::ios::beg);
-
- return (std::strcmp(magic, "!Typ") == 0 ||
- std::strcmp(magic, "\n!Ty") == 0 ||
- std::strcmp(magic, "\r\n!T") == 0);
-}
-
-unsigned int qif_parser_t::parse(std::istream& in,
- journal_t * journal,
- account_t * master,
- const optional<path>&)
-{
- std::auto_ptr<entry_t> entry;
- std::auto_ptr<amount_t> amount;
-
- transaction_t * xact;
- unsigned int count = 0;
- account_t * misc = NULL;
- commodity_t * def_commodity = NULL;
- bool saw_splits = false;
- bool saw_category = false;
- transaction_t * total = NULL;
-
- entry.reset(new entry_t);
- xact = new transaction_t(master);
- entry->add_transaction(xact);
-
- pathname = journal->sources.back();
- src_idx = journal->sources.size() - 1;
- linenum = 1;
-
- unsigned long beg_pos = 0;
- unsigned long beg_line = 0;
-
-#define SET_BEG_POS_AND_LINE() \
- if (! beg_line) { \
- beg_pos = in.tellg(); \
- beg_line = linenum; \
- }
-
- while (in.good() && ! in.eof()) {
- char c;
- in.get(c);
- switch (c) {
- case ' ':
- case '\t':
- if (peek_next_nonws(in) != '\n') {
- get_line(in);
- throw_(parse_error, "Line begins with whitespace");
- }
- // fall through...
-
- case '\n':
- linenum++;
- case '\r': // skip blank lines
- break;
-
- case '!':
- get_line(in);
-
- if (std::strcmp(line, "Type:Invst") == 0 ||
- std::strcmp(line, "Account") == 0 ||
- std::strcmp(line, "Type:Cat") == 0 ||
- std::strcmp(line, "Type:Class") == 0 ||
- std::strcmp(line, "Type:Memorized") == 0)
- throw_(parse_error,
- "QIF files of type " << line << " are not supported.");
- break;
-
- case 'D':
- SET_BEG_POS_AND_LINE();
- get_line(in);
- entry->_date = parse_datetime(line);
- break;
-
- case 'T':
- case '$': {
- SET_BEG_POS_AND_LINE();
- get_line(in);
- xact->amount = amount_t(line);
-
- unsigned char flags = xact->amount->commodity().flags();
- unsigned char prec = xact->amount->commodity().precision();
-
- if (! def_commodity) {
- def_commodity = amount_t::current_pool->find_or_create("$");
- assert(def_commodity);
- }
- xact->amount->set_commodity(*def_commodity);
-
- def_commodity->add_flags(flags);
- if (prec > def_commodity->precision())
- def_commodity->set_precision(prec);
-
- if (c == '$') {
- saw_splits = true;
- xact->amount->in_place_negate();
- } else {
- total = xact;
- }
- break;
- }
-
- case 'C':
- SET_BEG_POS_AND_LINE();
- c = in.peek();
- if (c == '*' || c == 'X') {
- in.get(c);
- xact->state = transaction_t::CLEARED;
- }
- break;
-
- case 'N':
- SET_BEG_POS_AND_LINE();
- get_line(in);
- entry->code = line;
- break;
-
- case 'P':
- case 'M':
- case 'L':
- case 'S':
- case 'E': {
- SET_BEG_POS_AND_LINE();
- get_line(in);
-
- switch (c) {
- case 'P':
- entry->payee = line;
- break;
-
- case 'S':
- xact = new transaction_t(NULL);
- entry->add_transaction(xact);
- // fall through...
- case 'L': {
- int len = std::strlen(line);
- if (line[len - 1] == ']')
- line[len - 1] = '\0';
- xact->account = journal->find_account(line[0] == '[' ?
- line + 1 : line);
- if (c == 'L')
- saw_category = true;
- break;
- }
-
- case 'M':
- case 'E':
- xact->note = line;
- break;
- }
- break;
- }
-
- case 'A':
- SET_BEG_POS_AND_LINE();
- // jww (2004-08-19): these are ignored right now
- get_line(in);
- break;
-
- case '^': {
- account_t * other;
- if (xact->account == master) {
- if (! misc)
- misc = journal->find_account("Miscellaneous");
- other = misc;
- } else {
- other = master;
- }
-
- if (total && saw_category) {
- if (! saw_splits)
- total->amount->in_place_negate(); // negate, to show correct flow
- else
- total->account = other;
- }
-
- if (! saw_splits) {
- transaction_t * nxact = new transaction_t(other);
- // The amount doesn't need to be set because the code below
- // will balance this transaction against the other.
- entry->add_transaction(nxact);
- }
-
- if (journal->add_entry(entry.get())) {
- entry->src_idx = src_idx;
- entry->beg_pos = beg_pos;
- entry->beg_line = beg_line;
- entry->end_pos = in.tellg();
- entry->end_line = linenum;
- entry.release();
- count++;
- }
-
- // reset things for the next entry
- entry.reset(new entry_t);
- xact = new transaction_t(master);
- entry->add_transaction(xact);
-
- saw_splits = false;
- saw_category = false;
- total = NULL;
- beg_line = 0;
- break;
- }
-
- default:
- get_line(in);
- break;
- }
- }
-
- return count;
-}
-
-} // namespace ledger
diff --git a/src/qif.h b/src/qif.h
deleted file mode 100644
index 6cce6520..00000000
--- a/src/qif.h
+++ /dev/null
@@ -1,52 +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 _QIF_H
-#define _QIF_H
-
-#include "parser.h"
-
-namespace ledger {
-
-class qif_parser_t : public parser_t
-{
- public:
- virtual bool test(std::istream& in) const;
-
- virtual unsigned int parse(std::istream& in,
- journal_t * journal,
- account_t * master = NULL,
- const optional<path>& original = none);
-};
-
-} // namespace ledger
-
-#endif // _QIF_H
diff --git a/src/quotes.cc b/src/quotes.cc
deleted file mode 100644
index 07417800..00000000
--- a/src/quotes.cc
+++ /dev/null
@@ -1,117 +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 "quotes.h"
-
-namespace ledger {
-
-optional<amount_t>
-quotes_by_script::operator()(commodity_t& commodity,
- const optional<moment_t>& date,
- const optional<moment_t>& moment,
- const optional<moment_t>& last)
-{
- LOGGER("quotes.download");
-
- IF_DEBUG_() {
- DEBUG_("commodity: " << commodity.symbol());
- DEBUG_(" now: " << now);
- if (date)
- DEBUG_(" date: " << date);
- if (moment)
- DEBUG_(" moment: " << moment);
- if (last)
- DEBUG_(" last: " << last);
- if (commodity.history())
- DEBUG_("last_lookup: " << commodity.history()->last_lookup);
- }
- DEBUG_("pricing_leeway is " << pricing_leeway);
-
- if ((commodity.history() &&
- (now - commodity.history()->last_lookup) < pricing_leeway) ||
- (last && (now - *last) < pricing_leeway) ||
- (moment && date && *moment > *date &&
- (*moment - *date) <= pricing_leeway))
- return none;
-
- DEBUG_("downloading quote for symbol " << commodity.symbol());
-
- char buf[256];
- buf[0] = '\0';
-
- bool success = true;
-
- if (FILE * fp = popen((string("getquote \"") +
- commodity.base_symbol() + "\"").c_str(), "r")) {
- if (feof(fp) || ! fgets(buf, 255, fp))
- success = false;
- if (pclose(fp) != 0)
- success = false;
- } else {
- success = false;
- }
-
- if (success && buf[0]) {
- char * p = strchr(buf, '\n');
- if (p) *p = '\0';
-
- DEBUG_("downloaded quote: " << buf);
-
- amount_t price;
- price.parse(buf);
- commodity.add_price(now, price);
-
- commodity.history()->last_lookup = now;
- cache_dirty = true;
-
- assert(! price_db.empty());
-
-#if defined(__GNUG__) && __GNUG__ < 3
- ofstream database(price_db, ios::out | ios::app);
-#else
- ofstream database(price_db, std::ios_base::out | std::ios_base::app);
-#endif
-#if 0
- // jww (2007-04-18): Need to convert to local time and print
- // here, print with UTC timezone specifier
- database << "P " << now.to_string("%Y/%m/%d %H:%M:%S")
- << " " << commodity.symbol << " " << price << endl;
-#endif
- return price;
- } else {
- throw_(download_error,
- "Failed to download price for '" << commodity.symbol() <<
- "' (command: \"getquote " << commodity.base_symbol() << "\")");
- }
- return none;
-}
-
-} // namespace ledger
diff --git a/src/reconcile.cc b/src/reconcile.cc
deleted file mode 100644
index 0b623407..00000000
--- a/src/reconcile.cc
+++ /dev/null
@@ -1,31 +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.
- */
-
diff --git a/src/reconcile.h b/src/reconcile.h
deleted file mode 100644
index 0b623407..00000000
--- a/src/reconcile.h
+++ /dev/null
@@ -1,31 +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.
- */
-
diff --git a/src/register.cc b/src/register.cc
index d3843887..98aafee1 100644
--- a/src/register.cc
+++ b/src/register.cc
@@ -125,15 +125,12 @@ string abbreviate(const string& str,
static void scan_for_transactions(std::ostream& out, const xml::node_t * node)
{
+#if 0
if (! node->has_flags(XML_NODE_IS_PARENT))
return;
-
- const xml::parent_node_t * parent = node->as_parent_node();
- for (const xml::node_t * child = parent->children();
- child;
- child = child->next)
- if (child->name_id == xml::document_t::TRANSACTION) {
+ foreach (const xml::node_t * child, node->as_parent_node()) {
+ if (child->name_id == xml::TRANSACTION_NODE) {
const xml::transaction_node_t * xact_node =
dynamic_cast<const xml::transaction_node_t *>(child);
assert(xact_node);
@@ -154,13 +151,14 @@ static void scan_for_transactions(std::ostream& out, const xml::node_t * node)
} else {
scan_for_transactions(out, child);
}
+#endif
}
void register_command::print_document(std::ostream& out,
xml::document_t * doc)
{
#if 1
- scan_for_transactions(out, doc->top);
+ scan_for_transactions(out, doc);
out.flush();
#else
value_t nodelist;
diff --git a/src/report.h b/src/report.h
index d6cfef3c..51ee9386 100644
--- a/src/report.h
+++ b/src/report.h
@@ -88,7 +88,9 @@ class report_t : public xml::xpath_t::scope_t
//
void eval(const string& expr) {
+#if 0
xml::xpath_t(expr).compile((xml::document_t *)NULL, this);
+#endif
}
void option_eval(value_t&, xml::xpath_t::scope_t * locals) {
eval(locals->args[0].as_string());
diff --git a/src/system.hh b/src/system.hh
index 217b1235..1c645794 100644
--- a/src/system.hh
+++ b/src/system.hh
@@ -146,6 +146,8 @@ extern "C" {
#include <boost/multi_index/hashed_index.hpp>
#include <boost/multi_index/key_extractors.hpp>
#include <boost/multi_index/ordered_index.hpp>
+#include <boost/multi_index/random_access_index.hpp>
+#include <boost/multi_index/sequenced_index.hpp>
#include <boost/multi_index_container.hpp>
#include <boost/operators.hpp>
#include <boost/optional.hpp>
diff --git a/src/textual.cc b/src/textual.cc
index 914b63c3..82c8fcbf 100644
--- a/src/textual.cc
+++ b/src/textual.cc
@@ -33,13 +33,15 @@
namespace ledger {
+using namespace xml;
+
#define MAX_LINE 1024
-typedef xml::builder_t::position_t position_t;
+typedef builder_t::position_t position_t;
-void parse_transaction(xml::builder_t& builder,
- char * line,
- position_t& end_of_line)
+void parse_transaction(builder_t& builder,
+ char * line,
+ position_t& end_of_line)
{
// First cut up the input line into its various parts.
@@ -125,7 +127,7 @@ void parse_transaction(xml::builder_t& builder,
builder.end_node(TRANSACTION_NODE, end_of_line);
}
-bool parse_transactions(std::istream& in, xml::builder_t& builder)
+bool parse_transactions(std::istream& in, builder_t& builder)
{
TRACE_START(entry_xacts, 1, "Time spent parsing transactions:");
@@ -155,10 +157,10 @@ bool parse_transactions(std::istream& in, xml::builder_t& builder)
return added;
}
-void parse_entry(std::istream& in,
- xml::builder_t& builder,
- char * line,
- position_t& end_of_line)
+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:");
@@ -226,7 +228,7 @@ void parse_entry(std::istream& in,
builder.push_attr(DATE_ATTR, date);
if (date_eff)
- builder.push_attr(DATE_EFF_ATTR, date_eff);
+ builder.push_attr(EFF_DATE_ATTR, date_eff);
if (statep) {
switch (*statep) {
@@ -273,9 +275,9 @@ bool textual_parser_t::test(std::istream& in) const
return true;
}
-void textual_parser_t::parse(std::istream& in,
- const path& pathname,
- xml::builder_t& builder)
+void textual_parser_t::parse(std::istream& in,
+ const path& pathname,
+ builder_t& builder)
{
TRACE_START(parsing_total, 1, "Total time spent parsing text:");
diff --git a/src/value.cc b/src/value.cc
index 63719266..12c6379d 100644
--- a/src/value.cc
+++ b/src/value.cc
@@ -30,7 +30,7 @@
*/
#include "value.h"
-#include "xml.h"
+#include "node.h"
namespace ledger {
@@ -1610,7 +1610,7 @@ std::ostream& operator<<(std::ostream& out, const value_t& val)
if (val.as_xml_node()->has_flags(XML_NODE_IS_PARENT))
out << '<' << val.as_xml_node()->name() << '>';
else
- out << val.as_xml_node()->text();
+ out << val.as_xml_node()->to_value();
break;
case value_t::POINTER:
diff --git a/src/xml.cc b/src/xml.cc
deleted file mode 100644
index 9b14f97c..00000000
--- a/src/xml.cc
+++ /dev/null
@@ -1,584 +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 "xml.h"
-#include "journal.h"
-
-namespace ledger {
-namespace xml {
-
-const std::size_t document_t::ledger_builtins_size = 12;
-const char * document_t::ledger_builtins[] = {
- "account",
- "account-path",
- "amount",
- "code",
- "commodity",
- "entries",
- "entry",
- "journal",
- "name",
- "note",
- "payee",
- "transaction"
-};
-
-document_t::~document_t()
-{
- TRACE_DTOR(xml::document_t);
- if (top && top != &stub)
- checked_delete(top);
-}
-
-void document_t::set_top(node_t * _top)
-{
- if (top && top != &stub)
- checked_delete(top);
- top = _top;
-}
-
-int document_t::register_name(const string& name)
-{
- int index = lookup_name_id(name);
- if (index != -1)
- return index;
-
- names.push_back(name);
- index = names.size() - 1;
-
- DEBUG("xml.lookup", this << " Inserting name: " << names.back());
-
- std::pair<names_map::iterator, bool> result =
- names_index.insert(names_map::value_type(names.back(), index));
- assert(result.second);
-
- return index + 1000;
-}
-
-int document_t::lookup_name_id(const string& name) const
-{
- int id;
- if ((id = lookup_builtin_id(name)) != -1)
- return id;
-
- DEBUG("xml.lookup", this << " Finding name: " << name);
-
- names_map::const_iterator i = names_index.find(name);
- if (i != names_index.end())
- return (*i).second + 1000;
-
- return -1;
-}
-
-int document_t::lookup_builtin_id(const string& name)
-{
- int first = 0;
- int last = (int)ledger_builtins_size;
-
- while (first <= last) {
- int mid = (first + last) / 2; // compute mid point.
-
- int result;
- if ((result = (int)name[0] - (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 mid + 10;
- }
-
- return -1;
-}
-
-const char * document_t::lookup_name(int id) const
-{
- if (id < 1000) {
- switch (id) {
- case CURRENT:
- return "CURRENT";
- case PARENT:
- return "PARENT";
- case ROOT:
- return "ROOT";
- case ALL:
- return "ALL";
- default:
- assert(id >= 10);
- return ledger_builtins[id - 10];
- }
- } else {
- return names[id - 1000].c_str();
- }
-}
-
-void document_t::print(std::ostream& out) const
-{
- if (top) {
- out << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>\n";
- top->print(out);
- }
-}
-
-#ifndef THREADSAFE
-document_t * node_t::document = NULL;
-#endif
-
-node_t::node_t(document_t * _document, parent_node_t * _parent, flags_t _flags)
- : supports_flags<>(_flags), name_id(0), parent(_parent),
- next(NULL), prev(NULL), attrs(NULL)
-{
- TRACE_CTOR(node_t, "document_t *, node_t *");
- document = _document;
- if (document && ! document->top)
- document->set_top(this);
- if (parent)
- parent->add_child(this);
-}
-
-void node_t::extract()
-{
- if (prev)
- prev->next = next;
-
- if (parent) {
- if (parent->_children == this)
- parent->_children = next;
-
- if (parent->_last_child == this)
- parent->_last_child = prev;
-
- parent = NULL;
- }
-
- if (next)
- next->prev = prev;
-
- next = NULL;
- prev = NULL;
-}
-
-const char * node_t::name() const
-{
- return document->lookup_name(name_id);
-}
-
-int node_t::set_name(const char * _name)
-{
- name_id = document->register_name(_name);
- return name_id;
-}
-
-node_t * node_t::lookup_child(const char * _name) const
-{
- int id = document->lookup_name_id(_name);
- return lookup_child(id);
-}
-
-node_t * node_t::lookup_child(const string& _name) const
-{
- int id = document->lookup_name_id(_name);
- return lookup_child(id);
-}
-
-void parent_node_t::clear()
-{
- node_t * child = _children;
- while (child) {
- node_t * tnext = child->next;
- checked_delete(child);
- child = tnext;
- }
-}
-
-void parent_node_t::add_child(node_t * node)
-{
- // It is important that this node is not called before children(),
- // otherwise, this node will not get auto-populated.
- if (_children == NULL) {
- assert(_last_child == NULL);
- _children = node;
- node->prev = NULL;
- } else {
- assert(_last_child != NULL);
- _last_child->next = node;
- node->prev = _last_child;
- }
-
- node->parent = this;
-
- while (node->next) {
- node_t * next_node = node->next;
- assert(next_node->prev == node);
- next_node->parent = this;
- node = next_node;
- }
-
- _last_child = node;
-}
-
-void parent_node_t::print(std::ostream& out, int depth) const
-{
- for (int i = 0; i < depth; i++) out << " ";
- out << '<' << name() << ">\n";
-
- for (node_t * child = children(); child; child = child->next)
- child->print(out, depth + 1);
-
- for (int i = 0; i < depth; i++) out << " ";
- out << "</" << name() << ">\n";
-}
-
-void terminal_node_t::print(std::ostream& out, int depth) const
-{
- for (int i = 0; i < depth; i++) out << " ";
-
- if (data.empty()) {
- out << '<' << name() << " />\n";
- } else {
- out << '<' << name() << ">"
- << text()
- << "</" << name() << ">\n";
- }
-}
-
-#if defined(HAVE_EXPAT) || defined(HAVE_XMLPARSE)
-
-template <typename T>
-inline T * create_node(document_t::parser_t * parser)
-{
- T * node = new T(parser->document, parser->node_stack.empty() ?
- NULL : parser->node_stack.front());
-
- node->set_name(parser->pending);
- node->attrs = parser->pending_attrs;
-
- parser->pending = NULL;
- parser->pending_attrs = NULL;
-
- return node;
-}
-
-static void startElement(void *userData, const char *name, const char **attrs)
-{
- document_t::parser_t * parser = static_cast<document_t::parser_t *>(userData);
-
- DEBUG("xml.parse", "startElement(" << name << ")");
-
- if (parser->pending) {
- parent_node_t * node = create_node<parent_node_t>(parser);
- if (parser->node_stack.empty())
- parser->document->top = node;
- parser->node_stack.push_front(node);
- }
-
- parser->pending = name;
-
- if (attrs) {
- for (const char ** p = attrs; *p; p += 2) {
- if (! parser->pending_attrs)
- parser->pending_attrs = new node_t::attrs_map;
-
- std::pair<node_t::attrs_map::iterator, bool> result
- = parser->pending_attrs->insert
- (node_t::attrs_map::value_type(*p, *(p + 1)));
- assert(result.second);
- }
- }
-}
-
-static void endElement(void *userData, const char *name)
-{
- document_t::parser_t * parser = static_cast<document_t::parser_t *>(userData);
-
- DEBUG("xml.parse", "endElement(" << name << ")");
-
- if (parser->pending) {
- terminal_node_t * node = create_node<terminal_node_t>(parser);
- if (parser->node_stack.empty()) {
- parser->document->top = node;
- return;
- }
- }
- else if (! parser->handled_data) {
- assert(! parser->node_stack.empty());
- parser->node_stack.pop_front();
- }
- else {
- parser->handled_data = false;
- }
-}
-
-static void dataHandler(void *userData, const char *s, int len)
-{
- document_t::parser_t * parser = static_cast<document_t::parser_t *>(userData);
-
- DEBUG("xml.parse", "dataHandler(" << string(s, len) << ")");
-
- bool all_whitespace = true;
- for (int i = 0; i < len; i++) {
- if (! std::isspace(s[i])) {
- all_whitespace = false;
- break;
- }
- }
-
- // jww (2006-09-28): I currently do not support text nodes within a
- // node that has children.
-
- if (! all_whitespace) {
- terminal_node_t * node = create_node<terminal_node_t>(parser);
-
- node->set_text(string(s, len));
- parser->handled_data = true;
-
- if (parser->node_stack.empty()) {
- parser->document->top = node;
- return;
- }
- }
-}
-
-bool document_t::parser_t::test(std::istream& in) const
-{
- char buf[80];
-
- in.getline(buf, 79);
- if (std::strncmp(buf, "<?xml", 5) != 0) {
- in.clear();
- in.seekg(0, std::ios::beg);
- return false;
- }
-
- in.clear();
- in.seekg(0, std::ios::beg);
- return true;
-}
-
-document_t * document_t::parser_t::parse(std::istream& in)
-{
- std::auto_ptr<document_t> doc(new document_t);
-
- document = doc.get();
-
- parser = XML_ParserCreate(NULL);
-
- XML_SetElementHandler(parser, startElement, endElement);
- XML_SetCharacterDataHandler(parser, dataHandler);
- XML_SetUserData(parser, this);
-
- char buf[BUFSIZ];
- while (! in.eof()) {
- in.getline(buf, BUFSIZ - 1);
- std::strcat(buf, "\n");
- bool result;
- try {
- result = XML_Parse(parser, buf, std::strlen(buf), in.eof());
- }
- catch (const std::exception& err) {
- //unsigned long line = XML_GetCurrentLineNumber(parser) - offset++;
- XML_ParserFree(parser);
- throw_(parse_error, err.what());
- }
-
- if (! have_error.empty()) {
- //unsigned long line = XML_GetCurrentLineNumber(parser) - offset++;
-#if 0
- // jww (2007-04-26): What is this doing??
- parse_error err(have_error);
- std::cerr << "Error: " << err.what() << std::endl;
-#endif
- have_error = "";
- }
-
- if (! result) {
- //unsigned long line = XML_GetCurrentLineNumber(parser) - offset++;
- const char * err = XML_ErrorString(XML_GetErrorCode(parser));
- XML_ParserFree(parser);
- throw_(parse_error, err);
- }
- }
-
- XML_ParserFree(parser);
-
- document = NULL;
- return doc.release();
-}
-
-#endif // HAVE_EXPAT || HAVE_XMLPARSE
-
-node_t * commodity_node_t::children() const
-{
- // jww (2007-04-19): Need to report the commodity and its details
- return NULL;
-}
-
-node_t * amount_node_t::children() const
-{
- // jww (2007-04-19): Need to report the quantity and commodity
- return NULL;
-}
-
-node_t * transaction_node_t::children() const
-{
- return parent_node_t::children();
-}
-
-node_t * transaction_node_t::lookup_child(int _name_id) const
-{
- switch (_name_id) {
- case document_t::PAYEE:
- payee_virtual_node = new terminal_node_t(document);
- payee_virtual_node->set_text(transaction->entry->payee);
- return payee_virtual_node;
-
- case document_t::ACCOUNT:
- return new account_node_t(document, transaction->account,
- const_cast<transaction_node_t *>(this));
- }
- return NULL;
-}
-
-value_t transaction_node_t::to_value() const
-{
- if (transaction->amount)
- return *transaction->amount;
- else
- return value_t();
-}
-
-node_t * entry_node_t::children() const
-{
- if (! _children)
- for (transactions_list::iterator i = entry->transactions.begin();
- i != entry->transactions.end();
- i++)
- new transaction_node_t(document, *i, const_cast<entry_node_t *>(this));
-
- return parent_node_t::children();
-}
-
-node_t * entry_node_t::lookup_child(int _name_id) const
-{
- switch (_name_id) {
- case document_t::CODE: {
- if (! entry->code)
- break;
-
- // jww (2007-04-20): I have to save this and then delete it later
- terminal_node_t * code_node =
- new terminal_node_t(document, const_cast<entry_node_t *>(this));
- code_node->set_name(document_t::CODE);
- code_node->set_text(*entry->code);
- return code_node;
- }
-
- case document_t::PAYEE: {
- // jww (2007-04-20): I have to save this and then delete it later
- terminal_node_t * payee_node =
- new terminal_node_t(document, const_cast<entry_node_t *>(this));
- payee_node->set_name(document_t::PAYEE);
- payee_node->set_text(entry->payee);
- return payee_node;
- }
- }
- return NULL;
-}
-
-node_t * account_node_t::children() const
-{
- if (! _children) {
- if (! account->name.empty()) {
- terminal_node_t * name_node =
- new terminal_node_t(document, const_cast<account_node_t *>(this));
- name_node->set_name(document_t::NAME);
- name_node->set_text(account->name);
- }
-
- if (account->note) {
- terminal_node_t * note_node =
- new terminal_node_t(document, const_cast<account_node_t *>(this));
- note_node->set_name(document_t::NOTE);
- note_node->set_text(*account->note);
- }
-
- for (accounts_map::iterator i = account->accounts.begin();
- i != account->accounts.end();
- i++)
- new account_node_t(document, (*i).second, const_cast<account_node_t *>(this));
- }
- return parent_node_t::children();
-}
-
-node_t * journal_node_t::children() const
-{
- if (! _children) {
-#if 0
- account_node_t * master_account =
- new account_node_t(document, journal->master, const_cast<journal_node_t *>(this));
-#endif
-
- parent_node_t * entries =
- new parent_node_t(document, const_cast<journal_node_t *>(this));
- entries->set_name(document_t::ENTRIES);
-
- for (entries_list::iterator i = journal->entries.begin();
- i != journal->entries.end();
- i++)
- new entry_node_t(document, *i, const_cast<journal_node_t *>(this));
- }
- return parent_node_t::children();
-}
-
-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;
- }
- }
-}
-
-} // namespace xml
-} // namespace ledger
diff --git a/src/xpath.cc b/src/xpath.cc
index a59126ae..caa7806a 100644
--- a/src/xpath.cc
+++ b/src/xpath.cc
@@ -562,7 +562,7 @@ bool xpath_t::function_scope_t::resolve(const string& name,
case 't':
if (name == "text") {
if (value->type == value_t::XML_NODE)
- result.set_string(value->as_xml_node()->text());
+ result = value->as_xml_node()->to_value();
else
throw_(calc_error, "Attempt to call text() on a non-node value");
return true;
@@ -679,14 +679,14 @@ xpath_t::parse_value_term(std::istream& in, unsigned short tflags) const
#endif
string ident = tok.value.as_string();
- int id = -1;
if (std::isdigit(ident[0])) {
node.reset(new op_t(op_t::ARG_INDEX));
node->arg_index = lexical_cast<unsigned int>(ident.c_str());
}
- else if ((id = document_t::lookup_builtin_id(ident)) != -1) {
+ else if (optional<node_t::nameid_t> id =
+ document_t::lookup_builtin_id(ident)) {
node.reset(new op_t(op_t::NODE_ID));
- node->name_id = id;
+ node->name_id = *id;
}
else {
node.reset(new op_t(op_t::NODE_NAME));
@@ -1213,11 +1213,8 @@ void xpath_t::op_t::find_values(value_t * context, scope_t * scope,
if (recursive) {
if (context->type == value_t::XML_NODE) {
node_t * ptr = context->as_xml_node();
- if (ptr->has_flags(XML_NODE_IS_PARENT)) {
- parent_node_t * parent = static_cast<parent_node_t *>(ptr);
- for (node_t * node = parent->children();
- node;
- node = node->next) {
+ if (ptr->is_parent_node()) {
+ foreach (node_t * node, ptr->as_parent_node()) {
value_t temp(node);
find_values(&temp, scope, result_seq, recursive);
}
@@ -1308,8 +1305,8 @@ xpath_t::op_t * xpath_t::op_t::compile(value_t * context, scope_t * scope,
case document_t::PARENT:
if (context->type != value_t::XML_NODE)
throw_(compile_error, "Referencing parent node from a non-node value");
- else if (context->as_xml_node()->parent)
- return wrap_value(context->as_xml_node()->parent)->acquire();
+ else if (context->as_xml_node()->parent())
+ return wrap_value(&*context->as_xml_node()->parent())->acquire();
else
throw_(compile_error, "Referencing parent node from the root node");
@@ -1317,15 +1314,14 @@ xpath_t::op_t * xpath_t::op_t::compile(value_t * context, scope_t * scope,
if (context->type != value_t::XML_NODE)
throw_(compile_error, "Referencing root node from a non-node value");
else
- return wrap_value(context->as_xml_node()->document->top)->acquire();
+ return wrap_value(&context->as_xml_node()->document())->acquire();
case document_t::ALL: {
if (context->type != value_t::XML_NODE)
throw_(compile_error, "Referencing child nodes from a non-node value");
- parent_node_t * parent = context->as_xml_node()->as_parent_node();
value_t::sequence_t nodes;
- for (node_t * node = parent->children(); node; node = node->next)
+ foreach (node_t * node, context->as_xml_node()->as_parent_node())
nodes.push_back(node);
return wrap_value(nodes)->acquire();
@@ -1343,37 +1339,37 @@ xpath_t::op_t * xpath_t::op_t::compile(value_t * context, scope_t * scope,
// First, look up the symbol as a node name within the current
// context. If any exist, then return the set of names.
- value_t::sequence_t nodes;
+ if (ptr->is_parent_node()) {
+ value_t::sequence_t nodes;
- if (ptr->has_flags(XML_NODE_IS_PARENT)) {
- parent_node_t * parent = static_cast<parent_node_t *>(ptr);
- for (node_t * node = parent->children();
- node;
- node = node->next) {
+ foreach (node_t * node, ptr->as_parent_node()) {
if ((kind == NODE_NAME &&
std::strcmp(name->c_str(), node->name()) == 0) ||
- (kind == NODE_ID && name_id == node->name_id))
+ (kind == NODE_ID && name_id == node->name_id()))
nodes.push_back(node);
}
+ return wrap_value(nodes)->acquire();
}
- return wrap_value(nodes)->acquire();
} else {
assert(ptr);
- int id = ptr->document->lookup_name_id(*name);
- if (id != -1) {
+ if (optional<node_t::nameid_t> id =
+ ptr->document().lookup_name_id(*name)) {
op_t * node = new_node(NODE_ID);
- node->name_id = id;
+ node->name_id = *id;
return node->acquire();
}
}
}
return acquire();
- case ATTR_NAME: {
- // jww (2006-09-29): Attrs should map strings to values, not strings
- const char * value = context->as_xml_node()->get_attr(name->c_str());
- return wrap_value(value)->acquire();
- }
+ case ATTR_NAME:
+ if (optional<node_t::nameid_t> id =
+ context->as_xml_node()->document().lookup_name_id(*name)) {
+ optional<const string&> value = context->as_xml_node()->get_attr(*id);
+ if (value)
+ return wrap_value(*value)->acquire();
+ }
+ return acquire();
case VAR_NAME:
case FUNC_NAME:
@@ -1903,23 +1899,16 @@ xpath_t::op_t * xpath_t::op_t::compile(value_t * context, scope_t * scope,
return NULL;
}
-void xpath_t::calc(value_t& result, node_t * node, scope_t * scope) const
+void xpath_t::calc(value_t& result, node_t& node, scope_t * scope) const
{
#if 0
try {
#endif
- if (node) {
- value_t context_node(node);
- xpath_t final(ptr->compile(&context_node, scope, true));
- // jww (2006-09-09): Give a better error here if this is not
- // actually a value
- final->get_value(result);
- } else {
- std::auto_ptr<terminal_node_t> fake_node(new terminal_node_t(NULL));
- value_t context_node(fake_node.get());
- xpath_t final(ptr->compile(&context_node, scope, true));
- final->get_value(result);
- }
+ value_t context_node(&node);
+ xpath_t final(ptr->compile(&context_node, scope, true));
+ // jww (2006-09-09): Give a better error here if this is not
+ // actually a value
+ final->get_value(result);
#if 0
}
catch (error * err) {
@@ -2041,11 +2030,7 @@ bool xpath_t::op_t::print(std::ostream& out,
break;
case NODE_ID:
-#ifdef THREADSAFE
out << '%' << name_id;
-#else
- out << node_t::document->lookup_name(name_id);
-#endif
break;
case NODE_NAME:
@@ -2331,11 +2316,7 @@ void xpath_t::op_t::dump(std::ostream& out, const int depth) const
break;
case NODE_ID:
-#ifdef THREADSAFE
out << "NODE_ID - " << name_id;
-#else
- out << "NODE_ID - " << node_t::document->lookup_name(name_id);
-#endif
break;
case ATTR_NAME:
diff --git a/src/xpath.h b/src/xpath.h
index a7e2dea0..8819d49e 100644
--- a/src/xpath.h
+++ b/src/xpath.h
@@ -32,7 +32,7 @@
#ifndef _XPATH_H
#define _XPATH_H
-#include "xml.h"
+#include "document.h"
namespace ledger {
namespace xml {
@@ -123,8 +123,7 @@ public:
void (T::*_mptr)(value_t& result))
: functor_t(_name, false), ptr(_ptr), mptr(_mptr) {}
- virtual void operator()(value_t& result,
- scope_t * locals = NULL) {
+ virtual void operator()(value_t& result, scope_t * locals = NULL) {
assert(ptr);
assert(mptr);
assert(locals || locals == NULL);
@@ -430,7 +429,7 @@ public:
string * name; // used by constant SYMBOL
unsigned int arg_index; // used by ARG_INDEX and O_ARG
functor_t * functor; // used by terminal FUNCTOR
- unsigned int name_id; // used by NODE_NAME and ATTR_NAME
+ node_t::nameid_t name_id; // used by NODE_NAME and ATTR_NAME
#if 0
mask_t * mask; // used by terminal MASK
#endif
@@ -720,30 +719,9 @@ public:
reset(tmp ? tmp->acquire() : NULL);
}
- void compile(const string& _expr, scope_t * scope = NULL,
- unsigned short _flags = XPATH_PARSE_RELAXED) {
- parse(_expr, _flags);
- // jww (2006-09-24): fix
- compile((node_t *)NULL, scope);
- }
- void compile(std::istream& in, scope_t * scope = NULL,
- unsigned short _flags = XPATH_PARSE_RELAXED) {
- parse(in, _flags);
- // jww (2006-09-24): fix
- compile((node_t *)NULL, scope);
- }
-
- void compile(document_t * document, scope_t * scope = NULL) {
- if (! document) {
- document_t tdoc;
- compile(tdoc.top, scope);
- } else {
- compile(document->top, scope);
- }
- }
- void compile(node_t * top_node, scope_t * scope = NULL) {
+ void compile(node_t& top_node, scope_t * scope = NULL) {
if (ptr) {
- value_t noderef(top_node);
+ value_t noderef(&top_node);
op_t * compiled = ptr->compile(&noderef, scope);
if (compiled == ptr)
compiled->release();
@@ -752,16 +730,9 @@ public:
}
}
- virtual void calc(value_t& result, node_t * node, scope_t * scope = NULL) const;
-
- virtual value_t calc(document_t * document, scope_t * scope = NULL) const {
- if (! ptr)
- return 0L;
- value_t temp;
- calc(temp, document ? document->top : NULL, scope);
- return temp;
- }
- virtual value_t calc(node_t * tcontext, scope_t * scope = NULL) const {
+ virtual void calc(value_t& result, node_t& node,
+ scope_t * scope = NULL) const;
+ virtual value_t calc(node_t& tcontext, scope_t * scope = NULL) const {
if (! ptr)
return 0L;
value_t temp;
@@ -769,15 +740,15 @@ public:
return temp;
}
- static void eval(value_t& result, const string& _expr,
- document_t * document, scope_t * scope = NULL) {
+ static void eval(value_t& result, const string& _expr, node_t& top,
+ scope_t * scope = NULL) {
xpath_t temp(_expr);
- temp.calc(result, document->top, scope);
+ temp.calc(result, top, scope);
}
- static value_t eval(const string& _expr, document_t * document,
+ static value_t eval(const string& _expr, node_t& top,
scope_t * scope = NULL) {
xpath_t temp(_expr);
- return temp.calc(document, scope);
+ return temp.calc(top, scope);
}
void print(std::ostream& out) const {