use std::auto_ptr wherever a thrown exception might otherwise leak memory
This commit is contained in:
parent
965e1fc28f
commit
bf923ab33e
8 changed files with 143 additions and 141 deletions
|
|
@ -90,9 +90,9 @@ static void parse_inclusion_specifier(const std::string& word,
|
||||||
*end = interval_t(0, saw_mon ? 1 : 0, saw_year ? 1 : 0).increment(*begin);
|
*end = interval_t(0, saw_mon ? 1 : 0, saw_year ? 1 : 0).increment(*begin);
|
||||||
}
|
}
|
||||||
|
|
||||||
interval_t * interval_t::parse(std::istream& in,
|
interval_t interval_t::parse(std::istream& in,
|
||||||
std::time_t * begin,
|
std::time_t * begin,
|
||||||
std::time_t * end)
|
std::time_t * end)
|
||||||
{
|
{
|
||||||
unsigned long years = 0;
|
unsigned long years = 0;
|
||||||
unsigned long months = 0;
|
unsigned long months = 0;
|
||||||
|
|
@ -203,7 +203,8 @@ interval_t * interval_t::parse(std::istream& in,
|
||||||
parse_inclusion_specifier(word, begin, end);
|
parse_inclusion_specifier(word, begin, end);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return new interval_t(seconds, months, years);
|
|
||||||
|
return interval_t(seconds, months, years);
|
||||||
}
|
}
|
||||||
|
|
||||||
bool parse_date_mask(const char * date_str, struct std::tm * result)
|
bool parse_date_mask(const char * date_str, struct std::tm * result)
|
||||||
|
|
|
||||||
11
datetime.h
11
datetime.h
|
|
@ -13,13 +13,18 @@ struct interval_t
|
||||||
int months;
|
int months;
|
||||||
int seconds;
|
int seconds;
|
||||||
|
|
||||||
interval_t(int _seconds, int _months = 0, int _years = 0)
|
interval_t(int _seconds = 0, int _months = 0, int _years = 0)
|
||||||
: years(_years), months(_months), seconds(_seconds) {}
|
: years(_years), months(_months), seconds(_seconds) {}
|
||||||
|
|
||||||
|
operator bool() const {
|
||||||
|
return seconds > 0 || months > 0 || years > 0;
|
||||||
|
}
|
||||||
|
|
||||||
std::time_t increment(const std::time_t);
|
std::time_t increment(const std::time_t);
|
||||||
|
|
||||||
static interval_t * parse(std::istream& in, std::time_t * begin,
|
static interval_t parse(std::istream& in,
|
||||||
std::time_t * end);
|
std::time_t * begin,
|
||||||
|
std::time_t * end);
|
||||||
};
|
};
|
||||||
|
|
||||||
extern std::time_t now;
|
extern std::time_t now;
|
||||||
|
|
|
||||||
15
format.cc
15
format.cc
|
|
@ -45,7 +45,8 @@ std::auto_ptr<value_expr_t> format_t::total_expr;
|
||||||
|
|
||||||
element_t * format_t::parse_elements(const std::string& fmt)
|
element_t * format_t::parse_elements(const std::string& fmt)
|
||||||
{
|
{
|
||||||
element_t * result = NULL;
|
std::auto_ptr<element_t> result;
|
||||||
|
|
||||||
element_t * current = NULL;
|
element_t * current = NULL;
|
||||||
|
|
||||||
static char buf[1024];
|
static char buf[1024];
|
||||||
|
|
@ -57,8 +58,9 @@ element_t * format_t::parse_elements(const std::string& fmt)
|
||||||
continue;
|
continue;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (! result) {
|
if (! result.get()) {
|
||||||
current = result = new element_t;
|
result.reset(new element_t);
|
||||||
|
current = result.get();
|
||||||
} else {
|
} else {
|
||||||
current->next = new element_t;
|
current->next = new element_t;
|
||||||
current = current->next;
|
current = current->next;
|
||||||
|
|
@ -148,8 +150,9 @@ element_t * format_t::parse_elements(const std::string& fmt)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (q != buf) {
|
if (q != buf) {
|
||||||
if (! result) {
|
if (! result.get()) {
|
||||||
current = result = new element_t;
|
result.reset(new element_t);
|
||||||
|
current = result.get();
|
||||||
} else {
|
} else {
|
||||||
current->next = new element_t;
|
current->next = new element_t;
|
||||||
current = current->next;
|
current = current->next;
|
||||||
|
|
@ -158,7 +161,7 @@ element_t * format_t::parse_elements(const std::string& fmt)
|
||||||
current->chars = std::string(buf, q);
|
current->chars = std::string(buf, q);
|
||||||
}
|
}
|
||||||
|
|
||||||
return result;
|
return result.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
void format_t::format_elements(std::ostream& out,
|
void format_t::format_elements(std::ostream& out,
|
||||||
|
|
|
||||||
19
ledger.cc
19
ledger.cc
|
|
@ -55,7 +55,8 @@ bool journal_t::remove_entry(entry_t * entry)
|
||||||
entry_t * journal_t::derive_entry(strings_list::iterator i,
|
entry_t * journal_t::derive_entry(strings_list::iterator i,
|
||||||
strings_list::iterator end) const
|
strings_list::iterator end) const
|
||||||
{
|
{
|
||||||
entry_t * added = new entry_t;
|
std::auto_ptr<entry_t> added(new entry_t);
|
||||||
|
|
||||||
entry_t * matching = NULL;
|
entry_t * matching = NULL;
|
||||||
|
|
||||||
if (! parse_date((*i).c_str(), &added->date)) {
|
if (! parse_date((*i).c_str(), &added->date)) {
|
||||||
|
|
@ -97,17 +98,17 @@ entry_t * journal_t::derive_entry(strings_list::iterator i,
|
||||||
m_xact = matching->transactions.front();
|
m_xact = matching->transactions.front();
|
||||||
|
|
||||||
amount_t amt(*i++);
|
amount_t amt(*i++);
|
||||||
first = xact = new transaction_t(added, m_xact->account, amt, amt);
|
first = xact = new transaction_t(added.get(), m_xact->account, amt, amt);
|
||||||
|
added->add_transaction(xact);
|
||||||
|
|
||||||
if (xact->amount.commodity->symbol.empty()) {
|
if (xact->amount.commodity->symbol.empty()) {
|
||||||
xact->amount.commodity = m_xact->amount.commodity;
|
xact->amount.commodity = m_xact->amount.commodity;
|
||||||
xact->cost.commodity = m_xact->amount.commodity;
|
xact->cost.commodity = m_xact->amount.commodity;
|
||||||
}
|
}
|
||||||
added->add_transaction(xact);
|
|
||||||
|
|
||||||
m_xact = matching->transactions.back();
|
m_xact = matching->transactions.back();
|
||||||
|
|
||||||
xact = new transaction_t(added, m_xact->account,
|
xact = new transaction_t(added.get(), m_xact->account,
|
||||||
- first->amount, - first->amount);
|
- first->amount, - first->amount);
|
||||||
added->add_transaction(xact);
|
added->add_transaction(xact);
|
||||||
|
|
||||||
|
|
@ -149,12 +150,11 @@ entry_t * journal_t::derive_entry(strings_list::iterator i,
|
||||||
}
|
}
|
||||||
|
|
||||||
amount_t amt(*i++);
|
amount_t amt(*i++);
|
||||||
transaction_t * xact = new transaction_t(added, acct, amt, amt);
|
transaction_t * xact = new transaction_t(added.get(), acct, amt, amt);
|
||||||
|
added->add_transaction(xact);
|
||||||
|
|
||||||
if (! xact->amount.commodity)
|
if (! xact->amount.commodity)
|
||||||
xact->amount.commodity = cmdty;
|
xact->amount.commodity = cmdty;
|
||||||
|
|
||||||
added->add_transaction(xact);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if (i != end && std::string(*i++) == "-from" && i != end) {
|
if (i != end && std::string(*i++) == "-from" && i != end) {
|
||||||
|
|
@ -169,12 +169,13 @@ entry_t * journal_t::derive_entry(strings_list::iterator i,
|
||||||
std::exit(1);
|
std::exit(1);
|
||||||
}
|
}
|
||||||
transaction_t * xact
|
transaction_t * xact
|
||||||
= new transaction_t(added, matching->transactions.back()->account);
|
= new transaction_t(added.get(),
|
||||||
|
matching->transactions.back()->account);
|
||||||
added->add_transaction(xact);
|
added->add_transaction(xact);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return added;
|
return added.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
int parse_journal_file(const std::string& path,
|
int parse_journal_file(const std::string& path,
|
||||||
|
|
|
||||||
30
main.cc
30
main.cc
|
|
@ -374,8 +374,9 @@ int main(int argc, char * argv[], char * envp[])
|
||||||
// Setup local and global variables, depending on config settings.
|
// Setup local and global variables, depending on config settings.
|
||||||
|
|
||||||
std::auto_ptr<std::ostream> output_stream;
|
std::auto_ptr<std::ostream> output_stream;
|
||||||
std::auto_ptr<interval_t> report_interval;
|
|
||||||
std::time_t interval_begin;
|
interval_t report_interval;
|
||||||
|
std::time_t interval_begin = 0;
|
||||||
|
|
||||||
if (config->download_quotes)
|
if (config->download_quotes)
|
||||||
commodity_t::updater = new quotes_by_script(config->price_db,
|
commodity_t::updater = new quotes_by_script(config->price_db,
|
||||||
|
|
@ -391,13 +392,12 @@ int main(int argc, char * argv[], char * envp[])
|
||||||
try {
|
try {
|
||||||
std::istringstream stream(config->interval_text);
|
std::istringstream stream(config->interval_text);
|
||||||
std::time_t begin = -1, end = -1;
|
std::time_t begin = -1, end = -1;
|
||||||
report_interval.reset(interval_t::parse(stream, &begin, &end));
|
|
||||||
if (report_interval->seconds == 0 &&
|
report_interval = interval_t::parse(stream, &begin, &end);
|
||||||
report_interval->months == 0 &&
|
|
||||||
report_interval->years == 0)
|
|
||||||
report_interval.release();
|
|
||||||
|
|
||||||
if (begin != -1) {
|
if (begin != -1) {
|
||||||
|
interval_begin = begin;
|
||||||
|
|
||||||
if (! config->predicate.empty())
|
if (! config->predicate.empty())
|
||||||
config->predicate += "&";
|
config->predicate += "&";
|
||||||
char buf[32];
|
char buf[32];
|
||||||
|
|
@ -481,12 +481,6 @@ int main(int argc, char * argv[], char * envp[])
|
||||||
} else {
|
} else {
|
||||||
formatter.reset(new format_transactions(OUT(), format, nformat));
|
formatter.reset(new format_transactions(OUT(), format, nformat));
|
||||||
|
|
||||||
// sort_transactions will sort all the transactions it sees, based
|
|
||||||
// on the `sort_order' value expression.
|
|
||||||
if (sort_order.get())
|
|
||||||
formatter.reset(new sort_transactions(formatter.release(),
|
|
||||||
sort_order.get()));
|
|
||||||
|
|
||||||
// filter_transactions will only pass through transactions
|
// filter_transactions will only pass through transactions
|
||||||
// matching the `display_predicate'.
|
// matching the `display_predicate'.
|
||||||
formatter.reset(new filter_transactions(formatter.release(),
|
formatter.reset(new filter_transactions(formatter.release(),
|
||||||
|
|
@ -498,6 +492,12 @@ int main(int argc, char * argv[], char * envp[])
|
||||||
formatter.reset(new calc_transactions(formatter.release(),
|
formatter.reset(new calc_transactions(formatter.release(),
|
||||||
config->show_inverted));
|
config->show_inverted));
|
||||||
|
|
||||||
|
// sort_transactions will sort all the transactions it sees, based
|
||||||
|
// on the `sort_order' value expression.
|
||||||
|
if (sort_order.get())
|
||||||
|
formatter.reset(new sort_transactions(formatter.release(),
|
||||||
|
sort_order.get()));
|
||||||
|
|
||||||
// changed_value_transactions adds virtual transactions to the
|
// changed_value_transactions adds virtual transactions to the
|
||||||
// list to account for changes in market value of commodities,
|
// list to account for changes in market value of commodities,
|
||||||
// which otherwise would affect the running total unpredictably.
|
// which otherwise would affect the running total unpredictably.
|
||||||
|
|
@ -524,9 +524,9 @@ int main(int argc, char * argv[], char * envp[])
|
||||||
// of the week.
|
// of the week.
|
||||||
if (config->show_subtotal)
|
if (config->show_subtotal)
|
||||||
formatter.reset(new subtotal_transactions(formatter.release()));
|
formatter.reset(new subtotal_transactions(formatter.release()));
|
||||||
else if (report_interval.get())
|
else if (report_interval)
|
||||||
formatter.reset(new interval_transactions(formatter.release(),
|
formatter.reset(new interval_transactions(formatter.release(),
|
||||||
*report_interval,
|
report_interval,
|
||||||
interval_begin));
|
interval_begin));
|
||||||
else if (config->days_of_the_week)
|
else if (config->days_of_the_week)
|
||||||
formatter.reset(new dow_transactions(formatter.release()));
|
formatter.reset(new dow_transactions(formatter.release()));
|
||||||
|
|
|
||||||
23
textual.cc
23
textual.cc
|
|
@ -54,7 +54,7 @@ transaction_t * parse_transaction_text(char * line, account_t * account,
|
||||||
{
|
{
|
||||||
// The account will be determined later...
|
// The account will be determined later...
|
||||||
|
|
||||||
transaction_t * xact = new transaction_t(entry, NULL);
|
std::auto_ptr<transaction_t> xact(new transaction_t(entry, NULL));
|
||||||
|
|
||||||
// The call to `next_element' will skip past the account name,
|
// The call to `next_element' will skip past the account name,
|
||||||
// and return a pointer to the beginning of the amount. Once
|
// and return a pointer to the beginning of the amount. Once
|
||||||
|
|
@ -100,7 +100,7 @@ transaction_t * parse_transaction_text(char * line, account_t * account,
|
||||||
if (! xact->cost.commodity)
|
if (! xact->cost.commodity)
|
||||||
xact->cost.commodity = commodity_t::null_commodity;
|
xact->cost.commodity = commodity_t::null_commodity;
|
||||||
|
|
||||||
return xact;
|
return xact.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
transaction_t * parse_transaction(std::istream& in, account_t * account,
|
transaction_t * parse_transaction(std::istream& in, account_t * account,
|
||||||
|
|
@ -220,7 +220,7 @@ namespace {
|
||||||
|
|
||||||
entry_t * parse_entry(std::istream& in, account_t * master)
|
entry_t * parse_entry(std::istream& in, account_t * master)
|
||||||
{
|
{
|
||||||
entry_t * curr = new entry_t;
|
std::auto_ptr<entry_t> curr(new entry_t);
|
||||||
|
|
||||||
static char line[MAX_LINE + 1];
|
static char line[MAX_LINE + 1];
|
||||||
in.getline(line, MAX_LINE);
|
in.getline(line, MAX_LINE);
|
||||||
|
|
@ -267,7 +267,7 @@ entry_t * parse_entry(std::istream& in, account_t * master)
|
||||||
TIMER_START(entry_xacts);
|
TIMER_START(entry_xacts);
|
||||||
|
|
||||||
while (! in.eof() && (in.peek() == ' ' || in.peek() == '\t'))
|
while (! in.eof() && (in.peek() == ' ' || in.peek() == '\t'))
|
||||||
if (transaction_t * xact = parse_transaction(in, master, curr))
|
if (transaction_t * xact = parse_transaction(in, master, curr.get()))
|
||||||
curr->add_transaction(xact);
|
curr->add_transaction(xact);
|
||||||
|
|
||||||
TIMER_STOP(entry_xacts);
|
TIMER_STOP(entry_xacts);
|
||||||
|
|
@ -276,14 +276,12 @@ entry_t * parse_entry(std::istream& in, account_t * master)
|
||||||
|
|
||||||
TIMER_START(entry_finish);
|
TIMER_START(entry_finish);
|
||||||
|
|
||||||
if (curr->transactions.empty() || ! finalize_entry(curr)) {
|
if (curr->transactions.empty() || ! finalize_entry(curr.get()))
|
||||||
delete curr;
|
return NULL; // ~auto_ptr will delete curr
|
||||||
return NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
TIMER_STOP(entry_finish);
|
TIMER_STOP(entry_finish);
|
||||||
|
|
||||||
return curr;
|
return curr.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
|
|
@ -380,7 +378,7 @@ unsigned int parse_textual_journal(std::istream& in, journal_t * journal,
|
||||||
|
|
||||||
struct std::tm when;
|
struct std::tm when;
|
||||||
if (strptime(date.c_str(), "%Y/%m/%d %H:%M:%S", &when)) {
|
if (strptime(date.c_str(), "%Y/%m/%d %H:%M:%S", &when)) {
|
||||||
entry_t * curr = new entry_t;
|
std::auto_ptr<entry_t> curr(new entry_t);
|
||||||
curr->date = std::mktime(&when);
|
curr->date = std::mktime(&when);
|
||||||
curr->state = entry_t::CLEARED;
|
curr->state = entry_t::CLEARED;
|
||||||
curr->code = "";
|
curr->code = "";
|
||||||
|
|
@ -394,11 +392,12 @@ unsigned int parse_textual_journal(std::istream& in, journal_t * journal,
|
||||||
time_commodity = amt.commodity;
|
time_commodity = amt.commodity;
|
||||||
|
|
||||||
transaction_t * xact
|
transaction_t * xact
|
||||||
= new transaction_t(curr, last_account, amt, amt,
|
= new transaction_t(curr.get(), last_account, amt, amt,
|
||||||
TRANSACTION_VIRTUAL);
|
TRANSACTION_VIRTUAL);
|
||||||
curr->add_transaction(xact);
|
curr->add_transaction(xact);
|
||||||
|
|
||||||
if (! finalize_entry(curr) || ! journal->add_entry(curr))
|
if (! finalize_entry(curr.get()) ||
|
||||||
|
! journal->add_entry(curr.release()))
|
||||||
assert(0);
|
assert(0);
|
||||||
|
|
||||||
count++;
|
count++;
|
||||||
|
|
|
||||||
170
valexpr.cc
170
valexpr.cc
|
|
@ -371,16 +371,16 @@ inline value_expr_t * parse_value_term(const char * p) {
|
||||||
|
|
||||||
value_expr_t * parse_value_term(std::istream& in)
|
value_expr_t * parse_value_term(std::istream& in)
|
||||||
{
|
{
|
||||||
value_expr_t * node = NULL;
|
std::auto_ptr<value_expr_t> node;
|
||||||
|
|
||||||
char c = peek_next_nonws(in);
|
char c = peek_next_nonws(in);
|
||||||
if (std::isdigit(c)) {
|
if (std::isdigit(c)) {
|
||||||
static char buf[2048];
|
static char buf[2048];
|
||||||
READ_INTO(in, buf, 2048, c, std::isdigit(c));
|
READ_INTO(in, buf, 2048, c, std::isdigit(c));
|
||||||
|
|
||||||
node = new value_expr_t(value_expr_t::CONSTANT_I);
|
node.reset(new value_expr_t(value_expr_t::CONSTANT_I));
|
||||||
node->constant_i = std::atol(buf);
|
node->constant_i = std::atol(buf);
|
||||||
return node;
|
return node.release();
|
||||||
}
|
}
|
||||||
else if (c == '{') {
|
else if (c == '{') {
|
||||||
static char buf[2048];
|
static char buf[2048];
|
||||||
|
|
@ -391,72 +391,72 @@ value_expr_t * parse_value_term(std::istream& in)
|
||||||
else
|
else
|
||||||
throw value_expr_error("Missing '}'");
|
throw value_expr_error("Missing '}'");
|
||||||
|
|
||||||
node = new value_expr_t(value_expr_t::CONSTANT_A);
|
node.reset(new value_expr_t(value_expr_t::CONSTANT_A));
|
||||||
node->constant_a.parse(buf);
|
node->constant_a.parse(buf);
|
||||||
return node;
|
return node.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
in.get(c);
|
in.get(c);
|
||||||
switch (c) {
|
switch (c) {
|
||||||
// Basic terms
|
// Basic terms
|
||||||
case 'N':
|
case 'N':
|
||||||
node = new value_expr_t(value_expr_t::CONSTANT_T);
|
node.reset(new value_expr_t(value_expr_t::CONSTANT_T));
|
||||||
node->constant_t = now;
|
node->constant_t = now;
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'a': node = new value_expr_t(value_expr_t::AMOUNT); break;
|
case 'a': node.reset(new value_expr_t(value_expr_t::AMOUNT)); break;
|
||||||
case 'c': node = new value_expr_t(value_expr_t::COST); break;
|
case 'c': node.reset(new value_expr_t(value_expr_t::COST)); break;
|
||||||
case 'd': node = new value_expr_t(value_expr_t::DATE); break;
|
case 'd': node.reset(new value_expr_t(value_expr_t::DATE)); break;
|
||||||
case 'X': node = new value_expr_t(value_expr_t::CLEARED); break;
|
case 'X': node.reset(new value_expr_t(value_expr_t::CLEARED)); break;
|
||||||
case 'R': node = new value_expr_t(value_expr_t::REAL); break;
|
case 'R': node.reset(new value_expr_t(value_expr_t::REAL)); break;
|
||||||
case 'n': node = new value_expr_t(value_expr_t::INDEX); break;
|
case 'n': node.reset(new value_expr_t(value_expr_t::INDEX)); break;
|
||||||
case 'l': node = new value_expr_t(value_expr_t::DEPTH); break;
|
case 'l': node.reset(new value_expr_t(value_expr_t::DEPTH)); break;
|
||||||
case 'B': node = new value_expr_t(value_expr_t::BALANCE); break;
|
case 'B': node.reset(new value_expr_t(value_expr_t::BALANCE)); break;
|
||||||
case 'O': node = new value_expr_t(value_expr_t::TOTAL); break;
|
case 'O': node.reset(new value_expr_t(value_expr_t::TOTAL)); break;
|
||||||
case 'C': node = new value_expr_t(value_expr_t::COST_TOTAL); break;
|
case 'C': node.reset(new value_expr_t(value_expr_t::COST_TOTAL)); break;
|
||||||
|
|
||||||
// Relating to format_t
|
// Relating to format_t
|
||||||
case 't': node = new value_expr_t(value_expr_t::VALUE_EXPR); break;
|
case 't': node.reset(new value_expr_t(value_expr_t::VALUE_EXPR)); break;
|
||||||
case 'T': node = new value_expr_t(value_expr_t::TOTAL_EXPR); break;
|
case 'T': node.reset(new value_expr_t(value_expr_t::TOTAL_EXPR)); break;
|
||||||
|
|
||||||
// Compound terms
|
// Compound terms
|
||||||
case 'v': node = parse_value_expr("P(a,d)"); break;
|
case 'v': node.reset(parse_value_expr("P(a,d)")); break;
|
||||||
case 'V': node = parse_value_term("P(O,d)"); break;
|
case 'V': node.reset(parse_value_term("P(O,d)")); break;
|
||||||
case 'g': node = parse_value_expr("v-c"); break;
|
case 'g': node.reset(parse_value_expr("v-c")); break;
|
||||||
case 'G': node = parse_value_expr("V-C"); break;
|
case 'G': node.reset(parse_value_expr("V-C")); break;
|
||||||
case 'o': node = parse_value_expr("d-b"); break;
|
case 'o': node.reset(parse_value_expr("d-b")); break;
|
||||||
case 'w': node = parse_value_expr("e-d"); break;
|
case 'w': node.reset(parse_value_expr("e-d")); break;
|
||||||
|
|
||||||
// Functions
|
// Functions
|
||||||
case '-':
|
case '-':
|
||||||
node = new value_expr_t(value_expr_t::F_NEG);
|
node.reset(new value_expr_t(value_expr_t::F_NEG));
|
||||||
node->left = parse_value_term(in);
|
node->left = parse_value_term(in);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'A':
|
case 'A':
|
||||||
node = new value_expr_t(value_expr_t::F_ABS);
|
node.reset(new value_expr_t(value_expr_t::F_ABS));
|
||||||
node->left = parse_value_term(in);
|
node->left = parse_value_term(in);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'S':
|
case 'S':
|
||||||
node = new value_expr_t(value_expr_t::F_STRIP);
|
node.reset(new value_expr_t(value_expr_t::F_STRIP));
|
||||||
node->left = parse_value_term(in);
|
node->left = parse_value_term(in);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'M':
|
case 'M':
|
||||||
node = new value_expr_t(value_expr_t::F_ARITH_MEAN);
|
node.reset(new value_expr_t(value_expr_t::F_ARITH_MEAN));
|
||||||
node->left = parse_value_term(in);
|
node->left = parse_value_term(in);
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case 'D': {
|
case 'D': {
|
||||||
node = new value_expr_t(value_expr_t::O_SUB);
|
node.reset(new value_expr_t(value_expr_t::O_SUB));
|
||||||
node->left = parse_value_term("a");
|
node->left = parse_value_term("a");
|
||||||
node->right = parse_value_term(in);
|
node->right = parse_value_term(in);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case 'P':
|
case 'P':
|
||||||
node = new value_expr_t(value_expr_t::F_VALUE);
|
node.reset(new value_expr_t(value_expr_t::F_VALUE));
|
||||||
if (peek_next_nonws(in) == '(') {
|
if (peek_next_nonws(in) == '(') {
|
||||||
in.get(c);
|
in.get(c);
|
||||||
node->left = parse_value_expr(in);
|
node->left = parse_value_expr(in);
|
||||||
|
|
@ -497,16 +497,16 @@ value_expr_t * parse_value_term(std::istream& in)
|
||||||
throw value_expr_error("Missing closing '/'");
|
throw value_expr_error("Missing closing '/'");
|
||||||
|
|
||||||
in.get(c);
|
in.get(c);
|
||||||
node = new value_expr_t(short_account_mask ?
|
node.reset(new value_expr_t(short_account_mask ?
|
||||||
value_expr_t::F_SHORT_ACCOUNT_MASK :
|
value_expr_t::F_SHORT_ACCOUNT_MASK :
|
||||||
(payee_mask ? value_expr_t::F_PAYEE_MASK :
|
(payee_mask ? value_expr_t::F_PAYEE_MASK :
|
||||||
value_expr_t::F_ACCOUNT_MASK));
|
value_expr_t::F_ACCOUNT_MASK)));
|
||||||
node->mask = new mask_t(buf);
|
node->mask = new mask_t(buf);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case '(':
|
case '(':
|
||||||
node = parse_value_expr(in);
|
node.reset(parse_value_expr(in));
|
||||||
if (peek_next_nonws(in) == ')')
|
if (peek_next_nonws(in) == ')')
|
||||||
in.get(c);
|
in.get(c);
|
||||||
else
|
else
|
||||||
|
|
@ -520,7 +520,7 @@ value_expr_t * parse_value_term(std::istream& in)
|
||||||
throw value_expr_error("Missing ']'");
|
throw value_expr_error("Missing ']'");
|
||||||
|
|
||||||
in.get(c);
|
in.get(c);
|
||||||
node = new value_expr_t(value_expr_t::CONSTANT_T);
|
node.reset(new value_expr_t(value_expr_t::CONSTANT_T));
|
||||||
if (! parse_date(buf, &node->constant_t))
|
if (! parse_date(buf, &node->constant_t))
|
||||||
throw value_expr_error("Failed to parse date");
|
throw value_expr_error("Failed to parse date");
|
||||||
break;
|
break;
|
||||||
|
|
@ -531,32 +531,30 @@ value_expr_t * parse_value_term(std::istream& in)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
return node;
|
return node.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
value_expr_t * parse_mul_expr(std::istream& in)
|
value_expr_t * parse_mul_expr(std::istream& in)
|
||||||
{
|
{
|
||||||
value_expr_t * node = NULL;
|
std::auto_ptr<value_expr_t> node(parse_value_term(in));
|
||||||
|
|
||||||
node = parse_value_term(in);
|
if (node.get() && ! in.eof()) {
|
||||||
|
|
||||||
if (node && ! in.eof()) {
|
|
||||||
char c = peek_next_nonws(in);
|
char c = peek_next_nonws(in);
|
||||||
while (c == '*' || c == '/') {
|
while (c == '*' || c == '/') {
|
||||||
in.get(c);
|
in.get(c);
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case '*': {
|
case '*': {
|
||||||
value_expr_t * prev = node;
|
std::auto_ptr<value_expr_t> prev(node.release());
|
||||||
node = new value_expr_t(value_expr_t::O_MUL);
|
node.reset(new value_expr_t(value_expr_t::O_MUL));
|
||||||
node->left = prev;
|
node->left = prev.release();
|
||||||
node->right = parse_value_term(in);
|
node->right = parse_value_term(in);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case '/': {
|
case '/': {
|
||||||
value_expr_t * prev = node;
|
std::auto_ptr<value_expr_t> prev(node.release());
|
||||||
node = new value_expr_t(value_expr_t::O_DIV);
|
node.reset(new value_expr_t(value_expr_t::O_DIV));
|
||||||
node->left = prev;
|
node->left = prev.release();
|
||||||
node->right = parse_value_term(in);
|
node->right = parse_value_term(in);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -565,32 +563,30 @@ value_expr_t * parse_mul_expr(std::istream& in)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return node;
|
return node.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
value_expr_t * parse_add_expr(std::istream& in)
|
value_expr_t * parse_add_expr(std::istream& in)
|
||||||
{
|
{
|
||||||
value_expr_t * node = NULL;
|
std::auto_ptr<value_expr_t> node(parse_mul_expr(in));
|
||||||
|
|
||||||
node = parse_mul_expr(in);
|
if (node.get() && ! in.eof()) {
|
||||||
|
|
||||||
if (node && ! in.eof()) {
|
|
||||||
char c = peek_next_nonws(in);
|
char c = peek_next_nonws(in);
|
||||||
while (c == '+' || c == '-') {
|
while (c == '+' || c == '-') {
|
||||||
in.get(c);
|
in.get(c);
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case '+': {
|
case '+': {
|
||||||
value_expr_t * prev = node;
|
std::auto_ptr<value_expr_t> prev(node.release());
|
||||||
node = new value_expr_t(value_expr_t::O_ADD);
|
node.reset(new value_expr_t(value_expr_t::O_ADD));
|
||||||
node->left = prev;
|
node->left = prev.release();
|
||||||
node->right = parse_mul_expr(in);
|
node->right = parse_mul_expr(in);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case '-': {
|
case '-': {
|
||||||
value_expr_t * prev = node;
|
std::auto_ptr<value_expr_t> prev(node.release());
|
||||||
node = new value_expr_t(value_expr_t::O_SUB);
|
node.reset(new value_expr_t(value_expr_t::O_SUB));
|
||||||
node->left = prev;
|
node->left = prev.release();
|
||||||
node->right = parse_mul_expr(in);
|
node->right = parse_mul_expr(in);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -599,56 +595,56 @@ value_expr_t * parse_add_expr(std::istream& in)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return node;
|
return node.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
value_expr_t * parse_logic_expr(std::istream& in)
|
value_expr_t * parse_logic_expr(std::istream& in)
|
||||||
{
|
{
|
||||||
value_expr_t * node = NULL;
|
std::auto_ptr<value_expr_t> node;
|
||||||
|
|
||||||
if (peek_next_nonws(in) == '!') {
|
if (peek_next_nonws(in) == '!') {
|
||||||
char c;
|
char c;
|
||||||
in.get(c);
|
in.get(c);
|
||||||
node = new value_expr_t(value_expr_t::O_NOT);
|
node.reset(new value_expr_t(value_expr_t::O_NOT));
|
||||||
node->left = parse_logic_expr(in);
|
node->left = parse_logic_expr(in);
|
||||||
return node;
|
return node.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
node = parse_add_expr(in);
|
node.reset(parse_add_expr(in));
|
||||||
|
|
||||||
if (node && ! in.eof()) {
|
if (node.get() && ! in.eof()) {
|
||||||
char c = peek_next_nonws(in);
|
char c = peek_next_nonws(in);
|
||||||
if (c == '=' || c == '<' || c == '>') {
|
if (c == '=' || c == '<' || c == '>') {
|
||||||
in.get(c);
|
in.get(c);
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case '=': {
|
case '=': {
|
||||||
value_expr_t * prev = node;
|
std::auto_ptr<value_expr_t> prev(node.release());
|
||||||
node = new value_expr_t(value_expr_t::O_EQ);
|
node.reset(new value_expr_t(value_expr_t::O_EQ));
|
||||||
node->left = prev;
|
node->left = prev.release();
|
||||||
node->right = parse_add_expr(in);
|
node->right = parse_add_expr(in);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case '<': {
|
case '<': {
|
||||||
value_expr_t * prev = node;
|
std::auto_ptr<value_expr_t> prev(node.release());
|
||||||
node = new value_expr_t(value_expr_t::O_LT);
|
node.reset(new value_expr_t(value_expr_t::O_LT));
|
||||||
if (peek_next_nonws(in) == '=') {
|
if (peek_next_nonws(in) == '=') {
|
||||||
in.get(c);
|
in.get(c);
|
||||||
node->kind = value_expr_t::O_LTE;
|
node->kind = value_expr_t::O_LTE;
|
||||||
}
|
}
|
||||||
node->left = prev;
|
node->left = prev.release();
|
||||||
node->right = parse_add_expr(in);
|
node->right = parse_add_expr(in);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case '>': {
|
case '>': {
|
||||||
value_expr_t * prev = node;
|
std::auto_ptr<value_expr_t> prev(node.release());
|
||||||
node = new value_expr_t(value_expr_t::O_GT);
|
node.reset(new value_expr_t(value_expr_t::O_GT));
|
||||||
if (peek_next_nonws(in) == '=') {
|
if (peek_next_nonws(in) == '=') {
|
||||||
in.get(c);
|
in.get(c);
|
||||||
node->kind = value_expr_t::O_GTE;
|
node->kind = value_expr_t::O_GTE;
|
||||||
}
|
}
|
||||||
node->left = prev;
|
node->left = prev.release();
|
||||||
node->right = parse_add_expr(in);
|
node->right = parse_add_expr(in);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -663,42 +659,40 @@ value_expr_t * parse_logic_expr(std::istream& in)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return node;
|
return node.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
value_expr_t * parse_value_expr(std::istream& in)
|
value_expr_t * parse_value_expr(std::istream& in)
|
||||||
{
|
{
|
||||||
value_expr_t * node = NULL;
|
std::auto_ptr<value_expr_t> node(parse_logic_expr(in));
|
||||||
|
|
||||||
node = parse_logic_expr(in);
|
if (node.get() && ! in.eof()) {
|
||||||
|
|
||||||
if (node && ! in.eof()) {
|
|
||||||
char c = peek_next_nonws(in);
|
char c = peek_next_nonws(in);
|
||||||
while (c == '&' || c == '|' || c == '?') {
|
while (c == '&' || c == '|' || c == '?') {
|
||||||
in.get(c);
|
in.get(c);
|
||||||
switch (c) {
|
switch (c) {
|
||||||
case '&': {
|
case '&': {
|
||||||
value_expr_t * prev = node;
|
std::auto_ptr<value_expr_t> prev(node.release());
|
||||||
node = new value_expr_t(value_expr_t::O_AND);
|
node.reset(new value_expr_t(value_expr_t::O_AND));
|
||||||
node->left = prev;
|
node->left = prev.release();
|
||||||
node->right = parse_logic_expr(in);
|
node->right = parse_logic_expr(in);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case '|': {
|
case '|': {
|
||||||
value_expr_t * prev = node;
|
std::auto_ptr<value_expr_t> prev(node.release());
|
||||||
node = new value_expr_t(value_expr_t::O_OR);
|
node.reset(new value_expr_t(value_expr_t::O_OR));
|
||||||
node->left = prev;
|
node->left = prev.release();
|
||||||
node->right = parse_logic_expr(in);
|
node->right = parse_logic_expr(in);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case '?': {
|
case '?': {
|
||||||
value_expr_t * prev = node;
|
std::auto_ptr<value_expr_t> prev(node.release());
|
||||||
node = new value_expr_t(value_expr_t::O_QUES);
|
node.reset(new value_expr_t(value_expr_t::O_QUES));
|
||||||
node->left = prev;
|
node->left = prev.release();
|
||||||
value_expr_t * choices = new value_expr_t(value_expr_t::O_COL);
|
value_expr_t * choices;
|
||||||
node->right = choices;
|
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 != ':') {
|
||||||
|
|
@ -722,7 +716,7 @@ value_expr_t * parse_value_expr(std::istream& in)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
return node;
|
return node.release();
|
||||||
}
|
}
|
||||||
|
|
||||||
#ifdef DEBUG_ENABLED
|
#ifdef DEBUG_ENABLED
|
||||||
|
|
|
||||||
7
walk.cc
7
walk.cc
|
|
@ -90,12 +90,11 @@ void changed_value_transactions::operator()(transaction_t * xact)
|
||||||
|
|
||||||
if (balance_t diff = cur_bal - prev_bal) {
|
if (balance_t diff = cur_bal - prev_bal) {
|
||||||
entry_t * entry = new entry_t;
|
entry_t * entry = new entry_t;
|
||||||
|
entry_temps.push_back(entry);
|
||||||
|
|
||||||
entry->payee = "Commodities revalued";
|
entry->payee = "Commodities revalued";
|
||||||
entry->date = current;
|
entry->date = current;
|
||||||
|
|
||||||
entry_temps.push_back(entry);
|
|
||||||
|
|
||||||
for (amounts_map::const_iterator i = diff.amounts.begin();
|
for (amounts_map::const_iterator i = diff.amounts.begin();
|
||||||
i != diff.amounts.end();
|
i != diff.amounts.end();
|
||||||
i++) {
|
i++) {
|
||||||
|
|
@ -138,10 +137,10 @@ void subtotal_transactions::flush(const char * spec_fmt)
|
||||||
}
|
}
|
||||||
|
|
||||||
entry_t * entry = new entry_t;
|
entry_t * entry = new entry_t;
|
||||||
entry->payee = buf;
|
|
||||||
|
|
||||||
entry_temps.push_back(entry);
|
entry_temps.push_back(entry);
|
||||||
|
|
||||||
|
entry->payee = buf;
|
||||||
|
|
||||||
for (balances_map::iterator i = balances.begin();
|
for (balances_map::iterator i = balances.begin();
|
||||||
i != balances.end();
|
i != balances.end();
|
||||||
i++) {
|
i++) {
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue