summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--Makefile.am19
-rw-r--r--src/builder.cc1
-rw-r--r--src/builder.h112
-rw-r--r--src/commodity.cc2
-rw-r--r--src/commodity.h2
-rw-r--r--src/main.cc20
-rw-r--r--src/parser.h29
-rw-r--r--src/session.cc28
-rw-r--r--src/session.h14
-rw-r--r--src/system.hh1
-rw-r--r--src/textual.cc63
-rw-r--r--src/textual.h30
-rw-r--r--src/utils.h2
-rw-r--r--src/xml.h41
14 files changed, 216 insertions, 148 deletions
diff --git a/Makefile.am b/Makefile.am
index 07d69aa7..645e3b34 100644
--- a/Makefile.am
+++ b/Makefile.am
@@ -41,24 +41,15 @@ libledger_la_SOURCES = \
src/amount.cc \
src/balance.cc \
src/value.cc \
- \
- src/session.cc \
+ src/xml.cc \
+ src/xpath.cc \
+ src/builder.cc \
src/journal.cc \
- src/binary.cc \
- src/qif.cc \
src/textual.cc \
- src/quotes.cc \
- src/csv.cc \
- src/derive.cc \
- src/emacs.cc \
- src/format.cc \
- src/reconcile.cc \
+ src/transform.cc \
src/register.cc \
src/report.cc \
- src/transform.cc \
- src/xml.cc \
- src/xmlparse.cc \
- src/xpath.cc
+ src/session.cc
#if HAVE_EXPAT
#libledger_la_CPPFLAGS += -DHAVE_EXPAT=1
diff --git a/src/builder.cc b/src/builder.cc
new file mode 100644
index 00000000..8b137891
--- /dev/null
+++ b/src/builder.cc
@@ -0,0 +1 @@
+
diff --git a/src/builder.h b/src/builder.h
index f89b9dcc..69fec3d9 100644
--- a/src/builder.h
+++ b/src/builder.h
@@ -4,6 +4,7 @@
#include "xml.h"
namespace ledger {
+namespace xml {
/**
* @class builder_t
@@ -22,61 +23,43 @@ public:
typedef uint_least32_t file_pos_t;
typedef uint_least32_t file_line_t;
- path pathname;
file_pos_t offset;
file_line_t linenum;
position_t() : offset(0), linenum(0) {}
- explicit position_t(path _pathname,
- file_pos_t _offset,
+ explicit position_t(file_pos_t _offset,
file_line_t _linenum)
- : pathname(_pathname),
- offset(_offset), linenum(_linenum) {}
+ : offset(_offset), linenum(_linenum) {}
};
position_t current_position;
- virtual void start_position(const std::istream& in,
- const path& pathname) {
- set_position(position_t(pathname, in.tellg(), 1));
- }
-
- virtual void set_position(const position_t& position) {
- current_position = position;
- }
-
- virtual position_t& position() {
- return current_position;
- }
+ virtual void set_start_position(std::istream& in) {}
+ virtual void set_position(const position_t& position) {}
+ virtual position_t& position() { return current_position; }
virtual void push_attr(const string& name,
const string& value) = 0;
- virtual void push_attr(const nameid_t name_id,
+ 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 nameid_t name_id) = 0;
-
- template <typename T>
- virtual void begin_node(typename T::pointer data) = 0;
+ virtual void begin_node(const node_t::nameid_t name_id) = 0;
virtual void push_node(const string& name,
- const optional<position_t>& end_pos) = 0;
- virtual void push_node(const nameid_t name_id,
- const optional<position_t>& end_pos) = 0;
+ const optional<position_t>& end_pos = none) = 0;
+ virtual void push_node(const node_t::nameid_t name_id,
+ const optional<position_t>& end_pos = none) = 0;
virtual node_t * current_node() = 0;
- template <typename T>
- virtual T * current_node() = 0;
-
virtual void append_text(const string& text) = 0;
virtual node_t * end_node(const string& name,
- const optional<position_t>& end_pos) = 0;
- virtual node_t * end_node(const nameid_t name_id,
- const optional<position_t>& end_pos) = 0;
+ const optional<position_t>& end_pos = none) = 0;
+ virtual node_t * end_node(const node_t::nameid_t name_id,
+ const optional<position_t>& end_pos = none) = 0;
};
/**
@@ -110,6 +93,14 @@ class xml_builder_t : public builder_t
*/
class journal_builder_t : public xml_builder_t
{
+public:
+ virtual void set_start_position(std::istream& in) {
+ set_position(position_t(in.tellg(), 1));
+ }
+
+ virtual void set_position(const position_t& position) {
+ current_position = position;
+ }
};
/**
@@ -124,8 +115,67 @@ class journal_builder_t : public xml_builder_t
*/
class xml_writer_t : public builder_t
{
+ typedef std::list<std::pair<string, string> > attrs_list;
+
+ attrs_list current_attrs;
+ std::ostream& outs;
+
+public:
+ xml_writer_t(std::ostream& _outs) : outs(_outs) {
+ outs << "<?xml version=\"1.0\" encoding=\"UTF-8\"?>";
+ begin_node("ledger");
+ }
+ ~xml_writer_t() {
+ end_node("ledger");
+ }
+
+ virtual void push_attr(const string& name,
+ const string& value) {
+ current_attrs.push_back(attrs_list::value_type(name, value));
+ }
+ virtual void push_attr(const node_t::nameid_t name_id,
+ const string& value) {
+ push_attr("hello", value);
+ }
+
+ virtual void begin_node(const string& name) {
+ 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) {
+ begin_node("hello");
+ }
+
+ virtual void push_node(const string& name,
+ const optional<position_t>& end_pos = none) {
+ begin_node(name);
+ end_node(name, end_pos);
+ }
+ virtual void push_node(const node_t::nameid_t name_id,
+ const optional<position_t>& end_pos = none) {
+ push_node("hello", end_pos);
+ }
+
+ virtual node_t * current_node() { return NULL; }
+
+ virtual void append_text(const string& text) {
+ outs << text;
+ }
+
+ virtual node_t * end_node(const string& name,
+ const optional<position_t>& end_pos = none) {
+ outs << "</" << name << '>';
+ }
+ virtual node_t * end_node(const node_t::nameid_t name_id,
+ const optional<position_t>& end_pos = none) {
+ end_node("hello", end_pos);
+ }
};
+} // namespace xml
} // namespace ledger
#endif // _BUILDER_H
diff --git a/src/commodity.cc b/src/commodity.cc
index 9eaa3ad8..4cc38e06 100644
--- a/src/commodity.cc
+++ b/src/commodity.cc
@@ -186,7 +186,7 @@ void commodity_t::parse_symbol(std::istream& in, string& symbol)
symbol = buf;
}
-void commodity_t::parse_symbol(const char *& p, string& symbol)
+void commodity_t::parse_symbol(char *& p, string& symbol)
{
if (*p == '"') {
char * q = std::strchr(p + 1, '"');
diff --git a/src/commodity.h b/src/commodity.h
index 2407ffec..84ca5fff 100644
--- a/src/commodity.h
+++ b/src/commodity.h
@@ -190,7 +190,7 @@ public:
optional<amount_t> value(const optional<moment_t>& moment = none);
static void parse_symbol(std::istream& in, string& symbol);
- static void parse_symbol(const char *& p, string& symbol);
+ static void parse_symbol(char *& p, string& symbol);
static string parse_symbol(std::istream& in) {
string temp;
parse_symbol(in, temp);
diff --git a/src/main.cc b/src/main.cc
index 12f614e5..010abd3c 100644
--- a/src/main.cc
+++ b/src/main.cc
@@ -31,11 +31,12 @@
#include "utils.h"
#include "option.h"
-#if defined(HAVE_EXPAT) || defined(HAVE_XMLPARSE)
-#include "gnucash.h"
-#endif
-#include "qif.h"
-#include "ofx.h"
+//#if defined(HAVE_EXPAT) || defined(HAVE_XMLPARSE)
+//#include "gnucash.h"
+//#endif
+//#include "qif.h"
+//#include "ofx.h"
+#include "builder.h"
#include <ledger.h>
@@ -211,7 +212,14 @@ static int read_and_report(report_t * report, int argc, char * argv[],
INFO_START(journal, "Read journal file");
journal_t * journal = session.read_data(report->account);
+ {
+ textual_parser_t text_parser;
+ ifstream input(session.data_file);
+ xml::xml_writer_t writer(std::cout);
+ text_parser.parse(input, session.data_file, writer);
+ }
INFO_FINISH(journal);
+ return 0;
TRACE_FINISH(entry_text, 1);
TRACE_FINISH(entry_date, 1);
@@ -459,7 +467,6 @@ int main(int argc, char * argv[], char * envp[])
#if 0
session->register_parser(new binary_parser_t);
-#endif
#if defined(HAVE_EXPAT) || defined(HAVE_XMLPARSE)
session->register_parser(new xml::xml_parser_t);
session->register_parser(new gnucash_parser_t);
@@ -469,6 +476,7 @@ int main(int argc, char * argv[], char * envp[])
#endif
session->register_parser(new qif_parser_t);
session->register_parser(new textual_parser_t);
+#endif
std::auto_ptr<ledger::report_t> report(new ledger::report_t(session.get()));
diff --git a/src/parser.h b/src/parser.h
index 8e9ccd4a..7cb1cd49 100644
--- a/src/parser.h
+++ b/src/parser.h
@@ -33,6 +33,7 @@
#define _PARSER_H
#include "utils.h"
+#include "builder.h"
namespace ledger {
@@ -46,10 +47,9 @@ class parser_t
virtual bool test(std::istream& in) const = 0;
- virtual unsigned int parse(std::istream& in,
- journal_t * journal,
- account_t * master = NULL,
- const optional<path>& original = none) = 0;
+ virtual void parse(std::istream& in,
+ const path& pathname,
+ xml::builder_t& builder) = 0;
};
DECLARE_EXCEPTION(parse_error);
@@ -65,6 +65,27 @@ inline char * skip_ws(char * ptr) {
return ptr;
}
+inline char * next_element(char * buf, bool variable = false) {
+ for (char * p = buf; *p; p++) {
+ if (! (*p == ' ' || *p == '\t'))
+ continue;
+
+ if (! variable) {
+ *p = '\0';
+ return skip_ws(p + 1);
+ }
+ else if (*p == '\t') {
+ *p = '\0';
+ return skip_ws(p + 1);
+ }
+ else if (*(p + 1) == ' ') {
+ *p = '\0';
+ return skip_ws(p + 2);
+ }
+ }
+ return NULL;
+}
+
inline char peek_next_nonws(std::istream& in) {
char c = in.peek();
while (! in.eof() && std::isspace(c)) {
diff --git a/src/session.cc b/src/session.cc
index 41591018..b94dc290 100644
--- a/src/session.cc
+++ b/src/session.cc
@@ -68,36 +68,34 @@ void release_session_context()
#endif
}
-unsigned int session_t::read_journal(std::istream& in,
- journal_t * journal,
- account_t * master,
- const optional<path>& original)
+void session_t::read_journal(std::istream& in,
+ const path& pathname,
+ xml::builder_t& builder)
{
+#if 0
if (! master)
master = journal->master;
+#endif
for (ptr_list<parser_t>::iterator i = parsers.begin();
i != parsers.end();
i++)
if (i->test(in))
- return i->parse(in, journal, master, original);
-
- return 0;
+ i->parse(in, pathname, builder);
}
-unsigned int session_t::read_journal(const path& pathname,
- journal_t * journal,
- account_t * master,
- const optional<path>& original)
+void session_t::read_journal(const path& pathname,
+ xml::builder_t& builder)
{
+#if 0
journal->sources.push_back(pathname);
+#endif
if (! exists(pathname))
throw_(std::logic_error, "Cannot read file" << pathname);
ifstream stream(pathname);
- return read_journal(stream, journal, master,
- original ? original : pathname);
+ read_journal(stream, pathname, builder);
}
void session_t::read_init()
@@ -115,6 +113,9 @@ void session_t::read_init()
journal_t * session_t::read_data(const string& master_account)
{
+#if 1
+ return NULL;
+#else
if (data_file.empty())
throw_(parse_error, "No journal file was specified (please use -f)");
@@ -180,6 +181,7 @@ journal_t * session_t::read_data(const string& master_account)
TRACE_STOP(parser, 1);
return journal;
+#endif
}
bool session_t::resolve(const string& name, value_t& result,
diff --git a/src/session.h b/src/session.h
index 4027bc95..cf75b600 100644
--- a/src/session.h
+++ b/src/session.h
@@ -148,15 +148,11 @@ class session_t : public xml::xpath_t::scope_t
checked_delete(journal);
}
- unsigned int read_journal(std::istream& in,
- journal_t * journal,
- account_t * master = NULL,
- const optional<path>& original = none);
-
- unsigned int read_journal(const path& pathname,
- journal_t * journal,
- account_t * master = NULL,
- const optional<path>& original = none);
+ void read_journal(std::istream& in,
+ const path& pathname,
+ xml::builder_t& builder);
+ void read_journal(const path& pathname,
+ xml::builder_t& builder);
void read_init();
diff --git a/src/system.hh b/src/system.hh
index 61dd9530..217b1235 100644
--- a/src/system.hh
+++ b/src/system.hh
@@ -138,6 +138,7 @@ extern "C" {
#include <boost/filesystem/fstream.hpp>
#include <boost/filesystem/operations.hpp>
#include <boost/filesystem/path.hpp>
+#include <boost/foreach.hpp>
#include <boost/function.hpp>
#include <boost/lambda/bind.hpp>
#include <boost/lambda/lambda.hpp>
diff --git a/src/textual.cc b/src/textual.cc
index 00a4ba6c..914b63c3 100644
--- a/src/textual.cc
+++ b/src/textual.cc
@@ -37,32 +37,9 @@ namespace ledger {
typedef xml::builder_t::position_t position_t;
-namespace {
- inline char * next_element(char * buf, bool variable = false) {
- for (char * p = buf; *p; p++) {
- if (! (*p == ' ' || *p == '\t'))
- continue;
-
- if (! variable) {
- *p = '\0';
- return skip_ws(p + 1);
- }
- else if (*p == '\t') {
- *p = '\0';
- return skip_ws(p + 1);
- }
- else if (*(p + 1) == ' ') {
- *p = '\0';
- return skip_ws(p + 2);
- }
- }
- return NULL;
- }
-}
-
-void parse_transaction(builder_t& builder,
- char * line,
- position_t& end_of_line,
+void parse_transaction(xml::builder_t& builder,
+ char * line,
+ position_t& end_of_line)
{
// First cut up the input line into its various parts.
@@ -99,8 +76,8 @@ void parse_transaction(builder_t& builder,
// Setup the details for this node
- if (statep) {
- switch (*statep) {
+ if (state) {
+ switch (*state) {
case '*':
builder.push_attr(CLEARED_ATTR, "yes");
break;
@@ -131,9 +108,11 @@ void parse_transaction(builder_t& builder,
// Parse the optional amount
- builder.begin_node(AMOUNT_EXPR_NODE);
- builder.append_text(account_path);
- builder.end_node(AMOUNT_EXPR_NODE);
+ if (amount) {
+ builder.begin_node(AMOUNT_EXPR_NODE);
+ builder.append_text(amount);
+ builder.end_node(AMOUNT_EXPR_NODE);
+ }
// Parse the optional note
@@ -146,7 +125,7 @@ void parse_transaction(builder_t& builder,
builder.end_node(TRANSACTION_NODE, end_of_line);
}
-bool parse_transactions(std::istream& in, builder_t& builder)
+bool parse_transactions(std::istream& in, xml::builder_t& builder)
{
TRACE_START(entry_xacts, 1, "Time spent parsing transactions:");
@@ -168,6 +147,7 @@ bool parse_transactions(std::istream& in, builder_t& builder)
break;
parse_transaction(builder, line, end_of_line);
+ added = true;
}
TRACE_STOP(entry_xacts, 1);
@@ -175,10 +155,10 @@ bool parse_transactions(std::istream& in, builder_t& builder)
return added;
}
-void parse_entry(std::istream& in,
- builder_t& builder,
- char * line,
- position_t& end_of_line)
+void parse_entry(std::istream& in,
+ xml::builder_t& builder,
+ char * line,
+ position_t& end_of_line)
{
TRACE_START(entry_text, 1, "Time spent preparing entry text:");
@@ -293,12 +273,13 @@ bool textual_parser_t::test(std::istream& in) const
return true;
}
-void textual_parser_t::parse(std::istream& in,
- builder_t& builder)
+void textual_parser_t::parse(std::istream& in,
+ const path& pathname,
+ xml::builder_t& builder)
{
TRACE_START(parsing_total, 1, "Total time spent parsing text:");
- INFO("Parsing file '" << builder.position().pathname.string() << "'");
+ INFO("Parsing file '" << pathname.string() << "'");
builder.begin_node(JOURNAL_NODE);
@@ -312,7 +293,7 @@ void textual_parser_t::parse(std::istream& in,
end_of_line.offset += std::strlen(line) + 1;
end_of_line.linenum++;
- PUSH_CONTEXT();
+ //PUSH_CONTEXT();
switch (line[0]) {
case '\0':
@@ -481,7 +462,7 @@ void textual_parser_t::parse(std::istream& in,
break;
}
- POP_CONTEXT(builder_context(builder));
+ //POP_CONTEXT(builder_context(builder));
}
builder.end_node(JOURNAL_NODE);
diff --git a/src/textual.h b/src/textual.h
index e569c81d..c6654979 100644
--- a/src/textual.h
+++ b/src/textual.h
@@ -41,35 +41,11 @@ class textual_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);
+ virtual void parse(std::istream& in,
+ const path& pathname,
+ xml::builder_t& builder);
};
-#if 0
-void write_textual_journal(journal_t& journal, string path,
- item_handler<transaction_t>& formatter,
- const string& write_hdr_format,
- std::ostream& out);
-#endif
-
-#if 0
-class include_context : public file_context {
- public:
- include_context(const string& file, unsigned long line,
- const string& desc = "") throw()
- : file_context(file, line, desc) {}
- virtual ~include_context() throw() {}
-
- virtual void describe(std::ostream& out) const throw() {
- if (! desc.empty())
- out << desc << ": ";
- out << "\"" << file << "\", line " << line << ":" << std::endl;
- }
-};
-#endif
-
} // namespace ledger
#endif // _TEXTUAL_H
diff --git a/src/utils.h b/src/utils.h
index 4dabd7ea..85f81239 100644
--- a/src/utils.h
+++ b/src/utils.h
@@ -511,6 +511,8 @@ inline void throw_unexpected_error(char, char) {
* General utility functions
*/
+#define foreach BOOST_FOREACH
+
namespace ledger {
path resolve_path(const path& pathname);
diff --git a/src/xml.h b/src/xml.h
index d36674cc..a247260b 100644
--- a/src/xml.h
+++ b/src/xml.h
@@ -34,7 +34,7 @@
#include "journal.h"
#include "value.h"
-#include "parser.h"
+//#include "parser.h"
namespace ledger {
@@ -47,6 +47,43 @@ namespace xml {
#define XML_NODE_IS_PARENT 0x1
+#define ACCOUNT_ATTR "account"
+#define ACCOUNT_PATH_NODE "account-path"
+#define AMOUNT_EXPR_NODE "amount-expr"
+#define ARG_ATTR "arg"
+#define AUTO_ENTRY_NODE "auto-entry"
+#define BALANCE_ATTR "balance"
+#define CHECKIN_NODE "checkin"
+#define CLEARED_ATTR "cleared"
+#define CODE_ATTR "code"
+#define COMMODITY_CONVERSION_NODE "commodity-conversion"
+#define COMMODITY_NOMARKET_NODE "commodity-nomarket"
+#define COMMODITY_TEMPLATE_NODE "commodity-template"
+#define CURRENT_YEAR_NODE "current-year"
+#define DATE_ATTR "date"
+#define DATE_EFF_ATTR "effective"
+#define DEFAULT_ACCOUNT_NODE "default-account"
+#define DIRECTIVE_NODE "directive"
+#define ENTRY_NODE "entry"
+#define FROM_ATTR "from"
+#define JOURNAL_NODE "journal"
+#define NAME_ATTR "name"
+#define NOTE_NODE "note"
+#define PAYEE_NODE "payee"
+#define PENDING_ATTR "pending"
+#define PERIOD_ENTRY_NODE "period-entry"
+#define PERIOD_NODE "period"
+#define PRICE_ATTR "price"
+#define PRICE_HISTORY_NODE "price-history"
+#define RULE_NODE "rule"
+#define SYMBOL_ATTR "symbol"
+#define TEMPLATE_ATTR "template"
+#define TIME_ATTR "time"
+#define TO_ATTR "to"
+#define TRANSACTION_NODE "transaction"
+#define VIRTUAL_ATTR "virtual"
+#define YEAR_ATTR "year"
+
DECLARE_EXCEPTION(conversion_error);
class parent_node_t;
@@ -290,6 +327,7 @@ public:
#endif
};
+#if 0
#if defined(HAVE_EXPAT) || defined(HAVE_XMLPARSE)
class xml_parser_t : public parser_t
@@ -306,6 +344,7 @@ class xml_parser_t : public parser_t
DECLARE_EXCEPTION(parse_error);
#endif
+#endif
class commodity_node_t : public parent_node_t
{