diff options
-rw-r--r-- | Makefile.am | 6 | ||||
-rw-r--r-- | derive.cc | 147 | ||||
-rw-r--r-- | derive.h | 14 | ||||
-rw-r--r-- | journal.cc | 113 | ||||
-rw-r--r-- | journal.h | 3 | ||||
-rw-r--r-- | ledger.h | 3 | ||||
-rw-r--r-- | main.cc | 3 | ||||
-rwxr-xr-x | main.py | 2 | ||||
-rw-r--r-- | python.cc | 2 |
9 files changed, 172 insertions, 121 deletions
diff --git a/Makefile.am b/Makefile.am index b362d3df..646a2f4a 100644 --- a/Makefile.am +++ b/Makefile.am @@ -1,8 +1,8 @@ lib_LTLIBRARIES = libledger.la libledger_la_CXXFLAGS = -libledger_la_SOURCES = amount.cc balance.cc value.cc autoxact.cc \ - binary.cc config.cc datetime.cc format.cc journal.cc option.cc \ - parser.cc qif.cc quotes.cc textual.cc valexpr.cc walk.cc +libledger_la_SOURCES = amount.cc autoxact.cc balance.cc binary.cc \ + config.cc datetime.cc derive.cc format.cc journal.cc option.cc \ + parser.cc qif.cc quotes.cc textual.cc valexpr.cc value.cc walk.cc if READ_GNUCASH libledger_la_SOURCES += gnucash.cc endif diff --git a/derive.cc b/derive.cc new file mode 100644 index 00000000..6089c03a --- /dev/null +++ b/derive.cc @@ -0,0 +1,147 @@ +#include "derive.h" +#include "datetime.h" +#include "valexpr.h" +#include "error.h" + +namespace ledger { + +entry_t * derive_new_entry(journal_t& journal, + strings_list::iterator i, + strings_list::iterator end) +{ + std::auto_ptr<entry_t> added(new entry_t); + + entry_t * matching = NULL; + + if (! parse_date((*i).c_str(), &added->date)) + throw error("Bad date passed to 'entry'"); + + if (++i == end) + throw error("Too few arguments to 'entry'"); + + mask_t regexp(*i++); + + for (entries_list::reverse_iterator 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 (i == end) + throw error("Too few arguments to 'entry'"); + + if ((*i)[0] == '-' || std::isdigit((*i)[0])) { + if (! matching) + throw error("Could not determine the account to draw from"); + + 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().symbol.empty()) + 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 != end) { + account_t * acct = journal.find_account_re(*i); + if (! acct) + acct = journal.find_account(*i); + if (acct) + added->transactions.back()->account = acct; + } + } else { + while (i != end) { + std::string& re_pat(*i++); + account_t * acct = NULL; + commodity_t * cmdty = NULL; + + if (matching) { + mask_t acct_regex(re_pat); + + for (transactions_list::const_iterator x + = matching->transactions.begin(); + x != matching->transactions.end(); + x++) { + if (acct_regex.match((*x)->account->fullname())) { + acct = (*x)->account; + cmdty = &(*x)->amount.commodity(); + break; + } + } + } + + if (! acct) { + acct = journal.find_account_re(re_pat); + if (acct && acct->transactions.size() > 0) + cmdty = &acct->transactions.back()->amount.commodity(); + } + + if (! acct) + acct = journal.find_account(re_pat); + + if (i == end) { + added->add_transaction(new transaction_t(acct)); + goto done; + } + + transaction_t * xact = new transaction_t(acct, amount_t(*i++)); + if (! xact->amount.commodity()) + xact->amount.set_commodity(*cmdty); + + added->add_transaction(xact); + } + + if (! matching) { + throw error("Could not determine the account to draw from"); + } else { + transaction_t * xact + = new transaction_t(matching->transactions.back()->account); + added->add_transaction(xact); + } + } + + done: + if (! run_hooks(journal.entry_finalize_hooks, *added)) + return NULL; + + return added.release(); +} + +} // namespace ledger + +#ifdef USE_BOOST_PYTHON + +#include <boost/python.hpp> +#include <boost/python/detail/api_placeholder.hpp> + +using namespace boost::python; +using namespace ledger; + +entry_t * py_derive_new_entry(journal_t& journal, list args) +{ + strings_list strs; + + int l = len(args); + for (int i = 0; i < l; i++) + strs.push_back(extract<std::string>(args[i])); + + return derive_new_entry(journal, strs.begin(), strs.end()); +} + +void export_derive() +{ + def("derive_new_entry", py_derive_new_entry, + return_value_policy<manage_new_object>()); +} + +#endif // USE_BOOST_PYTHON diff --git a/derive.h b/derive.h new file mode 100644 index 00000000..0df7f231 --- /dev/null +++ b/derive.h @@ -0,0 +1,14 @@ +#ifndef _DERIVE_H +#define _DERIVE_H + +#include "journal.h" + +namespace ledger { + +entry_t * derive_new_entry(journal_t& journal, + strings_list::iterator begin, + strings_list::iterator end); + +} // namespace ledger + +#endif // _DERIVE_H @@ -426,117 +426,6 @@ bool journal_t::remove_entry(entry_t * entry) return true; } -entry_t * journal_t::derive_entry(strings_list::iterator i, - strings_list::iterator end) -{ - std::auto_ptr<entry_t> added(new entry_t); - - entry_t * matching = NULL; - - if (! parse_date((*i).c_str(), &added->date)) - throw error("Bad date passed to 'entry'"); - - if (++i == end) - throw error("Too few arguments to 'entry'"); - - mask_t regexp(*i++); - - for (entries_list::reverse_iterator j = entries.rbegin(); - j != entries.rend(); - j++) - if (regexp.match((*j)->payee)) { - matching = *j; - break; - } - - added->payee = matching ? matching->payee : regexp.pattern; - - if (i == end) - throw error("Too few arguments to 'entry'"); - - if ((*i)[0] == '-' || std::isdigit((*i)[0])) { - if (! matching) - throw error("Could not determine the account to draw from"); - - 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().symbol.empty()) - 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 != end) { - account_t * acct = find_account_re(*i); - if (! acct) - acct = find_account(*i); - if (acct) - added->transactions.back()->account = acct; - } - } else { - while (i != end) { - std::string& re_pat(*i++); - account_t * acct = NULL; - commodity_t * cmdty = NULL; - - if (matching) { - mask_t acct_regex(re_pat); - - for (transactions_list::const_iterator x - = matching->transactions.begin(); - x != matching->transactions.end(); - x++) { - if (acct_regex.match((*x)->account->fullname())) { - acct = (*x)->account; - cmdty = &(*x)->amount.commodity(); - break; - } - } - } - - if (! acct) { - acct = find_account_re(re_pat); - if (acct && acct->transactions.size() > 0) - cmdty = &acct->transactions.back()->amount.commodity(); - } - - if (! acct) - acct = find_account(re_pat); - - if (i == end) { - added->add_transaction(new transaction_t(acct)); - goto done; - } - - transaction_t * xact = new transaction_t(acct, amount_t(*i++)); - if (! xact->amount.commodity()) - xact->amount.set_commodity(*cmdty); - - added->add_transaction(xact); - } - - if (! matching) { - throw error("Could not determine the account to draw from"); - } else { - transaction_t * xact - = new transaction_t(matching->transactions.back()->account); - added->add_transaction(xact); - } - } - - done: - if (! run_hooks(entry_finalize_hooks, *added)) - return NULL; - - return added.release(); -} - bool journal_t::valid() const { if (! master->valid()) @@ -798,8 +687,6 @@ void export_journal() .def("remove_entry_finalize_hook", py_remove_entry_finalize_hook) .def("run_entry_finalize_hooks", py_run_entry_finalize_hooks) #endif - .def("derive_entry", &journal_t::derive_entry, - return_value_policy<manage_new_object>()) .def("valid", &journal_t::valid) ; @@ -251,9 +251,6 @@ class journal_t bool add_entry(entry_t * entry); bool remove_entry(entry_t * entry); - entry_t * derive_entry(strings_list::iterator begin, - strings_list::iterator end); - bool valid() const; }; @@ -29,6 +29,9 @@ #include <textual.h> #include <autoxact.h> #include <binary.h> +#ifdef READ_GNUCASH +#include <gnucash.h> +#endif #include <qif.h> #include <error.h> @@ -11,6 +11,7 @@ #include "format.h" #include "walk.h" #include "quotes.h" +#include "derive.h" #include "option.h" #include "config.h" #include "debug.h" @@ -239,7 +240,7 @@ int parse_and_report(int argc, char * argv[], char * envp[]) std::auto_ptr<entry_t> new_entry; if (command == "e") { - new_entry.reset(journal->derive_entry(arg, args.end())); + new_entry.reset(derive_new_entry(*journal, arg, args.end())); if (! new_entry.get()) return 1; } @@ -118,7 +118,7 @@ config.process_options(command, args); new_entry = None if command == "e": - new_entry = journal.derive_entry (args) + new_entry = derive_new_entry (journal, args) if new_entry is None: sys.exit (1) @@ -29,6 +29,7 @@ void export_format(); void export_valexpr(); void export_datetime(); void export_autoxact(); +void export_derive(); void initialize_ledger_for_python() { @@ -50,6 +51,7 @@ void initialize_ledger_for_python() export_valexpr(); export_datetime(); export_autoxact(); + export_derive(); module_initialized = true; } |