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);
|
||||
}
|
||||
|
||||
interval_t * interval_t::parse(std::istream& in,
|
||||
std::time_t * begin,
|
||||
std::time_t * end)
|
||||
interval_t interval_t::parse(std::istream& in,
|
||||
std::time_t * begin,
|
||||
std::time_t * end)
|
||||
{
|
||||
unsigned long years = 0;
|
||||
unsigned long months = 0;
|
||||
|
|
@ -203,7 +203,8 @@ interval_t * interval_t::parse(std::istream& in,
|
|||
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)
|
||||
|
|
|
|||
11
datetime.h
11
datetime.h
|
|
@ -13,13 +13,18 @@ struct interval_t
|
|||
int months;
|
||||
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) {}
|
||||
|
||||
operator bool() const {
|
||||
return seconds > 0 || months > 0 || years > 0;
|
||||
}
|
||||
|
||||
std::time_t increment(const std::time_t);
|
||||
|
||||
static interval_t * parse(std::istream& in, std::time_t * begin,
|
||||
std::time_t * end);
|
||||
static interval_t parse(std::istream& in,
|
||||
std::time_t * begin,
|
||||
std::time_t * end);
|
||||
};
|
||||
|
||||
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 * result = NULL;
|
||||
std::auto_ptr<element_t> result;
|
||||
|
||||
element_t * current = NULL;
|
||||
|
||||
static char buf[1024];
|
||||
|
|
@ -57,8 +58,9 @@ element_t * format_t::parse_elements(const std::string& fmt)
|
|||
continue;
|
||||
}
|
||||
|
||||
if (! result) {
|
||||
current = result = new element_t;
|
||||
if (! result.get()) {
|
||||
result.reset(new element_t);
|
||||
current = result.get();
|
||||
} else {
|
||||
current->next = new element_t;
|
||||
current = current->next;
|
||||
|
|
@ -148,8 +150,9 @@ element_t * format_t::parse_elements(const std::string& fmt)
|
|||
}
|
||||
|
||||
if (q != buf) {
|
||||
if (! result) {
|
||||
current = result = new element_t;
|
||||
if (! result.get()) {
|
||||
result.reset(new element_t);
|
||||
current = result.get();
|
||||
} else {
|
||||
current->next = new element_t;
|
||||
current = current->next;
|
||||
|
|
@ -158,7 +161,7 @@ element_t * format_t::parse_elements(const std::string& fmt)
|
|||
current->chars = std::string(buf, q);
|
||||
}
|
||||
|
||||
return result;
|
||||
return result.release();
|
||||
}
|
||||
|
||||
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,
|
||||
strings_list::iterator end) const
|
||||
{
|
||||
entry_t * added = new entry_t;
|
||||
std::auto_ptr<entry_t> added(new entry_t);
|
||||
|
||||
entry_t * matching = NULL;
|
||||
|
||||
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();
|
||||
|
||||
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()) {
|
||||
xact->amount.commodity = m_xact->amount.commodity;
|
||||
xact->cost.commodity = m_xact->amount.commodity;
|
||||
}
|
||||
added->add_transaction(xact);
|
||||
|
||||
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);
|
||||
added->add_transaction(xact);
|
||||
|
||||
|
|
@ -149,12 +150,11 @@ entry_t * journal_t::derive_entry(strings_list::iterator 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)
|
||||
xact->amount.commodity = cmdty;
|
||||
|
||||
added->add_transaction(xact);
|
||||
}
|
||||
|
||||
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);
|
||||
}
|
||||
transaction_t * xact
|
||||
= new transaction_t(added, matching->transactions.back()->account);
|
||||
= new transaction_t(added.get(),
|
||||
matching->transactions.back()->account);
|
||||
added->add_transaction(xact);
|
||||
}
|
||||
}
|
||||
|
||||
return added;
|
||||
return added.release();
|
||||
}
|
||||
|
||||
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.
|
||||
|
||||
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)
|
||||
commodity_t::updater = new quotes_by_script(config->price_db,
|
||||
|
|
@ -391,13 +392,12 @@ int main(int argc, char * argv[], char * envp[])
|
|||
try {
|
||||
std::istringstream stream(config->interval_text);
|
||||
std::time_t begin = -1, end = -1;
|
||||
report_interval.reset(interval_t::parse(stream, &begin, &end));
|
||||
if (report_interval->seconds == 0 &&
|
||||
report_interval->months == 0 &&
|
||||
report_interval->years == 0)
|
||||
report_interval.release();
|
||||
|
||||
report_interval = interval_t::parse(stream, &begin, &end);
|
||||
|
||||
if (begin != -1) {
|
||||
interval_begin = begin;
|
||||
|
||||
if (! config->predicate.empty())
|
||||
config->predicate += "&";
|
||||
char buf[32];
|
||||
|
|
@ -481,12 +481,6 @@ int main(int argc, char * argv[], char * envp[])
|
|||
} else {
|
||||
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
|
||||
// matching the `display_predicate'.
|
||||
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(),
|
||||
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
|
||||
// list to account for changes in market value of commodities,
|
||||
// which otherwise would affect the running total unpredictably.
|
||||
|
|
@ -524,9 +524,9 @@ int main(int argc, char * argv[], char * envp[])
|
|||
// of the week.
|
||||
if (config->show_subtotal)
|
||||
formatter.reset(new subtotal_transactions(formatter.release()));
|
||||
else if (report_interval.get())
|
||||
else if (report_interval)
|
||||
formatter.reset(new interval_transactions(formatter.release(),
|
||||
*report_interval,
|
||||
report_interval,
|
||||
interval_begin));
|
||||
else if (config->days_of_the_week)
|
||||
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...
|
||||
|
||||
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,
|
||||
// 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)
|
||||
xact->cost.commodity = commodity_t::null_commodity;
|
||||
|
||||
return xact;
|
||||
return xact.release();
|
||||
}
|
||||
|
||||
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 * curr = new entry_t;
|
||||
std::auto_ptr<entry_t> curr(new entry_t);
|
||||
|
||||
static char line[MAX_LINE + 1];
|
||||
in.getline(line, MAX_LINE);
|
||||
|
|
@ -267,7 +267,7 @@ entry_t * parse_entry(std::istream& in, account_t * master)
|
|||
TIMER_START(entry_xacts);
|
||||
|
||||
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);
|
||||
|
||||
TIMER_STOP(entry_xacts);
|
||||
|
|
@ -276,14 +276,12 @@ entry_t * parse_entry(std::istream& in, account_t * master)
|
|||
|
||||
TIMER_START(entry_finish);
|
||||
|
||||
if (curr->transactions.empty() || ! finalize_entry(curr)) {
|
||||
delete curr;
|
||||
return NULL;
|
||||
}
|
||||
if (curr->transactions.empty() || ! finalize_entry(curr.get()))
|
||||
return NULL; // ~auto_ptr will delete curr
|
||||
|
||||
TIMER_STOP(entry_finish);
|
||||
|
||||
return curr;
|
||||
return curr.release();
|
||||
}
|
||||
|
||||
template <typename T>
|
||||
|
|
@ -380,7 +378,7 @@ unsigned int parse_textual_journal(std::istream& in, journal_t * journal,
|
|||
|
||||
struct std::tm 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->state = entry_t::CLEARED;
|
||||
curr->code = "";
|
||||
|
|
@ -394,11 +392,12 @@ unsigned int parse_textual_journal(std::istream& in, journal_t * journal,
|
|||
time_commodity = amt.commodity;
|
||||
|
||||
transaction_t * xact
|
||||
= new transaction_t(curr, last_account, amt, amt,
|
||||
= new transaction_t(curr.get(), last_account, amt, amt,
|
||||
TRANSACTION_VIRTUAL);
|
||||
curr->add_transaction(xact);
|
||||
|
||||
if (! finalize_entry(curr) || ! journal->add_entry(curr))
|
||||
if (! finalize_entry(curr.get()) ||
|
||||
! journal->add_entry(curr.release()))
|
||||
assert(0);
|
||||
|
||||
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 * node = NULL;
|
||||
std::auto_ptr<value_expr_t> node;
|
||||
|
||||
char c = peek_next_nonws(in);
|
||||
if (std::isdigit(c)) {
|
||||
static char buf[2048];
|
||||
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);
|
||||
return node;
|
||||
return node.release();
|
||||
}
|
||||
else if (c == '{') {
|
||||
static char buf[2048];
|
||||
|
|
@ -391,72 +391,72 @@ value_expr_t * parse_value_term(std::istream& in)
|
|||
else
|
||||
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);
|
||||
return node;
|
||||
return node.release();
|
||||
}
|
||||
|
||||
in.get(c);
|
||||
switch (c) {
|
||||
// Basic terms
|
||||
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;
|
||||
break;
|
||||
|
||||
case 'a': node = new value_expr_t(value_expr_t::AMOUNT); break;
|
||||
case 'c': node = new value_expr_t(value_expr_t::COST); break;
|
||||
case 'd': node = new value_expr_t(value_expr_t::DATE); break;
|
||||
case 'X': node = new value_expr_t(value_expr_t::CLEARED); break;
|
||||
case 'R': node = new value_expr_t(value_expr_t::REAL); break;
|
||||
case 'n': node = new value_expr_t(value_expr_t::INDEX); break;
|
||||
case 'l': node = new value_expr_t(value_expr_t::DEPTH); break;
|
||||
case 'B': node = new value_expr_t(value_expr_t::BALANCE); break;
|
||||
case 'O': node = new value_expr_t(value_expr_t::TOTAL); break;
|
||||
case 'C': node = new value_expr_t(value_expr_t::COST_TOTAL); break;
|
||||
case 'a': node.reset(new value_expr_t(value_expr_t::AMOUNT)); break;
|
||||
case 'c': node.reset(new value_expr_t(value_expr_t::COST)); break;
|
||||
case 'd': node.reset(new value_expr_t(value_expr_t::DATE)); break;
|
||||
case 'X': node.reset(new value_expr_t(value_expr_t::CLEARED)); break;
|
||||
case 'R': node.reset(new value_expr_t(value_expr_t::REAL)); break;
|
||||
case 'n': node.reset(new value_expr_t(value_expr_t::INDEX)); break;
|
||||
case 'l': node.reset(new value_expr_t(value_expr_t::DEPTH)); break;
|
||||
case 'B': node.reset(new value_expr_t(value_expr_t::BALANCE)); break;
|
||||
case 'O': node.reset(new value_expr_t(value_expr_t::TOTAL)); break;
|
||||
case 'C': node.reset(new value_expr_t(value_expr_t::COST_TOTAL)); break;
|
||||
|
||||
// Relating to format_t
|
||||
case 't': node = 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::VALUE_EXPR)); break;
|
||||
case 'T': node.reset(new value_expr_t(value_expr_t::TOTAL_EXPR)); break;
|
||||
|
||||
// Compound terms
|
||||
case 'v': node = parse_value_expr("P(a,d)"); break;
|
||||
case 'V': node = parse_value_term("P(O,d)"); break;
|
||||
case 'g': node = parse_value_expr("v-c"); break;
|
||||
case 'G': node = parse_value_expr("V-C"); break;
|
||||
case 'o': node = parse_value_expr("d-b"); break;
|
||||
case 'w': node = parse_value_expr("e-d"); break;
|
||||
case 'v': node.reset(parse_value_expr("P(a,d)")); break;
|
||||
case 'V': node.reset(parse_value_term("P(O,d)")); break;
|
||||
case 'g': node.reset(parse_value_expr("v-c")); break;
|
||||
case 'G': node.reset(parse_value_expr("V-C")); break;
|
||||
case 'o': node.reset(parse_value_expr("d-b")); break;
|
||||
case 'w': node.reset(parse_value_expr("e-d")); break;
|
||||
|
||||
// Functions
|
||||
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);
|
||||
break;
|
||||
|
||||
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);
|
||||
break;
|
||||
|
||||
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);
|
||||
break;
|
||||
|
||||
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);
|
||||
break;
|
||||
|
||||
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->right = parse_value_term(in);
|
||||
break;
|
||||
}
|
||||
|
||||
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) == '(') {
|
||||
in.get(c);
|
||||
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 '/'");
|
||||
|
||||
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 :
|
||||
(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);
|
||||
break;
|
||||
}
|
||||
|
||||
case '(':
|
||||
node = parse_value_expr(in);
|
||||
node.reset(parse_value_expr(in));
|
||||
if (peek_next_nonws(in) == ')')
|
||||
in.get(c);
|
||||
else
|
||||
|
|
@ -520,7 +520,7 @@ value_expr_t * parse_value_term(std::istream& in)
|
|||
throw value_expr_error("Missing ']'");
|
||||
|
||||
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))
|
||||
throw value_expr_error("Failed to parse date");
|
||||
break;
|
||||
|
|
@ -531,32 +531,30 @@ value_expr_t * parse_value_term(std::istream& in)
|
|||
break;
|
||||
}
|
||||
|
||||
return node;
|
||||
return node.release();
|
||||
}
|
||||
|
||||
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 && ! in.eof()) {
|
||||
if (node.get() && ! in.eof()) {
|
||||
char c = peek_next_nonws(in);
|
||||
while (c == '*' || c == '/') {
|
||||
in.get(c);
|
||||
switch (c) {
|
||||
case '*': {
|
||||
value_expr_t * prev = node;
|
||||
node = new value_expr_t(value_expr_t::O_MUL);
|
||||
node->left = prev;
|
||||
std::auto_ptr<value_expr_t> prev(node.release());
|
||||
node.reset(new value_expr_t(value_expr_t::O_MUL));
|
||||
node->left = prev.release();
|
||||
node->right = parse_value_term(in);
|
||||
break;
|
||||
}
|
||||
|
||||
case '/': {
|
||||
value_expr_t * prev = node;
|
||||
node = new value_expr_t(value_expr_t::O_DIV);
|
||||
node->left = prev;
|
||||
std::auto_ptr<value_expr_t> prev(node.release());
|
||||
node.reset(new value_expr_t(value_expr_t::O_DIV));
|
||||
node->left = prev.release();
|
||||
node->right = parse_value_term(in);
|
||||
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 * node = NULL;
|
||||
std::auto_ptr<value_expr_t> node(parse_mul_expr(in));
|
||||
|
||||
node = parse_mul_expr(in);
|
||||
|
||||
if (node && ! in.eof()) {
|
||||
if (node.get() && ! in.eof()) {
|
||||
char c = peek_next_nonws(in);
|
||||
while (c == '+' || c == '-') {
|
||||
in.get(c);
|
||||
switch (c) {
|
||||
case '+': {
|
||||
value_expr_t * prev = node;
|
||||
node = new value_expr_t(value_expr_t::O_ADD);
|
||||
node->left = prev;
|
||||
std::auto_ptr<value_expr_t> prev(node.release());
|
||||
node.reset(new value_expr_t(value_expr_t::O_ADD));
|
||||
node->left = prev.release();
|
||||
node->right = parse_mul_expr(in);
|
||||
break;
|
||||
}
|
||||
|
||||
case '-': {
|
||||
value_expr_t * prev = node;
|
||||
node = new value_expr_t(value_expr_t::O_SUB);
|
||||
node->left = prev;
|
||||
std::auto_ptr<value_expr_t> prev(node.release());
|
||||
node.reset(new value_expr_t(value_expr_t::O_SUB));
|
||||
node->left = prev.release();
|
||||
node->right = parse_mul_expr(in);
|
||||
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 * node = NULL;
|
||||
std::auto_ptr<value_expr_t> node;
|
||||
|
||||
if (peek_next_nonws(in) == '!') {
|
||||
char 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);
|
||||
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);
|
||||
if (c == '=' || c == '<' || c == '>') {
|
||||
in.get(c);
|
||||
switch (c) {
|
||||
case '=': {
|
||||
value_expr_t * prev = node;
|
||||
node = new value_expr_t(value_expr_t::O_EQ);
|
||||
node->left = prev;
|
||||
std::auto_ptr<value_expr_t> prev(node.release());
|
||||
node.reset(new value_expr_t(value_expr_t::O_EQ));
|
||||
node->left = prev.release();
|
||||
node->right = parse_add_expr(in);
|
||||
break;
|
||||
}
|
||||
|
||||
case '<': {
|
||||
value_expr_t * prev = node;
|
||||
node = new value_expr_t(value_expr_t::O_LT);
|
||||
std::auto_ptr<value_expr_t> prev(node.release());
|
||||
node.reset(new value_expr_t(value_expr_t::O_LT));
|
||||
if (peek_next_nonws(in) == '=') {
|
||||
in.get(c);
|
||||
node->kind = value_expr_t::O_LTE;
|
||||
}
|
||||
node->left = prev;
|
||||
node->left = prev.release();
|
||||
node->right = parse_add_expr(in);
|
||||
break;
|
||||
}
|
||||
|
||||
case '>': {
|
||||
value_expr_t * prev = node;
|
||||
node = new value_expr_t(value_expr_t::O_GT);
|
||||
std::auto_ptr<value_expr_t> prev(node.release());
|
||||
node.reset(new value_expr_t(value_expr_t::O_GT));
|
||||
if (peek_next_nonws(in) == '=') {
|
||||
in.get(c);
|
||||
node->kind = value_expr_t::O_GTE;
|
||||
}
|
||||
node->left = prev;
|
||||
node->left = prev.release();
|
||||
node->right = parse_add_expr(in);
|
||||
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 * node = NULL;
|
||||
std::auto_ptr<value_expr_t> node(parse_logic_expr(in));
|
||||
|
||||
node = parse_logic_expr(in);
|
||||
|
||||
if (node && ! in.eof()) {
|
||||
if (node.get() && ! in.eof()) {
|
||||
char c = peek_next_nonws(in);
|
||||
while (c == '&' || c == '|' || c == '?') {
|
||||
in.get(c);
|
||||
switch (c) {
|
||||
case '&': {
|
||||
value_expr_t * prev = node;
|
||||
node = new value_expr_t(value_expr_t::O_AND);
|
||||
node->left = prev;
|
||||
std::auto_ptr<value_expr_t> prev(node.release());
|
||||
node.reset(new value_expr_t(value_expr_t::O_AND));
|
||||
node->left = prev.release();
|
||||
node->right = parse_logic_expr(in);
|
||||
break;
|
||||
}
|
||||
|
||||
case '|': {
|
||||
value_expr_t * prev = node;
|
||||
node = new value_expr_t(value_expr_t::O_OR);
|
||||
node->left = prev;
|
||||
std::auto_ptr<value_expr_t> prev(node.release());
|
||||
node.reset(new value_expr_t(value_expr_t::O_OR));
|
||||
node->left = prev.release();
|
||||
node->right = parse_logic_expr(in);
|
||||
break;
|
||||
}
|
||||
|
||||
case '?': {
|
||||
value_expr_t * prev = node;
|
||||
node = new value_expr_t(value_expr_t::O_QUES);
|
||||
node->left = prev;
|
||||
value_expr_t * choices = new value_expr_t(value_expr_t::O_COL);
|
||||
node->right = choices;
|
||||
std::auto_ptr<value_expr_t> prev(node.release());
|
||||
node.reset(new value_expr_t(value_expr_t::O_QUES));
|
||||
node->left = prev.release();
|
||||
value_expr_t * choices;
|
||||
node->right = choices = new value_expr_t(value_expr_t::O_COL);
|
||||
choices->left = parse_logic_expr(in);
|
||||
c = peek_next_nonws(in);
|
||||
if (c != ':') {
|
||||
|
|
@ -722,7 +716,7 @@ value_expr_t * parse_value_expr(std::istream& in)
|
|||
}
|
||||
}
|
||||
|
||||
return node;
|
||||
return node.release();
|
||||
}
|
||||
|
||||
#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) {
|
||||
entry_t * entry = new entry_t;
|
||||
entry_temps.push_back(entry);
|
||||
|
||||
entry->payee = "Commodities revalued";
|
||||
entry->date = current;
|
||||
|
||||
entry_temps.push_back(entry);
|
||||
|
||||
for (amounts_map::const_iterator i = diff.amounts.begin();
|
||||
i != diff.amounts.end();
|
||||
i++) {
|
||||
|
|
@ -138,10 +137,10 @@ void subtotal_transactions::flush(const char * spec_fmt)
|
|||
}
|
||||
|
||||
entry_t * entry = new entry_t;
|
||||
entry->payee = buf;
|
||||
|
||||
entry_temps.push_back(entry);
|
||||
|
||||
entry->payee = buf;
|
||||
|
||||
for (balances_map::iterator i = balances.begin();
|
||||
i != balances.end();
|
||||
i++) {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue