diff options
-rw-r--r-- | datetime.cc | 9 | ||||
-rw-r--r-- | datetime.h | 11 | ||||
-rw-r--r-- | format.cc | 15 | ||||
-rw-r--r-- | ledger.cc | 19 | ||||
-rw-r--r-- | main.cc | 30 | ||||
-rw-r--r-- | textual.cc | 23 | ||||
-rw-r--r-- | valexpr.cc | 170 | ||||
-rw-r--r-- | walk.cc | 7 |
8 files changed, 143 insertions, 141 deletions
diff --git a/datetime.cc b/datetime.cc index 0714c4ad..5ddcecd2 100644 --- a/datetime.cc +++ b/datetime.cc @@ -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) @@ -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; @@ -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, @@ -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, @@ -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())); @@ -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++; @@ -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; - - node = parse_mul_expr(in); + std::auto_ptr<value_expr_t> 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; - - node = parse_logic_expr(in); + std::auto_ptr<value_expr_t> 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 @@ -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++) { |