optimize python iterations of entries, transactions; use exceptions more

This commit is contained in:
John Wiegley 2004-09-08 03:33:56 -04:00
parent 612e94ceaa
commit 842359474e
7 changed files with 93 additions and 87 deletions

View file

@ -392,7 +392,7 @@ OPT_BEGIN(set_price, "z:") {
if (std::strchr(optarg, '=')) if (std::strchr(optarg, '='))
config.price_settings.push_back(optarg); config.price_settings.push_back(optarg);
else else
std::cerr << "Error: Invalid price setting: " << optarg << std::endl; throw error(std::string("Invalid price setting: ") + optarg);
} OPT_END(set_price); } OPT_END(set_price);
OPT_BEGIN(account, "a:") { OPT_BEGIN(account, "a:") {

View file

@ -1,5 +1,6 @@
#include "gnucash.h" #include "gnucash.h"
#include "ledger.h" #include "ledger.h"
#include "error.h"
#include <iostream> #include <iostream>
#include <sstream> #include <sstream>
@ -218,21 +219,17 @@ static void dataHandler(void *userData, const char *s, int len)
case XACT_ACCOUNT: { case XACT_ACCOUNT: {
accounts_map::iterator i = accounts_by_id.find(std::string(s, len)); accounts_map::iterator i = accounts_by_id.find(std::string(s, len));
if (i == accounts_by_id.end()) { if (i == accounts_by_id.end())
std::cerr << "Could not find account " << std::string(s, len) throw error(std::string("Could not find account ") + std::string(s, len));
<< std::endl;
std::exit(1);
}
transaction_t * xact = curr_entry->transactions.back(); transaction_t * xact = curr_entry->transactions.back();
xact->account = (*i).second; xact->account = (*i).second;
account_comm_map::iterator ac = account_comms.find(xact->account); account_comm_map::iterator ac = account_comms.find(xact->account);
if (ac == account_comms.end()) { if (ac == account_comms.end())
std::cerr << "Could not find account " << *(xact->account) throw error(std::string("Could not find account ") +
<< std::endl; std::string(*(xact->account)));
std::exit(1);
}
commodity_t * default_commodity = (*ac).second; commodity_t * default_commodity = (*ac).second;
curr_quant.set_commodity(*default_commodity); curr_quant.set_commodity(*default_commodity);
@ -300,13 +297,10 @@ unsigned int gnucash_parser_t::parse(std::istream& in,
while (! in.eof()) { while (! in.eof()) {
in.getline(buf, BUFSIZ - 1); in.getline(buf, BUFSIZ - 1);
if (! XML_Parse(parser, buf, std::strlen(buf), in.eof()))
if (! XML_Parse(parser, buf, std::strlen(buf), in.eof())) { throw parse_error(original_file ? *original_file : "<gnucash>",
std::cerr << XML_ErrorString(XML_GetErrorCode(parser)) XML_GetCurrentLineNumber(parser),
<< " at line " << XML_GetCurrentLineNumber(parser) XML_ErrorString(XML_GetErrorCode(parser)));
<< std::endl;
return NULL;
}
} }
XML_ParserFree(parser); XML_ParserFree(parser);

View file

@ -267,16 +267,11 @@ entry_t * journal_t::derive_entry(strings_list::iterator i,
entry_t * matching = NULL; entry_t * matching = NULL;
if (! parse_date((*i).c_str(), &added->date)) { if (! parse_date((*i).c_str(), &added->date))
std::cerr << "Error: Bad entry date: " << *i << std::endl; throw error("Bad date passed to 'entry'");
return false;
}
++i;
if (i == end) { if (++i == end)
std::cerr << "Error: Too few arguments to 'entry'." << std::endl; throw error("Too few arguments to 'entry'");
return false;
}
mask_t regexp(*i++); mask_t regexp(*i++);
@ -290,17 +285,12 @@ entry_t * journal_t::derive_entry(strings_list::iterator i,
added->payee = matching ? matching->payee : regexp.pattern; added->payee = matching ? matching->payee : regexp.pattern;
if (i == end) { if (i == end)
std::cerr << "Error: Too few arguments to 'entry'." << std::endl; throw error("Too few arguments to 'entry'");
return false;
}
if ((*i)[0] == '-' || std::isdigit((*i)[0])) { if ((*i)[0] == '-' || std::isdigit((*i)[0])) {
if (! matching) { if (! matching)
std::cerr << "Error: Missing account name for non-matching entry." throw error("Missing account name for non-matching entry");
<< std::endl;
return false;
}
transaction_t * m_xact, * xact, * first; transaction_t * m_xact, * xact, * first;
m_xact = matching->transactions.front(); m_xact = matching->transactions.front();
@ -343,16 +333,12 @@ entry_t * journal_t::derive_entry(strings_list::iterator i,
if (! acct) if (! acct)
acct = find_account(acct_regex.pattern); acct = find_account(acct_regex.pattern);
if (! acct) { if (! acct)
std::cerr << "Error: Could not find account name '" throw error(std::string("Could not find account name '") +
<< acct_regex.pattern << "'." << std::endl; acct_regex.pattern + "'");
return false;
}
if (i == end) { if (i == end)
std::cerr << "Error: Too few arguments to 'entry'." << std::endl; throw error("Too few arguments to 'entry'");
return false;
}
amount_t amt(*i++); amount_t amt(*i++);
transaction_t * xact = new transaction_t(acct, amt); transaction_t * xact = new transaction_t(acct, amt);
@ -365,12 +351,11 @@ entry_t * journal_t::derive_entry(strings_list::iterator i,
if (i != end && std::string(*i++) == "-from" && i != end) { if (i != end && std::string(*i++) == "-from" && i != end) {
if (account_t * acct = find_account(*i++)) if (account_t * acct = find_account(*i++))
added->add_transaction(new transaction_t(acct)); added->add_transaction(new transaction_t(acct));
} else { }
if (! matching) { else if (! matching) {
std::cerr << "Error: Could not figure out the account to draw from." throw error("Could not figure out the account to draw from");
<< std::endl; }
std::exit(1); else {
}
transaction_t * xact transaction_t * xact
= new transaction_t(matching->transactions.back()->account); = new transaction_t(matching->transactions.back()->account);
added->add_transaction(xact); added->add_transaction(xact);
@ -419,6 +404,10 @@ unsigned int transactions_len(entry_t& entry)
transaction_t& transactions_getitem(entry_t& entry, int i) transaction_t& transactions_getitem(entry_t& entry, int i)
{ {
static int last_index = 0;
static entry_t * last_entry = NULL;
static transactions_list::iterator elem;
std::size_t len = entry.transactions.size(); std::size_t len = entry.transactions.size();
if (abs(i) >= len) { if (abs(i) >= len) {
@ -426,11 +415,19 @@ transaction_t& transactions_getitem(entry_t& entry, int i)
throw_error_already_set(); throw_error_already_set();
} }
if (&entry == last_entry && i == last_index + 1) {
last_index = i;
return **++elem;
}
int x = i < 0 ? len + i : i; int x = i < 0 ? len + i : i;
transactions_list::iterator elem = entry.transactions.begin(); elem = entry.transactions.begin();
while (--x >= 0) while (--x >= 0)
elem++; elem++;
last_entry = &entry;
last_index = i;
return **elem; return **elem;
} }
@ -441,6 +438,10 @@ unsigned int entries_len(journal_t& journal)
entry_t& entries_getitem(journal_t& journal, int i) 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(); std::size_t len = journal.entries.size();
if (abs(i) >= len) { if (abs(i) >= len) {
@ -448,11 +449,19 @@ entry_t& entries_getitem(journal_t& journal, int i)
throw_error_already_set(); throw_error_already_set();
} }
if (&journal == last_journal && i == last_index + 1) {
last_index = i;
return **++elem;
}
int x = i < 0 ? len + i : i; int x = i < 0 ? len + i : i;
entries_list::iterator elem = journal.entries.begin(); elem = journal.entries.begin();
while (--x >= 0) while (--x >= 0)
elem++; elem++;
last_journal = &journal;
last_index = i;
return **elem; return **elem;
} }
@ -461,21 +470,33 @@ unsigned int accounts_len(account_t& account)
return account.accounts.size(); return account.accounts.size();
} }
account_t& accounts_getitem(account_t& account, int index) 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(); std::size_t len = account.accounts.size();
if (abs(index) >= len) { if (abs(i) >= len) {
PyErr_SetString(PyExc_IndexError, "Index out of range"); PyErr_SetString(PyExc_IndexError, "Index out of range");
throw_error_already_set(); throw_error_already_set();
} }
int x = 0; if (&account == last_account && i == last_index + 1) {
for (accounts_map::iterator i = account.accounts.begin(); last_index = i;
i != account.accounts.end(); return *(*++elem).second;
i++) }
if (x++ == index)
return *((*i).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;
} }
void export_journal() void export_journal()

View file

@ -290,11 +290,8 @@ int parse_and_report(int argc, char * argv[], char * envp[])
command = "e"; command = "e";
else if (command == "equity") else if (command == "equity")
command = "E"; command = "E";
else { else
std::ostringstream msg; throw error(std::string("Unrecognized command '") + command + "'");
msg << "Unrecognized command '" << command << "'";
throw error(msg.str());
}
config.process_options(command, arg, args.end()); config.process_options(command, arg, args.end());

View file

@ -19,4 +19,5 @@ register_parser (parser)
journal = Journal () journal = Journal ()
parse_journal_file (args[0], journal) parse_journal_file (args[0], journal)
print journal[-1].payee for entry in journal:
print entry.payee

View file

@ -576,11 +576,8 @@ unsigned int textual_parser_t::parse(std::istream& in,
time_commodity->flags |= COMMODITY_STYLE_NOMARKET; time_commodity->flags |= COMMODITY_STYLE_NOMARKET;
} }
if (errors > 0) { if (errors > 0)
std::ostringstream msg; throw error(std::string("Errors parsing file '") + path + "'");
msg << "Errors parsing file '" << path << "'";
throw error(msg.str());
}
return count; return count;
} }

View file

@ -642,11 +642,10 @@ value_expr_t * parse_logic_expr(std::istream& in)
} }
default: default:
if (! in.eof()) { if (! in.eof())
std::ostringstream err; throw value_expr_error(std::string("Unexpected character '") +
err << "Unexpected character '" << c << "'"; c + "'");
throw value_expr_error(err.str()); break;
}
} }
} }
} }
@ -687,22 +686,19 @@ value_expr_t * parse_value_expr(std::istream& in)
node->right = choices = new value_expr_t(value_expr_t::O_COL); node->right = choices = new value_expr_t(value_expr_t::O_COL);
choices->left = parse_logic_expr(in); choices->left = parse_logic_expr(in);
c = peek_next_nonws(in); c = peek_next_nonws(in);
if (c != ':') { if (c != ':')
std::ostringstream err; throw value_expr_error(std::string("Unexpected character '") +
err << "Unexpected character '" << c << "'"; c + "'");
throw value_expr_error(err.str());
}
in.get(c); in.get(c);
choices->right = parse_logic_expr(in); choices->right = parse_logic_expr(in);
break; break;
} }
default: default:
if (! in.eof()) { if (! in.eof())
std::ostringstream err; throw value_expr_error(std::string("Unexpected character '") +
err << "Unexpected character '" << c << "'"; c + "'");
throw value_expr_error(err.str()); break;
}
} }
c = peek_next_nonws(in); c = peek_next_nonws(in);
} }