diff options
-rw-r--r-- | Makefile.am | 19 | ||||
-rw-r--r-- | src/builder.cc | 1 | ||||
-rw-r--r-- | src/builder.h | 112 | ||||
-rw-r--r-- | src/commodity.cc | 2 | ||||
-rw-r--r-- | src/commodity.h | 2 | ||||
-rw-r--r-- | src/main.cc | 20 | ||||
-rw-r--r-- | src/parser.h | 29 | ||||
-rw-r--r-- | src/session.cc | 28 | ||||
-rw-r--r-- | src/session.h | 14 | ||||
-rw-r--r-- | src/system.hh | 1 | ||||
-rw-r--r-- | src/textual.cc | 63 | ||||
-rw-r--r-- | src/textual.h | 30 | ||||
-rw-r--r-- | src/utils.h | 2 | ||||
-rw-r--r-- | src/xml.h | 41 |
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); @@ -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 { |