Pounded the logging and memory tracing code into better shape.
This commit is contained in:
parent
d0e9822ed1
commit
a85bd282d7
16 changed files with 527 additions and 287 deletions
|
|
@ -180,18 +180,11 @@ if HAVE_LIBOFX
|
|||
PYLIBS += ofx
|
||||
endif
|
||||
|
||||
if DEBUG
|
||||
DEBUG_LEVEL = 4
|
||||
else
|
||||
DEBUG_LEVEL = 0
|
||||
endif
|
||||
|
||||
ledger.so: pyledger.cc libledger.la gdtoa/libgdtoa.la libpyledger.la
|
||||
SRCDIR="$(srcdir)" \
|
||||
CFLAGS="$(CPPFLAGS) -I$(srcdir) $(libledger_la_CPPFLAGS)" \
|
||||
LDFLAGS="$(LDFLAGS) -L. -L.libs -Lgdtoa -Lgdtoa/.libs" \
|
||||
PYLIBS="$(PYLIBS)" \
|
||||
DEBUG_LEVEL="$(DEBUG_LEVEL)" \
|
||||
python $(srcdir)/setup.py build --build-lib=.
|
||||
|
||||
install-exec-hook:
|
||||
|
|
@ -199,7 +192,6 @@ install-exec-hook:
|
|||
CFLAGS="$(CPPFLAGS) -I$(srcdir) $(libledger_la_CPPFLAGS)" \
|
||||
LDFLAGS="$(LDFLAGS) -L. -L.libs -Lgdtoa -Lgdtoa/.libs" \
|
||||
PYLIBS="$(PYLIBS)" \
|
||||
DEBUG_LEVEL="$(DEBUG_LEVEL)" \
|
||||
python $(srcdir)/setup.py install --prefix=$(prefix)
|
||||
|
||||
endif
|
||||
|
|
|
|||
|
|
@ -418,8 +418,6 @@ lisp_LISP = ledger.el timeclock.el
|
|||
@HAVE_BOOST_PYTHON_TRUE@ boost_regex boost_python gmp \
|
||||
@HAVE_BOOST_PYTHON_TRUE@ $(am__append_14) $(am__append_15) \
|
||||
@HAVE_BOOST_PYTHON_TRUE@ $(am__append_16)
|
||||
@DEBUG_FALSE@@HAVE_BOOST_PYTHON_TRUE@DEBUG_LEVEL = 0
|
||||
@DEBUG_TRUE@@HAVE_BOOST_PYTHON_TRUE@DEBUG_LEVEL = 4
|
||||
UnitTests_SOURCES = tests/UnitTests.cc \
|
||||
\
|
||||
tests/corelib/numerics/BasicAmount.cc \
|
||||
|
|
@ -1723,7 +1721,6 @@ dist-hook:
|
|||
@HAVE_BOOST_PYTHON_TRUE@ CFLAGS="$(CPPFLAGS) -I$(srcdir) $(libledger_la_CPPFLAGS)" \
|
||||
@HAVE_BOOST_PYTHON_TRUE@ LDFLAGS="$(LDFLAGS) -L. -L.libs -Lgdtoa -Lgdtoa/.libs" \
|
||||
@HAVE_BOOST_PYTHON_TRUE@ PYLIBS="$(PYLIBS)" \
|
||||
@HAVE_BOOST_PYTHON_TRUE@ DEBUG_LEVEL="$(DEBUG_LEVEL)" \
|
||||
@HAVE_BOOST_PYTHON_TRUE@ python $(srcdir)/setup.py build --build-lib=.
|
||||
|
||||
@HAVE_BOOST_PYTHON_TRUE@install-exec-hook:
|
||||
|
|
@ -1731,7 +1728,6 @@ dist-hook:
|
|||
@HAVE_BOOST_PYTHON_TRUE@ CFLAGS="$(CPPFLAGS) -I$(srcdir) $(libledger_la_CPPFLAGS)" \
|
||||
@HAVE_BOOST_PYTHON_TRUE@ LDFLAGS="$(LDFLAGS) -L. -L.libs -Lgdtoa -Lgdtoa/.libs" \
|
||||
@HAVE_BOOST_PYTHON_TRUE@ PYLIBS="$(PYLIBS)" \
|
||||
@HAVE_BOOST_PYTHON_TRUE@ DEBUG_LEVEL="$(DEBUG_LEVEL)" \
|
||||
@HAVE_BOOST_PYTHON_TRUE@ python $(srcdir)/setup.py install --prefix=$(prefix)
|
||||
|
||||
PyUnitTests: PyUnitTests.py
|
||||
|
|
|
|||
86
amount.cc
86
amount.cc
|
|
@ -106,11 +106,11 @@ base_commodities_map commodity_base_t::commodities;
|
|||
|
||||
commodity_base_t::updater_t * commodity_base_t::updater = NULL;
|
||||
|
||||
commodities_map commodity_t::commodities;
|
||||
commodities_array commodity_t::commodities_by_ident;
|
||||
bool commodity_t::commodities_sorted = false;
|
||||
commodity_t * commodity_t::null_commodity;
|
||||
commodity_t * commodity_t::default_commodity = NULL;
|
||||
commodities_map commodity_t::commodities;
|
||||
commodities_array * commodity_t::commodities_by_ident;
|
||||
bool commodity_t::commodities_sorted = false;
|
||||
commodity_t * commodity_t::null_commodity;
|
||||
commodity_t * commodity_t::default_commodity = NULL;
|
||||
#endif
|
||||
|
||||
void amount_t::initialize()
|
||||
|
|
@ -123,6 +123,8 @@ void amount_t::initialize()
|
|||
|
||||
commodity_base_t::updater = NULL;
|
||||
|
||||
commodity_t::commodities_by_ident = new commodities_array;
|
||||
|
||||
commodity_t::default_commodity = NULL;
|
||||
commodity_t::null_commodity = commodity_t::create("");
|
||||
commodity_t::null_commodity->add_flags(COMMODITY_STYLE_NOMARKET |
|
||||
|
|
@ -159,7 +161,9 @@ void amount_t::shutdown()
|
|||
|
||||
commodity_base_t::commodities.clear();
|
||||
commodity_t::commodities.clear();
|
||||
commodity_t::commodities_by_ident.clear();
|
||||
|
||||
delete commodity_t::commodities_by_ident;
|
||||
commodity_t::commodities_by_ident = NULL;
|
||||
|
||||
commodity_t::null_commodity = NULL;
|
||||
commodity_t::default_commodity = NULL;
|
||||
|
|
@ -337,7 +341,7 @@ amount_t::amount_t(const double val)
|
|||
void amount_t::_release()
|
||||
{
|
||||
DEBUG_("amounts.refs",
|
||||
quantity << " ref--, now " << (quantity->ref - 1));
|
||||
quantity << " ref--, now " << (quantity->ref - 1));
|
||||
if (--quantity->ref == 0) {
|
||||
if (! (quantity->flags & BIGINT_BULK_ALLOC))
|
||||
delete quantity;
|
||||
|
|
@ -379,7 +383,7 @@ void amount_t::_copy(const amount_t& amt)
|
|||
} else {
|
||||
quantity = amt.quantity;
|
||||
DEBUG_("amounts.refs",
|
||||
quantity << " ref++, now " << (quantity->ref + 1));
|
||||
quantity << " ref++, now " << (quantity->ref + 1));
|
||||
quantity->ref++;
|
||||
}
|
||||
}
|
||||
|
|
@ -1211,10 +1215,10 @@ bool parse_annotations(std::istream& in, amount_t& price,
|
|||
} while (true);
|
||||
|
||||
DEBUG_("amounts.commodities",
|
||||
"Parsed commodity annotations: "
|
||||
<< " price " << price << " "
|
||||
<< " date " << date << " "
|
||||
<< " tag " << tag);
|
||||
"Parsed commodity annotations: "
|
||||
<< " price " << price << " "
|
||||
<< " date " << date << " "
|
||||
<< " tag " << tag);
|
||||
|
||||
return has_date;
|
||||
}
|
||||
|
|
@ -1401,7 +1405,7 @@ void amount_t::read(std::istream& in)
|
|||
else if (ident == 0)
|
||||
commodity_ = commodity_t::null_commodity;
|
||||
else
|
||||
commodity_ = commodity_t::commodities_by_ident[ident - 1];
|
||||
commodity_ = (*commodity_t::commodities_by_ident)[ident - 1];
|
||||
|
||||
read_quantity(in);
|
||||
}
|
||||
|
|
@ -1415,7 +1419,7 @@ void amount_t::read(char *& data)
|
|||
else if (ident == 0)
|
||||
commodity_ = commodity_t::null_commodity;
|
||||
else
|
||||
commodity_ = commodity_t::commodities_by_ident[ident - 1];
|
||||
commodity_ = (*commodity_t::commodities_by_ident)[ident - 1];
|
||||
|
||||
read_quantity(data);
|
||||
}
|
||||
|
|
@ -1470,7 +1474,7 @@ void amount_t::read_quantity(char *& data)
|
|||
|
||||
quantity = (bigint_t *) (bigints + (index - 1) * sizeof(bigint_t));
|
||||
DEBUG_("amounts.refs",
|
||||
quantity << " ref++, now " << (quantity->ref + 1));
|
||||
quantity << " ref++, now " << (quantity->ref + 1));
|
||||
quantity->ref++;
|
||||
}
|
||||
}
|
||||
|
|
@ -1585,10 +1589,10 @@ void amount_t::annotate_commodity(const amount_t& tprice,
|
|||
assert(this_base);
|
||||
|
||||
DEBUG_("amounts.commodities", "Annotating commodity for amount "
|
||||
<< *this << std::endl
|
||||
<< " price " << tprice << " "
|
||||
<< " date " << tdate << " "
|
||||
<< " tag " << tag);
|
||||
<< *this << std::endl
|
||||
<< " price " << tprice << " "
|
||||
<< " date " << tdate << " "
|
||||
<< " tag " << tag);
|
||||
|
||||
commodity_t * ann_comm =
|
||||
annotated_commodity_t::find_or_create
|
||||
|
|
@ -1610,10 +1614,10 @@ amount_t amount_t::strip_annotations(const bool _keep_price,
|
|||
return *this;
|
||||
|
||||
DEBUG_("amounts.commodities", "Reducing commodity for amount "
|
||||
<< *this << std::endl
|
||||
<< " keep price " << _keep_price << " "
|
||||
<< " keep date " << _keep_date << " "
|
||||
<< " keep tag " << _keep_tag);
|
||||
<< *this << std::endl
|
||||
<< " keep price " << _keep_price << " "
|
||||
<< " keep date " << _keep_date << " "
|
||||
<< " keep tag " << _keep_tag);
|
||||
|
||||
annotated_commodity_t&
|
||||
ann_comm(static_cast<annotated_commodity_t&>(commodity()));
|
||||
|
|
@ -1647,7 +1651,7 @@ amount_t amount_t::price() const
|
|||
amount_t t(((annotated_commodity_t *)commodity_)->price);
|
||||
t *= number();
|
||||
DEBUG_("amounts.commodities",
|
||||
"Returning price of " << *this << " = " << t);
|
||||
"Returning price of " << *this << " = " << t);
|
||||
return t;
|
||||
}
|
||||
return *this;
|
||||
|
|
@ -1657,8 +1661,8 @@ moment_t amount_t::date() const
|
|||
{
|
||||
if (commodity_ && commodity_->annotated) {
|
||||
DEBUG_("amounts.commodities",
|
||||
"Returning date of " << *this << " = "
|
||||
<< ((annotated_commodity_t *)commodity_)->date);
|
||||
"Returning date of " << *this << " = "
|
||||
<< ((annotated_commodity_t *)commodity_)->date);
|
||||
return ((annotated_commodity_t *)commodity_)->date;
|
||||
}
|
||||
return moment_t();
|
||||
|
|
@ -1720,7 +1724,7 @@ bool commodity_t::valid() const
|
|||
{
|
||||
if (symbol().empty() && this != null_commodity) {
|
||||
DEBUG_("ledger.validate",
|
||||
"commodity_t: symbol().empty() && this != null_commodity");
|
||||
"commodity_t: symbol().empty() && this != null_commodity");
|
||||
return false;
|
||||
}
|
||||
|
||||
|
|
@ -1752,15 +1756,15 @@ commodity_t * commodity_t::create(const string& symbol)
|
|||
}
|
||||
|
||||
DEBUG_("amounts.commodities",
|
||||
"Creating commodity " << commodity->qualified_symbol);
|
||||
"Creating commodity " << commodity->qualified_symbol);
|
||||
|
||||
std::pair<commodities_map::iterator, bool> result
|
||||
= commodities.insert(commodities_pair(symbol, commodity.get()));
|
||||
if (! result.second)
|
||||
return NULL;
|
||||
|
||||
commodity->ident = commodities_by_ident.size();
|
||||
commodities_by_ident.push_back(commodity.get());
|
||||
commodity->ident = commodities_by_ident->size();
|
||||
commodities_by_ident->push_back(commodity.get());
|
||||
|
||||
// Start out the new commodity with the default commodity's flags
|
||||
// and precision, if one has been defined.
|
||||
|
|
@ -1896,11 +1900,11 @@ annotated_commodity_t::create(const commodity_t& comm,
|
|||
commodity->qualified_symbol = comm.symbol();
|
||||
|
||||
DEBUG_("amounts.commodities", "Creating annotated commodity "
|
||||
<< "symbol " << commodity->symbol()
|
||||
<< " key " << mapping_key << std::endl
|
||||
<< " price " << price << " "
|
||||
<< " date " << date << " "
|
||||
<< " tag " << tag);
|
||||
<< "symbol " << commodity->symbol()
|
||||
<< " key " << mapping_key << std::endl
|
||||
<< " price " << price << " "
|
||||
<< " date " << date << " "
|
||||
<< " tag " << tag);
|
||||
|
||||
// Add the fully annotated name to the map, so that this symbol may
|
||||
// quickly be found again.
|
||||
|
|
@ -1909,8 +1913,8 @@ annotated_commodity_t::create(const commodity_t& comm,
|
|||
if (! result.second)
|
||||
return NULL;
|
||||
|
||||
commodity->ident = commodities_by_ident.size();
|
||||
commodities_by_ident.push_back(commodity.get());
|
||||
commodity->ident = commodities_by_ident->size();
|
||||
commodities_by_ident->push_back(commodity.get());
|
||||
|
||||
return commodity.release();
|
||||
}
|
||||
|
|
@ -1931,10 +1935,10 @@ namespace {
|
|||
annotated_commodity_t::write_annotations(name, price, date, tag);
|
||||
|
||||
DEBUG_("amounts.commodities", "make_qualified_name for "
|
||||
<< comm.qualified_symbol << std::endl
|
||||
<< " price " << price << " "
|
||||
<< " date " << date << " "
|
||||
<< " tag " << tag);
|
||||
<< comm.qualified_symbol << std::endl
|
||||
<< " price " << price << " "
|
||||
<< " date " << date << " "
|
||||
<< " tag " << tag);
|
||||
|
||||
DEBUG_("amounts.commodities", "qualified_name is " << name.str());
|
||||
|
||||
|
|
|
|||
10
amount.h
10
amount.h
|
|
@ -554,11 +554,11 @@ class commodity_t
|
|||
public:
|
||||
// This map remembers all commodities that have been defined.
|
||||
|
||||
static commodities_map commodities;
|
||||
static commodities_array commodities_by_ident;
|
||||
static bool commodities_sorted;
|
||||
static commodity_t * null_commodity;
|
||||
static commodity_t * default_commodity;
|
||||
static commodities_map commodities;
|
||||
static commodities_array * commodities_by_ident;
|
||||
static bool commodities_sorted;
|
||||
static commodity_t * null_commodity;
|
||||
static commodity_t * default_commodity;
|
||||
|
||||
static commodity_t * create(const string& symbol);
|
||||
static commodity_t * find(const string& name);
|
||||
|
|
|
|||
|
|
@ -4,7 +4,7 @@ namespace ledger {
|
|||
|
||||
#if 0
|
||||
static unsigned long binary_magic_number = 0xFFEED765;
|
||||
#ifdef DEBUG_ENABLED
|
||||
#if defined(DEBUG_ON)
|
||||
static unsigned long format_version = 0x00030000;
|
||||
#else
|
||||
static unsigned long format_version = 0x00030000;
|
||||
|
|
|
|||
55
main.cc
55
main.cc
|
|
@ -67,8 +67,8 @@ static int read_and_report(report_t * report, int argc, char * argv[],
|
|||
TRACE(1, "Binary cache is " << session.cache_file);
|
||||
TRACE(1, "Main journal is " << session.data_file);
|
||||
|
||||
TRACE(1, "Based on option settings, binary cache " <<
|
||||
(session.use_cache ? "WILL " : "will NOT ") << "be used");
|
||||
if (! session.use_cache)
|
||||
INFO("The binary cache mechanism will not be used");
|
||||
|
||||
// Read the command word and create a command object based on it
|
||||
|
||||
|
|
@ -134,7 +134,7 @@ static int read_and_report(report_t * report, int argc, char * argv[],
|
|||
else if (verb == "parse") {
|
||||
xml::xpath_t expr(*arg);
|
||||
|
||||
if (session.verbose_mode) {
|
||||
IF_INFO() {
|
||||
std::cout << "Value expression tree:" << std::endl;
|
||||
expr.dump(std::cout);
|
||||
std::cout << std::endl;
|
||||
|
|
@ -231,7 +231,7 @@ static int read_and_report(report_t * report, int argc, char * argv[],
|
|||
if (verb == "expr") {
|
||||
xml::xpath_t expr(*arg);
|
||||
|
||||
if (session.verbose_mode) {
|
||||
IF_INFO() {
|
||||
*out << "Value expression tree:" << std::endl;
|
||||
expr.dump(*out);
|
||||
*out << std::endl;
|
||||
|
|
@ -370,25 +370,46 @@ static int read_and_report(report_t * report, int argc, char * argv[],
|
|||
return 0;
|
||||
}
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
extern int new_calls;
|
||||
extern unsigned long new_size;
|
||||
#endif
|
||||
|
||||
int main(int argc, char * argv[], char * envp[])
|
||||
{
|
||||
int status = 1;
|
||||
|
||||
#if defined(FULL_DEBUG)
|
||||
ledger::verify_enabled = true;
|
||||
#endif
|
||||
|
||||
for (int i = 1; i < argc; i++)
|
||||
if (argv[i][0] == '-' && argv[i][1] == '-') {
|
||||
#if defined(VERIFY_ON)
|
||||
if (std::strcmp(argv[i], "--verify") == 0)
|
||||
ledger::verify_enabled = true;
|
||||
#endif
|
||||
#if defined(DEBUG_ON)
|
||||
if (i + 1 < argc && std::strcmp(argv[i], "--debug") == 0) {
|
||||
ledger::_log_level = LOG_DEBUG;
|
||||
ledger::_log_category = argv[i + 1];
|
||||
i++;
|
||||
}
|
||||
#endif
|
||||
#if defined(TRACING_ON)
|
||||
if (i + 1 < argc && std::strcmp(argv[i], "--trace") == 0) {
|
||||
ledger::_log_level = LOG_TRACE;
|
||||
ledger::_trace_level = std::atoi(argv[i + 1]);
|
||||
i++;
|
||||
}
|
||||
#endif
|
||||
}
|
||||
|
||||
try {
|
||||
std::ios::sync_with_stdio(false);
|
||||
|
||||
#if DEBUG_LEVEL < BETA
|
||||
ledger::initialize();
|
||||
|
||||
#if ! defined(FULL_DEBUG)
|
||||
ledger::do_cleanup = false;
|
||||
#endif
|
||||
TRACE(1, "Ledger starting");
|
||||
|
||||
ledger::amount_t::initialize();
|
||||
|
||||
std::auto_ptr<ledger::session_t> session(new ledger::session_t);
|
||||
|
||||
#if 0
|
||||
|
|
@ -411,9 +432,6 @@ int main(int argc, char * argv[], char * envp[])
|
|||
if (! ledger::do_cleanup) {
|
||||
report.release();
|
||||
session.release();
|
||||
ledger::xml::xpath_t::lookahead.clear();
|
||||
} else {
|
||||
ledger::amount_t::shutdown();
|
||||
}
|
||||
}
|
||||
#if 0
|
||||
|
|
@ -446,11 +464,8 @@ int main(int argc, char * argv[], char * envp[])
|
|||
status = _status;
|
||||
}
|
||||
|
||||
IF_DEBUG_("ledger.trace.memory") {
|
||||
report_memory(std::cerr);
|
||||
std::cerr << "Total calls to new: " << new_calls << std::endl
|
||||
<< "Total memory new'd: " << new_size << std::endl;
|
||||
}
|
||||
if (ledger::do_cleanup)
|
||||
ledger::shutdown();
|
||||
|
||||
return status;
|
||||
}
|
||||
|
|
|
|||
7
ofx.cc
7
ofx.cc
|
|
@ -76,12 +76,11 @@ int ofx_proc_transaction_cb(struct OfxTransactionData data,
|
|||
|
||||
if (data.unitprice_valid && data.unitprice != 1.0) {
|
||||
std::ostringstream cstream;
|
||||
stream << - data.unitprice;
|
||||
xact->cost = new amount_t(stream.str() + " " + default_commodity->base_symbol());
|
||||
stream << - data.unitprice << " " << default_commodity->base_symbol();
|
||||
xact->cost = new amount_t(stream.str());
|
||||
}
|
||||
|
||||
DEBUG_("ledger.ofx.parse", "xact " << xact->amount
|
||||
<< " from " << *xact->account);
|
||||
DEBUG_("ofx.parse", "xact " << xact->amount << " from " << *xact->account);
|
||||
|
||||
if (data.date_initiated_valid)
|
||||
entry->_date = data.date_initiated;
|
||||
|
|
|
|||
16
register.cc
16
register.cc
|
|
@ -127,10 +127,6 @@ static void scan_for_transactions(std::ostream& out, const xml::node_t * node)
|
|||
void register_command::print_document(std::ostream& out,
|
||||
xml::document_t * doc)
|
||||
{
|
||||
#if DEBUG_LEVEL >= BETA
|
||||
unsigned long old_new_size = new_size;
|
||||
#endif
|
||||
|
||||
#if 1
|
||||
scan_for_transactions(out, doc->top);
|
||||
out.flush();
|
||||
|
|
@ -138,12 +134,6 @@ void register_command::print_document(std::ostream& out,
|
|||
value_t nodelist;
|
||||
xml::xpath_t::eval(nodelist, "//transaction", doc);
|
||||
|
||||
#if DEBUG_LEVEL >= BETA
|
||||
std::cerr << "Memory requested preparing report: "
|
||||
<< (new_size - old_new_size) << std::endl;
|
||||
old_new_size = new_size;
|
||||
#endif
|
||||
|
||||
const value_t::sequence_t * xact_list = nodelist.to_sequence();
|
||||
assert(xact_list);
|
||||
|
||||
|
|
@ -170,12 +160,6 @@ void register_command::print_document(std::ostream& out,
|
|||
<< xact->amount
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
#if DEBUG_LEVEL >= BETA
|
||||
std::cerr << "Memory requested generating report: "
|
||||
<< (new_size - old_new_size) << std::endl;
|
||||
old_new_size = new_size;
|
||||
#endif
|
||||
#endif
|
||||
}
|
||||
|
||||
|
|
|
|||
36
session.cc
36
session.cc
|
|
@ -62,13 +62,11 @@ journal_t * session_t::read_data(const string& master_account)
|
|||
|
||||
unsigned int entry_count = 0;
|
||||
|
||||
DEBUG_("ledger.cache",
|
||||
"3. use_cache = " << use_cache);
|
||||
DEBUG_("ledger.cache", "3. use_cache = " << use_cache);
|
||||
|
||||
if (use_cache && ! cache_file.empty() &&
|
||||
! data_file.empty()) {
|
||||
DEBUG_("ledger.cache",
|
||||
"using_cache " << cache_file);
|
||||
DEBUG_("ledger.cache", "using_cache " << cache_file);
|
||||
cache_dirty = true;
|
||||
if (access(cache_file.c_str(), R_OK) != -1) {
|
||||
std::ifstream stream(cache_file.c_str());
|
||||
|
|
@ -95,14 +93,12 @@ journal_t * session_t::read_data(const string& master_account)
|
|||
if (read_journal(journal->price_db, journal)) {
|
||||
throw_(exception, "Entries not allowed in price history file");
|
||||
} else {
|
||||
DEBUG_("ledger.cache",
|
||||
"read price database " << journal->price_db);
|
||||
DEBUG_("ledger.cache", "read price database " << journal->price_db);
|
||||
journal->sources.pop_back();
|
||||
}
|
||||
}
|
||||
|
||||
DEBUG_("ledger.cache",
|
||||
"rejected cache, parsing " << data_file);
|
||||
DEBUG_("ledger.cache", "rejected cache, parsing " << data_file);
|
||||
if (data_file == "-") {
|
||||
use_cache = false;
|
||||
journal->sources.push_back("<stdin>");
|
||||
|
|
@ -171,14 +167,26 @@ xml::xpath_t::op_t * session_t::lookup(const string& name)
|
|||
if (std::strncmp(p, "option_", 7) == 0) {
|
||||
p = p + 7;
|
||||
switch (*p) {
|
||||
case 'd':
|
||||
if (std::strcmp(p, "debug") == 0)
|
||||
return MAKE_FUNCTOR(session_t, option_debug);
|
||||
break;
|
||||
|
||||
case 'f':
|
||||
if (! *(p + 1) || std::strcmp(p, "file") == 0)
|
||||
return MAKE_FUNCTOR(session_t, option_file);
|
||||
break;
|
||||
|
||||
case 't':
|
||||
if (std::strcmp(p, "trace") == 0)
|
||||
return MAKE_FUNCTOR(session_t, option_trace);
|
||||
break;
|
||||
|
||||
case 'v':
|
||||
if (std::strcmp(p, "verbose") == 0)
|
||||
if (! *(p + 1) || std::strcmp(p, "verbose") == 0)
|
||||
return MAKE_FUNCTOR(session_t, option_verbose);
|
||||
else if (std::strcmp(p, "verify") == 0)
|
||||
return MAKE_FUNCTOR(session_t, option_verify);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
|
@ -192,7 +200,11 @@ xml::xpath_t::op_t * session_t::lookup(const string& name)
|
|||
// session_t object
|
||||
void initialize()
|
||||
{
|
||||
IF_VERIFY()
|
||||
initialize_memory_tracing();
|
||||
|
||||
amount_t::initialize();
|
||||
xml::xpath_t::initialize();
|
||||
}
|
||||
|
||||
void shutdown()
|
||||
|
|
@ -200,7 +212,13 @@ void shutdown()
|
|||
#if defined(USE_BOOST_PYTHON)
|
||||
shutdown_for_python();
|
||||
#endif
|
||||
xml::xpath_t::shutdown();
|
||||
amount_t::shutdown();
|
||||
|
||||
IF_VERIFY() {
|
||||
TRACE(1, "Shutting down memory trace");
|
||||
shutdown_memory_tracing();
|
||||
}
|
||||
}
|
||||
|
||||
} // namespace ledger
|
||||
|
|
|
|||
24
session.h
24
session.h
|
|
@ -32,10 +32,6 @@ class session_t : public xml::xpath_t::scope_t
|
|||
bool download_quotes;
|
||||
bool use_cache;
|
||||
bool cache_dirty;
|
||||
bool debug_mode;
|
||||
bool verbose_mode;
|
||||
bool trace_alloc_mode;
|
||||
bool trace_class_mode;
|
||||
|
||||
moment_t now;
|
||||
|
||||
|
|
@ -87,10 +83,6 @@ class session_t : public xml::xpath_t::scope_t
|
|||
download_quotes(false),
|
||||
use_cache(false),
|
||||
cache_dirty(false),
|
||||
debug_mode(false),
|
||||
verbose_mode(false),
|
||||
trace_alloc_mode(false),
|
||||
trace_class_mode(false),
|
||||
|
||||
now(now),
|
||||
|
||||
|
|
@ -164,6 +156,18 @@ class session_t : public xml::xpath_t::scope_t
|
|||
xml::xpath_t::scope_t * locals = NULL);
|
||||
virtual xml::xpath_t::op_t * lookup(const string& name);
|
||||
|
||||
//
|
||||
// Debug options
|
||||
//
|
||||
|
||||
void option_verify(value_t&) {}
|
||||
void option_trace(value_t&, xml::xpath_t::scope_t * locals) {}
|
||||
void option_debug(value_t&, xml::xpath_t::scope_t * locals) {}
|
||||
|
||||
void option_verbose(value_t&) {
|
||||
_log_level = LOG_INFO;
|
||||
}
|
||||
|
||||
//
|
||||
// Option handlers
|
||||
//
|
||||
|
|
@ -172,10 +176,6 @@ class session_t : public xml::xpath_t::scope_t
|
|||
data_file = locals->args.to_string();
|
||||
}
|
||||
|
||||
void option_verbose(value_t&) {
|
||||
verbose_mode = true;
|
||||
}
|
||||
|
||||
#if 0
|
||||
#if defined(USE_BOOST_PYTHON)
|
||||
void option_import(value_t&) {
|
||||
|
|
|
|||
|
|
@ -1,3 +1,7 @@
|
|||
import sys
|
||||
sys.path.append("/home/johnw/src/ledger")
|
||||
sys.path.append("/home/johnw/Products/ledger")
|
||||
|
||||
import unittest
|
||||
import exceptions
|
||||
|
||||
|
|
|
|||
38
textual.cc
38
textual.cc
|
|
@ -53,10 +53,10 @@ parse_amount_expr(std::istream& in, journal_t *,
|
|||
xml::xpath_t xpath(in, flags | XPATH_PARSE_RELAXED | XPATH_PARSE_PARTIAL);
|
||||
|
||||
DEBUG_("ledger.textual.parse", "line " << linenum << ": " <<
|
||||
"Parsed an amount expression");
|
||||
"Parsed an amount expression");
|
||||
|
||||
#ifdef DEBUG_ENABLED
|
||||
DEBUG_IF("ledger.textual.parse") {
|
||||
#if 0
|
||||
IF_DEBUG_("ledger.textual.parse") {
|
||||
if (_debug_stream) {
|
||||
xpath.dump(*_debug_stream);
|
||||
*_debug_stream << std::endl;
|
||||
|
|
@ -67,7 +67,7 @@ parse_amount_expr(std::istream& in, journal_t *,
|
|||
amount = xpath.calc(static_cast<xml::transaction_node_t *>(xact.data)).to_amount();
|
||||
|
||||
DEBUG_("ledger.textual.parse", "line " << linenum << ": " <<
|
||||
"The transaction amount is " << amount);
|
||||
"The transaction amount is " << amount);
|
||||
}
|
||||
|
||||
transaction_t * parse_transaction(char * line,
|
||||
|
|
@ -125,12 +125,12 @@ transaction_t * parse_transaction(char * line,
|
|||
case '*':
|
||||
xact->state = transaction_t::CLEARED;
|
||||
DEBUG_("ledger.textual.parse", "line " << linenum << ": " <<
|
||||
"Parsed the CLEARED flag");
|
||||
"Parsed the CLEARED flag");
|
||||
break;
|
||||
case '!':
|
||||
xact->state = transaction_t::PENDING;
|
||||
DEBUG_("ledger.textual.parse", "line " << linenum << ": " <<
|
||||
"Parsed the PENDING flag");
|
||||
"Parsed the PENDING flag");
|
||||
break;
|
||||
}
|
||||
|
||||
|
|
@ -142,18 +142,18 @@ transaction_t * parse_transaction(char * line,
|
|||
(*b == '(' && *e == ')')) {
|
||||
xact->flags |= TRANSACTION_VIRTUAL;
|
||||
DEBUG_("ledger.textual.parse", "line " << linenum << ": " <<
|
||||
"Parsed a virtual account name");
|
||||
"Parsed a virtual account name");
|
||||
if (*b == '[') {
|
||||
xact->flags |= TRANSACTION_BALANCE;
|
||||
DEBUG_("ledger.textual.parse", "line " << linenum << ": " <<
|
||||
"Parsed a balanced virtual account name");
|
||||
"Parsed a balanced virtual account name");
|
||||
}
|
||||
*account_path++ = '\0';
|
||||
*e = '\0';
|
||||
}
|
||||
|
||||
DEBUG_("ledger.textual.parse", "line " << linenum << ": " <<
|
||||
"Parsed account name " << account_path);
|
||||
"Parsed account name " << account_path);
|
||||
if (account_aliases.size() > 0) {
|
||||
accounts_map::const_iterator i = account_aliases.find(account_path);
|
||||
if (i != account_aliases.end())
|
||||
|
|
@ -215,14 +215,14 @@ transaction_t * parse_transaction(char * line,
|
|||
char c = peek_next_nonws(in);
|
||||
if (c == '@') {
|
||||
DEBUG_("ledger.textual.parse", "line " << linenum << ": " <<
|
||||
"Found a price indicator");
|
||||
"Found a price indicator");
|
||||
bool per_unit = true;
|
||||
in.get(c);
|
||||
if (in.peek() == '@') {
|
||||
in.get(c);
|
||||
per_unit = false;
|
||||
DEBUG_("ledger.textual.parse", "line " << linenum << ": " <<
|
||||
"And it's for a total price");
|
||||
"And it's for a total price");
|
||||
}
|
||||
|
||||
if (in.good() && ! in.eof()) {
|
||||
|
|
@ -263,13 +263,13 @@ transaction_t * parse_transaction(char * line,
|
|||
xact->entry->code);
|
||||
|
||||
DEBUG_("ledger.textual.parse", "line " << linenum << ": " <<
|
||||
"Total cost is " << *xact->cost);
|
||||
"Total cost is " << *xact->cost);
|
||||
DEBUG_("ledger.textual.parse", "line " << linenum << ": " <<
|
||||
"Per-unit cost is " << per_unit_cost);
|
||||
"Per-unit cost is " << per_unit_cost);
|
||||
DEBUG_("ledger.textual.parse", "line " << linenum << ": " <<
|
||||
"Annotated amount is " << xact->amount);
|
||||
"Annotated amount is " << xact->amount);
|
||||
DEBUG_("ledger.textual.parse", "line " << linenum << ": " <<
|
||||
"Bare amount is " << xact->amount.number());
|
||||
"Bare amount is " << xact->amount.number());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
|
@ -277,7 +277,7 @@ transaction_t * parse_transaction(char * line,
|
|||
xact->amount.in_place_reduce();
|
||||
|
||||
DEBUG_("ledger.textual.parse", "line " << linenum << ": " <<
|
||||
"Reduced amount is " << xact->amount);
|
||||
"Reduced amount is " << xact->amount);
|
||||
}
|
||||
|
||||
// Parse the optional note
|
||||
|
|
@ -285,7 +285,7 @@ transaction_t * parse_transaction(char * line,
|
|||
if (note) {
|
||||
xact->note = note;
|
||||
DEBUG_("ledger.textual.parse", "line " << linenum << ": " <<
|
||||
"Parsed a note '" << xact->note << "'");
|
||||
"Parsed a note '" << xact->note << "'");
|
||||
|
||||
if (char * b = std::strchr(xact->note.c_str(), '['))
|
||||
if (char * e = std::strchr(xact->note.c_str(), ']')) {
|
||||
|
|
@ -294,7 +294,7 @@ transaction_t * parse_transaction(char * line,
|
|||
buf[e - b - 1] = '\0';
|
||||
|
||||
DEBUG_("ledger.textual.parse", "line " << linenum << ": " <<
|
||||
"Parsed a transaction date " << buf);
|
||||
"Parsed a transaction date " << buf);
|
||||
|
||||
if (char * p = std::strchr(buf, '=')) {
|
||||
*p++ = '\0';
|
||||
|
|
@ -840,7 +840,7 @@ unsigned int textual_parser_t::parse(std::istream& in,
|
|||
path = resolve_path(path);
|
||||
|
||||
DEBUG_("ledger.textual.include", "line " << linenum << ": " <<
|
||||
"Including path '" << path << "'");
|
||||
"Including path '" << path << "'");
|
||||
|
||||
include_stack.push_back(std::pair<string, int>
|
||||
(journal->sources.back(), linenum - 1));
|
||||
|
|
|
|||
389
utils.cc
389
utils.cc
|
|
@ -32,59 +32,68 @@ void debug_assert(const string& reason,
|
|||
#if defined(VERIFY_ON)
|
||||
|
||||
namespace ledger {
|
||||
|
||||
#if defined(FULL_DEBUG)
|
||||
bool verify_enabled = true;
|
||||
bool verify_enabled = true;
|
||||
#else
|
||||
bool verify_enabled = false;
|
||||
bool verify_enabled = false;
|
||||
#endif
|
||||
|
||||
int new_calls = 0;
|
||||
unsigned long new_size = 0;
|
||||
typedef std::pair<std::string, std::size_t> allocation_pair;
|
||||
typedef std::map<void *, allocation_pair> live_memory_map;
|
||||
typedef std::pair<void *, allocation_pair> live_memory_pair;
|
||||
typedef std::multimap<void *, allocation_pair> live_objects_map;
|
||||
typedef std::pair<void *, allocation_pair> live_objects_pair;
|
||||
typedef std::pair<unsigned int, std::size_t> count_size_pair;
|
||||
typedef std::map<std::string, count_size_pair> object_count_map;
|
||||
typedef std::pair<std::string, count_size_pair> object_count_pair;
|
||||
|
||||
static live_memory_map * live_memory = NULL;
|
||||
static object_count_map * live_memory_count = NULL;
|
||||
static object_count_map * total_memory_count = NULL;
|
||||
|
||||
static bool memory_tracing_active = false;
|
||||
|
||||
static live_objects_map * live_objects = NULL;
|
||||
static object_count_map * live_object_count = NULL;
|
||||
static object_count_map * total_object_count = NULL;
|
||||
static object_count_map * total_ctor_count = NULL;
|
||||
|
||||
void initialize_memory_tracing()
|
||||
{
|
||||
memory_tracing_active = false;
|
||||
|
||||
live_memory = new live_memory_map;
|
||||
live_memory_count = new object_count_map;
|
||||
total_memory_count = new object_count_map;
|
||||
|
||||
live_objects = new live_objects_map;
|
||||
live_object_count = new object_count_map;
|
||||
total_object_count = new object_count_map;
|
||||
total_ctor_count = new object_count_map;
|
||||
|
||||
memory_tracing_active = true;
|
||||
}
|
||||
|
||||
void * operator new(std::size_t size) throw (std::bad_alloc) {
|
||||
void * ptr = std::malloc(size);
|
||||
ledger::new_calls++;
|
||||
ledger::new_size += size;
|
||||
return ptr;
|
||||
}
|
||||
void * operator new[](std::size_t size) throw (std::bad_alloc) {
|
||||
void * ptr = std::malloc(size);
|
||||
ledger::new_calls++;
|
||||
ledger::new_size += size;
|
||||
return ptr;
|
||||
}
|
||||
void * operator new(std::size_t size, const std::nothrow_t&) throw() {
|
||||
void * ptr = std::malloc(size);
|
||||
ledger::new_calls++;
|
||||
ledger::new_size += size;
|
||||
return ptr;
|
||||
}
|
||||
void * operator new[](std::size_t size, const std::nothrow_t&) throw() {
|
||||
void * ptr = std::malloc(size);
|
||||
ledger::new_calls++;
|
||||
ledger::new_size += size;
|
||||
return ptr;
|
||||
}
|
||||
void operator delete(void * ptr) throw() {
|
||||
std::free(ptr);
|
||||
}
|
||||
void operator delete[](void * ptr) throw() {
|
||||
std::free(ptr);
|
||||
}
|
||||
void operator delete(void * ptr, const std::nothrow_t&) throw() {
|
||||
std::free(ptr);
|
||||
}
|
||||
void operator delete[](void * ptr, const std::nothrow_t&) throw() {
|
||||
std::free(ptr);
|
||||
}
|
||||
void shutdown_memory_tracing()
|
||||
{
|
||||
memory_tracing_active = false;
|
||||
|
||||
namespace ledger {
|
||||
IF_DEBUG_("memory.counts")
|
||||
report_memory(std::cerr, true);
|
||||
else
|
||||
IF_DEBUG_("memory.counts.live")
|
||||
report_memory(std::cerr);
|
||||
|
||||
live_objects_map live_objects;
|
||||
object_count_map ctor_count;
|
||||
object_count_map object_count;
|
||||
object_count_map live_count;
|
||||
delete live_memory; live_memory = NULL;
|
||||
delete live_memory_count; live_memory_count = NULL;
|
||||
delete total_memory_count; total_memory_count = NULL;
|
||||
|
||||
delete live_objects; live_objects = NULL;
|
||||
delete live_object_count; live_object_count = NULL;
|
||||
delete total_object_count; total_object_count = NULL;
|
||||
delete total_ctor_count; total_ctor_count = NULL;
|
||||
}
|
||||
|
||||
inline void add_to_count_map(object_count_map& the_map,
|
||||
const char * name, std::size_t size)
|
||||
|
|
@ -96,10 +105,117 @@ inline void add_to_count_map(object_count_map& the_map,
|
|||
} else {
|
||||
std::pair<object_count_map::iterator, bool> result =
|
||||
the_map.insert(object_count_pair(name, count_size_pair(1, size)));
|
||||
assert(result.second);
|
||||
VERIFY(result.second);
|
||||
}
|
||||
}
|
||||
|
||||
std::size_t current_memory_size()
|
||||
{
|
||||
std::size_t memory_size = 0;
|
||||
|
||||
for (object_count_map::const_iterator i = live_memory_count->begin();
|
||||
i != live_memory_count->end();
|
||||
i++)
|
||||
memory_size += (*i).second.second;
|
||||
|
||||
return memory_size;
|
||||
}
|
||||
|
||||
static void trace_new_func(void * ptr, const char * which, std::size_t size)
|
||||
{
|
||||
memory_tracing_active = false;
|
||||
|
||||
if (! live_memory) return;
|
||||
|
||||
live_memory->insert(live_memory_pair(ptr, allocation_pair(which, size)));
|
||||
|
||||
add_to_count_map(*live_memory_count, which, size);
|
||||
add_to_count_map(*total_memory_count, which, size);
|
||||
add_to_count_map(*total_memory_count, "__ALL__", size);
|
||||
|
||||
memory_tracing_active = true;
|
||||
}
|
||||
|
||||
static void trace_delete_func(void * ptr, const char * which)
|
||||
{
|
||||
memory_tracing_active = false;
|
||||
|
||||
if (! live_memory) return;
|
||||
|
||||
// Ignore deletions of memory not tracked, since it's possible that
|
||||
// a user (like boost) allocated a block of memory before memory
|
||||
// tracking began, and then deleted it before memory tracking ended.
|
||||
// If it really is a double-delete, the malloc library on OS/X will
|
||||
// notify me.
|
||||
|
||||
live_memory_map::iterator i = live_memory->find(ptr);
|
||||
if (i == live_memory->end())
|
||||
return;
|
||||
|
||||
std::size_t size = (*i).second.second;
|
||||
VERIFY((*i).second.first == which);
|
||||
|
||||
live_memory->erase(i);
|
||||
|
||||
object_count_map::iterator j = live_memory_count->find(which);
|
||||
VERIFY(j != live_memory_count->end());
|
||||
|
||||
(*j).second.second -= size;
|
||||
if (--(*j).second.first == 0)
|
||||
live_memory_count->erase(j);
|
||||
|
||||
memory_tracing_active = true;
|
||||
}
|
||||
|
||||
} // namespace ledger
|
||||
|
||||
void * operator new(std::size_t size) throw (std::bad_alloc) {
|
||||
void * ptr = std::malloc(size);
|
||||
if (DO_VERIFY() && ledger::memory_tracing_active)
|
||||
ledger::trace_new_func(ptr, "new", size);
|
||||
return ptr;
|
||||
}
|
||||
void * operator new(std::size_t size, const std::nothrow_t&) throw() {
|
||||
void * ptr = std::malloc(size);
|
||||
if (DO_VERIFY() && ledger::memory_tracing_active)
|
||||
ledger::trace_new_func(ptr, "new", size);
|
||||
return ptr;
|
||||
}
|
||||
void * operator new[](std::size_t size) throw (std::bad_alloc) {
|
||||
void * ptr = std::malloc(size);
|
||||
if (DO_VERIFY() && ledger::memory_tracing_active)
|
||||
ledger::trace_new_func(ptr, "new[]", size);
|
||||
return ptr;
|
||||
}
|
||||
void * operator new[](std::size_t size, const std::nothrow_t&) throw() {
|
||||
void * ptr = std::malloc(size);
|
||||
if (DO_VERIFY() && ledger::memory_tracing_active)
|
||||
ledger::trace_new_func(ptr, "new[]", size);
|
||||
return ptr;
|
||||
}
|
||||
void operator delete(void * ptr) throw() {
|
||||
if (DO_VERIFY() && ledger::memory_tracing_active)
|
||||
ledger::trace_delete_func(ptr, "new");
|
||||
std::free(ptr);
|
||||
}
|
||||
void operator delete(void * ptr, const std::nothrow_t&) throw() {
|
||||
if (DO_VERIFY() && ledger::memory_tracing_active)
|
||||
ledger::trace_delete_func(ptr, "new");
|
||||
std::free(ptr);
|
||||
}
|
||||
void operator delete[](void * ptr) throw() {
|
||||
if (DO_VERIFY() && ledger::memory_tracing_active)
|
||||
ledger::trace_delete_func(ptr, "new[]");
|
||||
std::free(ptr);
|
||||
}
|
||||
void operator delete[](void * ptr, const std::nothrow_t&) throw() {
|
||||
if (DO_VERIFY() && ledger::memory_tracing_active)
|
||||
ledger::trace_delete_func(ptr, "new[]");
|
||||
std::free(ptr);
|
||||
}
|
||||
|
||||
namespace ledger {
|
||||
|
||||
inline void report_count_map(std::ostream& out, object_count_map& the_map)
|
||||
{
|
||||
for (object_count_map::iterator i = the_map.begin();
|
||||
|
|
@ -111,88 +227,127 @@ inline void report_count_map(std::ostream& out, object_count_map& the_map)
|
|||
<< std::endl;
|
||||
}
|
||||
|
||||
bool trace_ctor_func(void * ptr, const char * cls_name, const char * args,
|
||||
std::size_t current_objects_size()
|
||||
{
|
||||
std::size_t objects_size = 0;
|
||||
|
||||
for (object_count_map::const_iterator i = live_object_count->begin();
|
||||
i != live_object_count->end();
|
||||
i++)
|
||||
objects_size += (*i).second.second;
|
||||
|
||||
return objects_size;
|
||||
}
|
||||
|
||||
void trace_ctor_func(void * ptr, const char * cls_name, const char * args,
|
||||
std::size_t cls_size)
|
||||
{
|
||||
memory_tracing_active = false;
|
||||
|
||||
if (! live_objects) return;
|
||||
|
||||
static char name[1024];
|
||||
std::strcpy(name, cls_name);
|
||||
std::strcat(name, "(");
|
||||
std::strcat(name, args);
|
||||
std::strcat(name, ")");
|
||||
|
||||
DEBUG_("ledger.trace.debug", "TRACE_CTOR " << ptr << " " << name);
|
||||
DEBUG_("verify.memory", "TRACE_CTOR " << ptr << " " << name);
|
||||
|
||||
live_objects.insert(live_objects_pair(ptr, cls_name));
|
||||
live_objects->insert(live_objects_pair(ptr, allocation_pair(cls_name, cls_size)));
|
||||
|
||||
add_to_count_map(ctor_count, name, cls_size);
|
||||
add_to_count_map(object_count, cls_name, cls_size);
|
||||
add_to_count_map(object_count, "__ALL__", cls_size);
|
||||
add_to_count_map(live_count, cls_name, cls_size);
|
||||
add_to_count_map(*live_object_count, cls_name, cls_size);
|
||||
add_to_count_map(*total_object_count, cls_name, cls_size);
|
||||
add_to_count_map(*total_object_count, "__ALL__", cls_size);
|
||||
add_to_count_map(*total_ctor_count, name, cls_size);
|
||||
|
||||
return true;
|
||||
memory_tracing_active = true;
|
||||
}
|
||||
|
||||
bool trace_dtor_func(void * ptr, const char * cls_name, std::size_t cls_size)
|
||||
void trace_dtor_func(void * ptr, const char * cls_name, std::size_t cls_size)
|
||||
{
|
||||
memory_tracing_active = false;
|
||||
|
||||
if (! live_objects) return;
|
||||
|
||||
DEBUG_("ledger.trace.debug", "TRACE_DTOR " << ptr << " " << cls_name);
|
||||
|
||||
live_objects_map::iterator i = live_objects.find(ptr);
|
||||
if (i == live_objects.end()) {
|
||||
std::cerr << "Destruction of unknown object of type " << cls_name
|
||||
<< " " << ptr << std::endl;
|
||||
assert(0);
|
||||
return false;
|
||||
}
|
||||
live_objects_map::iterator i = live_objects->find(ptr);
|
||||
VERIFY(i != live_objects->end());
|
||||
|
||||
int ptr_count = live_objects.count(ptr);
|
||||
int ptr_count = live_objects->count(ptr);
|
||||
for (int x = 0; x < ptr_count; x++, i++) {
|
||||
if ((*i).second == cls_name) {
|
||||
live_objects.erase(i);
|
||||
if ((*i).second.first == cls_name) {
|
||||
live_objects->erase(i);
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
object_count_map::iterator k = live_count.find(cls_name);
|
||||
if (k == live_count.end()) {
|
||||
std::cerr << "Destruction of unregistered class " << cls_name
|
||||
<< std::endl;;
|
||||
assert(0);
|
||||
return false;
|
||||
}
|
||||
object_count_map::iterator k = live_object_count->find(cls_name);
|
||||
VERIFY(k != live_object_count->end());
|
||||
|
||||
(*k).second.second -= cls_size;
|
||||
if (--(*k).second.first == 0)
|
||||
live_count.erase(k);
|
||||
live_object_count->erase(k);
|
||||
|
||||
return true;
|
||||
memory_tracing_active = true;
|
||||
}
|
||||
|
||||
void report_memory(std::ostream& out)
|
||||
void report_memory(std::ostream& out, bool report_all)
|
||||
{
|
||||
if (live_count.size() > 0) {
|
||||
out << "Live object counts:" << std::endl;
|
||||
report_count_map(out, live_count);
|
||||
if (! live_memory) return;
|
||||
|
||||
if (live_memory_count->size() > 0) {
|
||||
out << "NOTE: There may be memory held by Boost "
|
||||
<< "and libstdc++ after ledger::shutdown()" << std::endl;
|
||||
out << "Live memory count:" << std::endl;
|
||||
report_count_map(out, *live_memory_count);
|
||||
}
|
||||
|
||||
if (live_objects.size() > 0) {
|
||||
out << "Live objects:" << std::endl;
|
||||
if (live_memory->size() > 0) {
|
||||
out << "Live memory:" << std::endl;
|
||||
|
||||
for (live_objects_map::iterator i = live_objects.begin();
|
||||
i != live_objects.end();
|
||||
for (live_memory_map::const_iterator i = live_memory->begin();
|
||||
i != live_memory->end();
|
||||
i++)
|
||||
out << " " << std::right << std::setw(7) << (*i).first
|
||||
<< " " << std::left << (*i).second
|
||||
<< " " << std::right << std::setw(7) << (*i).second.second
|
||||
<< " " << std::left << (*i).second.first
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
if (object_count.size() > 0) {
|
||||
out << "Object counts:" << std::endl;
|
||||
report_count_map(out, object_count);
|
||||
if (report_all && total_memory_count->size() > 0) {
|
||||
out << "Total memory counts:" << std::endl;
|
||||
report_count_map(out, *total_memory_count);
|
||||
}
|
||||
|
||||
if (ctor_count.size() > 0) {
|
||||
out << "Constructor counts:" << std::endl;
|
||||
report_count_map(out, ctor_count);
|
||||
if (live_object_count->size() > 0) {
|
||||
out << "Live object count:" << std::endl;
|
||||
report_count_map(out, *live_object_count);
|
||||
}
|
||||
|
||||
if (live_objects->size() > 0) {
|
||||
out << "Live objects:" << std::endl;
|
||||
|
||||
for (live_objects_map::const_iterator i = live_objects->begin();
|
||||
i != live_objects->end();
|
||||
i++)
|
||||
out << " " << std::right << std::setw(7) << (*i).first
|
||||
<< " " << std::right << std::setw(7) << (*i).second.second
|
||||
<< " " << std::left << (*i).second.first
|
||||
<< std::endl;
|
||||
}
|
||||
|
||||
if (report_all) {
|
||||
if (total_object_count->size() > 0) {
|
||||
out << "Total object counts:" << std::endl;
|
||||
report_count_map(out, *total_object_count);
|
||||
}
|
||||
|
||||
if (total_ctor_count->size() > 0) {
|
||||
out << "Total constructor counts:" << std::endl;
|
||||
report_count_map(out, *total_ctor_count);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
|
@ -255,8 +410,64 @@ std::string _log_category;
|
|||
std::ostream * _log_stream = &std::cerr;
|
||||
std::ostringstream _log_buffer;
|
||||
|
||||
static inline void stream_memory_size(std::ostream& out, std::size_t size)
|
||||
{
|
||||
if (size < 1024)
|
||||
out << size << 'b';
|
||||
else if (size < (1024 * 1024))
|
||||
out << (double(size) / 1024.0) << 'K';
|
||||
else if (size < (1024 * 1024 * 1024))
|
||||
out << (double(size) / (1024.0 * 1024.0)) << 'M';
|
||||
else if (size < (1024 * 1024 * 1024 * 1024))
|
||||
out << (double(size) / (1024.0 * 1024.0 * 1024.0)) << 'G';
|
||||
else
|
||||
assert(false);
|
||||
}
|
||||
|
||||
static bool logger_has_run = false;
|
||||
|
||||
bool logger_func(log_level_t level)
|
||||
{
|
||||
if (! logger_has_run) {
|
||||
logger_has_run = true;
|
||||
IF_VERIFY()
|
||||
*_log_stream << " TIME OBJSZ MEMSZ LEVEL MESSAGE" << std::endl;
|
||||
else
|
||||
*_log_stream << " TIME LEVEL MESSAGE" << std::endl;
|
||||
}
|
||||
|
||||
*_log_stream << std::right << std::setw(6)
|
||||
<< (double(std::clock()) / double(CLOCKS_PER_SEC));
|
||||
|
||||
IF_VERIFY() {
|
||||
*_log_stream << std::right << std::setw(6) << std::setprecision(3);
|
||||
stream_memory_size(*_log_stream, current_objects_size());
|
||||
*_log_stream << std::right << std::setw(6) << std::setprecision(3);
|
||||
stream_memory_size(*_log_stream, current_memory_size());
|
||||
}
|
||||
|
||||
*_log_stream << " " << std::left << std::setw(7);
|
||||
|
||||
switch (level) {
|
||||
case LOG_CRIT: *_log_stream << "[CRIT]"; break;
|
||||
case LOG_FATAL: *_log_stream << "[FATAL]"; break;
|
||||
case LOG_ASSERT: *_log_stream << "[ASSRT]"; break;
|
||||
case LOG_ERROR: *_log_stream << "[ERROR]"; break;
|
||||
case LOG_VERIFY: *_log_stream << "[VERFY]"; break;
|
||||
case LOG_WARN: *_log_stream << "[WARN]"; break;
|
||||
case LOG_INFO: *_log_stream << "[INFO]"; break;
|
||||
case LOG_EXCEPT: *_log_stream << "[EXCPT]"; break;
|
||||
case LOG_DEBUG: *_log_stream << "[DEBUG]"; break;
|
||||
case LOG_TRACE: *_log_stream << "[TRACE]"; break;
|
||||
|
||||
case LOG_OFF:
|
||||
case LOG_ALL:
|
||||
assert(false);
|
||||
break;
|
||||
}
|
||||
|
||||
*_log_stream << ' ' << _log_buffer.str() << std::endl;
|
||||
|
||||
_log_buffer.str("");
|
||||
}
|
||||
|
||||
|
|
|
|||
87
utils.h
87
utils.h
|
|
@ -73,32 +73,26 @@ namespace ledger {
|
|||
|
||||
extern bool verify_enabled;
|
||||
|
||||
#define VERIFY(x) (verify_enabled ? assert(x) : ((void)0))
|
||||
#define VERIFY(x) (ledger::verify_enabled ? assert(x) : ((void)0))
|
||||
#define DO_VERIFY() ledger::verify_enabled
|
||||
#define IF_VERIFY() if (DO_VERIFY())
|
||||
|
||||
extern int new_calls;
|
||||
extern unsigned long new_size;
|
||||
void initialize_memory_tracing();
|
||||
void shutdown_memory_tracing();
|
||||
|
||||
typedef std::multimap<void *, std::string> live_objects_map;
|
||||
typedef std::pair<void *, std::string> live_objects_pair;
|
||||
typedef std::pair<unsigned int, std::size_t> count_size_pair;
|
||||
typedef std::map<std::string, count_size_pair> object_count_map;
|
||||
typedef std::pair<std::string, count_size_pair> object_count_pair;
|
||||
std::size_t current_memory_size();
|
||||
std::size_t current_objects_size();
|
||||
|
||||
extern live_objects_map live_objects;
|
||||
extern object_count_map live_count;
|
||||
extern object_count_map ctor_count;
|
||||
extern object_count_map object_count;
|
||||
|
||||
bool trace_ctor_func(void * ptr, const char * cls_name, const char * args,
|
||||
void trace_ctor_func(void * ptr, const char * cls_name, const char * args,
|
||||
std::size_t cls_size);
|
||||
bool trace_dtor_func(void * ptr, const char * cls_name, std::size_t cls_size);
|
||||
void trace_dtor_func(void * ptr, const char * cls_name, std::size_t cls_size);
|
||||
|
||||
#define TRACE_CTOR(cls, args) \
|
||||
VERIFY(trace_ctor_func(this, #cls, args, sizeof(cls)))
|
||||
(DO_VERIFY() ? trace_ctor_func(this, #cls, args, sizeof(cls)) : ((void)0))
|
||||
#define TRACE_DTOR(cls) \
|
||||
VERIFY(trace_dtor_func(this, #cls, sizeof(cls)))
|
||||
(DO_VERIFY() ? trace_dtor_func(this, #cls, sizeof(cls)) : ((void)0))
|
||||
|
||||
void report_memory(std::ostream& out);
|
||||
void report_memory(std::ostream& out, bool report_all = false);
|
||||
|
||||
#if ! defined(USE_BOOST_PYTHON)
|
||||
|
||||
|
|
@ -213,20 +207,21 @@ bool logger_func(log_level_t level);
|
|||
static const char * const _this_category = cat
|
||||
|
||||
#define SHOW_TRACE(lvl) \
|
||||
(_log_level >= LOG_TRACE && lvl >= _trace_level)
|
||||
(_log_level >= LOG_TRACE && lvl <= _trace_level)
|
||||
|
||||
#define SHOW_DEBUG_(cat) \
|
||||
(_log_level >= LOG_DEBUG && \
|
||||
(_log_category == cat || \
|
||||
_log_category.find(string(cat) + ".") == 0))
|
||||
inline bool category_matches(const char * cat) {
|
||||
return (_log_category == cat ||
|
||||
(std::strlen(cat) > _log_category.size() + 1 &&
|
||||
std::strncmp(cat, _log_category.c_str(),
|
||||
_log_category.size()) == 0 &&
|
||||
cat[_log_category.size()] == '.'));
|
||||
}
|
||||
|
||||
#define SHOW_DEBUG_(cat) \
|
||||
(_log_level >= LOG_DEBUG && category_matches(cat))
|
||||
#define SHOW_DEBUG() SHOW_DEBUG_(_this_category)
|
||||
|
||||
#define SHOW_INFO_(cat) \
|
||||
(_log_level >= LOG_INFO && \
|
||||
(_log_category == cat || \
|
||||
_log_category.find(string(cat) + ".") == 0))
|
||||
#define SHOW_INFO() SHOW_INFO_(_this_category)
|
||||
|
||||
#define SHOW_INFO() (_log_level >= LOG_INFO)
|
||||
#define SHOW_WARN() (_log_level >= LOG_WARN)
|
||||
#define SHOW_ERROR() (_log_level >= LOG_ERROR)
|
||||
#define SHOW_FATAL() (_log_level >= LOG_FATAL)
|
||||
|
|
@ -248,14 +243,11 @@ bool logger_func(log_level_t level);
|
|||
#define DEBUG(msg)
|
||||
#endif
|
||||
|
||||
#define INFO_(cat, msg) \
|
||||
(SHOW_INFO(cat) ? ((_log_buffer << msg), logger_func(LOG_INFO)) : false)
|
||||
#define INFO(msg) INFO_(_this_category, msg)
|
||||
|
||||
#define LOG_MACRO(level, msg) \
|
||||
(_log_level >= level ? \
|
||||
((_log_buffer << msg), logger_func(level)) : false)
|
||||
|
||||
#define INFO(msg) LOG_MACRO(LOG_INFO, msg)
|
||||
#define WARN(msg) LOG_MACRO(LOG_WARN, msg)
|
||||
#define ERROR(msg) LOG_MACRO(LOG_ERROR, msg)
|
||||
#define FATAL(msg) LOG_MACRO(LOG_FATAL, msg)
|
||||
|
|
@ -271,7 +263,6 @@ bool logger_func(log_level_t level);
|
|||
#define SHOW_TRACE(lvl) false
|
||||
#define SHOW_DEBUG_(cat) false
|
||||
#define SHOW_DEBUG() false
|
||||
#define SHOW_INFO_(cat) false
|
||||
#define SHOW_INFO() false
|
||||
#define SHOW_WARN() false
|
||||
#define SHOW_ERROR() false
|
||||
|
|
@ -282,7 +273,6 @@ bool logger_func(log_level_t level);
|
|||
#define DEBUG(msg)
|
||||
#define DEBUG_(cat, msg)
|
||||
#define INFO(msg)
|
||||
#define INFO_(cat, msg)
|
||||
#define WARN(msg)
|
||||
#define ERROR(msg)
|
||||
#define FATAL(msg)
|
||||
|
|
@ -293,7 +283,6 @@ bool logger_func(log_level_t level);
|
|||
#define IF_TRACE(lvl) if (SHOW_TRACE(lvl))
|
||||
#define IF_DEBUG_(cat) if (SHOW_DEBUG_(cat))
|
||||
#define IF_DEBUG() if (SHOW_DEBUG())
|
||||
#define IF_INFO_(cat) if (SHOW_INFO_(cat))
|
||||
#define IF_INFO() if (SHOW_INFO())
|
||||
#define IF_WARN() if (SHOW_WARN())
|
||||
#define IF_ERROR() if (SHOW_ERROR())
|
||||
|
|
@ -354,18 +343,12 @@ void finish_timer(const char * name);
|
|||
#define DEBUG_FINISH(name)
|
||||
#endif
|
||||
|
||||
#define info_start_(name, cat, msg) \
|
||||
(info_(cat, msg) && start_timer(#name))
|
||||
#define info_start(name, msg) \
|
||||
info_start_(name, _this_category, msg)
|
||||
#define info_stop_(name, cat) \
|
||||
(show_info_(cat) ? stop_timer(#name) : ((void)0))
|
||||
#define info_stop(name) \
|
||||
info_stop_(name, _this_category)
|
||||
#define info_finish_(name, cat) \
|
||||
(show_info_(cat) ? finish_timer(#name) : ((void)0))
|
||||
#define info_finish(name) \
|
||||
info_finish_(name, _this_category)
|
||||
#define INFO_START(name, msg) \
|
||||
(INFO(msg) && start_timer(#name))
|
||||
#define INFO_STOP(name) \
|
||||
(SHOW_INFO() ? stop_timer(#name) : ((void)0))
|
||||
#define INFO_FINISH(name) \
|
||||
(SHOW_INFO() ? finish_timer(#name) : ((void)0))
|
||||
|
||||
} // namespace ledger
|
||||
|
||||
|
|
@ -380,10 +363,10 @@ void finish_timer(const char * name);
|
|||
#define DEBUG_STOP(name)
|
||||
#define DEBUG_FINISH(name)
|
||||
|
||||
#define info_start(name, msg)
|
||||
#define info_start_(name, cat, msg)
|
||||
#define info_stop(name)
|
||||
#define info_finish(name)
|
||||
#define INFO_START(name, msg)
|
||||
#define INFO_START_(name, cat, msg)
|
||||
#define INFO_STOP(name)
|
||||
#define INFO_FINISH(name)
|
||||
|
||||
#endif // TIMERS_ON
|
||||
|
||||
|
|
|
|||
21
xpath.cc
21
xpath.cc
|
|
@ -10,9 +10,20 @@ namespace ledger {
|
|||
namespace xml {
|
||||
|
||||
#ifndef THREADSAFE
|
||||
xpath_t::token_t xpath_t::lookahead;
|
||||
xpath_t::token_t * xpath_t::lookahead = NULL;
|
||||
#endif
|
||||
|
||||
void xpath_t::initialize()
|
||||
{
|
||||
lookahead = new xpath_t::token_t;
|
||||
}
|
||||
|
||||
void xpath_t::shutdown()
|
||||
{
|
||||
delete lookahead;
|
||||
lookahead = NULL;
|
||||
}
|
||||
|
||||
void xpath_t::token_t::parse_ident(std::istream& in)
|
||||
{
|
||||
if (in.eof()) {
|
||||
|
|
@ -1130,9 +1141,17 @@ xpath_t::parse_expr(std::istream& in, unsigned short tflags) const
|
|||
|
||||
if (use_lookahead) {
|
||||
use_lookahead = false;
|
||||
#ifdef THREADSAFE
|
||||
lookahead.rewind(in);
|
||||
#else
|
||||
lookahead->rewind(in);
|
||||
#endif
|
||||
}
|
||||
#ifdef THREADSAFE
|
||||
lookahead.clear();
|
||||
#else
|
||||
lookahead->clear();
|
||||
#endif
|
||||
|
||||
return node.release();
|
||||
}
|
||||
|
|
|
|||
27
xpath.h
27
xpath.h
|
|
@ -11,6 +11,9 @@ class xpath_t
|
|||
public:
|
||||
struct op_t;
|
||||
|
||||
static void initialize();
|
||||
static void shutdown();
|
||||
|
||||
DECLARE_EXCEPTION(parse_exception);
|
||||
DECLARE_EXCEPTION(compile_exception);
|
||||
DECLARE_EXCEPTION(calc_exception);
|
||||
|
|
@ -422,21 +425,21 @@ public:
|
|||
|
||||
void release() const {
|
||||
DEBUG_("ledger.xpath.memory",
|
||||
"Releasing " << this << ", refc now " << refc - 1);
|
||||
"Releasing " << this << ", refc now " << refc - 1);
|
||||
assert(refc > 0);
|
||||
if (--refc == 0)
|
||||
delete this;
|
||||
}
|
||||
op_t * acquire() {
|
||||
DEBUG_("ledger.xpath.memory",
|
||||
"Acquiring " << this << ", refc now " << refc + 1);
|
||||
"Acquiring " << this << ", refc now " << refc + 1);
|
||||
assert(refc >= 0);
|
||||
refc++;
|
||||
return this;
|
||||
}
|
||||
const op_t * acquire() const {
|
||||
DEBUG_("ledger.xpath.memory",
|
||||
"Acquiring " << this << ", refc now " << refc + 1);
|
||||
"Acquiring " << this << ", refc now " << refc + 1);
|
||||
assert(refc >= 0);
|
||||
refc++;
|
||||
return this;
|
||||
|
|
@ -521,21 +524,33 @@ public:
|
|||
}
|
||||
|
||||
#ifdef THREADSAFE
|
||||
mutable token_t lookahead;
|
||||
mutable token_t lookahead;
|
||||
#else
|
||||
static token_t lookahead;
|
||||
static token_t * lookahead;
|
||||
#endif
|
||||
mutable bool use_lookahead;
|
||||
mutable bool use_lookahead;
|
||||
|
||||
token_t& next_token(std::istream& in, unsigned short tflags) const {
|
||||
if (use_lookahead)
|
||||
use_lookahead = false;
|
||||
else
|
||||
#ifdef THREADSAFE
|
||||
lookahead.next(in, tflags);
|
||||
#else
|
||||
lookahead->next(in, tflags);
|
||||
#endif
|
||||
#ifdef THREADSAFE
|
||||
return lookahead;
|
||||
#else
|
||||
return *lookahead;
|
||||
#endif
|
||||
}
|
||||
void push_token(const token_t& tok) const {
|
||||
#ifdef THREADSAFE
|
||||
assert(&tok == &lookahead);
|
||||
#else
|
||||
assert(&tok == lookahead);
|
||||
#endif
|
||||
use_lookahead = true;
|
||||
}
|
||||
void push_token() const {
|
||||
|
|
|
|||
Loading…
Add table
Reference in a new issue