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