summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--binary.cc4
-rw-r--r--config.cc84
-rw-r--r--datetime.cc6
-rw-r--r--debug.cc78
-rw-r--r--debug.h13
-rw-r--r--option.cc9
-rw-r--r--option.h8
-rw-r--r--valexpr.cc3
8 files changed, 140 insertions, 65 deletions
diff --git a/binary.cc b/binary.cc
index 8f622cb7..1f0fc106 100644
--- a/binary.cc
+++ b/binary.cc
@@ -23,7 +23,7 @@ static std::vector<commodity_t *> commodities;
static commodity_t::ident_t c_ident;
-#ifdef RELEASE_LEVEL >= ALPHA
+#if RELEASE_LEVEL >= ALPHA
#define read_binary_guard(in, id) { \
unsigned short guard; \
in.read((char *)&guard, sizeof(guard)); \
@@ -252,7 +252,7 @@ unsigned int read_binary_journal(std::istream& in,
}
-#ifdef RELEASE_LEVEL >= ALPHA
+#if RELEASE_LEVEL >= ALPHA
#define write_binary_guard(in, id) { \
unsigned short guard = id; \
out.write((char *)&guard, sizeof(guard)); \
diff --git a/config.cc b/config.cc
index d96ce291..3a9ce1ac 100644
--- a/config.cc
+++ b/config.cc
@@ -113,21 +113,21 @@ Commands:\n\
DEF_OPT_HANDLERS();
-OPT_BEGIN(help, "h", false) {
+OPT_BEGIN(help, "h") {
option_help(std::cout);
std::exit(0);
} OPT_END(help);
-OPT_BEGIN(version, "v", false) {
+OPT_BEGIN(version, "v") {
show_version(std::cout);
std::exit(0);
} OPT_END(version);
-OPT_BEGIN(init, "i:", true) {
+OPT_BEGIN(init, "i:") {
config->init_file = optarg;
} OPT_END(init);
-OPT_BEGIN(file, "f:", true) {
+OPT_BEGIN(file, "f:") {
char * buf = new char[std::strlen(optarg) + 1];
std::strcpy(buf, optarg);
for (char * p = std::strtok(buf, ":");
@@ -137,16 +137,16 @@ OPT_BEGIN(file, "f:", true) {
delete[] buf;
} OPT_END(file);
-OPT_BEGIN(cache, ":", false) {
+OPT_BEGIN(cache, ":") {
config->cache_file = optarg;
} OPT_END(cache);
-OPT_BEGIN(output, "o:", false) {
+OPT_BEGIN(output, "o:") {
if (std::string(optarg) != "-")
config->output_file = optarg;
} OPT_END(output);
-OPT_BEGIN(set_price, "p:", true) {
+OPT_BEGIN(set_price, "p:") {
if (std::strchr(optarg, '='))
config->price_settings.push_back(optarg);
else
@@ -157,7 +157,7 @@ OPT_BEGIN(set_price, "p:", true) {
//
// Report filtering
-OPT_BEGIN(begin_date, "b:", false) {
+OPT_BEGIN(begin_date, "b:") {
if (! config->predicate.empty())
config->predicate += "&";
config->predicate += "(d>=[";
@@ -165,7 +165,7 @@ OPT_BEGIN(begin_date, "b:", false) {
config->predicate += "])";
} OPT_END(begin_date);
-OPT_BEGIN(end_date, "e:", false) {
+OPT_BEGIN(end_date, "e:") {
if (! config->predicate.empty())
config->predicate += "&";
config->predicate += "(d<[";
@@ -173,25 +173,25 @@ OPT_BEGIN(end_date, "e:", false) {
config->predicate += "])";
} OPT_END(end_date);
-OPT_BEGIN(current, "c", false) {
+OPT_BEGIN(current, "c") {
if (! config->predicate.empty())
config->predicate += "&";
config->predicate += "(d<t)";
} OPT_END(current);
-OPT_BEGIN(cleared, "C", false) {
+OPT_BEGIN(cleared, "C") {
if (! config->predicate.empty())
config->predicate += "&";
config->predicate += "X";
} OPT_END(cleared);
-OPT_BEGIN(uncleared, "U", false) {
+OPT_BEGIN(uncleared, "U") {
if (! config->predicate.empty())
config->predicate += "&";
config->predicate += "!X";
} OPT_END(uncleared);
-OPT_BEGIN(real, "R", false) {
+OPT_BEGIN(real, "R") {
if (! config->predicate.empty())
config->predicate += "&";
config->predicate += "R";
@@ -201,55 +201,55 @@ OPT_BEGIN(real, "R", false) {
//
// Output customization
-OPT_BEGIN(format, "F:", false) {
+OPT_BEGIN(format, "F:") {
config->format_string = optarg;
} OPT_END(format);
-OPT_BEGIN(date_format, "y:", false) {
+OPT_BEGIN(date_format, "y:") {
config->date_format = optarg;
} OPT_END(date_format);
-OPT_BEGIN(empty, "E", false) {
+OPT_BEGIN(empty, "E") {
config->show_empty = true;
} OPT_END(empty);
-OPT_BEGIN(collapse, "n", false) {
+OPT_BEGIN(collapse, "n") {
config->show_subtotals = false;
} OPT_END(collapse);
-OPT_BEGIN(show_all, "s", false) {
+OPT_BEGIN(show_all, "s") {
config->show_expanded = true;
} OPT_END(show_all);
-OPT_BEGIN(sort, "S:", false) {
+OPT_BEGIN(sort, "S:") {
config->sort_string = optarg;
} OPT_END(sort);
-OPT_BEGIN(related, "r", false) {
+OPT_BEGIN(related, "r") {
config->show_related = true;
} OPT_END(related);
-OPT_BEGIN(interval, "z:", false) {
+OPT_BEGIN(interval, "z:") {
config->interval_text = optarg;
} OPT_END(interval);
-OPT_BEGIN(weekly, "W", false) {
+OPT_BEGIN(weekly, "W") {
config->interval_text = "weekly";
} OPT_END(weekly);
-OPT_BEGIN(dow, "w", false) {
+OPT_BEGIN(dow, "w") {
config->days_of_the_week = true;
} OPT_END(dow);
-OPT_BEGIN(monthly, "M", false) {
+OPT_BEGIN(monthly, "M") {
config->interval_text = "monthly";
} OPT_END(monthly);
-OPT_BEGIN(yearly, "Y", false) {
+OPT_BEGIN(yearly, "Y") {
config->interval_text = "yearly";
} OPT_END(yearly);
-OPT_BEGIN(limit, "l:", false) {
+OPT_BEGIN(limit, "l:") {
if (! config->predicate.empty())
config->predicate += "&";
config->predicate += "(";
@@ -257,7 +257,7 @@ OPT_BEGIN(limit, "l:", false) {
config->predicate += ")";
} OPT_END(limit);
-OPT_BEGIN(display, "d:", false) {
+OPT_BEGIN(display, "d:") {
if (! config->display_predicate.empty())
config->display_predicate += "&";
config->display_predicate += "(";
@@ -265,20 +265,20 @@ OPT_BEGIN(display, "d:", false) {
config->display_predicate += ")";
} OPT_END(display);
-OPT_BEGIN(value, "t:", false) {
+OPT_BEGIN(value, "t:") {
config->value_expr = optarg;
} OPT_END(value);
-OPT_BEGIN(total, "T:", false) {
+OPT_BEGIN(total, "T:") {
config->total_expr = optarg;
} OPT_END(total);
-OPT_BEGIN(value_data, "j", false) {
+OPT_BEGIN(value_data, "j") {
config->value_expr = "S" + config->value_expr;
config->format_string = plot_value_fmt;
} OPT_END(value_data);
-OPT_BEGIN(total_data, "J", false) {
+OPT_BEGIN(total_data, "J") {
config->total_expr = "S" + config->total_expr;
config->format_string = plot_total_fmt;
} OPT_END(total_data);
@@ -287,36 +287,36 @@ OPT_BEGIN(total_data, "J", false) {
//
// Commodity reporting
-OPT_BEGIN(price_db, "P:", false) {
+OPT_BEGIN(price_db, "P:") {
config->price_db = optarg;
} OPT_END(price_db);
-OPT_BEGIN(price_exp, "L:", false) {
+OPT_BEGIN(price_exp, "L:") {
config->pricing_leeway = std::atol(optarg) * 60;
} OPT_END(price_exp);
-OPT_BEGIN(download, "Q", false) {
+OPT_BEGIN(download, "Q") {
config->download_quotes = true;
} OPT_END(download);
-OPT_BEGIN(quantity, "O", false) {
+OPT_BEGIN(quantity, "O") {
config->value_expr = "a";
config->total_expr = "T";
} OPT_END(quantity);
-OPT_BEGIN(basis, "B", false) {
+OPT_BEGIN(basis, "B") {
config->value_expr = "c";
config->total_expr = "C";
} OPT_END(basis);
-OPT_BEGIN(market, "V", false) {
+OPT_BEGIN(market, "V") {
config->show_revalued = true;
config->value_expr = "v";
config->total_expr = "V";
} OPT_END(market);
-OPT_BEGIN(gain, "G", false) {
+OPT_BEGIN(gain, "G") {
config->show_revalued =
config->show_revalued_only = true;
@@ -324,22 +324,22 @@ OPT_BEGIN(gain, "G", false) {
config->total_expr = "G";
} OPT_END(gain);
-OPT_BEGIN(average, "A", false) {
+OPT_BEGIN(average, "A") {
config->value_expr = "a";
config->total_expr = "MT";
} OPT_END(average);
-OPT_BEGIN(deviation, "D", false) {
+OPT_BEGIN(deviation, "D") {
config->value_expr = "a";
config->total_expr = "DMT";
} OPT_END(deviation);
-OPT_BEGIN(trend, "X", false) {
+OPT_BEGIN(trend, "X") {
config->value_expr = "a";
config->total_expr = "MDMT";
} OPT_END(trend);
-OPT_BEGIN(weighted_trend, "Z", false) {
+OPT_BEGIN(weighted_trend, "Z") {
config->value_expr = "a";
config->total_expr
= "MD(MT/(1+(((t-d)/(30*86400))<0?0:((t-d)/(30*86400)))))";
diff --git a/datetime.cc b/datetime.cc
index a2badd39..586722b5 100644
--- a/datetime.cc
+++ b/datetime.cc
@@ -169,14 +169,10 @@ bool quick_parse_date(char * date_str, std::time_t * result)
if (base == -1 || year != base_year) {
struct std::tm when;
-
- when.tm_hour = 0;
- when.tm_min = 0;
- when.tm_sec = 0;
+ std::memset(&when, 0, sizeof(when));
base_year = year == -1 ? now_tm->tm_year + 1900 : year;
when.tm_year = year == -1 ? now_tm->tm_year : year - 1900;
- when.tm_mon = 0;
when.tm_mday = 1;
base = std::mktime(&when);
diff --git a/debug.cc b/debug.cc
index d8139ecc..1f49fc9e 100644
--- a/debug.cc
+++ b/debug.cc
@@ -2,8 +2,79 @@
#ifdef DEBUG_ENABLED
+#include <map>
#include <fstream>
#include <cstdlib>
+#include <cstring>
+
+int offset = 0;
+
+std::map<void *, int> ptrs;
+
+#define PRINT_INC(x) { \
+ char buf[128]; \
+ std::sprintf(buf, "%d: %p: %s", ++offset, ptr, x); \
+ write(1, buf, std::strlen(buf)); \
+}
+
+#define PRINT_DEC(x) { \
+ char buf[128]; \
+ std::sprintf(buf, "%d: %p: %s", --offset, ptr, x); \
+ write(1, buf, std::strlen(buf)); \
+}
+
+void * operator new(std::size_t size) throw (std::bad_alloc) {
+ void * ptr = std::malloc(size);
+ if (DEBUG("ledger.debug.alloc")) {
+ PRINT_INC("void * operator new(std::size_t size) throw (std::bad_alloc)\n");
+ }
+ return ptr;
+}
+void * operator new[](std::size_t size) throw (std::bad_alloc) {
+ void * ptr = std::malloc(size);
+ if (DEBUG("ledger.debug.alloc")) {
+ PRINT_INC("void * operator new[](std::size_t) throw (std::bad_alloc)\n");
+ }
+ return ptr;
+}
+void * operator new(std::size_t size, const std::nothrow_t&) throw() {
+ void * ptr = std::malloc(size);
+ if (DEBUG("ledger.debug.alloc")) {
+ PRINT_INC("void * operator new(std::size_t size, const std::nothrow_t&) throw()\n");
+ }
+ return ptr;
+}
+void * operator new[](std::size_t size, const std::nothrow_t&) throw() {
+ void * ptr = std::malloc(size);
+ if (DEBUG("ledger.debug.alloc")) {
+ PRINT_INC("void * operator new[](std::size_t size, const std::nothrow_t&) throw()\n");
+ }
+ return ptr;
+}
+void operator delete(void * ptr) throw() {
+ if (DEBUG("ledger.debug.alloc")) {
+ PRINT_DEC("void operator delete(void * ptr) throw()\n");
+ }
+ std::free(ptr);
+}
+void operator delete[](void * ptr) throw() {
+ if (DEBUG("ledger.debug.alloc")) {
+ PRINT_DEC("void operator delete[](void * ptr) throw()\n");
+ }
+ std::free(ptr);
+}
+void operator delete(void * ptr, const std::nothrow_t&) throw() {
+ if (DEBUG("ledger.debug.alloc")) {
+ PRINT_DEC("void operator delete(void * ptr, const std::nothrow_t&) throw()\n");
+ }
+ std::free(ptr);
+}
+void operator delete[](void * ptr, const std::nothrow_t&) throw() {
+ if (DEBUG("ledger.debug.alloc")) {
+ PRINT_DEC("void operator delete[](void * ptr, const std::nothrow_t&) throw()\n");
+ }
+ std::free(ptr);
+}
namespace ledger {
@@ -19,16 +90,13 @@ static struct init_streams {
free_debug_stream = true;
}
}
-} _debug_init;
-
-static struct free_streams {
- ~free_streams() {
+ ~init_streams() {
if (free_debug_stream && debug_stream) {
delete debug_stream;
debug_stream = NULL;
}
}
-} _debug_cleanup;
+} _debug_init;
} // namespace ledger
diff --git a/debug.h b/debug.h
index 7fb97c7f..047741c2 100644
--- a/debug.h
+++ b/debug.h
@@ -139,4 +139,17 @@ extern std::ostream * warning_stream;
} // namespace ledger
+#ifdef DEBUG_ENABLED
+
+void * operator new(std::size_t) throw (std::bad_alloc);
+void * operator new[](std::size_t) throw (std::bad_alloc);
+void operator delete(void*) throw();
+void operator delete[](void*) throw();
+void * operator new(std::size_t, const std::nothrow_t&) throw();
+void * operator new[](std::size_t, const std::nothrow_t&) throw();
+void operator delete(void*, const std::nothrow_t&) throw();
+void operator delete[](void*, const std::nothrow_t&) throw();
+
+#endif // DEBUG_ENABLED
+
#endif // _DEBUG_H
diff --git a/option.cc b/option.cc
index 8a3303b3..ec55d41e 100644
--- a/option.cc
+++ b/option.cc
@@ -4,9 +4,8 @@
#include <cstdarg>
option_handler::option_handler(const std::string& label,
- const std::string& opt_chars,
- const bool _multiple)
- : handled(false), multiple(_multiple)
+ const std::string& opt_chars)
+ : handled(false)
{
option_t opt;
@@ -33,7 +32,7 @@ option_handler::option_handler(const std::string& label,
static inline void process_option(const option_t& opt,
const char * arg = NULL) {
- if (! opt.handler->handled || opt.handler->multiple) {
+ if (! opt.handler->handled) {
opt.handler->handle_option(arg);
opt.handler->handled = true;
}
@@ -43,7 +42,7 @@ bool process_option(const std::string& opt, const char * arg)
{
option_handler_map::iterator handler = option_handler::handlers.find(opt);
if (handler != option_handler::handlers.end()) {
- if (! (*handler).second->handled || (*handler).second->multiple) {
+ if (! (*handler).second->handled) {
(*handler).second->handle_option(arg);
(*handler).second->handled = true;
}
diff --git a/option.h b/option.h
index 943d5193..c930fc09 100644
--- a/option.h
+++ b/option.h
@@ -22,14 +22,12 @@ typedef std::pair<const std::string, option_handler *> option_handler_pair;
struct option_handler {
bool handled;
- bool multiple;
static std::vector<option_t> options;
static option_handler_map handlers;
option_handler(const std::string& label,
- const std::string& opt_chars,
- const bool _multiple);
+ const std::string& opt_chars);
virtual void handle_option(const char * arg = NULL) = 0;
};
@@ -43,9 +41,9 @@ void process_environment(char ** envp, const std::string& tag);
std::vector<option_t> option_handler::options; \
option_handler_map option_handler::handlers
-#define OPT_BEGIN(tag, chars, multi) \
+#define OPT_BEGIN(tag, chars) \
static struct tag ## _handler : public option_handler { \
- tag ## _handler() : option_handler(#tag, chars, multi) {} \
+ tag ## _handler() : option_handler(#tag, chars) {} \
virtual void handle_option(const char * optarg)
#define OPT_END(tag) } tag ## _handler_obj
diff --git a/valexpr.cc b/valexpr.cc
index c70c8ea1..f0eaa0e3 100644
--- a/valexpr.cc
+++ b/valexpr.cc
@@ -886,7 +886,8 @@ void dump_value_expr(std::ostream& out, const value_expr_t * node)
int main(int argc, char *argv[])
{
- ledger::dump_value_exp(std::cout, ledger::parse_value_expr(argv[1]));
+ std::auto_ptr<ledger::value_expr_t> expr(ledger::parse_value_expr(argv[1]));
+ ledger::dump_value_expr(std::cout, expr.get());
std::cout << std::endl;
}