summaryrefslogtreecommitdiff
path: root/parser.cc
diff options
context:
space:
mode:
Diffstat (limited to 'parser.cc')
-rw-r--r--parser.cc212
1 files changed, 37 insertions, 175 deletions
diff --git a/parser.cc b/parser.cc
index 7cb65519..78076683 100644
--- a/parser.cc
+++ b/parser.cc
@@ -1,193 +1,55 @@
-#include "parser.h"
-#include "journal.h"
-#include "config.h"
-
-#include <fstream>
-#ifdef WIN32
-#include <io.h>
+#ifdef USE_PCH
+#include "pch.h"
#else
-#include <unistd.h>
+#include "parser.h"
#endif
-namespace ledger {
-
-typedef std::list<parser_t *> parsers_list;
-
-static parsers_list * parsers = NULL;
-
-void initialize_parser_support()
-{
- parsers = new parsers_list;
-}
-
-void shutdown_parser_support()
-{
- if (parsers) {
- delete parsers;
- parsers = NULL;
- }
-}
-
-bool register_parser(parser_t * parser)
-{
- parsers_list::iterator i;
- for (i = parsers->begin(); i != parsers->end(); i++)
- if (*i == parser)
- break;
- if (i != parsers->end())
- return false;
-
- parsers->push_back(parser);
-
- return true;
-}
-
-bool unregister_parser(parser_t * parser)
-{
- parsers_list::iterator i;
- for (i = parsers->begin(); i != parsers->end(); i++)
- if (*i == parser)
- break;
- if (i == parsers->end())
- return false;
-
- parsers->erase(i);
-
- return true;
-}
-
-unsigned int parse_journal(std::istream& in,
- config_t& config,
- journal_t * journal,
- account_t * master,
- const std::string * original_file)
-{
- if (! master)
- master = journal->master;
-
- for (parsers_list::iterator i = parsers->begin();
- i != parsers->end();
- i++)
- if ((*i)->test(in))
- return (*i)->parse(in, config, journal, master, original_file);
-
- return 0;
-}
-
-unsigned int parse_journal_file(const std::string& path,
- config_t& config,
- journal_t * journal,
- account_t * master,
- const std::string * original_file)
-{
- journal->sources.push_back(path);
+#ifdef USE_BOOST_PYTHON
- if (access(path.c_str(), R_OK) == -1)
- throw new error(std::string("Cannot read file '") + path + "'");
-
- if (! original_file)
- original_file = &path;
-
- std::ifstream stream(path.c_str());
- return parse_journal(stream, config, journal, master, original_file);
-}
+#ifndef USE_PCH
+#include <boost/python.hpp>
+#include <Python.h>
+#endif
-extern parser_t * binary_parser_ptr;
-extern parser_t * xml_parser_ptr;
-extern parser_t * textual_parser_ptr;
+using namespace boost::python;
+using namespace ledger;
-unsigned int parse_ledger_data(config_t& config,
- journal_t * journal,
- parser_t * cache_parser,
- parser_t * xml_parser,
- parser_t * stdin_parser)
+struct py_parser_t : public parser_t
{
- unsigned int entry_count = 0;
-
- if (! cache_parser)
- cache_parser = binary_parser_ptr;
- if (! xml_parser)
- xml_parser = xml_parser_ptr;
- if (! stdin_parser)
- stdin_parser = textual_parser_ptr;
+ PyObject * self;
+ py_parser_t(PyObject * self_) : self(self_) {}
- DEBUG_PRINT("ledger.config.cache",
- "3. use_cache = " << config.use_cache);
-
- if (! config.init_file.empty() &&
- access(config.init_file.c_str(), R_OK) != -1) {
- if (parse_journal_file(config.init_file, config, journal) ||
- journal->auto_entries.size() > 0 ||
- journal->period_entries.size() > 0)
- throw new error(std::string("Entries found in initialization file '") +
- config.init_file + "'");
-
- journal->sources.pop_front(); // remove init file
+ virtual bool test(std::istream& in) const {
+ return call_method<bool>(self, "test", in);
}
- if (config.use_cache && ! config.cache_file.empty() &&
- ! config.data_file.empty()) {
- DEBUG_PRINT("ledger.config.cache",
- "using_cache " << config.cache_file);
- config.cache_dirty = true;
- if (access(config.cache_file.c_str(), R_OK) != -1) {
- std::ifstream stream(config.cache_file.c_str());
- if (cache_parser && cache_parser->test(stream)) {
- std::string price_db_orig = journal->price_db;
- journal->price_db = config.price_db;
- entry_count += cache_parser->parse(stream, config, journal,
- NULL, &config.data_file);
- if (entry_count > 0)
- config.cache_dirty = false;
- else
- journal->price_db = price_db_orig;
- }
- }
+ virtual repitem_t * parse(std::istream& in,
+ journal_t * journal,
+ account_t * master = NULL,
+ const std::string * original_file = NULL) {
+ return call_method<unsigned int>(self, "parse", in, journal, master,
+ original_file);
}
+};
- if (entry_count == 0 && ! config.data_file.empty()) {
- account_t * acct = NULL;
- if (! config.account.empty())
- acct = journal->find_account(config.account);
+BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(parser_parse_overloads,
+ py_parser_t::parse, 2, 4)
- journal->price_db = config.price_db;
- if (! journal->price_db.empty() &&
- access(journal->price_db.c_str(), R_OK) != -1) {
- if (parse_journal_file(journal->price_db, config, journal)) {
- throw new error("Entries not allowed in price history file");
- } else {
- DEBUG_PRINT("ledger.config.cache",
- "read price database " << journal->price_db);
- journal->sources.pop_back();
- }
- }
+BOOST_PYTHON_FUNCTION_OVERLOADS(parse_journal_overloads, parse_journal, 2, 4)
+BOOST_PYTHON_FUNCTION_OVERLOADS(parse_journal_file_overloads,
+ parse_journal_file, 2, 4)
- DEBUG_PRINT("ledger.config.cache",
- "rejected cache, parsing " << config.data_file);
- if (config.data_file == "-") {
- config.use_cache = false;
- journal->sources.push_back("<stdin>");
-#if 0
- // jww (2006-03-23): Why doesn't XML work on stdin?
- if (xml_parser && std::cin.peek() == '<')
- entry_count += xml_parser->parse(std::cin, config, journal,
- acct);
- else if (stdin_parser)
-#endif
- entry_count += stdin_parser->parse(std::cin, config,
- journal, acct);
- }
- else if (access(config.data_file.c_str(), R_OK) != -1) {
- entry_count += parse_journal_file(config.data_file, config,
- journal, acct);
- if (! journal->price_db.empty())
- journal->sources.push_back(journal->price_db);
- }
- }
+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())
+ ;
- VALIDATE(journal->valid());
+ def("register_parser", register_parser);
+ def("unregister_parser", unregister_parser);
- return entry_count;
+ def("parse_journal", parse_journal, parse_journal_overloads());
+ def("parse_journal_file", parse_journal_file, parse_journal_file_overloads());
}
-} // namespace ledger
+#endif // USE_BOOST_PYTHON