summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--COPYRIGHT30
-rw-r--r--amount.cc168
-rw-r--r--amount.h8
-rw-r--r--balance.cc25
-rw-r--r--error.h15
-rw-r--r--format.cc4
-rw-r--r--format.h7
-rw-r--r--gnucash.cc5
-rw-r--r--gnucash.h4
-rw-r--r--journal.cc38
-rw-r--r--journal.h12
-rw-r--r--main.cc73
-rw-r--r--mask.h6
-rw-r--r--ofx.cc8
-rw-r--r--option.cc35
-rw-r--r--option.h6
-rw-r--r--parser.h60
-rw-r--r--py_amount.cc10
-rw-r--r--py_eval.cc19
-rw-r--r--qif.cc10
-rw-r--r--quotes.cc27
-rw-r--r--register.cc89
-rw-r--r--register.h13
-rw-r--r--report.cc4
-rw-r--r--session.cc27
-rw-r--r--session.h1
-rw-r--r--system.hh7
-rw-r--r--tests/corelib/numerics/BasicAmount.cc4
-rw-r--r--tests/corelib/numerics/Commodity.cc4
-rw-r--r--tests/corelib/numerics/CommodityAmount.cc46
-rw-r--r--textual.cc117
-rw-r--r--textual.h2
-rw-r--r--times.cc2
-rw-r--r--times.h14
-rw-r--r--util.cc146
-rw-r--r--util.h88
-rw-r--r--utils.cc226
-rw-r--r--utils.h301
-rw-r--r--value.cc498
-rw-r--r--value.h10
-rw-r--r--xml.cc23
-rw-r--r--xml.h19
-rw-r--r--xmlparse.cc7
-rw-r--r--xpath.cc152
-rw-r--r--xpath.h44
45 files changed, 1264 insertions, 1150 deletions
diff --git a/COPYRIGHT b/COPYRIGHT
new file mode 100644
index 00000000..c9d4bd18
--- /dev/null
+++ b/COPYRIGHT
@@ -0,0 +1,30 @@
+/*
+ * Copyright (c) 2003-2007, John Wiegley. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * - Neither the name of New Artisans LLC nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
diff --git a/amount.cc b/amount.cc
index 199b9325..2556552e 100644
--- a/amount.cc
+++ b/amount.cc
@@ -1,33 +1,44 @@
-// amount.cc
-
-// Copyright (c) 2003-2007, John Wiegley. All rights reserved.
-//
-// Redistribution and use in source and binary forms, with or without
-// modification, are permitted provided that the following conditions are
-// met:
-//
-// - Redistributions of source code must retain the above copyright
-// notice, this list of conditions and the following disclaimer.
-//
-// - Redistributions in binary form must reproduce the above copyright
-// notice, this list of conditions and the following disclaimer in the
-// documentation and/or other materials provided with the distribution.
-//
-// - Neither the name of New Artisans LLC nor the names of its
-// contributors may be used to endorse or promote products derived from
-// this software without specific prior written permission.
-//
-// THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
-// "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
-// LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
-// A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
-// OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
-// SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
-// LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
-// DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
-// THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
-// (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
-// OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+/**
+ * @file amount.cc
+ * @author John Wiegley
+ * @date Thu Apr 26 15:19:46 2007
+ *
+ * @brief Types for handling commoditized math.
+ *
+ * This file defines member functions for amount_t and the various
+ * flavors of commodity_t.
+ */
+
+/*
+ * Copyright (c) 2003-2007, John Wiegley. All rights reserved.
+ *
+ * Redistribution and use in source and binary forms, with or without
+ * modification, are permitted provided that the following conditions are
+ * met:
+ *
+ * - Redistributions of source code must retain the above copyright
+ * notice, this list of conditions and the following disclaimer.
+ *
+ * - Redistributions in binary form must reproduce the above copyright
+ * notice, this list of conditions and the following disclaimer in the
+ * documentation and/or other materials provided with the distribution.
+ *
+ * - Neither the name of New Artisans LLC nor the names of its
+ * contributors may be used to endorse or promote products derived from
+ * this software without specific prior written permission.
+ *
+ * THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
+ * "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
+ * LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
+ * A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
+ * OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
+ * SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
+ * LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
+ * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
+ * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
+ * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
+ * OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
+ */
#include "amount.h"
#include "binary.h"
@@ -325,7 +336,7 @@ amount_t::amount_t(const double val)
void amount_t::_release()
{
- DEBUG_PRINT("amounts.refs",
+ DEBUG_("amounts.refs",
quantity << " ref--, now " << (quantity->ref - 1));
if (--quantity->ref == 0) {
if (! (quantity->flags & BIGINT_BULK_ALLOC))
@@ -367,7 +378,7 @@ void amount_t::_copy(const amount_t& amt)
quantity = new bigint_t(*amt.quantity);
} else {
quantity = amt.quantity;
- DEBUG_PRINT("amounts.refs",
+ DEBUG_("amounts.refs",
quantity << " ref++, now " << (quantity->ref + 1));
quantity->ref++;
}
@@ -473,10 +484,11 @@ void amount_t::_clear()
amount_t& amount_t::operator+=(const amount_t& amt)
{
if (commodity() != amt.commodity()) {
- throw new amount_error
+ throw amount_exception
(string("Adding amounts with different commodities: ") +
(has_commodity() ? commodity_->qualified_symbol : "NONE") + " != " +
- (amt.has_commodity() ? amt.commodity_->qualified_symbol : "NONE"));
+ (amt.has_commodity() ? amt.commodity_->qualified_symbol : "NONE"),
+ context());
}
if (! amt.quantity)
@@ -508,10 +520,11 @@ amount_t& amount_t::operator+=(const amount_t& amt)
amount_t& amount_t::operator-=(const amount_t& amt)
{
if (commodity() != amt.commodity())
- throw new amount_error
+ throw amount_exception
(string("Subtracting amounts with different commodities: ") +
(has_commodity() ? commodity_->qualified_symbol : "NONE") + " != " +
- (amt.has_commodity() ? amt.commodity_->qualified_symbol : "NONE"));
+ (amt.has_commodity() ? amt.commodity_->qualified_symbol : "NONE"),
+ context());
if (! amt.quantity)
return *this;
@@ -545,10 +558,11 @@ amount_t& amount_t::operator*=(const amount_t& amt)
{
if (has_commodity() && amt.has_commodity() &&
commodity() != amt.commodity()) {
- throw new amount_error
+ throw amount_exception
(string("Multiplying amounts with different commodities: ") +
(has_commodity() ? commodity_->qualified_symbol : "NONE") + " != " +
- (amt.has_commodity() ? amt.commodity_->qualified_symbol : "NONE"));
+ (amt.has_commodity() ? amt.commodity_->qualified_symbol : "NONE"),
+ context());
}
if (! amt.quantity) {
@@ -585,14 +599,15 @@ amount_t& amount_t::operator/=(const amount_t& amt)
{
if (has_commodity() && amt.has_commodity() &&
commodity() != amt.commodity()) {
- throw new amount_error
+ throw amount_exception
(string("Dividing amounts with different commodities: ") +
(has_commodity() ? commodity_->qualified_symbol : "NONE") + " != " +
- (amt.has_commodity() ? amt.commodity_->qualified_symbol : "NONE"));
+ (amt.has_commodity() ? amt.commodity_->qualified_symbol : "NONE"),
+ context());
}
if (! amt.quantity || ! amt) {
- throw new amount_error("Divide by zero");
+ throw amount_exception("Divide by zero", context());
}
else if (! quantity) {
*this = amt;
@@ -658,9 +673,10 @@ int amount_t::compare(const amount_t& amt) const
return sign();
if (has_commodity() && amt.commodity() && commodity() != amt.commodity())
- throw new amount_error
+ throw amount_exception
(string("Cannot compare amounts with different commodities: ") +
- commodity().symbol() + " and " + amt.commodity().symbol());
+ commodity().symbol() + " and " + amt.commodity().symbol(),
+ context());
if (quantity->prec == amt.quantity->prec) {
return mpz_cmp(MPZ(quantity), MPZ(amt.quantity));
@@ -1119,7 +1135,8 @@ static void parse_commodity(std::istream& in, string& symbol)
if (c == '"')
in.get(c);
else
- throw new amount_error("Quoted commodity symbol lacks closing quote");
+ throw amount_exception("Quoted commodity symbol lacks closing quote",
+ context());
} else {
READ_INTO(in, buf, 255, c, ! invalid_chars[(unsigned char)c]);
}
@@ -1136,14 +1153,15 @@ bool parse_annotations(std::istream& in, amount_t& price,
char c = peek_next_nonws(in);
if (c == '{') {
if (price)
- throw new amount_error("Commodity specifies more than one price");
+ throw amount_exception("Commodity specifies more than one price",
+ context());
in.get(c);
READ_INTO(in, buf, 255, c, c != '}');
if (c == '}')
in.get(c);
else
- throw new amount_error("Commodity price lacks closing brace");
+ throw amount_exception("Commodity price lacks closing brace", context());
price.parse(buf, AMOUNT_PARSE_NO_MIGRATE);
price.in_place_reduce();
@@ -1158,28 +1176,32 @@ bool parse_annotations(std::istream& in, amount_t& price,
}
else if (c == '[') {
if (is_valid_moment(date))
- throw new amount_error("Commodity specifies more than one date");
+ throw amount_exception("Commodity specifies more than one date",
+ context());
in.get(c);
READ_INTO(in, buf, 255, c, c != ']');
if (c == ']')
in.get(c);
else
- throw new amount_error("Commodity date lacks closing bracket");
+ throw amount_exception("Commodity date lacks closing bracket",
+ context());
date = parse_datetime(buf);
has_date = true;
}
else if (c == '(') {
if (! tag.empty())
- throw new amount_error("Commodity specifies more than one tag");
+ throw amount_exception("Commodity specifies more than one tag",
+ context());
in.get(c);
READ_INTO(in, buf, 255, c, c != ')');
if (c == ')')
in.get(c);
else
- throw new amount_error("Commodity tag lacks closing parenthesis");
+ throw amount_exception("Commodity tag lacks closing parenthesis",
+ context());
tag = buf;
}
@@ -1188,7 +1210,7 @@ bool parse_annotations(std::istream& in, amount_t& price,
}
} while (true);
- DEBUG_PRINT("amounts.commodities",
+ DEBUG_("amounts.commodities",
"Parsed commodity annotations: "
<< " price " << price << " "
<< " date " << date << " "
@@ -1251,7 +1273,8 @@ void amount_t::parse(std::istream& in, unsigned char flags)
}
if (quant.empty())
- throw new amount_error("No quantity specified for amount");
+ throw amount_exception("No quantity specified for amount",
+ context());
_init();
@@ -1446,7 +1469,7 @@ void amount_t::read_quantity(char *& data)
data += sizeof(unsigned int);
quantity = (bigint_t *) (bigints + (index - 1) * sizeof(bigint_t));
- DEBUG_PRINT("amounts.refs",
+ DEBUG_("amounts.refs",
quantity << " ref++, now " << (quantity->ref + 1));
quantity->ref++;
}
@@ -1535,12 +1558,12 @@ bool amount_t::valid() const
{
if (quantity) {
if (quantity->ref == 0) {
- DEBUG_PRINT("ledger.validate", "amount_t: quantity->ref == 0");
+ DEBUG_("ledger.validate", "amount_t: quantity->ref == 0");
return false;
}
}
else if (commodity_) {
- DEBUG_PRINT("ledger.validate", "amount_t: commodity_ != NULL");
+ DEBUG_("ledger.validate", "amount_t: commodity_ != NULL");
return false;
}
return true;
@@ -1561,7 +1584,7 @@ void amount_t::annotate_commodity(const amount_t& tprice,
}
assert(this_base);
- DEBUG_PRINT("amounts.commodities", "Annotating commodity for amount "
+ DEBUG_("amounts.commodities", "Annotating commodity for amount "
<< *this << std::endl
<< " price " << tprice << " "
<< " date " << tdate << " "
@@ -1575,7 +1598,7 @@ void amount_t::annotate_commodity(const amount_t& tprice,
if (ann_comm)
set_commodity(*ann_comm);
- DEBUG_PRINT("amounts.commodities", " Annotated amount is " << *this);
+ DEBUG_("amounts.commodities", " Annotated amount is " << *this);
}
amount_t amount_t::strip_annotations(const bool _keep_price,
@@ -1586,7 +1609,7 @@ amount_t amount_t::strip_annotations(const bool _keep_price,
(_keep_price && _keep_date && _keep_tag))
return *this;
- DEBUG_PRINT("amounts.commodities", "Reducing commodity for amount "
+ DEBUG_("amounts.commodities", "Reducing commodity for amount "
<< *this << std::endl
<< " keep price " << _keep_price << " "
<< " keep date " << _keep_date << " "
@@ -1613,7 +1636,7 @@ amount_t amount_t::strip_annotations(const bool _keep_price,
amount_t t(*this);
t.set_commodity(*new_comm);
- DEBUG_PRINT("amounts.commodities", " Reduced amount is " << t);
+ DEBUG_("amounts.commodities", " Reduced amount is " << t);
return t;
}
@@ -1623,7 +1646,7 @@ amount_t amount_t::price() const
if (commodity_ && commodity_->annotated) {
amount_t t(((annotated_commodity_t *)commodity_)->price);
t *= number();
- DEBUG_PRINT("amounts.commodities",
+ DEBUG_("amounts.commodities",
"Returning price of " << *this << " = " << t);
return t;
}
@@ -1633,7 +1656,7 @@ amount_t amount_t::price() const
moment_t amount_t::date() const
{
if (commodity_ && commodity_->annotated) {
- DEBUG_PRINT("amounts.commodities",
+ DEBUG_("amounts.commodities",
"Returning date of " << *this << " = "
<< ((annotated_commodity_t *)commodity_)->date);
return ((annotated_commodity_t *)commodity_)->date;
@@ -1675,7 +1698,7 @@ commodity_base_t * commodity_base_t::create(const string& symbol)
{
commodity_base_t * commodity = new commodity_base_t(symbol);
- DEBUG_PRINT("amounts.commodities", "Creating base commodity " << symbol);
+ DEBUG_("amounts.commodities", "Creating base commodity " << symbol);
std::pair<base_commodities_map::iterator, bool> result
= commodities.insert(base_commodities_pair(symbol, commodity));
@@ -1696,18 +1719,18 @@ bool commodity_t::needs_quotes(const string& symbol)
bool commodity_t::valid() const
{
if (symbol().empty() && this != null_commodity) {
- DEBUG_PRINT("ledger.validate",
+ DEBUG_("ledger.validate",
"commodity_t: symbol().empty() && this != null_commodity");
return false;
}
if (annotated && ! base) {
- DEBUG_PRINT("ledger.validate", "commodity_t: annotated && ! base");
+ DEBUG_("ledger.validate", "commodity_t: annotated && ! base");
return false;
}
if (precision() > 16) {
- DEBUG_PRINT("ledger.validate", "commodity_t: precision() > 16");
+ DEBUG_("ledger.validate", "commodity_t: precision() > 16");
return false;
}
@@ -1728,7 +1751,7 @@ commodity_t * commodity_t::create(const string& symbol)
commodity->qualified_symbol = symbol;
}
- DEBUG_PRINT("amounts.commodities",
+ DEBUG_("amounts.commodities",
"Creating commodity " << commodity->qualified_symbol);
std::pair<commodities_map::iterator, bool> result
@@ -1750,7 +1773,7 @@ commodity_t * commodity_t::create(const string& symbol)
commodity_t * commodity_t::find_or_create(const string& symbol)
{
- DEBUG_PRINT("amounts.commodities", "Find-or-create commodity " << symbol);
+ DEBUG_("amounts.commodities", "Find-or-create commodity " << symbol);
commodity_t * commodity = find(symbol);
if (commodity)
@@ -1760,7 +1783,7 @@ commodity_t * commodity_t::find_or_create(const string& symbol)
commodity_t * commodity_t::find(const string& symbol)
{
- DEBUG_PRINT("amounts.commodities", "Find commodity " << symbol);
+ DEBUG_("amounts.commodities", "Find commodity " << symbol);
commodities_map::const_iterator i = commodities.find(symbol);
if (i != commodities.end())
@@ -1872,7 +1895,7 @@ annotated_commodity_t::create(const commodity_t& comm,
commodity->qualified_symbol = comm.symbol();
- DEBUG_PRINT("amounts.commodities", "Creating annotated commodity "
+ DEBUG_("amounts.commodities", "Creating annotated commodity "
<< "symbol " << commodity->symbol()
<< " key " << mapping_key << std::endl
<< " price " << price << " "
@@ -1899,20 +1922,21 @@ namespace {
const string& tag)
{
if (price < 0)
- throw new amount_error("A commodity's price may not be negative");
+ throw amount_exception("A commodity's price may not be negative",
+ context());
std::ostringstream name;
comm.write(name);
annotated_commodity_t::write_annotations(name, price, date, tag);
- DEBUG_PRINT("amounts.commodities", "make_qualified_name for "
+ DEBUG_("amounts.commodities", "make_qualified_name for "
<< comm.qualified_symbol << std::endl
<< " price " << price << " "
<< " date " << date << " "
<< " tag " << tag);
- DEBUG_PRINT("amounts.commodities", "qualified_name is " << name.str());
+ DEBUG_("amounts.commodities", "qualified_name is " << name.str());
return name.str();
}
diff --git a/amount.h b/amount.h
index 6575a82e..9592e25e 100644
--- a/amount.h
+++ b/amount.h
@@ -746,16 +746,10 @@ inline commodity_t& amount_t::commodity() const {
return *commodity_;
}
-
void parse_conversion(const string& larger_str,
const string& smaller_str);
-
-class amount_error : public error {
- public:
- amount_error(const string& _reason) throw() : error(_reason) {}
- virtual ~amount_error() throw() {}
-};
+DECLARE_EXCEPTION(amount_exception);
struct compare_amount_commodities {
bool operator()(const amount_t * left, const amount_t * right) const;
diff --git a/balance.cc b/balance.cc
index 810d1934..328e6382 100644
--- a/balance.cc
+++ b/balance.cc
@@ -15,10 +15,8 @@ amount_t balance_t::amount(const commodity_t& commodity) const
if (temp.amounts.size() == 1)
return temp.amount(commodity);
- std::ostringstream errmsg;
- errmsg << "Requested amount of a balance with multiple commodities: "
- << temp;
- throw new amount_error(errmsg.str());
+ throw_(amount_exception,
+ "Requested amount of a balance with multiple commodities: " << temp);
}
}
else if (amounts.size() > 0) {
@@ -176,7 +174,7 @@ balance_t& balance_t::operator*=(const balance_t& bal)
std::ostringstream errmsg;
errmsg << "Cannot multiply two balances: " << temp << " * " << bal;
- throw new amount_error(errmsg.str());
+ throw amount_exception(errmsg.str(), context());
}
}
@@ -215,7 +213,7 @@ balance_t& balance_t::operator*=(const amount_t& amt)
errmsg << "Attempt to multiply balance by a commodity"
<< " not found in that balance: "
<< temp << " * " << amt;
- throw new amount_error(errmsg.str());
+ throw amount_exception(errmsg.str(), context());
}
}
return *this;
@@ -226,7 +224,7 @@ balance_t& balance_t::operator/=(const balance_t& bal)
if (bal.realzero()) {
std::ostringstream errmsg;
errmsg << "Attempt to divide by zero: " << *this << " / " << bal;
- throw new amount_error(errmsg.str());
+ throw amount_exception(errmsg.str(), context());
}
else if (realzero()) {
return *this = 0L;
@@ -245,7 +243,7 @@ balance_t& balance_t::operator/=(const balance_t& bal)
std::ostringstream errmsg;
errmsg << "Cannot divide between two balances: " << temp << " / " << bal;
- throw new amount_error(errmsg.str());
+ throw amount_exception(errmsg.str(), context());
}
}
@@ -254,7 +252,7 @@ balance_t& balance_t::operator/=(const amount_t& amt)
if (amt.realzero()) {
std::ostringstream errmsg;
errmsg << "Attempt to divide by zero: " << *this << " / " << amt;
- throw new amount_error(errmsg.str());
+ throw amount_exception(errmsg.str(), context());
}
else if (realzero()) {
return *this = 0L;
@@ -286,7 +284,7 @@ balance_t& balance_t::operator/=(const amount_t& amt)
errmsg << "Attempt to divide balance by a commodity"
<< " not found in that balance: "
<< temp << " * " << amt;
- throw new amount_error(errmsg.str());
+ throw amount_exception(errmsg.str(), context());
}
}
return *this;
@@ -306,10 +304,9 @@ balance_t::operator amount_t() const
if (temp.amounts.size() == 1)
return (*temp.amounts.begin()).second;
- std::ostringstream errmsg;
- errmsg << "Cannot convert a balance with "
- << "multiple commodities to an amount: " << temp;
- throw new amount_error(errmsg.str());
+ throw_(amount_exception,
+ "Cannot convert a balance with " <<
+ "multiple commodities to an amount: " << temp);
}
}
diff --git a/error.h b/error.h
index 44bca430..5cbf54fb 100644
--- a/error.h
+++ b/error.h
@@ -16,19 +16,24 @@ public:
exception(const string& _reason,
const context& immediate_ctxt) throw()
: reason(_reason) {
+ EXCEPTION(reason);
push(immediate_ctxt);
}
+ virtual ~exception() throw() {}
+
void push(const context& intermediate_ctxt) throw() {
context_stack.push_front(intermediate_ctxt);
}
void write(std::ostream& out) const throw() {
+#if 0
for (std::list<context>::const_iterator
- i = context.begin();
- i != context.end();
+ i = context_stack.begin();
+ i != context_stack.end();
i++)
(*i).write(out);
+#endif
}
const char * what() const throw() {
@@ -36,13 +41,13 @@ public:
}
};
-#define DEFINE_EXCEPTION(name) \
+#define DECLARE_EXCEPTION(name) \
class name : public exception { \
public: \
name(const string& _reason, \
const context& immediate_ctxt) throw() \
: exception(_reason, immediate_ctxt) {} \
- };
+ }
#if 0
@@ -125,6 +130,7 @@ class fatal_assert : public fatal {
inline void unexpected(char c, char wanted)
{
+#if 0
if ((unsigned char) c == 0xff) {
if (wanted)
throw new error(string("Missing '") + wanted + "'");
@@ -137,6 +143,7 @@ inline void unexpected(char c, char wanted)
else
throw new error(string("Invalid char '") + c + "'");
}
+#endif
}
} // namespace ledger
diff --git a/format.cc b/format.cc
index 78734d72..1b4be467 100644
--- a/format.cc
+++ b/format.cc
@@ -89,7 +89,7 @@ void format_t::parse(const string& fmt)
if (current->max_width != -1 && current->min_width != -1 &&
current->max_width < current->min_width)
- throw new format_error("Maximum width is less than the minimum width");
+ throw_(format_exception, "Maximum width is less than the minimum width");
switch (*p) {
case '|':
@@ -111,7 +111,7 @@ void format_t::parse(const string& fmt)
p++;
}
if (*p != close)
- throw new format_error(string("Missing '") + close + "'");
+ throw_(format_exception, "Missing '" << close << "'");
if (open == '{') {
assert(! current->xpath);
diff --git a/format.h b/format.h
index e2c6a3db..1ddd8202 100644
--- a/format.h
+++ b/format.h
@@ -101,12 +101,7 @@ class format_t
}
};
-class format_error : public error {
- public:
- format_error(const string& reason, error_context * ctxt = NULL) throw()
- : error(reason, ctxt) {}
- virtual ~format_error() throw() {}
-};
+DECLARE_EXCEPTION(format_exception);
} // namespace ledger
diff --git a/gnucash.cc b/gnucash.cc
index a4b5499c..abe8c555 100644
--- a/gnucash.cc
+++ b/gnucash.cc
@@ -341,13 +341,16 @@ unsigned int gnucash_parser_t::parse(std::istream& in,
//unsigned long line = XML_GetCurrentLineNumber(parser) - offset++;
const char * msg = XML_ErrorString(XML_GetErrorCode(parser));
XML_ParserFree(parser);
- throw new parse_error(msg);
+ throw_(parse_exception, msg);
}
if (! have_error.empty()) {
//unsigned long line = XML_GetCurrentLineNumber(parser) - offset++;
+#if 0
+ // jww (2007-04-26): What is this doing?
parse_error err(have_error);
std::cerr << "Error: " << err.what() << std::endl;
+#endif
have_error = "";
}
}
diff --git a/gnucash.h b/gnucash.h
index 299acdc7..a0d9fb18 100644
--- a/gnucash.h
+++ b/gnucash.h
@@ -32,9 +32,9 @@ struct gnucash_parser_t : public parser_t
std::istream * instreamp;
unsigned int offset;
XML_Parser parser;
- string path;
+ string path;
unsigned int src_idx;
- istream_pos_type beg_pos;
+ unsigned long beg_pos;
unsigned long beg_line;
transaction_t::state_t curr_state;
diff --git a/journal.cc b/journal.cc
index b8e743c5..1867899f 100644
--- a/journal.cc
+++ b/journal.cc
@@ -35,12 +35,12 @@ moment_t transaction_t::effective_date() const
bool transaction_t::valid() const
{
if (! entry) {
- DEBUG_PRINT("ledger.validate", "transaction_t: ! entry");
+ DEBUG_("ledger.validate", "transaction_t: ! entry");
return false;
}
if (state != UNCLEARED && state != CLEARED && state != PENDING) {
- DEBUG_PRINT("ledger.validate", "transaction_t: state is bad");
+ DEBUG_("ledger.validate", "transaction_t: state is bad");
return false;
}
@@ -53,27 +53,27 @@ bool transaction_t::valid() const
break;
}
if (! found) {
- DEBUG_PRINT("ledger.validate", "transaction_t: ! found");
+ DEBUG_("ledger.validate", "transaction_t: ! found");
return false;
}
if (! account) {
- DEBUG_PRINT("ledger.validate", "transaction_t: ! account");
+ DEBUG_("ledger.validate", "transaction_t: ! account");
return false;
}
if (! amount.valid()) {
- DEBUG_PRINT("ledger.validate", "transaction_t: ! amount.valid()");
+ DEBUG_("ledger.validate", "transaction_t: ! amount.valid()");
return false;
}
if (cost && ! cost->valid()) {
- DEBUG_PRINT("ledger.validate", "transaction_t: cost && ! cost->valid()");
+ DEBUG_("ledger.validate", "transaction_t: cost && ! cost->valid()");
return false;
}
if (flags & ~0x003f) {
- DEBUG_PRINT("ledger.validate", "transaction_t: flags are bad");
+ DEBUG_("ledger.validate", "transaction_t: flags are bad");
return false;
}
@@ -199,7 +199,7 @@ bool entry_base_t::finalize()
continue;
if (! empty_allowed)
- throw new error("Only one transaction with null amount allowed per entry");
+ throw_(exception, "Only one transaction with null amount allowed per entry");
empty_allowed = false;
// If one transaction gives no value at all, its value will become
@@ -255,12 +255,16 @@ bool entry_base_t::finalize()
}
if (balance) {
+#if 1
+ throw_(balance_exception, "Entry does not balance");
+#else
error * err =
new balance_error("Entry does not balance",
new entry_context(*this, "While balancing entry:"));
err->context.push_front
(new value_context(balance, "Unbalanced remainder is:"));
throw err;
+#endif
}
return true;
@@ -307,7 +311,7 @@ void entry_t::add_transaction(transaction_t * xact)
bool entry_t::valid() const
{
if (! is_valid_moment(_date) || ! journal) {
- DEBUG_PRINT("ledger.validate", "entry_t: ! _date || ! journal");
+ DEBUG_("ledger.validate", "entry_t: ! _date || ! journal");
return false;
}
@@ -315,7 +319,7 @@ bool entry_t::valid() const
i != transactions.end();
i++)
if ((*i)->entry != this || ! (*i)->valid()) {
- DEBUG_PRINT("ledger.validate", "entry_t: transaction not valid");
+ DEBUG_("ledger.validate", "entry_t: transaction not valid");
return false;
}
@@ -466,7 +470,7 @@ std::ostream& operator<<(std::ostream& out, const account_t& account)
bool account_t::valid() const
{
if (depth > 256 || ! journal) {
- DEBUG_PRINT("ledger.validate", "account_t: depth > 256 || ! journal");
+ DEBUG_("ledger.validate", "account_t: depth > 256 || ! journal");
return false;
}
@@ -474,12 +478,12 @@ bool account_t::valid() const
i != accounts.end();
i++) {
if (this == (*i).second) {
- DEBUG_PRINT("ledger.validate", "account_t: parent refers to itself!");
+ DEBUG_("ledger.validate", "account_t: parent refers to itself!");
return false;
}
if (! (*i).second->valid()) {
- DEBUG_PRINT("ledger.validate", "account_t: child not valid");
+ DEBUG_("ledger.validate", "account_t: child not valid");
return false;
}
}
@@ -575,7 +579,7 @@ bool journal_t::remove_entry(entry_t * entry)
bool journal_t::valid() const
{
if (! master->valid()) {
- DEBUG_PRINT("ledger.validate", "journal_t: master not valid");
+ DEBUG_("ledger.validate", "journal_t: master not valid");
return false;
}
@@ -583,7 +587,7 @@ bool journal_t::valid() const
i != entries.end();
i++)
if (! (*i)->valid()) {
- DEBUG_PRINT("ledger.validate", "journal_t: entry not valid");
+ DEBUG_("ledger.validate", "journal_t: entry not valid");
return false;
}
@@ -591,7 +595,7 @@ bool journal_t::valid() const
i != commodity_t::commodities.end();
i++)
if (! (*i).second->valid()) {
- DEBUG_PRINT("ledger.validate", "journal_t: commodity not valid");
+ DEBUG_("ledger.validate", "journal_t: commodity not valid");
return false;
}
@@ -634,6 +638,7 @@ void print_entry(std::ostream& out, const entry_base_t& entry_base,
#endif
}
+#if 0
void entry_context::describe(std::ostream& out) const throw()
{
if (! desc.empty())
@@ -657,6 +662,7 @@ xact_context::xact_context(const ledger::transaction_t& _xact,
}
line = xact.beg_line;
}
+#endif
} // namespace ledger
diff --git a/journal.h b/journal.h
index 25a1d395..1995e0f3 100644
--- a/journal.h
+++ b/journal.h
@@ -85,6 +85,7 @@ class transaction_t
bool valid() const;
};
+#if 0
class xact_context : public file_context {
public:
const transaction_t& xact;
@@ -93,6 +94,7 @@ class xact_context : public file_context {
const string& desc = "") throw();
virtual ~xact_context() throw() {}
};
+#endif
class journal_t;
@@ -196,6 +198,7 @@ struct entry_finalizer_t {
void print_entry(std::ostream& out, const entry_base_t& entry,
const string& prefix = "");
+#if 0
class entry_context : public error_context {
public:
const entry_base_t& entry;
@@ -207,14 +210,9 @@ class entry_context : public error_context {
virtual void describe(std::ostream& out) const throw();
};
+#endif
-class balance_error : public error {
- public:
- balance_error(const string& _reason,
- error_context * _ctxt = NULL) throw()
- : error(_reason, _ctxt) {}
- virtual ~balance_error() throw() {}
-};
+DECLARE_EXCEPTION(balance_exception);
class auto_entry_t : public entry_base_t
diff --git a/main.cc b/main.cc
index 188b21d9..49a93586 100644
--- a/main.cc
+++ b/main.cc
@@ -38,11 +38,11 @@ static int read_and_report(report_t * report, int argc, char * argv[],
else
session.use_cache = session.data_file.empty() && session.price_db.empty();
- DEBUG_PRINT("ledger.session.cache", "1. use_cache = " << session.use_cache);
+ DEBUG_("ledger.session.cache", "1. use_cache = " << session.use_cache);
// Process the environment settings
- TRACE(main, "Processing options and environment settings");
+ TRACE(1, "Processing options and environment settings");
process_environment(const_cast<const char **>(envp), "LEDGER_", report);
@@ -60,15 +60,15 @@ static int read_and_report(report_t * report, int argc, char * argv[],
if (session.data_file == session.cache_file)
session.use_cache = false;
- DEBUG_PRINT("ledger.session.cache", "2. use_cache = " << session.use_cache);
+ DEBUG_("ledger.session.cache", "2. use_cache = " << session.use_cache);
- TRACE(main, string("Initialization file is ") + session.init_file);
- TRACE(main, string("Price database is ") + session.price_db);
- TRACE(main, string("Binary cache is ") + session.cache_file);
- TRACE(main, string("Main journal is ") + session.data_file);
+ TRACE(1, "Initialization file is " << session.init_file);
+ TRACE(1, "Price database is " << session.price_db);
+ TRACE(1, "Binary cache is " << session.cache_file);
+ TRACE(1, "Main journal is " << session.data_file);
- TRACE(main, string("Based on option settings, binary cache ") +
- (session.use_cache ? "WILL " : "will NOT ") + "be used");
+ TRACE(1, "Based on option settings, binary cache " <<
+ (session.use_cache ? "WILL " : "will NOT ") << "be used");
// Read the command word and create a command object based on it
@@ -160,7 +160,7 @@ static int read_and_report(report_t * report, int argc, char * argv[],
command.reset(def->functor_obj());
if (! command.get())
- throw new error(string("Unrecognized command '") + verb + "'");
+ throw_(exception, string("Unrecognized command '") + verb + "'");
}
// Parse the initialization file, which can only be textual; then
@@ -186,11 +186,11 @@ static int read_and_report(report_t * report, int argc, char * argv[],
else if (! report->pager.empty()) {
status = pipe(pfd);
if (status == -1)
- throw new error("Failed to create pipe");
+ throw_(exception, "Failed to create pipe");
status = fork();
if (status < 0) {
- throw new error("Failed to fork child process");
+ throw_(exception, "Failed to fork child process");
}
else if (status == 0) { // child
const char *arg0;
@@ -332,29 +332,29 @@ static int read_and_report(report_t * report, int argc, char * argv[],
if (session.use_cache && session.cache_dirty &&
! session.cache_file.empty()) {
- TRACE_PUSH(binary_cache, "Writing journal file");
+ TRACE_START(binary_cache, 1, "Writing journal file");
std::ofstream stream(session.cache_file.c_str());
#if 0
write_binary_journal(stream, journal);
#endif
- TRACE_POP(binary_cache, "Finished writing");
+ TRACE_FINISH(binary_cache, 1);
}
+#if defined(FREE_MEMORY)
// Cleanup memory -- if this is a beta or development build.
-#if DEBUG_LEVEL >= BETA
- { TRACE_PUSH(cleanup, "Cleaning up allocated memory");
+ TRACE_START(cleanup, 1, "Cleaning up allocated memory");
#ifdef USE_BOOST_PYTHON
- shutdown_ledger_for_python();
+ shutdown_ledger_for_python();
#endif
- if (! report->output_file.empty())
- delete out;
+ if (! report->output_file.empty())
+ delete out;
- TRACE_POP(cleanup, "Finished cleaning"); }
+ TRACE_STOP(cleanup, 1);
#endif
// If the user specified a pager, wait for it to exit now
@@ -367,7 +367,7 @@ static int read_and_report(report_t * report, int argc, char * argv[],
// Wait for child to finish
wait(&status);
if (status & 0xffff != 0)
- throw new error("Something went wrong in the pager");
+ throw_(exception, "Something went wrong in the pager");
}
#endif
@@ -388,10 +388,8 @@ int main(int argc, char * argv[], char * envp[])
#if DEBUG_LEVEL < BETA
ledger::do_cleanup = false;
-#else
- ledger::tracing_active = true;
#endif
- TRACE_PUSH(main, "Ledger starting");
+ TRACE(1, "Ledger starting");
ledger::amount_t::initialize();
@@ -410,12 +408,6 @@ int main(int argc, char * argv[], char * envp[])
session->register_parser(new qif_parser_t);
session->register_parser(new textual_parser_t);
-#if DEBUG_LEVEL >= BETA
- DEBUG_IF("ledger.trace.memory") {
- ledger::trace_class_mode = true;
- }
-#endif
-
std::auto_ptr<ledger::report_t> report(new ledger::report_t(session.get()));
status = read_and_report(report.get(), argc, argv, envp);
@@ -427,9 +419,8 @@ int main(int argc, char * argv[], char * envp[])
} else {
ledger::amount_t::shutdown();
}
-
- TRACE_POP(main, "Ledger done");
}
+#if 0
catch (error * err) {
std::cout.flush();
// Push a null here since there's no file context
@@ -439,9 +430,6 @@ int main(int argc, char * argv[], char * envp[])
err->reveal_context(std::cerr, "Error");
std::cerr << err->what() << std::endl;
delete err;
-#if DEBUG_LEVEL >= BETA
- ledger::tracing_active = false;
-#endif
}
catch (fatal * err) {
std::cout.flush();
@@ -452,32 +440,21 @@ int main(int argc, char * argv[], char * envp[])
err->reveal_context(std::cerr, "Fatal");
std::cerr << err->what() << std::endl;
delete err;
-#if DEBUG_LEVEL >= BETA
- ledger::tracing_active = false;
-#endif
}
+#endif
catch (const std::exception& err) {
std::cout.flush();
std::cerr << "Error: " << err.what() << std::endl;
-#if DEBUG_LEVEL >= BETA
- ledger::tracing_active = false;
-#endif
}
catch (int _status) {
-#if DEBUG_LEVEL >= BETA
- ledger::tracing_active = false;
-#endif
status = _status;
}
-#if DEBUG_LEVEL >= BETA
- DEBUG_IF("ledger.trace.memory") {
+ 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;
}
- ledger::tracing_active = false;
-#endif
return status;
}
diff --git a/mask.h b/mask.h
index eb729901..82634c19 100644
--- a/mask.h
+++ b/mask.h
@@ -21,12 +21,6 @@ class mask_t
}
};
-class mask_error : public error {
- public:
- mask_error(const string& _reason) throw() : error(_reason) {}
- virtual ~mask_error() throw() {}
-};
-
} // namespace ledger
#endif // _MASK_H
diff --git a/ofx.cc b/ofx.cc
index e14d643c..29f33cf9 100644
--- a/ofx.cc
+++ b/ofx.cc
@@ -23,7 +23,7 @@ int ofx_proc_account_cb(struct OfxAccountData data, void * account_data)
if (! data.account_id_valid)
return -1;
- DEBUG_PRINT("ledger.ofx.parse", "account " << data.account_name);
+ DEBUG_("ledger.ofx.parse", "account " << data.account_name);
account_t * account = new account_t(master_account, data.account_name);
curr_journal->add_account(account);
ofx_accounts.insert(accounts_pair(data.account_id, account));
@@ -80,7 +80,7 @@ int ofx_proc_transaction_cb(struct OfxTransactionData data,
xact->cost = new amount_t(stream.str() + " " + default_commodity->base_symbol());
}
- DEBUG_PRINT("ledger.ofx.parse", "xact " << xact->amount
+ DEBUG_("ledger.ofx.parse", "xact " << xact->amount
<< " from " << *xact->account);
if (data.date_initiated_valid)
@@ -142,13 +142,13 @@ int ofx_proc_security_cb(struct OfxSecurityData data, void * security_data)
commodities_map::iterator i = ofx_securities.find(data.unique_id);
if (i == ofx_securities.end()) {
- DEBUG_PRINT("ledger.ofx.parse", "security " << symbol);
+ DEBUG_("ledger.ofx.parse", "security " << symbol);
ofx_securities.insert(commodities_pair(data.unique_id, commodity));
}
// jww (2005-02-09): What is the commodity for data.unitprice?
if (data.date_unitprice_valid && data.unitprice_valid) {
- DEBUG_PRINT("ledger.ofx.parse", " price " << data.unitprice);
+ DEBUG_("ledger.ofx.parse", " price " << data.unitprice);
commodity->add_price(data.date_unitprice, amount_t(data.unitprice));
}
diff --git a/option.cc b/option.cc
index 3ba31e71..b8657cd5 100644
--- a/option.cc
+++ b/option.cc
@@ -45,7 +45,9 @@ namespace {
void process_option(xml::xpath_t::functor_t * opt, xml::xpath_t::scope_t * scope,
const char * arg)
{
+#if 0
try {
+#endif
std::auto_ptr<xml::xpath_t::scope_t> args;
if (arg) {
args.reset(new xml::xpath_t::scope_t(scope, xml::xpath_t::scope_t::ARGUMENT));
@@ -54,17 +56,17 @@ namespace {
value_t temp;
(*opt)(temp, args.get());
+#if 0
}
catch (error * err) {
-#if 0
err->context.push_back
(new error_context
(string("While parsing option '--") + opt->long_opt +
"'" + (opt->short_opt != '\0' ?
(string(" (-") + opt->short_opt + "):") : ":")));
-#endif
throw err;
}
+#endif
}
}
@@ -103,9 +105,15 @@ void process_environment(const char ** envp, const string& tag,
*r = '\0';
if (*q == '=') {
+#if 0
try {
+#endif
if (! process_option(buf, scope, q + 1))
- /*throw new option_error("unknown option")*/;
+#if 0
+ throw new option_error("unknown option")
+#endif
+ ;
+#if 0
}
catch (error * err) {
err->context.push_back
@@ -114,6 +122,7 @@ void process_environment(const char ** envp, const string& tag,
*p + "':"));
throw err;
}
+#endif
}
}
}
@@ -149,22 +158,21 @@ void process_arguments(int argc, char ** argv, const bool anywhere,
std::auto_ptr<xml::xpath_t::op_t> opt(find_option(scope, name));
if (! opt.get())
- throw new option_error(string("illegal option --") + name);
+ throw_(option_exception, "illegal option --" << name);
xml::xpath_t::functor_t * def = opt->functor_obj();
if (! def)
- throw new option_error(string("illegal option --") + name);
+ throw_(option_exception, "illegal option --" << name);
if (def->wants_args && value == NULL) {
value = *++i;
if (value == NULL)
- throw new option_error(string("missing option argument for --") +
- name);
+ throw_(option_exception, "missing option argument for --" << name);
}
process_option(def, scope, value);
}
else if ((*i)[1] == '\0') {
- throw new option_error(string("illegal option -"));
+ throw_(option_exception, "illegal option -");
}
else {
std::list<xml::xpath_t::op_t *> option_queue;
@@ -173,11 +181,11 @@ void process_arguments(int argc, char ** argv, const bool anywhere,
for (char c = (*i)[x]; c != '\0'; x++, c = (*i)[x]) {
xml::xpath_t::op_t * opt = find_option(scope, c);
if (! opt)
- throw new option_error(string("illegal option -") + c);
+ throw_(option_exception, "illegal option -" << c);
xml::xpath_t::functor_t * def = opt->functor_obj();
if (! def)
- throw new option_error(string("illegal option -") + c);
+ throw_(option_exception, "illegal option -" << c);
option_queue.push_back(opt);
}
@@ -194,12 +202,13 @@ void process_arguments(int argc, char ** argv, const bool anywhere,
if (def->wants_args) {
value = *++i;
if (value == NULL)
- throw new option_error(string("missing option argument for -") +
+ throw_(option_exception, "missing option argument for -" <<
#if 0
- def->short_opt);
+ def->short_opt
#else
- '?');
+ '?'
#endif
+ );
}
process_option(def, scope, value);
diff --git a/option.h b/option.h
index 2cfbb495..c9664ae3 100644
--- a/option.h
+++ b/option.h
@@ -15,11 +15,7 @@ void process_arguments(int argc, char ** argv, const bool anywhere,
xml::xpath_t::scope_t * scope,
std::list<string>& args);
-class option_error : public error {
- public:
- option_error(const string& reason) throw() : error(reason) {}
- virtual ~option_error() throw() {}
-};
+DECLARE_EXCEPTION(option_exception);
} // namespace ledger
diff --git a/parser.h b/parser.h
index 689846da..2bdc4622 100644
--- a/parser.h
+++ b/parser.h
@@ -21,7 +21,65 @@ class parser_t
const string * original_file = NULL) = 0;
};
-DEFINE_EXCEPTION(parse_exception)
+DECLARE_EXCEPTION(parse_exception);
+
+/************************************************************************
+ *
+ * General utility parsing functions
+ */
+
+inline char * skip_ws(char * ptr) {
+ while (*ptr == ' ' || *ptr == '\t' || *ptr == '\n')
+ ptr++;
+ return ptr;
+}
+
+inline char peek_next_nonws(std::istream& in) {
+ char c = in.peek();
+ while (! in.eof() && std::isspace(c)) {
+ in.get(c);
+ c = in.peek();
+ }
+ return c;
+}
+
+#define READ_INTO(str, targ, size, var, cond) { \
+ char * _p = targ; \
+ var = str.peek(); \
+ while (! str.eof() && var != '\n' && (cond) && _p - targ < size) { \
+ str.get(var); \
+ if (str.eof()) \
+ break; \
+ if (var == '\\') { \
+ str.get(var); \
+ if (in.eof()) \
+ break; \
+ } \
+ *_p++ = var; \
+ var = str.peek(); \
+ } \
+ *_p = '\0'; \
+}
+
+#define READ_INTO_(str, targ, size, var, idx, cond) { \
+ char * _p = targ; \
+ var = str.peek(); \
+ while (! str.eof() && var != '\n' && (cond) && _p - targ < size) { \
+ str.get(var); \
+ if (str.eof()) \
+ break; \
+ idx++; \
+ if (var == '\\') { \
+ str.get(var); \
+ if (in.eof()) \
+ break; \
+ idx++; \
+ } \
+ *_p++ = var; \
+ var = str.peek(); \
+ } \
+ *_p = '\0'; \
+}
} // namespace ledger
diff --git a/py_amount.cc b/py_amount.cc
index 6b13c9af..607d0be5 100644
--- a/py_amount.cc
+++ b/py_amount.cc
@@ -46,11 +46,11 @@ commodity_t * py_find_commodity(const string& symbol)
}
#define EXC_TRANSLATOR(type) \
- void exc_translate_ ## type(const type * const err) { \
- PyErr_SetString(PyExc_ArithmeticError, err->what()); \
+ void exc_translate_ ## type(const type& err) { \
+ PyErr_SetString(PyExc_ArithmeticError, err.what()); \
}
-EXC_TRANSLATOR(amount_error)
+EXC_TRANSLATOR(amount_exception)
void export_amount()
{
@@ -236,7 +236,7 @@ void export_amount()
;
#define EXC_TRANSLATE(type) \
- register_exception_translator<type *>(&exc_translate_ ## type);
+ register_exception_translator<type>(&exc_translate_ ## type);
- EXC_TRANSLATE(amount_error);
+ EXC_TRANSLATE(amount_exception);
}
diff --git a/py_eval.cc b/py_eval.cc
index 04be8750..6113b693 100644
--- a/py_eval.cc
+++ b/py_eval.cc
@@ -71,7 +71,7 @@ object python_interpreter_t::import(const string& str)
try {
PyObject * mod = PyImport_Import(PyString_FromString(str.c_str()));
if (! mod)
- throw error(string("Failed to import Python module ") + str);
+ throw_(exception, "Failed to import Python module " << str);
object newmod(handle<>(borrowed(mod)));
@@ -86,7 +86,7 @@ object python_interpreter_t::import(const string& str)
}
catch (const error_already_set&) {
PyErr_Print();
- throw error(string("Importing Python module ") + str);
+ throw_(exception, "Importing Python module " << str);
}
}
@@ -120,7 +120,7 @@ object python_interpreter_t::eval(std::istream& in, py_eval_mode_t mode)
}
catch (const error_already_set&) {
PyErr_Print();
- throw error("Evaluating Python code");
+ throw_(exception, "Evaluating Python code");
}
}
@@ -138,7 +138,7 @@ object python_interpreter_t::eval(const string& str, py_eval_mode_t mode)
}
catch (const error_already_set&) {
PyErr_Print();
- throw error("Evaluating Python code");
+ throw_(exception, "Evaluating Python code");
}
}
@@ -165,8 +165,8 @@ void python_interpreter_t::functor_t::operator()(value_t& result,
}
else if (PyObject * err = PyErr_Occurred()) {
PyErr_Print();
- throw new xml::xpath_t::calc_error
- (string("While calling Python function '") + name() + "'");
+ throw_(xml::xpath_t::calc_exception,
+ "While calling Python function '" << name() << "'");
} else {
assert(0);
}
@@ -177,8 +177,8 @@ void python_interpreter_t::functor_t::operator()(value_t& result,
}
catch (const error_already_set&) {
PyErr_Print();
- throw new xml::xpath_t::calc_error
- (string("While calling Python function '") + name() + "'");
+ throw_(xml::xpath_t::calc_exception,
+ "While calling Python function '" << name() << "'");
}
}
@@ -194,7 +194,8 @@ void python_interpreter_t::lambda_t::operator()(value_t& result,
}
catch (const error_already_set&) {
PyErr_Print();
- throw new xml::xpath_t::calc_error("While evaluating Python lambda expression");
+ throw_(xml::xpath_t::calc_exception,
+ "While evaluating Python lambda expression");
}
}
diff --git a/qif.cc b/qif.cc
index cc0b3daa..5e567ea0 100644
--- a/qif.cc
+++ b/qif.cc
@@ -56,8 +56,8 @@ unsigned int qif_parser_t::parse(std::istream& in,
src_idx = journal->sources.size() - 1;
linenum = 1;
- istream_pos_type beg_pos = 0;
- unsigned long beg_line = 0;
+ unsigned long beg_pos = 0;
+ unsigned long beg_line = 0;
#define SET_BEG_POS_AND_LINE() \
if (! beg_line) { \
@@ -73,7 +73,7 @@ unsigned int qif_parser_t::parse(std::istream& in,
case '\t':
if (peek_next_nonws(in) != '\n') {
get_line(in);
- throw new parse_error("Line begins with whitespace");
+ throw_(parse_exception, "Line begins with whitespace");
}
// fall through...
@@ -90,8 +90,8 @@ unsigned int qif_parser_t::parse(std::istream& in,
std::strcmp(line, "Type:Cat") == 0 ||
std::strcmp(line, "Type:Class") == 0 ||
std::strcmp(line, "Type:Memorized") == 0)
- throw new parse_error(string("QIF files of type ") + line +
- " are not supported.");
+ throw_(parse_exception,
+ "QIF files of type " << line << " are not supported.");
break;
case 'D':
diff --git a/quotes.cc b/quotes.cc
index 8a1e90c3..204e6fdc 100644
--- a/quotes.cc
+++ b/quotes.cc
@@ -8,17 +8,17 @@ void quotes_by_script::operator()(commodity_base_t& commodity,
const ptime& last,
amount_t& price)
{
- DEBUG_CLASS("ledger.quotes.download");
+ logger("quotes.download");
- DEBUG_PRINT_("commodity: " << commodity.symbol);
- DEBUG_PRINT_TIME_(now);
- DEBUG_PRINT_TIME_(moment);
- DEBUG_PRINT_TIME_(date);
- DEBUG_PRINT_TIME_(last);
+ DEBUG("commodity: " << commodity.symbol);
+ DEBUG(" now: " << now);
+ DEBUG(" moment: " << moment);
+ DEBUG(" date: " << date);
+ DEBUG(" last: " << last);
- if (commodity.history)
- DEBUG_PRINT_TIME_(commodity.history->last_lookup);
- DEBUG_PRINT_("pricing_leeway is " << pricing_leeway);
+ if (SHOW_DEBUG() && commodity.history)
+ DEBUG("last_lookup: " << commodity.history->last_lookup);
+ DEBUG("pricing_leeway is " << pricing_leeway);
if ((commodity.history &&
(time_now - commodity.history->last_lookup) < pricing_leeway) ||
@@ -26,7 +26,7 @@ void quotes_by_script::operator()(commodity_base_t& commodity,
(price && moment > date && (moment - date) <= pricing_leeway))
return;
- DEBUG_PRINT_("downloading quote for symbol " << commodity.symbol);
+ DEBUG("downloading quote for symbol " << commodity.symbol);
char buf[256];
buf[0] = '\0';
@@ -47,7 +47,7 @@ void quotes_by_script::operator()(commodity_base_t& commodity,
char * p = strchr(buf, '\n');
if (p) *p = '\0';
- DEBUG_PRINT_("downloaded quote: " << buf);
+ DEBUG("downloaded quote: " << buf);
price.parse(buf);
commodity.add_price(now, price);
@@ -70,9 +70,10 @@ void quotes_by_script::operator()(commodity_base_t& commodity,
#endif
}
} else {
- throw new error(string("Failed to download price for '") +
+ throw exception(string("Failed to download price for '") +
commodity.symbol + "' (command: \"getquote " +
- commodity.symbol + "\")");
+ commodity.symbol + "\")",
+ context());
}
}
diff --git a/register.cc b/register.cc
index 8df5f556..2633def6 100644
--- a/register.cc
+++ b/register.cc
@@ -3,6 +3,95 @@
namespace ledger {
+string abbreviate(const string& str,
+ unsigned int width,
+ elision_style_t elision_style,
+ const bool is_account,
+ int abbrev_length)
+{
+ const unsigned int len = str.length();
+ if (len <= width)
+ return str;
+
+ assert(width < 4095);
+
+ static char buf[4096];
+
+ switch (elision_style) {
+ case TRUNCATE_LEADING:
+ // This method truncates at the beginning.
+ std::strncpy(buf, str.c_str() + (len - width), width);
+ buf[0] = '.';
+ buf[1] = '.';
+ break;
+
+ case TRUNCATE_MIDDLE:
+ // This method truncates in the middle.
+ std::strncpy(buf, str.c_str(), width / 2);
+ std::strncpy(buf + width / 2,
+ str.c_str() + (len - (width / 2 + width % 2)),
+ width / 2 + width % 2);
+ buf[width / 2 - 1] = '.';
+ buf[width / 2] = '.';
+ break;
+
+ case ABBREVIATE:
+ if (is_account) {
+ std::list<string> parts;
+ string::size_type beg = 0;
+ for (string::size_type pos = str.find(':');
+ pos != string::npos;
+ beg = pos + 1, pos = str.find(':', beg))
+ parts.push_back(string(str, beg, pos - beg));
+ parts.push_back(string(str, beg));
+
+ string result;
+ unsigned int newlen = len;
+ for (std::list<string>::iterator i = parts.begin();
+ i != parts.end();
+ i++) {
+ // Don't contract the last element
+ std::list<string>::iterator x = i;
+ if (++x == parts.end()) {
+ result += *i;
+ break;
+ }
+
+ if (newlen > width) {
+ result += string(*i, 0, abbrev_length);
+ result += ":";
+ newlen -= (*i).length() - abbrev_length;
+ } else {
+ result += *i;
+ result += ":";
+ }
+ }
+
+ if (newlen > width) {
+ // Even abbreviated its too big to show the last account, so
+ // abbreviate all but the last and truncate at the beginning.
+ std::strncpy(buf, result.c_str() + (result.length() - width), width);
+ buf[0] = '.';
+ buf[1] = '.';
+ } else {
+ std::strcpy(buf, result.c_str());
+ }
+ break;
+ }
+ // fall through...
+
+ case TRUNCATE_TRAILING:
+ // This method truncates at the end (the default).
+ std::strncpy(buf, str.c_str(), width - 2);
+ buf[width - 2] = '.';
+ buf[width - 1] = '.';
+ break;
+ }
+ buf[width] = '\0';
+
+ return buf;
+}
+
static void scan_for_transactions(std::ostream& out, const xml::node_t * node)
{
if (! (node->flags & XML_NODE_IS_PARENT))
diff --git a/register.h b/register.h
index 73078892..ba2020ec 100644
--- a/register.h
+++ b/register.h
@@ -20,6 +20,19 @@ class register_command : public xml::xpath_t::functor_t
virtual void print_document(std::ostream& out, xml::document_t * doc);
};
+enum elision_style_t {
+ TRUNCATE_TRAILING,
+ TRUNCATE_MIDDLE,
+ TRUNCATE_LEADING,
+ ABBREVIATE
+};
+
+string abbreviate(const string& str,
+ unsigned int width,
+ elision_style_t elision_style = TRUNCATE_TRAILING,
+ const bool is_account = false,
+ int abbrev_length = 2);
+
} // namespace ledger
#endif // _REGISTER_H
diff --git a/report.cc b/report.cc
index e17bebe3..019bc669 100644
--- a/report.cc
+++ b/report.cc
@@ -22,7 +22,7 @@ void report_t::apply_transforms(xml::document_t * document)
void report_t::abbrev(value_t& result, xml::xpath_t::scope_t * locals)
{
if (locals->args.size() < 2)
- throw new error("usage: abbrev(STRING, WIDTH [, STYLE, ABBREV_LEN])");
+ throw_(exception, "usage: abbrev(STRING, WIDTH [, STYLE, ABBREV_LEN])");
string str = locals->args[0].to_string();
long wid = locals->args[1];
@@ -41,7 +41,7 @@ void report_t::abbrev(value_t& result, xml::xpath_t::scope_t * locals)
void report_t::ftime(value_t&, xml::xpath_t::scope_t * locals)
{
if (locals->args.size() < 1)
- throw new error("usage: ftime(DATE [, DATE_FORMAT])");
+ throw_(exception, "usage: ftime(DATE [, DATE_FORMAT])");
moment_t date = locals->args[0].to_datetime();
diff --git a/session.cc b/session.cc
index 8cd86e11..6d6215e8 100644
--- a/session.cc
+++ b/session.cc
@@ -27,7 +27,7 @@ unsigned int session_t::read_journal(const string& path,
journal->sources.push_back(path);
if (access(path.c_str(), R_OK) == -1)
- throw new error(string("Cannot read file '") + path + "'");
+ throw_(exception, "Cannot read file '" << path << "'");
if (! original_file)
original_file = &path;
@@ -42,7 +42,7 @@ void session_t::read_init()
return;
if (access(init_file.c_str(), R_OK) == -1)
- throw new error(string("Cannot read init file '") + init_file + "'");
+ throw_(exception, "Cannot read init file '" << init_file << "'");
std::ifstream init(init_file.c_str());
@@ -51,7 +51,7 @@ void session_t::read_init()
journal_t * session_t::read_data(const string& master_account)
{
- TRACE_PUSH(parser, "Parsing journal file");
+ TRACE_START(parser, 1, "Parsing journal file");
journal_t * journal = new_journal();
journal->document = new xml::document_t;
@@ -59,12 +59,12 @@ journal_t * session_t::read_data(const string& master_account)
unsigned int entry_count = 0;
- DEBUG_PRINT("ledger.cache",
+ DEBUG_("ledger.cache",
"3. use_cache = " << use_cache);
if (use_cache && ! cache_file.empty() &&
! data_file.empty()) {
- DEBUG_PRINT("ledger.cache",
+ DEBUG_("ledger.cache",
"using_cache " << cache_file);
cache_dirty = true;
if (access(cache_file.c_str(), R_OK) != -1) {
@@ -90,15 +90,15 @@ journal_t * session_t::read_data(const string& master_account)
if (! journal->price_db.empty() &&
access(journal->price_db.c_str(), R_OK) != -1) {
if (read_journal(journal->price_db, journal)) {
- throw new error("Entries not allowed in price history file");
+ throw_(exception, "Entries not allowed in price history file");
} else {
- DEBUG_PRINT("ledger.cache",
+ DEBUG_("ledger.cache",
"read price database " << journal->price_db);
journal->sources.pop_back();
}
}
- DEBUG_PRINT("ledger.cache",
+ DEBUG_("ledger.cache",
"rejected cache, parsing " << data_file);
if (data_file == "-") {
use_cache = false;
@@ -112,13 +112,13 @@ journal_t * session_t::read_data(const string& master_account)
}
}
- VALIDATE(journal->valid());
+ VERIFY(journal->valid());
if (entry_count == 0)
- throw new error("Failed to locate any journal entries; "
- "did you specify a valid file with -f?");
+ throw_(exception, "Failed to locate any journal entries; "
+ "did you specify a valid file with -f?");
- TRACE_POP(parser, "Finished parsing");
+ TRACE_STOP(parser, 1);
return journal;
}
@@ -185,6 +185,8 @@ xml::xpath_t::op_t * session_t::lookup(const string& name)
return xml::xpath_t::scope_t::lookup(name);
}
+// jww (2007-04-26): All of Ledger should be accessed through a
+// session_t object
void initialize()
{
amount_t::initialize();
@@ -193,7 +195,6 @@ void initialize()
void shutdown()
{
amount_t::shutdown();
- assert(live_count.size() == 0);
}
} // namespace ledger
diff --git a/session.h b/session.h
index a3bfb92f..a848c126 100644
--- a/session.h
+++ b/session.h
@@ -3,6 +3,7 @@
#include "journal.h"
#include "parser.h"
+#include "register.h"
namespace ledger {
diff --git a/system.hh b/system.hh
index 138af88a..a61e168e 100644
--- a/system.hh
+++ b/system.hh
@@ -21,16 +21,17 @@
#include <algorithm>
#include <exception>
-#include <fstream>
#include <iostream>
+#include <streambuf>
+#include <iomanip>
+#include <fstream>
+#include <sstream>
#include <iterator>
#include <list>
#include <map>
#include <memory>
#include <new>
-#include <sstream>
#include <stack>
-#include <streambuf>
#include <string>
#include <vector>
diff --git a/tests/corelib/numerics/BasicAmount.cc b/tests/corelib/numerics/BasicAmount.cc
index fbab8877..90cf26ec 100644
--- a/tests/corelib/numerics/BasicAmount.cc
+++ b/tests/corelib/numerics/BasicAmount.cc
@@ -339,7 +339,7 @@ void BasicAmountTestCase::testIntegerDivision()
amount_t x1(123L);
amount_t y1(456L);
- assertThrow(x1 / 0L, amount_error *);
+ assertThrow(x1 / 0L, amount_exception);
assertEqual(amount_t(0L), amount_t(0L) / x1);
assertEqual(amount_t(0L), 0L / x1);
assertEqual(x1, x1 / 1L);
@@ -376,7 +376,7 @@ void BasicAmountTestCase::testFractionalDivision()
amount_t x1(123.123);
amount_t y1(456.456);
- assertThrow(x1 / 0L, amount_error *);
+ assertThrow(x1 / 0L, amount_exception);
assertEqual(amount_t("0.008121959"), amount_t(1.0) / x1);
assertEqual(amount_t("0.008121959"), 1.0 / x1);
assertEqual(x1, x1 / 1.0);
diff --git a/tests/corelib/numerics/Commodity.cc b/tests/corelib/numerics/Commodity.cc
index e43ee7b7..e7e2a18c 100644
--- a/tests/corelib/numerics/Commodity.cc
+++ b/tests/corelib/numerics/Commodity.cc
@@ -3,10 +3,10 @@
CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(CommodityTestCase, "numerics");
void CommodityTestCase::setUp() {
- amount_t::initialize();
+ ledger::initialize();
}
void CommodityTestCase::tearDown() {
- amount_t::shutdown();
+ ledger::shutdown();
}
void CommodityTestCase::testPriceHistory()
diff --git a/tests/corelib/numerics/CommodityAmount.cc b/tests/corelib/numerics/CommodityAmount.cc
index afdbe89e..7ed7f403 100644
--- a/tests/corelib/numerics/CommodityAmount.cc
+++ b/tests/corelib/numerics/CommodityAmount.cc
@@ -6,7 +6,7 @@ CPPUNIT_TEST_SUITE_NAMED_REGISTRATION(CommodityAmountTestCase, "numerics");
void CommodityAmountTestCase::setUp()
{
- amount_t::initialize();
+ ledger::initialize();
// Cause the display precision for dollars to be initialized to 2.
amount_t x1("$1.00");
@@ -17,7 +17,7 @@ void CommodityAmountTestCase::setUp()
void CommodityAmountTestCase::tearDown()
{
amount_t::full_strings = false;
- amount_t::shutdown();
+ ledger::shutdown();
}
void CommodityAmountTestCase::testConstructors()
@@ -232,13 +232,13 @@ void CommodityAmountTestCase::testAddition()
assertEqual(string("$246.90"), (x1 + x1).to_string());
assertEqual(string("$246.91"), (x1 + x2).to_string());
- assertThrow(x1 + x0, amount_error *);
- assertThrow(x1 + x3, amount_error *);
- assertThrow(x1 + x4, amount_error *);
- assertThrow(x1 + x5, amount_error *);
- assertThrow(x1 + x6, amount_error *);
- assertThrow(x1 + 123.45, amount_error *);
- assertThrow(x1 + 123L, amount_error *);
+ assertThrow(x1 + x0, amount_exception);
+ assertThrow(x1 + x3, amount_exception);
+ assertThrow(x1 + x4, amount_exception);
+ assertThrow(x1 + x5, amount_exception);
+ assertThrow(x1 + x6, amount_exception);
+ assertThrow(x1 + 123.45, amount_exception);
+ assertThrow(x1 + 123L, amount_exception);
assertEqual(amount_t("DM 246.90"), x3 + x3);
assertEqual(amount_t("246.90 euro"), x4 + x4);
@@ -290,13 +290,13 @@ void CommodityAmountTestCase::testSubtraction()
assertEqual(string("$0.00"), (x1 - x1).to_string());
assertEqual(string("$-0.01"), (x1 - x2).to_string());
- assertThrow(x1 - x0, amount_error *);
- assertThrow(x1 - x3, amount_error *);
- assertThrow(x1 - x4, amount_error *);
- assertThrow(x1 - x5, amount_error *);
- assertThrow(x1 - x6, amount_error *);
- assertThrow(x1 - 123.45, amount_error *);
- assertThrow(x1 - 123L, amount_error *);
+ assertThrow(x1 - x0, amount_exception);
+ assertThrow(x1 - x3, amount_exception);
+ assertThrow(x1 - x4, amount_exception);
+ assertThrow(x1 - x5, amount_exception);
+ assertThrow(x1 - x6, amount_exception);
+ assertThrow(x1 - 123.45, amount_exception);
+ assertThrow(x1 - 123L, amount_exception);
assertEqual(amount_t("DM 0.00"), x3 - x3);
assertEqual(amount_t("DM 23.45"), x3 - amount_t("DM 100.00"));
@@ -374,9 +374,9 @@ void CommodityAmountTestCase::testMultiplication()
assertEqual(string("$15200.00"), (x1 * x2).to_string());
assertEqual(string("$15199.99986168"), (x2 * x1).to_string());
- assertThrow(x1 * x3, amount_error *);
- assertThrow(x1 * x4, amount_error *);
- assertThrow(x1 * x5, amount_error *);
+ assertThrow(x1 * x3, amount_exception);
+ assertThrow(x1 * x4, amount_exception);
+ assertThrow(x1 * x5, amount_exception);
x1 *= amount_t("123.12");
assertEqual(internalAmount("$15158.5344"), x1);
@@ -410,7 +410,7 @@ void CommodityAmountTestCase::testDivision()
amount_t x4("123.45 euro");
amount_t x5("123.45€");
- assertThrow(x1 / 0L, amount_error *);
+ assertThrow(x1 / 0L, amount_exception);
assertEqual(amount_t("$0.00"), 0L / x1);
assertEqual(x1, x1 / 1L);
assertEqual(internalAmount("$0.00812216"), 1L / x1);
@@ -428,9 +428,9 @@ void CommodityAmountTestCase::testDivision()
assertEqual(string("$1.00"), (x1 / x2).to_string());
assertEqual(string("$1.00273545321637426901"), (x2 / x1).to_string());
- assertThrow(x1 / x3, amount_error *);
- assertThrow(x1 / x4, amount_error *);
- assertThrow(x1 / x5, amount_error *);
+ assertThrow(x1 / x3, amount_exception);
+ assertThrow(x1 / x4, amount_exception);
+ assertThrow(x1 / x5, amount_exception);
x1 /= amount_t("123.12");
assertEqual(internalAmount("$1.00"), x1);
diff --git a/textual.cc b/textual.cc
index d73afb12..1aa96abd 100644
--- a/textual.cc
+++ b/textual.cc
@@ -52,7 +52,7 @@ parse_amount_expr(std::istream& in, journal_t *,
{
xml::xpath_t xpath(in, flags | XPATH_PARSE_RELAXED | XPATH_PARSE_PARTIAL);
- DEBUG_PRINT("ledger.textual.parse", "line " << linenum << ": " <<
+ DEBUG_("ledger.textual.parse", "line " << linenum << ": " <<
"Parsed an amount expression");
#ifdef DEBUG_ENABLED
@@ -66,7 +66,7 @@ parse_amount_expr(std::istream& in, journal_t *,
amount = xpath.calc(static_cast<xml::transaction_node_t *>(xact.data)).to_amount();
- DEBUG_PRINT("ledger.textual.parse", "line " << linenum << ": " <<
+ DEBUG_("ledger.textual.parse", "line " << linenum << ": " <<
"The transaction amount is " << amount);
}
@@ -112,7 +112,9 @@ transaction_t * parse_transaction(char * line,
}
string err_desc;
+#if 0
try {
+#endif
xact->entry = entry; // this might be NULL
@@ -122,12 +124,12 @@ transaction_t * parse_transaction(char * line,
switch (*state) {
case '*':
xact->state = transaction_t::CLEARED;
- DEBUG_PRINT("ledger.textual.parse", "line " << linenum << ": " <<
+ DEBUG_("ledger.textual.parse", "line " << linenum << ": " <<
"Parsed the CLEARED flag");
break;
case '!':
xact->state = transaction_t::PENDING;
- DEBUG_PRINT("ledger.textual.parse", "line " << linenum << ": " <<
+ DEBUG_("ledger.textual.parse", "line " << linenum << ": " <<
"Parsed the PENDING flag");
break;
}
@@ -139,18 +141,18 @@ transaction_t * parse_transaction(char * line,
if ((*b == '[' && *e == ']') ||
(*b == '(' && *e == ')')) {
xact->flags |= TRANSACTION_VIRTUAL;
- DEBUG_PRINT("ledger.textual.parse", "line " << linenum << ": " <<
+ DEBUG_("ledger.textual.parse", "line " << linenum << ": " <<
"Parsed a virtual account name");
if (*b == '[') {
xact->flags |= TRANSACTION_BALANCE;
- DEBUG_PRINT("ledger.textual.parse", "line " << linenum << ": " <<
+ DEBUG_("ledger.textual.parse", "line " << linenum << ": " <<
"Parsed a balanced virtual account name");
}
*account_path++ = '\0';
*e = '\0';
}
- DEBUG_PRINT("ledger.textual.parse", "line " << linenum << ": " <<
+ DEBUG_("ledger.textual.parse", "line " << linenum << ": " <<
"Parsed account name " << account_path);
if (account_aliases.size() > 0) {
accounts_map::const_iterator i = account_aliases.find(account_path);
@@ -202,9 +204,9 @@ transaction_t * parse_transaction(char * line,
xact->amount_expr = string(line, beg, end - beg);
}
}
- catch (error * err) {
+ catch (exception& err) {
err_desc = "While parsing transaction amount:";
- throw err;
+ throw;
}
// Parse the optional cost (@ PER-UNIT-COST, @@ TOTAL-COST)
@@ -212,14 +214,14 @@ transaction_t * parse_transaction(char * line,
if (in.good() && ! in.eof()) {
char c = peek_next_nonws(in);
if (c == '@') {
- DEBUG_PRINT("ledger.textual.parse", "line " << linenum << ": " <<
+ DEBUG_("ledger.textual.parse", "line " << linenum << ": " <<
"Found a price indicator");
bool per_unit = true;
in.get(c);
if (in.peek() == '@') {
in.get(c);
per_unit = false;
- DEBUG_PRINT("ledger.textual.parse", "line " << linenum << ": " <<
+ DEBUG_("ledger.textual.parse", "line " << linenum << ": " <<
"And it's for a total price");
}
@@ -240,13 +242,13 @@ transaction_t * parse_transaction(char * line,
xact->cost_expr = (string("@@") +
string(amount, beg, end - beg));
}
- catch (error * err) {
+ catch (exception& err) {
err_desc = "While parsing transaction cost:";
- throw err;
+ throw;
}
if (*xact->cost < 0)
- throw new parse_error("A transaction's cost may not be negative");
+ throw_(parse_exception, "A transaction's cost may not be negative");
amount_t per_unit_cost(*xact->cost);
if (per_unit)
@@ -260,13 +262,13 @@ transaction_t * parse_transaction(char * line,
xact->entry->actual_date(),
xact->entry->code);
- DEBUG_PRINT("ledger.textual.parse", "line " << linenum << ": " <<
+ DEBUG_("ledger.textual.parse", "line " << linenum << ": " <<
"Total cost is " << *xact->cost);
- DEBUG_PRINT("ledger.textual.parse", "line " << linenum << ": " <<
+ DEBUG_("ledger.textual.parse", "line " << linenum << ": " <<
"Per-unit cost is " << per_unit_cost);
- DEBUG_PRINT("ledger.textual.parse", "line " << linenum << ": " <<
+ DEBUG_("ledger.textual.parse", "line " << linenum << ": " <<
"Annotated amount is " << xact->amount);
- DEBUG_PRINT("ledger.textual.parse", "line " << linenum << ": " <<
+ DEBUG_("ledger.textual.parse", "line " << linenum << ": " <<
"Bare amount is " << xact->amount.number());
}
}
@@ -274,7 +276,7 @@ transaction_t * parse_transaction(char * line,
xact->amount.in_place_reduce();
- DEBUG_PRINT("ledger.textual.parse", "line " << linenum << ": " <<
+ DEBUG_("ledger.textual.parse", "line " << linenum << ": " <<
"Reduced amount is " << xact->amount);
}
@@ -282,7 +284,7 @@ transaction_t * parse_transaction(char * line,
if (note) {
xact->note = note;
- DEBUG_PRINT("ledger.textual.parse", "line " << linenum << ": " <<
+ DEBUG_("ledger.textual.parse", "line " << linenum << ": " <<
"Parsed a note '" << xact->note << "'");
if (char * b = std::strchr(xact->note.c_str(), '['))
@@ -291,7 +293,7 @@ transaction_t * parse_transaction(char * line,
std::strncpy(buf, b + 1, e - b - 1);
buf[e - b - 1] = '\0';
- DEBUG_PRINT("ledger.textual.parse", "line " << linenum << ": " <<
+ DEBUG_("ledger.textual.parse", "line " << linenum << ": " <<
"Parsed a transaction date " << buf);
if (char * p = std::strchr(buf, '=')) {
@@ -305,6 +307,7 @@ transaction_t * parse_transaction(char * line,
return xact.release();
+#if 0
}
catch (error * err) {
err->context.push_back
@@ -312,6 +315,7 @@ transaction_t * parse_transaction(char * line,
err_desc : "While parsing transaction:"));
throw err;
}
+#endif
}
bool parse_transactions(std::istream& in,
@@ -345,13 +349,6 @@ bool parse_transactions(std::istream& in,
return added;
}
-namespace {
- TIMER_DEF(parsing_total, "total parsing time")
- TIMER_DEF(entry_xacts, "parsing transactions")
- TIMER_DEF(entry_details, "parsing entry details")
- TIMER_DEF(entry_date, "parsing entry date")
-}
-
entry_t * parse_entry(std::istream& in, char * line, journal_t * journal,
account_t * master, textual_parser_t& /* parser */,
unsigned long beg_pos)
@@ -415,18 +412,18 @@ entry_t * parse_entry(std::istream& in, char * line, journal_t * journal,
// Parse the date
- TIMER_START(entry_date);
+ TRACE_START(entry_date, 2, "Parsing entry date");
curr->_date = parse_datetime(date);
if (date_eff)
curr->_date_eff = parse_datetime(date_eff);
- TIMER_STOP(entry_date);
+ TRACE_STOP(entry_date, 2);
// Parse the optional cleared flag: *
- TIMER_START(entry_details);
+ TRACE_START(entry_details, 2, "Parsing entry details");
transaction_t::state_t state = transaction_t::UNCLEARED;
if (statep) {
@@ -450,11 +447,11 @@ entry_t * parse_entry(std::istream& in, char * line, journal_t * journal,
assert(payee);
curr->payee = *payee != '\0' ? payee : "<Unspecified payee>";
- TIMER_STOP(entry_details);
+ TRACE_STOP(entry_details, 2);
// Parse all of the transactions associated with this entry
- TIMER_START(entry_xacts);
+ TRACE_START(entry_xacts, 2, "Parsing entry transactions");
unsigned long end_pos;
unsigned long beg_line = linenum;
@@ -495,7 +492,7 @@ entry_t * parse_entry(std::istream& in, char * line, journal_t * journal,
curr->data = NULL;
}
- TIMER_STOP(entry_xacts);
+ TRACE_STOP(entry_xacts, 2);
return curr.release();
}
@@ -513,7 +510,7 @@ static inline void parse_symbol(char *& p, string& symbol)
if (*p == '"') {
char * q = std::strchr(p + 1, '"');
if (! q)
- throw new parse_error("Quoted commodity symbol lacks closing quote");
+ throw_(parse_exception, "Quoted commodity symbol lacks closing quote");
symbol = string(p + 1, 0, q - p - 1);
p = q + 2;
} else {
@@ -525,7 +522,7 @@ static inline void parse_symbol(char *& p, string& symbol)
p += symbol.length();
}
if (symbol.empty())
- throw new parse_error("Failed to parse commodity");
+ throw_(parse_exception, "Failed to parse commodity");
}
bool textual_parser_t::test(std::istream& in) const
@@ -535,9 +532,9 @@ bool textual_parser_t::test(std::istream& in) const
in.read(buf, 5);
if (std::strncmp(buf, "<?xml", 5) == 0) {
#if defined(HAVE_EXPAT) || defined(HAVE_XMLPARSE)
- throw new parse_error("Ledger file contains XML data, but format was not recognized");
+ throw_(parse_exception, "Ledger file contains XML data, but format was not recognized");
#else
- throw new parse_error("Ledger file contains XML data, but no XML support present");
+ throw_(parse_exception, "Ledger file contains XML data, but no XML support present");
#endif
}
@@ -559,11 +556,11 @@ static void clock_out_from_timelog(const moment_t& when,
time_entries.clear();
}
else if (time_entries.empty()) {
- throw new parse_error("Timelog check-out event without a check-in");
+ throw_(parse_exception, "Timelog check-out event without a check-in");
}
else if (! account) {
- throw new parse_error
- ("When multiple check-ins are active, checking out requires an account");
+ throw_(parse_exception,
+ "When multiple check-ins are active, checking out requires an account");
}
else {
bool found = false;
@@ -579,8 +576,8 @@ static void clock_out_from_timelog(const moment_t& when,
}
if (! found)
- throw new parse_error
- ("Timelog check-out event does not match any current check-ins");
+ throw_(parse_exception,
+ "Timelog check-out event does not match any current check-ins");
}
if (desc && event.desc.empty()) {
@@ -594,8 +591,8 @@ static void clock_out_from_timelog(const moment_t& when,
curr->payee = event.desc;
if (curr->_date < event.checkin)
- throw new parse_error
- ("Timelog check-out date less than corresponding check-in");
+ throw_(parse_exception,
+ "Timelog check-out date less than corresponding check-in");
char buf[32];
std::sprintf(buf, "%lds", (long)(curr->_date - event.checkin).total_seconds());
@@ -608,7 +605,7 @@ static void clock_out_from_timelog(const moment_t& when,
curr->add_transaction(xact);
if (! journal->add_entry(curr.get()))
- throw new parse_error("Failed to record 'out' timelog entry");
+ throw_(parse_exception, "Failed to record 'out' timelog entry");
else
curr.release();
}
@@ -623,7 +620,7 @@ unsigned int textual_parser_t::parse(std::istream& in,
unsigned int count = 0;
unsigned int errors = 0;
- TIMER_START(parsing_total);
+ TRACE_START(parsing_total, 2, "Parsing textual file");
std::list<account_t *> account_stack;
@@ -643,7 +640,9 @@ unsigned int textual_parser_t::parse(std::istream& in,
unsigned long beg_line = linenum;
while (in.good() && ! in.eof()) {
+#if 0
try {
+#endif
in.getline(line, MAX_LINE);
if (in.eof())
break;
@@ -659,7 +658,7 @@ unsigned int textual_parser_t::parse(std::istream& in,
case '\t': {
char * p = skip_ws(line);
if (*p && *p != '\r')
- throw new parse_error("Line begins with whitespace");
+ throw_(parse_exception, "Line begins with whitespace");
break;
}
@@ -681,8 +680,8 @@ unsigned int textual_parser_t::parse(std::istream& in,
i != time_entries.end();
i++)
if (event.account == (*i).account)
- throw new parse_error
- ("Cannot double check-in to the same account");
+ throw_(parse_exception,
+ "Cannot double check-in to the same account");
time_entries.push_back(event);
break;
@@ -691,7 +690,7 @@ unsigned int textual_parser_t::parse(std::istream& in,
case 'o':
case 'O':
if (time_entries.empty()) {
- throw new parse_error("Timelog check-out event without a check-in");
+ throw_(parse_exception, "Timelog check-out event without a check-in");
} else {
string date(line, 2, 19);
@@ -776,7 +775,7 @@ unsigned int textual_parser_t::parse(std::istream& in,
break;
case '-': // option setting
- throw new parse_error("Option settings are not allowed in journal files");
+ throw_(parse_exception, "Option settings are not allowed in journal files");
case '=': { // automated entry
if (! added_auto_entry_hook) {
@@ -800,7 +799,7 @@ unsigned int textual_parser_t::parse(std::istream& in,
case '~': { // period entry
period_entry_t * pe = new period_entry_t(skip_ws(line + 1));
if (! pe->period)
- throw new parse_error(string("Parsing time period '") + skip_ws(line + 1) + "'");
+ throw_(parse_exception, string("Parsing time period '") + skip_ws(line + 1) + "'");
if (parse_transactions(in, journal, account_stack.front(), *pe,
"period", end_pos)) {
@@ -813,7 +812,7 @@ unsigned int textual_parser_t::parse(std::istream& in,
pe->end_pos = end_pos;
pe->end_line = linenum;
} else {
- throw new parse_error("Period entry failed to balance");
+ throw_(parse_exception, "Period entry failed to balance");
}
}
break;
@@ -840,7 +839,7 @@ unsigned int textual_parser_t::parse(std::istream& in,
}
path = resolve_path(path);
- DEBUG_PRINT("ledger.textual.include", "line " << linenum << ": " <<
+ DEBUG_("ledger.textual.include", "line " << linenum << ": " <<
"Including path '" << path << "'");
include_stack.push_back(std::pair<string, int>
@@ -903,15 +902,16 @@ unsigned int textual_parser_t::parse(std::istream& in,
count++;
} else {
delete entry;
- throw new parse_error("Entry does not balance");
+ throw_(parse_exception, "Entry does not balance");
}
} else {
- throw new parse_error("Failed to parse entry");
+ throw_(parse_exception, "Failed to parse entry");
}
end_pos = pos;
break;
}
}
+#if 0
}
catch (error * err) {
for (std::list<std::pair<string, int> >::reverse_iterator i =
@@ -930,6 +930,7 @@ unsigned int textual_parser_t::parse(std::istream& in,
delete err;
errors++;
}
+#endif
beg_pos = end_pos;
}
@@ -947,7 +948,7 @@ unsigned int textual_parser_t::parse(std::istream& in,
if (errors > 0)
throw (int)errors;
- TIMER_STOP(parsing_total);
+ TRACE_STOP(parsing_total, 2);
return count;
}
diff --git a/textual.h b/textual.h
index e69e726b..bf05b1fc 100644
--- a/textual.h
+++ b/textual.h
@@ -23,6 +23,7 @@ void write_textual_journal(journal_t& journal, string path,
std::ostream& out);
#endif
+#if 0
class include_context : public file_context {
public:
include_context(const string& file, unsigned long line,
@@ -36,6 +37,7 @@ class include_context : public file_context {
out << "\"" << file << "\", line " << line << ":" << std::endl;
}
};
+#endif
} // namespace ledger
diff --git a/times.cc b/times.cc
index e8eede6b..989bf055 100644
--- a/times.cc
+++ b/times.cc
@@ -46,4 +46,4 @@ moment_t datetime_range_from_stream(std::istream& in)
{
}
-}
+} // namespace ledger
diff --git a/times.h b/times.h
index 22a44f3a..38ed5e27 100644
--- a/times.h
+++ b/times.h
@@ -36,11 +36,7 @@ inline bool is_valid_moment(const moment_t& moment) {
extern moment_t& now;
-class datetime_error : public error {
- public:
- datetime_error(const string& _reason) throw() : error(_reason) {}
- virtual ~datetime_error() throw() {}
-};
+DECLARE_EXCEPTION(datetime_exception);
class interval_t
{
@@ -86,6 +82,7 @@ extern ptime time_now;
extern date date_now;
extern bool day_before_month;
+#if 0
struct intorchar
{
int ival;
@@ -97,8 +94,9 @@ struct intorchar
intorchar(const intorchar& o) : ival(o.ival), sval(o.sval) {}
};
-}
-
ledger::moment_t parse_abs_datetime(std::istream& input);
+#endif
+
+} // namespace ledger
-#endif /* _TIMES_H */
+#endif // _TIMES_H
diff --git a/util.cc b/util.cc
deleted file mode 100644
index 09d35b2f..00000000
--- a/util.cc
+++ /dev/null
@@ -1,146 +0,0 @@
-#include "utils.h"
-
-namespace ledger {
-
-string expand_path(const string& path)
-{
- if (path.length() == 0 || path[0] != '~')
- return path;
-
- const char * pfx = NULL;
- string::size_type pos = path.find_first_of('/');
-
- if (path.length() == 1 || pos == 1) {
- pfx = std::getenv("HOME");
-#ifdef HAVE_GETPWUID
- if (! pfx) {
- // Punt. We're trying to expand ~/, but HOME isn't set
- struct passwd * pw = getpwuid(getuid());
- if (pw)
- pfx = pw->pw_dir;
- }
-#endif
- }
-#ifdef HAVE_GETPWNAM
- else {
- string user(path, 1, pos == string::npos ?
- string::npos : pos - 1);
- struct passwd * pw = getpwnam(user.c_str());
- if (pw)
- pfx = pw->pw_dir;
- }
-#endif
-
- // if we failed to find an expansion, return the path unchanged.
-
- if (! pfx)
- return path;
-
- string result(pfx);
-
- if (pos == string::npos)
- return result;
-
- if (result.length() == 0 || result[result.length() - 1] != '/')
- result += '/';
-
- result += path.substr(pos + 1);
-
- return result;
-}
-
-string resolve_path(const string& path)
-{
- if (path[0] == '~')
- return expand_path(path);
- return path;
-}
-
-string abbreviate(const string& str, unsigned int width,
- elision_style_t elision_style, const bool is_account,
- int abbrev_length)
-{
- const unsigned int len = str.length();
- if (len <= width)
- return str;
-
- assert(width < 4095);
-
- static char buf[4096];
-
- switch (elision_style) {
- case TRUNCATE_LEADING:
- // This method truncates at the beginning.
- std::strncpy(buf, str.c_str() + (len - width), width);
- buf[0] = '.';
- buf[1] = '.';
- break;
-
- case TRUNCATE_MIDDLE:
- // This method truncates in the middle.
- std::strncpy(buf, str.c_str(), width / 2);
- std::strncpy(buf + width / 2,
- str.c_str() + (len - (width / 2 + width % 2)),
- width / 2 + width % 2);
- buf[width / 2 - 1] = '.';
- buf[width / 2] = '.';
- break;
-
- case ABBREVIATE:
- if (is_account) {
- std::list<string> parts;
- string::size_type beg = 0;
- for (string::size_type pos = str.find(':');
- pos != string::npos;
- beg = pos + 1, pos = str.find(':', beg))
- parts.push_back(string(str, beg, pos - beg));
- parts.push_back(string(str, beg));
-
- string result;
- unsigned int newlen = len;
- for (std::list<string>::iterator i = parts.begin();
- i != parts.end();
- i++) {
- // Don't contract the last element
- std::list<string>::iterator x = i;
- if (++x == parts.end()) {
- result += *i;
- break;
- }
-
- if (newlen > width) {
- result += string(*i, 0, abbrev_length);
- result += ":";
- newlen -= (*i).length() - abbrev_length;
- } else {
- result += *i;
- result += ":";
- }
- }
-
- if (newlen > width) {
- // Even abbreviated its too big to show the last account, so
- // abbreviate all but the last and truncate at the beginning.
- std::strncpy(buf, result.c_str() + (result.length() - width), width);
- buf[0] = '.';
- buf[1] = '.';
- } else {
- std::strcpy(buf, result.c_str());
- }
- break;
- }
- // fall through...
-
- case TRUNCATE_TRAILING:
- // This method truncates at the end (the default).
- std::strncpy(buf, str.c_str(), width - 2);
- buf[width - 2] = '.';
- buf[width - 1] = '.';
- break;
- }
- buf[width] = '\0';
-
- return buf;
-}
-
-} // namespace ledger
diff --git a/util.h b/util.h
deleted file mode 100644
index 5965a5ed..00000000
--- a/util.h
+++ /dev/null
@@ -1,88 +0,0 @@
-#ifndef _UTIL_H
-#define _UTIL_H
-
-namespace ledger {
-
-inline char * skip_ws(char * ptr) {
- while (*ptr == ' ' || *ptr == '\t' || *ptr == '\n')
- ptr++;
- return ptr;
-}
-
-inline char peek_next_nonws(std::istream& in) {
- char c = in.peek();
- while (! in.eof() && std::isspace(c)) {
- in.get(c);
- c = in.peek();
- }
- return c;
-}
-
-#define READ_INTO(str, targ, size, var, cond) { \
- char * _p = targ; \
- var = str.peek(); \
- while (! str.eof() && var != '\n' && (cond) && _p - targ < size) { \
- str.get(var); \
- if (str.eof()) \
- break; \
- if (var == '\\') { \
- str.get(var); \
- if (in.eof()) \
- break; \
- } \
- *_p++ = var; \
- var = str.peek(); \
- } \
- *_p = '\0'; \
-}
-
-#define READ_INTO_(str, targ, size, var, idx, cond) { \
- char * _p = targ; \
- var = str.peek(); \
- while (! str.eof() && var != '\n' && (cond) && _p - targ < size) { \
- str.get(var); \
- if (str.eof()) \
- break; \
- idx++; \
- if (var == '\\') { \
- str.get(var); \
- if (in.eof()) \
- break; \
- idx++; \
- } \
- *_p++ = var; \
- var = str.peek(); \
- } \
- *_p = '\0'; \
-}
-
-ledger::string resolve_path(const ledger::string& path);
-
-#ifdef HAVE_REALPATH
-extern "C" char *realpath(const char *, char resolved_path[]);
-#endif
-
-enum elision_style_t {
- TRUNCATE_TRAILING,
- TRUNCATE_MIDDLE,
- TRUNCATE_LEADING,
- ABBREVIATE
-};
-
-ledger::string abbreviate(const ledger::string& str, unsigned int width,
- elision_style_t elision_style = TRUNCATE_TRAILING,
- const bool is_account = false, int abbrev_length = 2);
-
-static inline const
-ledger::string& either_or(const ledger::string& first,
- const ledger::string& second)
-{
- if (first.empty())
- return second;
- else
- return first;
-}
-
-} // namespace ledger
-
-#endif // _UTIL_H
diff --git a/utils.cc b/utils.cc
index 5c4cbef7..4b8a4835 100644
--- a/utils.cc
+++ b/utils.cc
@@ -1,10 +1,14 @@
#include "utils.h"
-#include "times.h"
-namespace ledger
+/**********************************************************************
+ *
+ * Assertions
+ */
#if defined(ASSERTS_ON)
+namespace ledger {
+
void debug_assert(const string& reason,
const string& func,
const string& file,
@@ -16,35 +20,50 @@ void debug_assert(const string& reason,
throw exception(buf.str(), context());
}
+} // namespace ledger
+
#endif
+/**********************************************************************
+ *
+ * Verification (basically, very slow asserts)
+ */
+
#if defined(VERIFY_ON)
-int new_calls = 0;
-unsigned long new_size = 0;
+namespace ledger {
+#if defined(FULL_DEBUG)
+ bool verify_enabled = true;
+#else
+ bool verify_enabled = false;
+#endif
+
+ int new_calls = 0;
+ unsigned long new_size = 0;
+}
void * operator new(std::size_t size) throw (std::bad_alloc) {
void * ptr = std::malloc(size);
- new_calls++;
- new_size += 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);
- new_calls++;
- new_size += 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);
- new_calls++;
- new_size += 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);
- new_calls++;
- new_size += size;
+ ledger::new_calls++;
+ ledger::new_size += size;
return ptr;
}
void operator delete(void * ptr) throw() {
@@ -60,6 +79,8 @@ void operator delete[](void * ptr, const std::nothrow_t&) throw() {
std::free(ptr);
}
+namespace ledger {
+
live_objects_map live_objects;
object_count_map ctor_count;
object_count_map object_count;
@@ -99,8 +120,7 @@ bool trace_ctor_func(void * ptr, const char * cls_name, const char * args,
std::strcat(name, args);
std::strcat(name, ")");
- DEBUG_PRINT("ledger.trace.debug",
- "trace_ctor " << ptr << " " << name);
+ DEBUG_("ledger.trace.debug", "TRACE_CTOR " << ptr << " " << name);
live_objects.insert(live_objects_pair(ptr, cls_name));
@@ -114,7 +134,7 @@ bool trace_ctor_func(void * ptr, const char * cls_name, const char * args,
bool trace_dtor_func(void * ptr, const char * cls_name, std::size_t cls_size)
{
- DEBUG_PRINT("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);
if (i == live_objects.end()) {
@@ -179,103 +199,177 @@ void report_memory(std::ostream& out)
#if ! defined(USE_BOOST_PYTHON)
string::string() : std::string() {
- trace_ctor(string, "");
+ TRACE_CTOR(string, "");
}
string::string(const string& str) : std::string(str) {
- trace_ctor(string, "const string&");
+ TRACE_CTOR(string, "const string&");
}
string::string(const std::string& str) : std::string(str) {
- trace_ctor(string, "const std::string&");
+ TRACE_CTOR(string, "const std::string&");
}
string::string(const int len, char x) : std::string(len, x) {
- trace_ctor(string, "const int, char");
+ TRACE_CTOR(string, "const int, char");
}
string::string(const char * str) : std::string(str) {
- trace_ctor(string, "const char *");
+ TRACE_CTOR(string, "const char *");
}
string::string(const char * str, const char * end) : std::string(str, end) {
- trace_ctor(string, "const char *, const char *");
+ TRACE_CTOR(string, "const char *, const char *");
}
string::string(const string& str, int x) : std::string(str, x) {
- trace_ctor(string, "const string&, int");
+ TRACE_CTOR(string, "const string&, int");
}
string::string(const string& str, int x, int y) : std::string(str, x, y) {
- trace_ctor(string, "const string&, int, int");
+ TRACE_CTOR(string, "const string&, int, int");
}
string::string(const char * str, int x) : std::string(str, x) {
- trace_ctor(string, "const char *, int");
+ TRACE_CTOR(string, "const char *, int");
}
string::string(const char * str, int x, int y) : std::string(str, x, y) {
- trace_ctor(string, "const char *, int, int");
+ TRACE_CTOR(string, "const char *, int, int");
}
string::~string() {
- trace_dtor(string);
+ TRACE_DTOR(string);
}
#endif
+} // namespace ledger
+
#endif // VERIFY_ON
-#if defined(TIMERS_ON)
+/**********************************************************************
+ *
+ * Logging
+ */
+
+#if defined(LOGGING_ON) && defined(DEBUG_ON)
+
+#include <boost/regex.hpp>
+
+namespace ledger {
+
+log_level_t _log_level;
+unsigned int _trace_level;
+std::string _log_category;
+std::ostream * _log_stream = &std::cerr;
+std::ostringstream _log_buffer;
+
+bool logger_func(log_level_t level)
+{
+ _log_buffer.str("");
+}
+
+} // namespace ledger
+
+#endif // LOGGING_ON && DEBUG_ON
+
+/**********************************************************************
+ *
+ * Timers (allows log entries to specify cumulative time spent)
+ */
+
+#if defined(LOGGING_ON) && defined(TIMERS_ON)
+
+namespace ledger {
void start_timer(const char * name)
{
+#if 0
begin = std::clock();
+#endif
}
void stop_timer(const char * name)
{
+#if 0
cumulative += std::clock() - begin;
+#endif
}
void finish_timer(const char * name)
{
- DEBUG_PRINT(cls.c_str(), file << ":" << line << ": "
- << category << " = "
- << (double(cumulative) / double(CLOCKS_PER_SEC)) << "s");
+#if 0
+ DEBUG_(cls.c_str(), file << ":" << line << ": "
+ << category << " = "
+ << (double(cumulative) / double(CLOCKS_PER_SEC)) << "s");
+#endif
}
-#endif // TIMERS_ON
+} // namespace ledger
+
+#endif // LOGGING_ON && TIMERS_ON
-#if defined(LOGGING_ON) && defined(DEBUG_ON)
+/**********************************************************************
+ *
+ * Exception handling
+ */
+
+namespace ledger {
+
+std::ostringstream _exc_buffer;
+
+} // namespace ledger
+
+/**********************************************************************
+ *
+ * General utility functions
+ */
-std::ostream * _debug_stream = &std::cerr;
-bool _free_debug_stream = false;
-boost::regex _debug_regex;
-bool _set_debug_regex = false;
-bool _debug_regex_on = false;
-
-bool _debug_active(const char * const cls) {
- if (! _set_debug_regex) {
- const char * user_class = std::getenv("DEBUG_CLASS");
- if (user_class) {
- _debug_regex = user_class;
- _debug_regex_on = true;
+namespace ledger {
+
+string expand_path(const string& path)
+{
+ if (path.length() == 0 || path[0] != '~')
+ return path;
+
+ const char * pfx = NULL;
+ string::size_type pos = path.find_first_of('/');
+
+ if (path.length() == 1 || pos == 1) {
+ pfx = std::getenv("HOME");
+#ifdef HAVE_GETPWUID
+ if (! pfx) {
+ // Punt. We're trying to expand ~/, but HOME isn't set
+ struct passwd * pw = getpwuid(getuid());
+ if (pw)
+ pfx = pw->pw_dir;
}
- _set_debug_regex = true;
+#endif
}
- if (_debug_regex_on)
- return boost::regex_match(cls, _debug_regex);
- return false;
-}
-
-static struct init_streams {
- init_streams() {
- // If debugging is enabled and DEBUG_FILE is set, all debugging
- // output goes to that file.
- if (const char * p = std::getenv("DEBUG_FILE")) {
- _debug_stream = new std::ofstream(p);
- _free_debug_stream = true;
- }
+#ifdef HAVE_GETPWNAM
+ else {
+ string user(path, 1, pos == string::npos ?
+ string::npos : pos - 1);
+ struct passwd * pw = getpwnam(user.c_str());
+ if (pw)
+ pfx = pw->pw_dir;
}
- ~init_streams() {
- if (_free_debug_stream && _debug_stream) {
- delete _debug_stream;
- _debug_stream = NULL;
- }
- }
-} _debug_init;
+#endif
-#endif // LOGGING_ON && DEBUG_ON
+ // if we failed to find an expansion, return the path unchanged.
+
+ if (! pfx)
+ return path;
+
+ string result(pfx);
+
+ if (pos == string::npos)
+ return result;
+
+ if (result.length() == 0 || result[result.length() - 1] != '/')
+ result += '/';
+
+ result += path.substr(pos + 1);
+
+ return result;
+}
+
+string resolve_path(const string& path)
+{
+ if (path[0] == '~')
+ return expand_path(path);
+ return path;
+}
} // namespace ledger
diff --git a/utils.h b/utils.h
index 24d4ad61..c6654828 100644
--- a/utils.h
+++ b/utils.h
@@ -3,7 +3,18 @@
#include <system.hh>
+/**********************************************************************
+ *
+ * Forward declarations
+ */
+
namespace ledger {
+#if ! defined(USE_BOOST_PYTHON)
+ class string;
+#else
+ typedef std::string string;
+#endif
+}
/**********************************************************************
*
@@ -11,15 +22,17 @@ namespace ledger {
*/
#if defined(FULL_DEBUG)
-#define VERIFY_ON 1
-#define TRACING_ON 1
-#define DEBUG_ON 1
-#define TIMERS_ON 1
+#define VERIFY_ON 1
+#define TRACING_ON 1
+#define DEBUG_ON 1
+#define TIMERS_ON 1
+#define FREE_MEMORY 1
#elif defined(NO_DEBUG)
-#define NO_ASSERTS 1
-#define NO_LOGGING 1
+#define NO_ASSERTS 1
+#define NO_LOGGING 1
#else
-#define TIMERS_ON 1 // jww (2007-04-25): is this correct?
+#define VERIFY_ON 1 // compiled in, use --verify to enable
+#define TIMERS_ON 1 // jww (2007-04-25): is this correct?
#endif
/**********************************************************************
@@ -38,14 +51,14 @@ namespace ledger {
#include <boost/current_function.hpp>
-void debug_assert(const ledger::string& reason,
- const ledger::string& func,
- const ledger::string& file,
- unsigned long line);
+namespace ledger {
+ void debug_assert(const string& reason, const string& func,
+ const string& file, unsigned long line);
+}
#define assert(x) \
((x) ? ((void)0) : debug_assert(#x, BOOST_CURRENT_FUNCTION, \
- __FILE__, __LINE__)
+ __FILE__, __LINE__))
#endif // ASSERTS_ON
@@ -56,22 +69,15 @@ void debug_assert(const ledger::string& reason,
#if defined(VERIFY_ON)
+namespace ledger {
+
extern bool verify_enabled;
-#define verify(x) (verify_enabled ? assert(x) : ((void)0))
+#define VERIFY(x) (verify_enabled ? assert(x) : ((void)0))
extern int new_calls;
extern unsigned long new_size;
-void * operator new(std::size_t) throw(std::bad_alloc);
-void * operator new[](std::size_t) throw(std::bad_alloc);
-void operator delete(void*) throw();
-void operator delete[](void*) throw();
-void * operator new(std::size_t, const std::nothrow_t&) throw();
-void * operator new[](std::size_t, const std::nothrow_t&) throw();
-void operator delete(void*, const std::nothrow_t&) throw();
-void operator delete[](void*, const std::nothrow_t&) throw();
-
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;
@@ -87,10 +93,10 @@ bool 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);
-#define trace_ctor(cls, args) \
- verify(trace_ctor_func(this, #cls, args, sizeof(cls)))
-#define trace_dtor(cls) \
- verify(trace_dtor_func(this, #cls, sizeof(cls)))
+#define TRACE_CTOR(cls, args) \
+ VERIFY(trace_ctor_func(this, #cls, args, sizeof(cls)))
+#define TRACE_DTOR(cls) \
+ VERIFY(trace_dtor_func(this, #cls, sizeof(cls)))
void report_memory(std::ostream& out);
@@ -158,11 +164,13 @@ inline bool operator!=(const string& __lhs, const char* __rhs)
#endif
+} // namespace ledger
+
#else // ! VERIFY_ON
-#define verify(x)
-#define trace_ctor(cls, args)
-#define trace_dtor(cls)
+#define VERIFY(x)
+#define TRACE_CTOR(cls, args)
+#define TRACE_DTOR(cls)
#endif // VERIFY_ON
@@ -176,7 +184,7 @@ inline bool operator!=(const string& __lhs, const char* __rhs)
#endif
#if defined(LOGGING_ON)
-// Logging
+namespace ledger {
enum log_level_t {
LOG_OFF = 0,
@@ -199,65 +207,99 @@ extern std::string _log_category;
extern std::ostream * _log_stream;
extern std::ostringstream _log_buffer;
-#define category(cat) \
- static const char * const _this_category = (cat)
+bool logger_func(log_level_t level);
+
+#define logger(cat) \
+ static const char * const _this_category = cat
+
+#define SHOW_TRACE(lvl) \
+ (_log_level >= LOG_TRACE && lvl >= _trace_level)
+
+#define SHOW_DEBUG_(cat) \
+ (_log_level >= LOG_DEBUG && \
+ (_log_category == cat || \
+ _log_category.find(string(cat) + ".") == 0))
+#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)
-bool logger(log_level_t level);
+#define SHOW_WARN() (_log_level >= LOG_WARN)
+#define SHOW_ERROR() (_log_level >= LOG_ERROR)
+#define SHOW_FATAL() (_log_level >= LOG_FATAL)
+#define SHOW_CRITICAL() (_log_level >= LOG_CRIT)
#if defined(TRACING_ON)
-#define trace(lvl, msg) \
- (_log_level >= LOG_TRACE && lvl >= _trace_level ? \
- ((_log_buffer << msg), logger(LOG_TRACE)) : false)
+#define TRACE(lvl, msg) \
+ (SHOW_TRACE(lvl) ? ((_log_buffer << msg), logger_func(LOG_TRACE)) : false)
#else
-#define trace(lvl, msg)
+#define TRACE(lvl, msg)
#endif
#if defined(DEBUG_ON)
-#define debug_(cat, msg) \
- (_log_level >= LOG_DEBUG && \
- (_log_category == cat || \
- _log_category.find(cat ".") == 0) ? \
- ((_log_buffer << msg), logger(LOG_DEBUG)) : false)
-#define debug(msg) debug_(_this_category, msg)
+#define DEBUG_(cat, msg) \
+ (SHOW_DEBUG_(cat) ? ((_log_buffer << msg), logger_func(LOG_DEBUG)) : false)
+#define DEBUG(msg) DEBUG_(_this_category, msg)
#else
-#define debug_(cat, msg)
-#define debug(msg)
+#define DEBUG_(cat, msg)
+#define DEBUG(msg)
#endif
-#define exception_occurred(msg) \
- log_macro(LOG_EXCEPT, msg)
+#define INFO_(cat, msg) \
+ (SHOW_INFO(cat) ? ((_log_buffer << msg), logger_func(LOG_INFO)) : false)
+#define INFO(msg) INFO_(_this_category, msg)
-#define info_(cat, msg) \
- (_log_level >= LOG_INFO && \
- (_log_category == cat || \
- _log_category.find(cat ".") == 0) ? \
- ((_log_buffer << msg), logger(LOG_INFO)) : false)
-#define info(msg) info_(_this_category, msg)
-
-#define log_macro(level, msg) \
+#define LOG_MACRO(level, msg) \
(_log_level >= level ? \
- ((_log_buffer << msg), logger(level)) : false)
+ ((_log_buffer << msg), logger_func(level)) : false)
+
+#define WARN(msg) LOG_MACRO(LOG_WARN, msg)
+#define ERROR(msg) LOG_MACRO(LOG_ERROR, msg)
+#define FATAL(msg) LOG_MACRO(LOG_FATAL, msg)
+#define CRITICAL(msg) LOG_MACRO(LOG_CRIT, msg)
+#define EXCEPTION(msg) LOG_MACRO(LOG_EXCEPT, 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)
-#define critical(msg) log_macro(LOG_CRIT, msg)
+} // namespace ledger
#else // ! LOGGING_ON
-#define category(cat)
-#define trace(lvl, msg)
-#define debug(msg)
-#define debug_(cat, msg)
-#define info(msg)
-#define info_(cat, msg)
-#define warn(msg)
-#define error(msg)
-#define fatal(msg)
-#define critical(msg)
+#define logger(cat)
+
+#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
+#define SHOW_FATAL() false
+#define SHOW_CRITICAL() false
+
+#define TRACE(lvl, msg)
+#define DEBUG(msg)
+#define DEBUG_(cat, msg)
+#define INFO(msg)
+#define INFO_(cat, msg)
+#define WARN(msg)
+#define ERROR(msg)
+#define FATAL(msg)
+#define CRITICAL(msg)
#endif // LOGGING_ON
+#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())
+#define IF_FATAL() if (SHOW_FATAL())
+#define IF_CRITICAL() if (SHOW_CRITICAL())
+
/**********************************************************************
*
* Timers (allows log entries to specify cumulative time spent)
@@ -265,6 +307,8 @@ bool logger(log_level_t level);
#if defined(LOGGING_ON) && defined(TIMERS_ON)
+namespace ledger {
+
struct timer_t {
std::clock_t count;
std::string message;
@@ -278,46 +322,63 @@ void stop_timer(const char * name);
void finish_timer(const char * name);
#if defined(TRACING_ON)
-#define trace_start(name, lvl, msg) \
- (trace(lvl, msg) && start_timer(name))
-#define trace_stop(name) stop_timer(name)
-#define trace_finish(name) finish_timer(name)
+#define TRACE_START(name, lvl, msg) \
+ (TRACE(lvl, msg) ? start_timer(#name) : ((void)0))
+#define TRACE_STOP(name, lvl) \
+ (SHOW_TRACE(lvl) ? stop_timer(#name) : ((void)0))
+#define TRACE_FINISH(name, lvl) \
+ (SHOW_TRACE(lvl) ? finish_timer(#name) : ((void)0))
#else
-#define trace_start(name, lvl, msg)
-#define trace_stop(name)
-#define trace_finish(name)
+#define TRACE_START(name, lvl, msg)
+#define TRACE_STOP(name)
+#define TRACE_FINISH(name)
#endif
#if defined(DEBUG_ON)
-#define debug_start(name, msg) \
- (debug(msg) && start_timer(name))
-#define debug_start_(name, cat, msg) \
- (debug_(cat, msg) && start_timer(name))
-#define debug_stop(name) stop_timer(name)
-#define debug_finish(name) finish_timer(name)
+#define DEBUG_START_(name, cat, msg) \
+ (DEBUG_(cat, msg) ? start_timer(#name) : ((void)0))
+#define DEBUG_START(name, msg) \
+ DEBUG_START_(name, _this_category, msg)
+#define DEBUG_STOP_(name, cat) \
+ (SHOW_DEBUG_(cat) ? stop_timer(#name) : ((void)0))
+#define DEBUG_STOP(name) \
+ DEBUG_STOP_(name, _this_category)
+#define DEBUG_FINISH_(name, cat) \
+ (SHOW_DEBUG_(cat) ? finish_timer(#name) : ((void)0))
+#define DEBUG_FINISH(name) \
+ DEBUG_FINISH_(name, _this_category)
#else
-#define debug_start(name, msg)
-#define debug_start_(name, cat, msg)
-#define debug_stop(name)
-#define debug_finish(name)
+#define DEBUG_START(name, msg)
+#define DEBUG_START_(name, cat, msg)
+#define DEBUG_STOP(name)
+#define DEBUG_FINISH(name)
#endif
-#define info_start(name, msg) \
- (info(msg) && start_timer(name))
-#define info_start_(name, cat, msg)
-#define info_stop(name) stop_timer(name)
-#define info_finish(name) finish_timer(name)
+#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)
+
+} // namespace ledger
#else // ! (LOGGING_ON && TIMERS_ON)
-#define trace_start(lvl, msg, name)
-#define trace_stop(name)
-#define trace_finish(name)
+#define TRACE_START(lvl, msg, name)
+#define TRACE_STOP(name)
+#define TRACE_FINISH(name)
-#define debug_start(name, msg)
-#define debug_start_(name, cat, msg)
-#define debug_stop(name)
-#define debug_finish(name)
+#define DEBUG_START(name, msg)
+#define DEBUG_START_(name, cat, msg)
+#define DEBUG_STOP(name)
+#define DEBUG_FINISH(name)
#define info_start(name, msg)
#define info_start_(name, cat, msg)
@@ -328,30 +389,44 @@ void finish_timer(const char * name);
/**********************************************************************
*
- * Debug macros
+ * Exception handling
*/
-#if defined(DEBUG_ON)
+#include "error.h"
-#define if_debug_(cat) \
- if (_log_level >= LOG_DEBUG && \
- (_log_category == cat || \
- _log_category.find(cat ".") == 0))
-#define if_debug() if_debug_(_this_category)
-
-#else // ! DEBUG_ON
+namespace ledger {
-#define if_debug(cat) if (false)
+extern std::ostringstream _exc_buffer;
-#endif // DEBUG_ON
+template <typename T>
+inline void throw_func(const std::string& message) {
+ _exc_buffer.str("");
+ throw T(message, context());
+}
+
+#define throw_(cls, msg) \
+ ((_exc_buffer << msg), throw_func<cls>(_exc_buffer.str()))
+
+} // namespace ledger
/**********************************************************************
*
- * Exception handling
+ * General utility functions
*/
-#import "error.h"
+namespace ledger {
+
+string resolve_path(const string& path);
+
+#ifdef HAVE_REALPATH
+extern "C" char * realpath(const char *, char resolved_path[]);
+#endif
+
+inline const string& either_or(const string& first,
+ const string& second) {
+ return first.empty() ? second : first;
+}
-// } namespace ledger
+} // namespace ledger
#endif // _UTILS_H
diff --git a/value.cc b/value.cc
index b89435d4..49d4ff09 100644
--- a/value.cc
+++ b/value.cc
@@ -85,7 +85,7 @@ xml::node_t * value_t::to_xml_node() const
if (type == XML_NODE)
return *(xml::node_t **) data;
else
- throw new value_error("Value is not an XML node");
+ throw_(value_exception, "Value is not an XML node");
}
void * value_t::to_pointer() const
@@ -93,7 +93,7 @@ void * value_t::to_pointer() const
if (type == POINTER)
return *(void **) data;
else
- throw new value_error("Value is not a pointer");
+ throw_(value_exception, "Value is not a pointer");
}
value_t::sequence_t * value_t::to_sequence() const
@@ -101,7 +101,7 @@ value_t::sequence_t * value_t::to_sequence() const
if (type == SEQUENCE)
return *(sequence_t **) data;
else
- throw new value_error("Value is not a sequence");
+ throw_(value_exception, "Value is not a sequence");
}
void value_t::destroy()
@@ -130,7 +130,7 @@ void value_t::destroy()
void value_t::simplify()
{
if (realzero()) {
- DEBUG_PRINT("amounts.values.simplify", "Zeroing type " << type);
+ DEBUG_("amounts.values.simplify", "Zeroing type " << type);
*this = 0L;
return;
}
@@ -138,19 +138,19 @@ void value_t::simplify()
if (type == BALANCE_PAIR &&
(! ((balance_pair_t *) data)->cost ||
((balance_pair_t *) data)->cost->realzero())) {
- DEBUG_PRINT("amounts.values.simplify", "Reducing balance pair to balance");
+ DEBUG_("amounts.values.simplify", "Reducing balance pair to balance");
in_place_cast(BALANCE);
}
if (type == BALANCE &&
((balance_t *) data)->amounts.size() == 1) {
- DEBUG_PRINT("amounts.values.simplify", "Reducing balance to amount");
+ DEBUG_("amounts.values.simplify", "Reducing balance to amount");
in_place_cast(AMOUNT);
}
if (type == AMOUNT &&
! ((amount_t *) data)->commodity()) {
- DEBUG_PRINT("amounts.values.simplify", "Reducing amount to integer");
+ DEBUG_("amounts.values.simplify", "Reducing amount to integer");
in_place_cast(INTEGER);
}
}
@@ -249,19 +249,19 @@ value_t& value_t::operator=(const value_t& val)
value_t& value_t::operator+=(const value_t& val)
{
if (val.type == BOOLEAN)
- throw new value_error("Cannot add a boolean to a value");
+ throw_(value_exception, "Cannot add a boolean to a value");
else if (val.type == DATETIME)
- throw new value_error("Cannot add a date/time to a value");
+ throw_(value_exception, "Cannot add a date/time to a value");
else if (val.type == POINTER)
- throw new value_error("Cannot add a pointer to a value");
+ throw_(value_exception, "Cannot add a pointer to a value");
else if (val.type == SEQUENCE)
- throw new value_error("Cannot add a sequence to a value");
+ throw_(value_exception, "Cannot add a sequence to a value");
else if (val.type == XML_NODE) // recurse
return *this += (*(xml::node_t **) val.data)->to_value();
switch (type) {
case BOOLEAN:
- throw new value_error("Cannot add a value to a boolean");
+ throw_(value_exception, "Cannot add a value to a boolean");
case INTEGER:
switch (val.type) {
@@ -281,7 +281,7 @@ value_t& value_t::operator+=(const value_t& val)
*((balance_pair_t *) data) += *((balance_pair_t *) val.data);
break;
case STRING:
- throw new value_error("Cannot add a string to an integer");
+ throw_(value_exception, "Cannot add a string to an integer");
default:
assert(0);
break;
@@ -303,7 +303,7 @@ value_t& value_t::operator+=(const value_t& val)
*((moment_t *) data) += date_duration(long(*((balance_pair_t *) val.data)));
break;
case STRING:
- throw new value_error("Cannot add a string to an date/time");
+ throw_(value_exception, "Cannot add a string to an date/time");
default:
assert(0);
break;
@@ -341,7 +341,7 @@ value_t& value_t::operator+=(const value_t& val)
break;
case STRING:
- throw new value_error("Cannot add a string to an amount");
+ throw_(value_exception, "Cannot add a string to an amount");
default:
assert(0);
@@ -365,7 +365,7 @@ value_t& value_t::operator+=(const value_t& val)
*((balance_pair_t *) data) += *((balance_pair_t *) val.data);
break;
case STRING:
- throw new value_error("Cannot add a string to an balance");
+ throw_(value_exception, "Cannot add a string to an balance");
default:
assert(0);
break;
@@ -387,7 +387,7 @@ value_t& value_t::operator+=(const value_t& val)
*((balance_pair_t *) data) += *((balance_pair_t *) val.data);
break;
case STRING:
- throw new value_error("Cannot add a string to an balance pair");
+ throw_(value_exception, "Cannot add a string to an balance pair");
default:
assert(0);
break;
@@ -397,13 +397,13 @@ value_t& value_t::operator+=(const value_t& val)
case STRING:
switch (val.type) {
case INTEGER:
- throw new value_error("Cannot add an integer to a string");
+ throw_(value_exception, "Cannot add an integer to a string");
case AMOUNT:
- throw new value_error("Cannot add an amount to a string");
+ throw_(value_exception, "Cannot add an amount to a string");
case BALANCE:
- throw new value_error("Cannot add a balance to a string");
+ throw_(value_exception, "Cannot add a balance to a string");
case BALANCE_PAIR:
- throw new value_error("Cannot add a balance pair to a string");
+ throw_(value_exception, "Cannot add a balance pair to a string");
case STRING:
**(string **) data += **(string **) val.data;
break;
@@ -414,13 +414,13 @@ value_t& value_t::operator+=(const value_t& val)
break;
case XML_NODE:
- throw new value_error("Cannot add a value to an XML node");
+ throw_(value_exception, "Cannot add a value to an XML node");
case POINTER:
- throw new value_error("Cannot add a value to a pointer");
+ throw_(value_exception, "Cannot add a value to a pointer");
case SEQUENCE:
- throw new value_error("Cannot add a value to a sequence");
+ throw_(value_exception, "Cannot add a value to a sequence");
default:
assert(0);
@@ -432,21 +432,21 @@ value_t& value_t::operator+=(const value_t& val)
value_t& value_t::operator-=(const value_t& val)
{
if (val.type == BOOLEAN)
- throw new value_error("Cannot subtract a boolean from a value");
+ throw_(value_exception, "Cannot subtract a boolean from a value");
else if (val.type == DATETIME && type != DATETIME)
- throw new value_error("Cannot subtract a date/time from a value");
+ throw_(value_exception, "Cannot subtract a date/time from a value");
else if (val.type == STRING)
- throw new value_error("Cannot subtract a string from a value");
+ throw_(value_exception, "Cannot subtract a string from a value");
else if (val.type == POINTER)
- throw new value_error("Cannot subtract a pointer from a value");
+ throw_(value_exception, "Cannot subtract a pointer from a value");
else if (val.type == SEQUENCE)
- throw new value_error("Cannot subtract a sequence from a value");
+ throw_(value_exception, "Cannot subtract a sequence from a value");
else if (val.type == XML_NODE) // recurse
return *this -= (*(xml::node_t **) val.data)->to_value();
switch (type) {
case BOOLEAN:
- throw new value_error("Cannot subtract a value from a boolean");
+ throw_(value_exception, "Cannot subtract a value from a boolean");
case INTEGER:
switch (val.type) {
@@ -575,13 +575,13 @@ value_t& value_t::operator-=(const value_t& val)
break;
case STRING:
- throw new value_error("Cannot subtract a value from a string");
+ throw_(value_exception, "Cannot subtract a value from a string");
case XML_NODE:
- throw new value_error("Cannot subtract a value from an XML node");
+ throw_(value_exception, "Cannot subtract a value from an XML node");
case POINTER:
- throw new value_error("Cannot subtract a value from a pointer");
+ throw_(value_exception, "Cannot subtract a value from a pointer");
case SEQUENCE:
- throw new value_error("Cannot subtract a value from a sequence");
+ throw_(value_exception, "Cannot subtract a value from a sequence");
default:
assert(0);
@@ -596,15 +596,15 @@ value_t& value_t::operator-=(const value_t& val)
value_t& value_t::operator*=(const value_t& val)
{
if (val.type == BOOLEAN)
- throw new value_error("Cannot multiply a value by a boolean");
+ throw_(value_exception, "Cannot multiply a value by a boolean");
else if (val.type == DATETIME)
- throw new value_error("Cannot multiply a value by a date/time");
+ throw_(value_exception, "Cannot multiply a value by a date/time");
else if (val.type == STRING)
- throw new value_error("Cannot multiply a value by a string");
+ throw_(value_exception, "Cannot multiply a value by a string");
else if (val.type == POINTER)
- throw new value_error("Cannot multiply a value by a pointer");
+ throw_(value_exception, "Cannot multiply a value by a pointer");
else if (val.type == SEQUENCE)
- throw new value_error("Cannot multiply a value by a sequence");
+ throw_(value_exception, "Cannot multiply a value by a sequence");
else if (val.type == XML_NODE) // recurse
return *this *= (*(xml::node_t **) val.data)->to_value();
@@ -615,7 +615,7 @@ value_t& value_t::operator*=(const value_t& val)
switch (type) {
case BOOLEAN:
- throw new value_error("Cannot multiply a value by a boolean");
+ throw_(value_exception, "Cannot multiply a value by a boolean");
case INTEGER:
switch (val.type) {
@@ -722,9 +722,9 @@ value_t& value_t::operator*=(const value_t& val)
break;
}
case BALANCE:
- throw new value_error("Cannot multiply a string by a balance");
+ throw_(value_exception, "Cannot multiply a string by a balance");
case BALANCE_PAIR:
- throw new value_error("Cannot multiply a string by a balance pair");
+ throw_(value_exception, "Cannot multiply a string by a balance pair");
default:
assert(0);
break;
@@ -732,11 +732,11 @@ value_t& value_t::operator*=(const value_t& val)
break;
case XML_NODE:
- throw new value_error("Cannot multiply an XML node by a value");
+ throw_(value_exception, "Cannot multiply an XML node by a value");
case POINTER:
- throw new value_error("Cannot multiply a pointer by a value");
+ throw_(value_exception, "Cannot multiply a pointer by a value");
case SEQUENCE:
- throw new value_error("Cannot multiply a sequence by a value");
+ throw_(value_exception, "Cannot multiply a sequence by a value");
default:
assert(0);
@@ -748,21 +748,21 @@ value_t& value_t::operator*=(const value_t& val)
value_t& value_t::operator/=(const value_t& val)
{
if (val.type == BOOLEAN)
- throw new value_error("Cannot divide a boolean by a value");
+ throw_(value_exception, "Cannot divide a boolean by a value");
else if (val.type == DATETIME)
- throw new value_error("Cannot divide a date/time by a value");
+ throw_(value_exception, "Cannot divide a date/time by a value");
else if (val.type == STRING)
- throw new value_error("Cannot divide a string by a value");
+ throw_(value_exception, "Cannot divide a string by a value");
else if (val.type == POINTER)
- throw new value_error("Cannot divide a pointer by a value");
+ throw_(value_exception, "Cannot divide a pointer by a value");
else if (val.type == SEQUENCE)
- throw new value_error("Cannot divide a value by a sequence");
+ throw_(value_exception, "Cannot divide a value by a sequence");
else if (val.type == XML_NODE) // recurse
return *this /= (*(xml::node_t **) val.data)->to_value();
switch (type) {
case BOOLEAN:
- throw new value_error("Cannot divide a value by a boolean");
+ throw_(value_exception, "Cannot divide a value by a boolean");
case INTEGER:
switch (val.type) {
@@ -851,13 +851,13 @@ value_t& value_t::operator/=(const value_t& val)
break;
case STRING:
- throw new value_error("Cannot divide a value from a string");
+ throw_(value_exception, "Cannot divide a value from a string");
case XML_NODE:
- throw new value_error("Cannot divide a value from an XML node");
+ throw_(value_exception, "Cannot divide a value from an XML node");
case POINTER:
- throw new value_error("Cannot divide a value from a pointer");
+ throw_(value_exception, "Cannot divide a value from a pointer");
case SEQUENCE:
- throw new value_error("Cannot divide a value from a sequence");
+ throw_(value_exception, "Cannot divide a value from a sequence");
default:
assert(0);
@@ -905,25 +905,25 @@ value_t::operator long() const
{
switch (type) {
case BOOLEAN:
- throw new value_error("Cannot convert a boolean to an integer");
+ throw_(value_exception, "Cannot convert a boolean to an integer");
case INTEGER:
return *((long *) data);
case DATETIME:
- throw new value_error("Cannot convert a date/time to an integer");
+ throw_(value_exception, "Cannot convert a date/time to an integer");
case AMOUNT:
return *((amount_t *) data);
case BALANCE:
- throw new value_error("Cannot convert a balance to an integer");
+ throw_(value_exception, "Cannot convert a balance to an integer");
case BALANCE_PAIR:
- throw new value_error("Cannot convert a balance pair to an integer");
+ throw_(value_exception, "Cannot convert a balance pair to an integer");
case STRING:
- throw new value_error("Cannot convert a string to an integer");
+ throw_(value_exception, "Cannot convert a string to an integer");
case XML_NODE:
return (*(xml::node_t **) data)->to_value().to_integer();
case POINTER:
- throw new value_error("Cannot convert a pointer to an integer");
+ throw_(value_exception, "Cannot convert a pointer to an integer");
case SEQUENCE:
- throw new value_error("Cannot convert a sequence to an integer");
+ throw_(value_exception, "Cannot convert a sequence to an integer");
default:
assert(0);
@@ -938,25 +938,25 @@ value_t::operator moment_t() const
{
switch (type) {
case BOOLEAN:
- throw new value_error("Cannot convert a boolean to a date/time");
+ throw_(value_exception, "Cannot convert a boolean to a date/time");
case INTEGER:
- throw new value_error("Cannot convert an integer to a date/time");
+ throw_(value_exception, "Cannot convert an integer to a date/time");
case DATETIME:
return *((moment_t *) data);
case AMOUNT:
- throw new value_error("Cannot convert an amount to a date/time");
+ throw_(value_exception, "Cannot convert an amount to a date/time");
case BALANCE:
- throw new value_error("Cannot convert a balance to a date/time");
+ throw_(value_exception, "Cannot convert a balance to a date/time");
case BALANCE_PAIR:
- throw new value_error("Cannot convert a balance pair to a date/time");
+ throw_(value_exception, "Cannot convert a balance pair to a date/time");
case STRING:
- throw new value_error("Cannot convert a string to a date/time");
+ throw_(value_exception, "Cannot convert a string to a date/time");
case XML_NODE:
return (*(xml::node_t **) data)->to_value().to_datetime();
case POINTER:
- throw new value_error("Cannot convert a pointer to a date/time");
+ throw_(value_exception, "Cannot convert a pointer to a date/time");
case SEQUENCE:
- throw new value_error("Cannot convert a sequence to a date/time");
+ throw_(value_exception, "Cannot convert a sequence to a date/time");
default:
assert(0);
@@ -971,25 +971,25 @@ value_t::operator double() const
{
switch (type) {
case BOOLEAN:
- throw new value_error("Cannot convert a boolean to a double");
+ throw_(value_exception, "Cannot convert a boolean to a double");
case INTEGER:
return *((long *) data);
case DATETIME:
- throw new value_error("Cannot convert a date/time to a double");
+ throw_(value_exception, "Cannot convert a date/time to a double");
case AMOUNT:
return *((amount_t *) data);
case BALANCE:
- throw new value_error("Cannot convert a balance to a double");
+ throw_(value_exception, "Cannot convert a balance to a double");
case BALANCE_PAIR:
- throw new value_error("Cannot convert a balance pair to a double");
+ throw_(value_exception, "Cannot convert a balance pair to a double");
case STRING:
- throw new value_error("Cannot convert a string to a double");
+ throw_(value_exception, "Cannot convert a string to a double");
case XML_NODE:
return (*(xml::node_t **) data)->to_value().to_amount().number();
case POINTER:
- throw new value_error("Cannot convert a pointer to a double");
+ throw_(value_exception, "Cannot convert a pointer to a double");
case SEQUENCE:
- throw new value_error("Cannot convert a sequence to a double");
+ throw_(value_exception, "Cannot convert a sequence to a double");
default:
assert(0);
@@ -1019,9 +1019,9 @@ value_t::operator string() const
return (*(xml::node_t **) data)->to_value().to_string();
case POINTER:
- throw new value_error("Cannot convert a pointer to a string");
+ throw_(value_exception, "Cannot convert a pointer to a string");
case SEQUENCE:
- throw new value_error("Cannot convert a sequence to a string");
+ throw_(value_exception, "Cannot convert a sequence to a string");
default:
assert(0);
@@ -1044,7 +1044,7 @@ bool value_t::operator OP(const value_t& val) \
return *((bool *) data) OP bool(*((long *) val.data)); \
\
case DATETIME: \
- throw new value_error("Cannot compare a boolean to a date/time"); \
+ throw_(value_exception, "Cannot compare a boolean to a date/time"); \
\
case AMOUNT: \
return *((bool *) data) OP bool(*((amount_t *) val.data)); \
@@ -1056,15 +1056,15 @@ bool value_t::operator OP(const value_t& val) \
return *((bool *) data) OP bool(*((balance_pair_t *) val.data)); \
\
case STRING: \
- throw new value_error("Cannot compare a boolean to a string"); \
+ throw_(value_exception, "Cannot compare a boolean to a string"); \
\
case XML_NODE: \
return *this OP (*(xml::node_t **) data)->to_value(); \
\
case POINTER: \
- throw new value_error("Cannot compare a boolean to a pointer"); \
+ throw_(value_exception, "Cannot compare a boolean to a pointer"); \
case SEQUENCE: \
- throw new value_error("Cannot compare a boolean to a sequence"); \
+ throw_(value_exception, "Cannot compare a boolean to a sequence"); \
\
default: \
assert(0); \
@@ -1082,7 +1082,7 @@ bool value_t::operator OP(const value_t& val) \
return (*((long *) data) OP *((long *) val.data)); \
\
case DATETIME: \
- throw new value_error("Cannot compare an integer to a date/time"); \
+ throw_(value_exception, "Cannot compare an integer to a date/time"); \
\
case AMOUNT: \
return (amount_t(*((long *) data)) OP \
@@ -1097,15 +1097,15 @@ bool value_t::operator OP(const value_t& val) \
*((balance_pair_t *) val.data)); \
\
case STRING: \
- throw new value_error("Cannot compare an integer to a string"); \
+ throw_(value_exception, "Cannot compare an integer to a string"); \
\
case XML_NODE: \
return *this OP (*(xml::node_t **) data)->to_value(); \
\
case POINTER: \
- throw new value_error("Cannot compare an integer to a pointer"); \
+ throw_(value_exception, "Cannot compare an integer to a pointer"); \
case SEQUENCE: \
- throw new value_error("Cannot compare an integer to a sequence"); \
+ throw_(value_exception, "Cannot compare an integer to a sequence"); \
\
default: \
assert(0); \
@@ -1116,30 +1116,30 @@ bool value_t::operator OP(const value_t& val) \
case DATETIME: \
switch (val.type) { \
case BOOLEAN: \
- throw new value_error("Cannot compare a date/time to a boolean"); \
+ throw_(value_exception, "Cannot compare a date/time to a boolean"); \
\
case INTEGER: \
- throw new value_error("Cannot compare a date/time to an integer"); \
+ throw_(value_exception, "Cannot compare a date/time to an integer"); \
\
case DATETIME: \
return *((moment_t *) data) OP *((moment_t *) val.data); \
\
case AMOUNT: \
- throw new value_error("Cannot compare a date/time to an amount"); \
+ throw_(value_exception, "Cannot compare a date/time to an amount"); \
case BALANCE: \
- throw new value_error("Cannot compare a date/time to a balance"); \
+ throw_(value_exception, "Cannot compare a date/time to a balance"); \
case BALANCE_PAIR: \
- throw new value_error("Cannot compare a date/time to a balance pair"); \
+ throw_(value_exception, "Cannot compare a date/time to a balance pair"); \
case STRING: \
- throw new value_error("Cannot compare a date/time to a string"); \
+ throw_(value_exception, "Cannot compare a date/time to a string"); \
\
case XML_NODE: \
return *this OP (*(xml::node_t **) data)->to_value(); \
\
case POINTER: \
- throw new value_error("Cannot compare a date/time to a pointer"); \
+ throw_(value_exception, "Cannot compare a date/time to a pointer"); \
case SEQUENCE: \
- throw new value_error("Cannot compare a date/time to a sequence"); \
+ throw_(value_exception, "Cannot compare a date/time to a sequence"); \
\
default: \
assert(0); \
@@ -1150,14 +1150,14 @@ bool value_t::operator OP(const value_t& val) \
case AMOUNT: \
switch (val.type) { \
case BOOLEAN: \
- throw new value_error("Cannot compare an amount to a boolean"); \
+ throw_(value_exception, "Cannot compare an amount to a boolean"); \
\
case INTEGER: \
return (*((amount_t *) data) OP \
amount_t(*((long *) val.data))); \
\
case DATETIME: \
- throw new value_error("Cannot compare an amount to a date/time"); \
+ throw_(value_exception, "Cannot compare an amount to a date/time"); \
\
case AMOUNT: \
return *((amount_t *) data) OP *((amount_t *) val.data); \
@@ -1171,15 +1171,15 @@ bool value_t::operator OP(const value_t& val) \
*((balance_pair_t *) val.data)); \
\
case STRING: \
- throw new value_error("Cannot compare an amount to a string"); \
+ throw_(value_exception, "Cannot compare an amount to a string"); \
\
case XML_NODE: \
return *this OP (*(xml::node_t **) data)->to_value(); \
\
case POINTER: \
- throw new value_error("Cannot compare an amount to a pointer"); \
+ throw_(value_exception, "Cannot compare an amount to a pointer"); \
case SEQUENCE: \
- throw new value_error("Cannot compare an amount to a sequence"); \
+ throw_(value_exception, "Cannot compare an amount to a sequence"); \
\
default: \
assert(0); \
@@ -1190,13 +1190,13 @@ bool value_t::operator OP(const value_t& val) \
case BALANCE: \
switch (val.type) { \
case BOOLEAN: \
- throw new value_error("Cannot compare a balance to a boolean"); \
+ throw_(value_exception, "Cannot compare a balance to a boolean"); \
\
case INTEGER: \
return *((balance_t *) data) OP *((long *) val.data); \
\
case DATETIME: \
- throw new value_error("Cannot compare a balance to a date/time"); \
+ throw_(value_exception, "Cannot compare a balance to a date/time"); \
\
case AMOUNT: \
return *((balance_t *) data) OP *((amount_t *) val.data); \
@@ -1209,15 +1209,15 @@ bool value_t::operator OP(const value_t& val) \
((balance_pair_t *) val.data)->quantity); \
\
case STRING: \
- throw new value_error("Cannot compare a balance to a string"); \
+ throw_(value_exception, "Cannot compare a balance to a string"); \
\
case XML_NODE: \
return *this OP (*(xml::node_t **) data)->to_value(); \
\
case POINTER: \
- throw new value_error("Cannot compare a balance to a pointer"); \
+ throw_(value_exception, "Cannot compare a balance to a pointer"); \
case SEQUENCE: \
- throw new value_error("Cannot compare a balance to a sequence"); \
+ throw_(value_exception, "Cannot compare a balance to a sequence"); \
\
default: \
assert(0); \
@@ -1228,14 +1228,14 @@ bool value_t::operator OP(const value_t& val) \
case BALANCE_PAIR: \
switch (val.type) { \
case BOOLEAN: \
- throw new value_error("Cannot compare a balance pair to a boolean"); \
+ throw_(value_exception, "Cannot compare a balance pair to a boolean"); \
\
case INTEGER: \
return (((balance_pair_t *) data)->quantity OP \
*((long *) val.data)); \
\
case DATETIME: \
- throw new value_error("Cannot compare a balance pair to a date/time"); \
+ throw_(value_exception, "Cannot compare a balance pair to a date/time"); \
\
case AMOUNT: \
return (((balance_pair_t *) data)->quantity OP \
@@ -1250,15 +1250,15 @@ bool value_t::operator OP(const value_t& val) \
*((balance_pair_t *) val.data)); \
\
case STRING: \
- throw new value_error("Cannot compare a balance pair to a string"); \
+ throw_(value_exception, "Cannot compare a balance pair to a string"); \
\
case XML_NODE: \
return *this OP (*(xml::node_t **) data)->to_value(); \
\
case POINTER: \
- throw new value_error("Cannot compare a balance pair to a pointer"); \
+ throw_(value_exception, "Cannot compare a balance pair to a pointer"); \
case SEQUENCE: \
- throw new value_error("Cannot compare a balance pair to a sequence"); \
+ throw_(value_exception, "Cannot compare a balance pair to a sequence"); \
\
default: \
assert(0); \
@@ -1269,17 +1269,17 @@ bool value_t::operator OP(const value_t& val) \
case STRING: \
switch (val.type) { \
case BOOLEAN: \
- throw new value_error("Cannot compare a string to a boolean"); \
+ throw_(value_exception, "Cannot compare a string to a boolean"); \
case INTEGER: \
- throw new value_error("Cannot compare a string to an integer"); \
+ throw_(value_exception, "Cannot compare a string to an integer"); \
case DATETIME: \
- throw new value_error("Cannot compare a string to a date/time"); \
+ throw_(value_exception, "Cannot compare a string to a date/time"); \
case AMOUNT: \
- throw new value_error("Cannot compare a string to an amount"); \
+ throw_(value_exception, "Cannot compare a string to an amount"); \
case BALANCE: \
- throw new value_error("Cannot compare a string to a balance"); \
+ throw_(value_exception, "Cannot compare a string to a balance"); \
case BALANCE_PAIR: \
- throw new value_error("Cannot compare a string to a balance pair"); \
+ throw_(value_exception, "Cannot compare a string to a balance pair"); \
\
case STRING: \
return (**((string **) data) OP \
@@ -1289,9 +1289,9 @@ bool value_t::operator OP(const value_t& val) \
return *this OP (*(xml::node_t **) data)->to_value(); \
\
case POINTER: \
- throw new value_error("Cannot compare a string to a pointer"); \
+ throw_(value_exception, "Cannot compare a string to a pointer"); \
case SEQUENCE: \
- throw new value_error("Cannot compare a string to a sequence"); \
+ throw_(value_exception, "Cannot compare a string to a sequence"); \
\
default: \
assert(0); \
@@ -1321,9 +1321,9 @@ bool value_t::operator OP(const value_t& val) \
(*(xml::node_t **) val.data)->to_value()); \
\
case POINTER: \
- throw new value_error("Cannot compare an XML node to a pointer"); \
+ throw_(value_exception, "Cannot compare an XML node to a pointer"); \
case SEQUENCE: \
- throw new value_error("Cannot compare an XML node to a sequence"); \
+ throw_(value_exception, "Cannot compare an XML node to a sequence"); \
\
default: \
assert(0); \
@@ -1334,25 +1334,25 @@ bool value_t::operator OP(const value_t& val) \
case POINTER: \
switch (val.type) { \
case BOOLEAN: \
- throw new value_error("Cannot compare a pointer to a boolean"); \
+ throw_(value_exception, "Cannot compare a pointer to a boolean"); \
case INTEGER: \
- throw new value_error("Cannot compare a pointer to an integer"); \
+ throw_(value_exception, "Cannot compare a pointer to an integer"); \
case DATETIME: \
- throw new value_error("Cannot compare a pointer to a date/time"); \
+ throw_(value_exception, "Cannot compare a pointer to a date/time"); \
case AMOUNT: \
- throw new value_error("Cannot compare a pointer to an amount"); \
+ throw_(value_exception, "Cannot compare a pointer to an amount"); \
case BALANCE: \
- throw new value_error("Cannot compare a pointer to a balance"); \
+ throw_(value_exception, "Cannot compare a pointer to a balance"); \
case BALANCE_PAIR: \
- throw new value_error("Cannot compare a pointer to a balance pair"); \
+ throw_(value_exception, "Cannot compare a pointer to a balance pair"); \
case STRING: \
- throw new value_error("Cannot compare a pointer to a string node"); \
+ throw_(value_exception, "Cannot compare a pointer to a string node"); \
case XML_NODE: \
- throw new value_error("Cannot compare a pointer to an XML node"); \
+ throw_(value_exception, "Cannot compare a pointer to an XML node"); \
case POINTER: \
return (*((void **) data) OP *((void **) val.data)); \
case SEQUENCE: \
- throw new value_error("Cannot compare a pointer to a sequence"); \
+ throw_(value_exception, "Cannot compare a pointer to a sequence"); \
\
default: \
assert(0); \
@@ -1361,7 +1361,7 @@ bool value_t::operator OP(const value_t& val) \
break; \
\
case SEQUENCE: \
- throw new value_error("Cannot compare a value to a sequence"); \
+ throw_(value_exception, "Cannot compare a value to a sequence"); \
\
default: \
assert(0); \
@@ -1384,24 +1384,24 @@ void value_t::in_place_cast(type_t cast_type)
case BOOLEAN:
break;
case INTEGER:
- throw new value_error("Cannot convert a boolean to an integer");
+ throw_(value_exception, "Cannot convert a boolean to an integer");
case DATETIME:
- throw new value_error("Cannot convert a boolean to a date/time");
+ throw_(value_exception, "Cannot convert a boolean to a date/time");
case AMOUNT:
- throw new value_error("Cannot convert a boolean to an amount");
+ throw_(value_exception, "Cannot convert a boolean to an amount");
case BALANCE:
- throw new value_error("Cannot convert a boolean to a balance");
+ throw_(value_exception, "Cannot convert a boolean to a balance");
case BALANCE_PAIR:
- throw new value_error("Cannot convert a boolean to a balance pair");
+ throw_(value_exception, "Cannot convert a boolean to a balance pair");
case STRING:
*(string **) data = new string(*((bool *) data) ? "true" : "false");
break;
case XML_NODE:
- throw new value_error("Cannot convert a boolean to an XML node");
+ throw_(value_exception, "Cannot convert a boolean to an XML node");
case POINTER:
- throw new value_error("Cannot convert a boolean to a pointer");
+ throw_(value_exception, "Cannot convert a boolean to a pointer");
case SEQUENCE:
- throw new value_error("Cannot convert a boolean to a sequence");
+ throw_(value_exception, "Cannot convert a boolean to a sequence");
default:
assert(0);
@@ -1417,7 +1417,7 @@ void value_t::in_place_cast(type_t cast_type)
case INTEGER:
break;
case DATETIME:
- throw new value_error("Cannot convert an integer to a date/time");
+ throw_(value_exception, "Cannot convert an integer to a date/time");
case AMOUNT:
new((amount_t *)data) amount_t(*((long *) data));
@@ -1435,11 +1435,11 @@ void value_t::in_place_cast(type_t cast_type)
break;
}
case XML_NODE:
- throw new value_error("Cannot convert an integer to an XML node");
+ throw_(value_exception, "Cannot convert an integer to an XML node");
case POINTER:
- throw new value_error("Cannot convert an integer to a pointer");
+ throw_(value_exception, "Cannot convert an integer to a pointer");
case SEQUENCE:
- throw new value_error("Cannot convert an integer to a sequence");
+ throw_(value_exception, "Cannot convert an integer to a sequence");
default:
assert(0);
@@ -1453,23 +1453,23 @@ void value_t::in_place_cast(type_t cast_type)
*((bool *) data) = is_valid_moment(*((moment_t *) data));
break;
case INTEGER:
- throw new value_error("Cannot convert a date/time to an integer");
+ throw_(value_exception, "Cannot convert a date/time to an integer");
case DATETIME:
break;
case AMOUNT:
- throw new value_error("Cannot convert a date/time to an amount");
+ throw_(value_exception, "Cannot convert a date/time to an amount");
case BALANCE:
- throw new value_error("Cannot convert a date/time to a balance");
+ throw_(value_exception, "Cannot convert a date/time to a balance");
case BALANCE_PAIR:
- throw new value_error("Cannot convert a date/time to a balance pair");
+ throw_(value_exception, "Cannot convert a date/time to a balance pair");
case STRING:
- throw new value_error("Cannot convert a date/time to a string");
+ throw_(value_exception, "Cannot convert a date/time to a string");
case XML_NODE:
- throw new value_error("Cannot convert a date/time to an XML node");
+ throw_(value_exception, "Cannot convert a date/time to an XML node");
case POINTER:
- throw new value_error("Cannot convert a date/time to a pointer");
+ throw_(value_exception, "Cannot convert a date/time to a pointer");
case SEQUENCE:
- throw new value_error("Cannot convert a date/time to a sequence");
+ throw_(value_exception, "Cannot convert a date/time to a sequence");
default:
assert(0);
@@ -1492,7 +1492,7 @@ void value_t::in_place_cast(type_t cast_type)
break;
}
case DATETIME:
- throw new value_error("Cannot convert an amount to a date/time");
+ throw_(value_exception, "Cannot convert an amount to a date/time");
case AMOUNT:
break;
case BALANCE: {
@@ -1515,11 +1515,11 @@ void value_t::in_place_cast(type_t cast_type)
break;
}
case XML_NODE:
- throw new value_error("Cannot convert an amount to an XML node");
+ throw_(value_exception, "Cannot convert an amount to an XML node");
case POINTER:
- throw new value_error("Cannot convert an amount to a pointer");
+ throw_(value_exception, "Cannot convert an amount to a pointer");
case SEQUENCE:
- throw new value_error("Cannot convert an amount to a sequence");
+ throw_(value_exception, "Cannot convert an amount to a sequence");
default:
assert(0);
@@ -1536,9 +1536,9 @@ void value_t::in_place_cast(type_t cast_type)
break;
}
case INTEGER:
- throw new value_error("Cannot convert a balance to an integer");
+ throw_(value_exception, "Cannot convert a balance to an integer");
case DATETIME:
- throw new value_error("Cannot convert a balance to a date/time");
+ throw_(value_exception, "Cannot convert a balance to a date/time");
case AMOUNT: {
balance_t * temp = (balance_t *) data;
@@ -1551,7 +1551,7 @@ void value_t::in_place_cast(type_t cast_type)
new((amount_t *)data) amount_t();
}
else {
- throw new value_error("Cannot convert a balance with "
+ throw_(value_exception, "Cannot convert a balance with "
"multiple commodities to an amount");
}
break;
@@ -1565,13 +1565,13 @@ void value_t::in_place_cast(type_t cast_type)
break;
}
case STRING:
- throw new value_error("Cannot convert a balance to a string");
+ throw_(value_exception, "Cannot convert a balance to a string");
case XML_NODE:
- throw new value_error("Cannot convert a balance to an XML node");
+ throw_(value_exception, "Cannot convert a balance to an XML node");
case POINTER:
- throw new value_error("Cannot convert a balance to a pointer");
+ throw_(value_exception, "Cannot convert a balance to a pointer");
case SEQUENCE:
- throw new value_error("Cannot convert a balance to a sequence");
+ throw_(value_exception, "Cannot convert a balance to a sequence");
default:
assert(0);
@@ -1588,9 +1588,9 @@ void value_t::in_place_cast(type_t cast_type)
break;
}
case INTEGER:
- throw new value_error("Cannot convert a balance pair to an integer");
+ throw_(value_exception, "Cannot convert a balance pair to an integer");
case DATETIME:
- throw new value_error("Cannot convert a balance pair to a date/time");
+ throw_(value_exception, "Cannot convert a balance pair to a date/time");
case AMOUNT: {
balance_t * temp = &((balance_pair_t *) data)->quantity;
@@ -1603,7 +1603,7 @@ void value_t::in_place_cast(type_t cast_type)
new((amount_t *)data) amount_t();
}
else {
- throw new value_error("Cannot convert a balance pair with "
+ throw_(value_exception, "Cannot convert a balance pair with "
"multiple commodities to an amount");
}
break;
@@ -1617,13 +1617,13 @@ void value_t::in_place_cast(type_t cast_type)
case BALANCE_PAIR:
break;
case STRING:
- throw new value_error("Cannot convert a balance pair to a string");
+ throw_(value_exception, "Cannot convert a balance pair to a string");
case XML_NODE:
- throw new value_error("Cannot convert a balance pair to an XML node");
+ throw_(value_exception, "Cannot convert a balance pair to an XML node");
case POINTER:
- throw new value_error("Cannot convert a balance pair to a pointer");
+ throw_(value_exception, "Cannot convert a balance pair to a pointer");
case SEQUENCE:
- throw new value_error("Cannot convert a balance pair to a sequence");
+ throw_(value_exception, "Cannot convert a balance pair to a sequence");
default:
assert(0);
@@ -1643,7 +1643,7 @@ void value_t::in_place_cast(type_t cast_type)
*(bool *) data = false;
}
else {
- throw new value_error("Cannot convert string to an boolean");
+ throw_(value_exception, "Cannot convert string to an boolean");
}
break;
}
@@ -1661,13 +1661,13 @@ void value_t::in_place_cast(type_t cast_type)
destroy();
*(long *) data = temp;
} else {
- throw new value_error("Cannot convert string to an integer");
+ throw_(value_exception, "Cannot convert string to an integer");
}
break;
}
case DATETIME:
- throw new value_error("Cannot convert a string to a date/time");
+ throw_(value_exception, "Cannot convert a string to a date/time");
case AMOUNT: {
amount_t temp = **(string **) data;
@@ -1676,17 +1676,17 @@ void value_t::in_place_cast(type_t cast_type)
break;
}
case BALANCE:
- throw new value_error("Cannot convert a string to a balance");
+ throw_(value_exception, "Cannot convert a string to a balance");
case BALANCE_PAIR:
- throw new value_error("Cannot convert a string to a balance pair");
+ throw_(value_exception, "Cannot convert a string to a balance pair");
case STRING:
break;
case XML_NODE:
- throw new value_error("Cannot convert a string to an XML node");
+ throw_(value_exception, "Cannot convert a string to an XML node");
case POINTER:
- throw new value_error("Cannot convert a string to a pointer");
+ throw_(value_exception, "Cannot convert a string to a pointer");
case SEQUENCE:
- throw new value_error("Cannot convert a string to a sequence");
+ throw_(value_exception, "Cannot convert a string to a sequence");
default:
assert(0);
@@ -1708,9 +1708,9 @@ void value_t::in_place_cast(type_t cast_type)
case XML_NODE:
break;
case POINTER:
- throw new value_error("Cannot convert an XML node to a pointer");
+ throw_(value_exception, "Cannot convert an XML node to a pointer");
case SEQUENCE:
- throw new value_error("Cannot convert an XML node to a sequence");
+ throw_(value_exception, "Cannot convert an XML node to a sequence");
default:
assert(0);
@@ -1721,25 +1721,25 @@ void value_t::in_place_cast(type_t cast_type)
case POINTER:
switch (cast_type) {
case BOOLEAN:
- throw new value_error("Cannot convert a pointer to a boolean");
+ throw_(value_exception, "Cannot convert a pointer to a boolean");
case INTEGER:
- throw new value_error("Cannot convert a pointer to an integer");
+ throw_(value_exception, "Cannot convert a pointer to an integer");
case DATETIME:
- throw new value_error("Cannot convert a pointer to a date/time");
+ throw_(value_exception, "Cannot convert a pointer to a date/time");
case AMOUNT:
- throw new value_error("Cannot convert a pointer to an amount");
+ throw_(value_exception, "Cannot convert a pointer to an amount");
case BALANCE:
- throw new value_error("Cannot convert a pointer to a balance");
+ throw_(value_exception, "Cannot convert a pointer to a balance");
case BALANCE_PAIR:
- throw new value_error("Cannot convert a pointer to a balance pair");
+ throw_(value_exception, "Cannot convert a pointer to a balance pair");
case STRING:
- throw new value_error("Cannot convert a pointer to a string");
+ throw_(value_exception, "Cannot convert a pointer to a string");
case XML_NODE:
- throw new value_error("Cannot convert a pointer to an XML node");
+ throw_(value_exception, "Cannot convert a pointer to an XML node");
case POINTER:
break;
case SEQUENCE:
- throw new value_error("Cannot convert a pointer to a sequence");
+ throw_(value_exception, "Cannot convert a pointer to a sequence");
default:
assert(0);
@@ -1750,23 +1750,23 @@ void value_t::in_place_cast(type_t cast_type)
case SEQUENCE:
switch (cast_type) {
case BOOLEAN:
- throw new value_error("Cannot convert a sequence to a boolean");
+ throw_(value_exception, "Cannot convert a sequence to a boolean");
case INTEGER:
- throw new value_error("Cannot convert a sequence to an integer");
+ throw_(value_exception, "Cannot convert a sequence to an integer");
case DATETIME:
- throw new value_error("Cannot convert a sequence to a date/time");
+ throw_(value_exception, "Cannot convert a sequence to a date/time");
case AMOUNT:
- throw new value_error("Cannot convert a sequence to an amount");
+ throw_(value_exception, "Cannot convert a sequence to an amount");
case BALANCE:
- throw new value_error("Cannot convert a sequence to a balance");
+ throw_(value_exception, "Cannot convert a sequence to a balance");
case BALANCE_PAIR:
- throw new value_error("Cannot convert a sequence to a balance pair");
+ throw_(value_exception, "Cannot convert a sequence to a balance pair");
case STRING:
- throw new value_error("Cannot convert a sequence to a string");
+ throw_(value_exception, "Cannot convert a sequence to a string");
case XML_NODE:
- throw new value_error("Cannot compare a sequence to an XML node");
+ throw_(value_exception, "Cannot compare a sequence to an XML node");
case POINTER:
- throw new value_error("Cannot convert a sequence to a pointer");
+ throw_(value_exception, "Cannot convert a sequence to a pointer");
case SEQUENCE:
break;
@@ -1793,7 +1793,7 @@ void value_t::in_place_negate()
*((long *) data) = - *((long *) data);
break;
case DATETIME:
- throw new value_error("Cannot negate a date/time");
+ throw_(value_exception, "Cannot negate a date/time");
case AMOUNT:
((amount_t *) data)->in_place_negate();
break;
@@ -1804,15 +1804,15 @@ void value_t::in_place_negate()
((balance_pair_t *) data)->in_place_negate();
break;
case STRING:
- throw new value_error("Cannot negate a string");
+ throw_(value_exception, "Cannot negate a string");
case XML_NODE:
*this = (*(xml::node_t **) data)->to_value();
in_place_negate();
break;
case POINTER:
- throw new value_error("Cannot negate a pointer");
+ throw_(value_exception, "Cannot negate a pointer");
case SEQUENCE:
- throw new value_error("Cannot negate a sequence");
+ throw_(value_exception, "Cannot negate a sequence");
default:
assert(0);
@@ -1841,15 +1841,15 @@ void value_t::in_place_abs()
((balance_pair_t *) data)->abs();
break;
case STRING:
- throw new value_error("Cannot take the absolute value of a string");
+ throw_(value_exception, "Cannot take the absolute value of a string");
case XML_NODE:
*this = (*(xml::node_t **) data)->to_value();
in_place_abs();
break;
case POINTER:
- throw new value_error("Cannot take the absolute value of a pointer");
+ throw_(value_exception, "Cannot take the absolute value of a pointer");
case SEQUENCE:
- throw new value_error("Cannot take the absolute value of a sequence");
+ throw_(value_exception, "Cannot take the absolute value of a sequence");
default:
assert(0);
@@ -1861,9 +1861,9 @@ value_t value_t::value(const moment_t& moment) const
{
switch (type) {
case BOOLEAN:
- throw new value_error("Cannot find the value of a boolean");
+ throw_(value_exception, "Cannot find the value of a boolean");
case DATETIME:
- throw new value_error("Cannot find the value of a date/time");
+ throw_(value_exception, "Cannot find the value of a date/time");
case INTEGER:
return *this;
case AMOUNT:
@@ -1873,13 +1873,13 @@ value_t value_t::value(const moment_t& moment) const
case BALANCE_PAIR:
return ((balance_pair_t *) data)->quantity.value(moment);
case STRING:
- throw new value_error("Cannot find the value of a string");
+ throw_(value_exception, "Cannot find the value of a string");
case XML_NODE:
return (*(xml::node_t **) data)->to_value().value(moment);
case POINTER:
- throw new value_error("Cannot find the value of a pointer");
+ throw_(value_exception, "Cannot find the value of a pointer");
case SEQUENCE:
- throw new value_error("Cannot find the value of a sequence");
+ throw_(value_exception, "Cannot find the value of a sequence");
default:
assert(0);
return value_t();
@@ -1903,15 +1903,15 @@ void value_t::in_place_reduce()
((balance_pair_t *) data)->in_place_reduce();
break;
case STRING:
- throw new value_error("Cannot reduce a string");
+ throw_(value_exception, "Cannot reduce a string");
case XML_NODE:
*this = (*(xml::node_t **) data)->to_value();
in_place_reduce(); // recurse
break;
case POINTER:
- throw new value_error("Cannot reduce a pointer");
+ throw_(value_exception, "Cannot reduce a pointer");
case SEQUENCE:
- throw new value_error("Cannot reduce a sequence");
+ throw_(value_exception, "Cannot reduce a sequence");
}
}
@@ -1919,9 +1919,9 @@ value_t value_t::round() const
{
switch (type) {
case BOOLEAN:
- throw new value_error("Cannot round a boolean");
+ throw_(value_exception, "Cannot round a boolean");
case DATETIME:
- throw new value_error("Cannot round a date/time");
+ throw_(value_exception, "Cannot round a date/time");
case INTEGER:
return *this;
case AMOUNT:
@@ -1931,13 +1931,13 @@ value_t value_t::round() const
case BALANCE_PAIR:
return ((balance_pair_t *) data)->round();
case STRING:
- throw new value_error("Cannot round a string");
+ throw_(value_exception, "Cannot round a string");
case XML_NODE:
return (*(xml::node_t **) data)->to_value().round();
case POINTER:
- throw new value_error("Cannot round a pointer");
+ throw_(value_exception, "Cannot round a pointer");
case SEQUENCE:
- throw new value_error("Cannot round a sequence");
+ throw_(value_exception, "Cannot round a sequence");
}
assert(0);
return value_t();
@@ -1947,9 +1947,9 @@ value_t value_t::unround() const
{
switch (type) {
case BOOLEAN:
- throw new value_error("Cannot un-round a boolean");
+ throw_(value_exception, "Cannot un-round a boolean");
case DATETIME:
- throw new value_error("Cannot un-round a date/time");
+ throw_(value_exception, "Cannot un-round a date/time");
case INTEGER:
return *this;
case AMOUNT:
@@ -1959,13 +1959,13 @@ value_t value_t::unround() const
case BALANCE_PAIR:
return ((balance_pair_t *) data)->unround();
case STRING:
- throw new value_error("Cannot un-round a string");
+ throw_(value_exception, "Cannot un-round a string");
case XML_NODE:
return (*(xml::node_t **) data)->to_value().unround();
case POINTER:
- throw new value_error("Cannot un-round a pointer");
+ throw_(value_exception, "Cannot un-round a pointer");
case SEQUENCE:
- throw new value_error("Cannot un-round a sequence");
+ throw_(value_exception, "Cannot un-round a sequence");
}
assert(0);
return value_t();
@@ -1975,11 +1975,11 @@ value_t value_t::price() const
{
switch (type) {
case BOOLEAN:
- throw new value_error("Cannot find the price of a boolean");
+ throw_(value_exception, "Cannot find the price of a boolean");
case INTEGER:
return *this;
case DATETIME:
- throw new value_error("Cannot find the price of a date/time");
+ throw_(value_exception, "Cannot find the price of a date/time");
case AMOUNT:
return ((amount_t *) data)->price();
@@ -1989,15 +1989,15 @@ value_t value_t::price() const
return ((balance_pair_t *) data)->quantity.price();
case STRING:
- throw new value_error("Cannot find the price of a string");
+ throw_(value_exception, "Cannot find the price of a string");
case XML_NODE:
return (*(xml::node_t **) data)->to_value().price();
case POINTER:
- throw new value_error("Cannot find the price of a pointer");
+ throw_(value_exception, "Cannot find the price of a pointer");
case SEQUENCE:
- throw new value_error("Cannot find the price of a sequence");
+ throw_(value_exception, "Cannot find the price of a sequence");
default:
assert(0);
@@ -2011,9 +2011,9 @@ value_t value_t::date() const
{
switch (type) {
case BOOLEAN:
- throw new value_error("Cannot find the date of a boolean");
+ throw_(value_exception, "Cannot find the date of a boolean");
case INTEGER:
- throw new value_error("Cannot find the date of an integer");
+ throw_(value_exception, "Cannot find the date of an integer");
case DATETIME:
return *this;
@@ -2026,15 +2026,15 @@ value_t value_t::date() const
return ((balance_pair_t *) data)->quantity.date();
case STRING:
- throw new value_error("Cannot find the date of a string");
+ throw_(value_exception, "Cannot find the date of a string");
case XML_NODE:
return (*(xml::node_t **) data)->to_value().date();
case POINTER:
- throw new value_error("Cannot find the date of a pointer");
+ throw_(value_exception, "Cannot find the date of a pointer");
case SEQUENCE:
- throw new value_error("Cannot find the date of a sequence");
+ throw_(value_exception, "Cannot find the date of a sequence");
default:
assert(0);
@@ -2083,13 +2083,13 @@ value_t value_t::cost() const
{
switch (type) {
case BOOLEAN:
- throw new value_error("Cannot find the cost of a boolean");
+ throw_(value_exception, "Cannot find the cost of a boolean");
case INTEGER:
case AMOUNT:
case BALANCE:
return *this;
case DATETIME:
- throw new value_error("Cannot find the cost of a date/time");
+ throw_(value_exception, "Cannot find the cost of a date/time");
case BALANCE_PAIR:
assert(((balance_pair_t *) data)->cost);
@@ -2099,13 +2099,13 @@ value_t value_t::cost() const
return ((balance_pair_t *) data)->quantity;
case STRING:
- throw new value_error("Cannot find the cost of a string");
+ throw_(value_exception, "Cannot find the cost of a string");
case XML_NODE:
return (*(xml::node_t **) data)->to_value().cost();
case POINTER:
- throw new value_error("Cannot find the cost of a pointer");
+ throw_(value_exception, "Cannot find the cost of a pointer");
case SEQUENCE:
- throw new value_error("Cannot find the cost of a sequence");
+ throw_(value_exception, "Cannot find the cost of a sequence");
default:
assert(0);
@@ -2119,9 +2119,9 @@ value_t& value_t::add(const amount_t& amount, const amount_t * tcost)
{
switch (type) {
case BOOLEAN:
- throw new value_error("Cannot add an amount to a boolean");
+ throw_(value_exception, "Cannot add an amount to a boolean");
case DATETIME:
- throw new value_error("Cannot add an amount to a date/time");
+ throw_(value_exception, "Cannot add an amount to a date/time");
case INTEGER:
case AMOUNT:
if (tcost) {
@@ -2153,13 +2153,13 @@ value_t& value_t::add(const amount_t& amount, const amount_t * tcost)
break;
case STRING:
- throw new value_error("Cannot add an amount to a string");
+ throw_(value_exception, "Cannot add an amount to a string");
case XML_NODE:
- throw new value_error("Cannot add an amount to an XML node");
+ throw_(value_exception, "Cannot add an amount to an XML node");
case POINTER:
- throw new value_error("Cannot add an amount to a pointer");
+ throw_(value_exception, "Cannot add an amount to a pointer");
case SEQUENCE:
- throw new value_error("Cannot add an amount to a sequence");
+ throw_(value_exception, "Cannot add an amount to a sequence");
default:
assert(0);
@@ -2188,7 +2188,7 @@ void value_t::write(std::ostream& out, const int first_width,
case SEQUENCE:
assert(0); // jww (2006-09-28): write them all out!
- throw new value_error("Cannot write out a sequence");
+ throw_(value_exception, "Cannot write out a sequence");
case BALANCE:
((balance_t *) data)->write(out, first_width, latter_width);
@@ -2231,7 +2231,7 @@ std::ostream& operator<<(std::ostream& out, const value_t& val)
break;
case value_t::POINTER:
- throw new value_error("Cannot output a pointer value");
+ throw_(value_exception, "Cannot output a pointer value");
case value_t::SEQUENCE: {
out << '(';
@@ -2257,6 +2257,7 @@ std::ostream& operator<<(std::ostream& out, const value_t& val)
return out;
}
+#if 0
value_context::value_context(const value_t& _bal,
const string& _desc) throw()
: error_context(_desc), bal(new value_t(_bal)) {}
@@ -2305,6 +2306,7 @@ void value_context::describe(std::ostream& out) const throw()
}
out << std::endl;
}
+#endif
} // namespace ledger
@@ -2361,13 +2363,13 @@ amount_t value_getitem(value_t& val, int i)
switch (val.type) {
case value_t::BOOLEAN:
- throw new value_error("Cannot cast a boolean to an amount");
+ throw_(value_exception, "Cannot cast a boolean to an amount");
case value_t::INTEGER:
return long(val);
case value_t::DATETIME:
- throw new value_error("Cannot cast a date/time to an amount");
+ throw_(value_exception, "Cannot cast a date/time to an amount");
case value_t::AMOUNT:
return *((amount_t *) val.data);
@@ -2379,13 +2381,13 @@ amount_t value_getitem(value_t& val, int i)
return balance_pair_getitem(*((balance_pair_t *) val.data), i);
case value_t::STRING:
- throw new value_error("Cannot cast a string to an amount");
+ throw_(value_exception, "Cannot cast a string to an amount");
case value_t::XML_NODE:
return (*(xml::node_t **) data)->to_value();
case value_t::POINTER:
- throw new value_error("Cannot cast a pointer to an amount");
+ throw_(value_exception, "Cannot cast a pointer to an amount");
case value_t::SEQUENCE:
return (*(value_t::sequence_t **) val.data)[i];
diff --git a/value.h b/value.h
index 2382d98f..2b0adf2b 100644
--- a/value.h
+++ b/value.h
@@ -560,6 +560,7 @@ template <> value_t::operator string() const;
std::ostream& operator<<(std::ostream& out, const value_t& val);
+#if 0
class value_context : public error_context
{
value_t * bal;
@@ -570,14 +571,9 @@ class value_context : public error_context
virtual void describe(std::ostream& out) const throw();
};
+#endif
-class value_error : public error {
- public:
- value_error(const string& _reason,
- error_context * _ctxt = NULL) throw()
- : error(_reason, _ctxt) {}
- virtual ~value_error() throw() {}
-};
+DECLARE_EXCEPTION(value_exception);
} // namespace ledger
diff --git a/xml.cc b/xml.cc
index 82e41eca..3b791892 100644
--- a/xml.cc
+++ b/xml.cc
@@ -48,7 +48,7 @@ int document_t::register_name(const string& name)
names.push_back(name);
index = names.size() - 1;
- DEBUG_PRINT("xml.lookup", this << " Inserting name: " << names.back());
+ DEBUG_("xml.lookup", this << " Inserting name: " << names.back());
std::pair<names_map::iterator, bool> result =
names_index.insert(names_pair(names.back(), index));
@@ -63,7 +63,7 @@ int document_t::lookup_name_id(const string& name) const
if ((id = lookup_builtin_id(name)) != -1)
return id;
- DEBUG_PRINT("xml.lookup", this << " Finding name: " << name);
+ DEBUG_("xml.lookup", this << " Finding name: " << name);
names_map::const_iterator i = names_index.find(name);
if (i != names_index.end())
@@ -131,7 +131,7 @@ document_t * node_t::document;
node_t::node_t(document_t * _document, parent_node_t * _parent,
unsigned int _flags)
: name_id(0), parent(_parent), next(NULL), prev(NULL),
- flags(_flags), info(NULL), attrs(NULL)
+ flags(_flags), attrs(NULL)
{
TRACE_CTOR(node_t, "document_t *, node_t *");
document = _document;
@@ -268,7 +268,7 @@ static void startElement(void *userData, const char *name, const char **attrs)
{
parser_t * parser = static_cast<parser_t *>(userData);
- DEBUG_PRINT("xml.parse", "startElement(" << name << ")");
+ DEBUG_("xml.parse", "startElement(" << name << ")");
if (parser->pending) {
parent_node_t * node = create_node<parent_node_t>(parser);
@@ -295,7 +295,7 @@ static void endElement(void *userData, const char *name)
{
parser_t * parser = static_cast<parser_t *>(userData);
- DEBUG_PRINT("xml.parse", "endElement(" << name << ")");
+ DEBUG_("xml.parse", "endElement(" << name << ")");
if (parser->pending) {
terminal_node_t * node = create_node<terminal_node_t>(parser);
@@ -317,7 +317,7 @@ static void dataHandler(void *userData, const char *s, int len)
{
parser_t * parser = static_cast<parser_t *>(userData);
- DEBUG_PRINT("xml.parse", "dataHandler(" << string(s, len) << ")");
+ DEBUG_("xml.parse", "dataHandler(" << string(s, len) << ")");
bool all_whitespace = true;
for (int i = 0; i < len; i++) {
@@ -382,21 +382,24 @@ document_t * parser_t::parse(std::istream& in)
catch (const std::exception& err) {
//unsigned long line = XML_GetCurrentLineNumber(parser) - offset++;
XML_ParserFree(parser);
- throw new parse_error(err.what());
+ throw_(parse_exception, err.what());
}
if (! have_error.empty()) {
//unsigned long line = XML_GetCurrentLineNumber(parser) - offset++;
- parse_error err(have_error);
+#if 0
+ // jww (2007-04-26): What is this doing??
+ parse_exception err(have_error);
std::cerr << "Error: " << err.what() << std::endl;
+#endif
have_error = "";
}
if (! result) {
//unsigned long line = XML_GetCurrentLineNumber(parser) - offset++;
- const char * err = XML_ErrorString(XML_GetErrorCode(parser));
+ const char * err = XML_ErrorString(XML_GetErrorCode(parser));
XML_ParserFree(parser);
- throw new parse_error(err);
+ throw_(parse_exception, err);
}
}
diff --git a/xml.h b/xml.h
index eeed15c3..023388d8 100644
--- a/xml.h
+++ b/xml.h
@@ -14,13 +14,7 @@ namespace xml {
#define XML_NODE_IS_PARENT 0x1
-class conversion_error : public error {
- public:
- conversion_error(const string& _reason,
- error_context * _ctxt = NULL) throw()
- : error(_reason, _ctxt) {}
- virtual ~conversion_error() throw() {}
-};
+DECLARE_EXCEPTION(conversion_exception);
class parent_node_t;
class document_t;
@@ -38,7 +32,6 @@ public:
node_t * next;
node_t * prev;
unsigned int flags;
- void * info;
typedef std::map<string, string> attrs_map;
typedef std::pair<string, string> attrs_pair;
@@ -91,7 +84,7 @@ public:
}
virtual value_t to_value() const {
- throw new conversion_error("Cannot convert node to a value");
+ throw_(conversion_exception, "Cannot convert node to a value");
}
virtual void write(std::ostream& out, int depth = 0) const = 0;
@@ -248,13 +241,7 @@ class parser_t
virtual document_t * parse(std::istream& in);
};
-class parse_error : public error {
- public:
- parse_error(const string& _reason,
- error_context * _ctxt = NULL) throw()
- : error(_reason, _ctxt) {}
- virtual ~parse_error() throw() {}
-};
+DECLARE_EXCEPTION(parse_exception);
#endif
diff --git a/xmlparse.cc b/xmlparse.cc
index bcd6cefb..35d26e5a 100644
--- a/xmlparse.cc
+++ b/xmlparse.cc
@@ -207,13 +207,16 @@ unsigned int xml_parser_t::parse(std::istream& in,
catch (const std::exception& err) {
//unsigned long line = XML_GetCurrentLineNumber(parser) - offset++;
XML_ParserFree(parser);
- throw new parse_error(err.what());
+ throw_(parse_exception, err.what());
}
if (! have_error.empty()) {
//unsigned long line = XML_GetCurrentLineNumber(parser) - offset++;
+#if 0
+ // jww (2007-04-26): What is this code doing?
parse_error err(have_error);
std::cerr << "Error: " << err.what() << std::endl;
+#endif
have_error = "";
}
@@ -221,7 +224,7 @@ unsigned int xml_parser_t::parse(std::istream& in,
//unsigned long line = XML_GetCurrentLineNumber(parser) - offset++;
const char * err = XML_ErrorString(XML_GetErrorCode(parser));
XML_ParserFree(parser);
- throw new parse_error(err);
+ throw_(parse_exception, err);
}
}
diff --git a/xpath.cc b/xpath.cc
index c2e26ae4..70f924e6 100644
--- a/xpath.cc
+++ b/xpath.cc
@@ -1,4 +1,5 @@
#include "xpath.h"
+#include "parser.h"
#if 0
#ifdef USE_BOOST_PYTHON
#include "py_eval.h"
@@ -375,14 +376,12 @@ void xpath_t::token_t::next(std::istream& in, unsigned short flags)
kind = VALUE;
value = temp;
}
- catch (amount_error * err) {
+ catch (amount_exception& err) {
// If the amount had no commodity, it must be an unambiguous
// variable reference
// jww (2007-04-19): There must be a more efficient way to do this!
- if (std::strcmp(err->what(), "No quantity specified for amount") == 0) {
- delete err;
-
+ if (std::strcmp(err.what(), "No quantity specified for amount") == 0) {
in.clear();
in.seekg(pos, std::ios::beg);
@@ -390,7 +389,7 @@ void xpath_t::token_t::next(std::istream& in, unsigned short flags)
assert(! (std::isdigit(c) || c == '.'));
parse_ident(in);
} else {
- throw err;
+ throw;
}
}
}
@@ -409,15 +408,13 @@ void xpath_t::token_t::unexpected()
{
switch (kind) {
case TOK_EOF:
- throw new parse_error("Unexpected end of expression");
+ throw_(parse_exception, "Unexpected end of expression");
case IDENT:
- throw new parse_error(string("Unexpected symbol '") +
- value.to_string() + "'");
+ throw_(parse_exception, "Unexpected symbol '" << value << "'");
case VALUE:
- throw new parse_error(string("Unexpected value '") +
- value.to_string() + "'");
+ throw_(parse_exception, "Unexpected value '" << value << "'");
default:
- throw new parse_error(string("Unexpected operator '") + symbol + "'");
+ throw_(parse_exception, "Unexpected operator '" << symbol << "'");
}
}
@@ -425,15 +422,15 @@ void xpath_t::token_t::unexpected(char c, char wanted)
{
if ((unsigned char) c == 0xff) {
if (wanted)
- throw new parse_error(string("Missing '") + wanted + "'");
+ throw_(parse_exception, "Missing '" << wanted << "'");
else
- throw new parse_error("Unexpected end");
+ throw_(parse_exception, "Unexpected end");
} else {
if (wanted)
- throw new parse_error(string("Invalid char '") + c +
- "' (wanted '" + wanted + "')");
+ throw_(parse_exception, "Invalid char '" << c <<
+ "' (wanted '" << wanted << "')");
else
- throw new parse_error(string("Invalid char '") + c + "'");
+ throw_(parse_exception, "Invalid char '" << c << "'");
}
}
@@ -472,7 +469,7 @@ xpath_t::op_t * xpath_t::wrap_mask(const string& pattern)
void xpath_t::scope_t::define(const string& name, op_t * def)
{
- DEBUG_PRINT("ledger.xpath.syms", "Defining '" << name << "' = " << def);
+ DEBUG_("ledger.xpath.syms", "Defining '" << name << "' = " << def);
std::pair<symbol_map::iterator, bool> result
= symbols.insert(symbol_pair(name, def));
@@ -485,8 +482,8 @@ void xpath_t::scope_t::define(const string& name, op_t * def)
std::pair<symbol_map::iterator, bool> result2
= symbols.insert(symbol_pair(name, def));
if (! result2.second)
- throw new compile_error(string("Redefinition of '") +
- name + "' in same scope");
+ throw_(compile_exception,
+ "Redefinition of '" << name << "' in same scope");
}
def->acquire();
}
@@ -533,7 +530,7 @@ bool xpath_t::function_scope_t::resolve(const string& name,
if (value->type == value_t::XML_NODE)
result.set_string(value->to_xml_node()->text());
else
- throw new calc_error("Attempt to call text() on a non-node value");
+ throw_(calc_exception, "Attempt to call text() on a non-node value");
return true;
}
break;
@@ -545,7 +542,7 @@ xpath_t::op_t::~op_t()
{
TRACE_DTOR(xpath_t::op_t);
- DEBUG_PRINT("ledger.xpath.memory", "Destroying " << this);
+ DEBUG_("ledger.xpath.memory", "Destroying " << this);
assert(refc == 0);
switch (kind) {
@@ -600,13 +597,9 @@ void xpath_t::op_t::get_value(value_t& result) const
case ARG_INDEX:
result = (long)arg_index;
break;
- default: {
- std::ostringstream buf;
- write(buf);
- throw new calc_error
- (string("Cannot determine value of expression symbol '") +
- string(buf.str()) + "'");
- }
+ default:
+ throw_(calc_exception,
+ "Cannot determine value of expression symbol '" << *this << "'");
}
}
@@ -646,7 +639,7 @@ xpath_t::parse_value_term(std::istream& in, unsigned short tflags) const
goto done;
}
catch(const boost::python::error_already_set&) {
- throw new parse_error("Error parsing lambda expression");
+ throw_(parse_exception, "Error parsing lambda expression");
}
#endif /* USE_BOOST_PYTHON */
#endif
@@ -690,7 +683,7 @@ xpath_t::parse_value_term(std::istream& in, unsigned short tflags) const
case token_t::AT_SYM:
tok = next_token(in, tflags);
if (tok.kind != token_t::IDENT)
- throw parse_error("@ symbol must be followed by attribute name");
+ throw_(parse_exception, "@ symbol must be followed by attribute name");
node.reset(new op_t(op_t::ATTR_NAME));
node->name = new string(tok.value.to_string());
@@ -728,8 +721,8 @@ xpath_t::parse_value_term(std::istream& in, unsigned short tflags) const
case token_t::LPAREN:
node.reset(parse_value_expr(in, tflags | XPATH_PARSE_PARTIAL));
if (! node.get())
- throw new parse_error(string(tok.symbol) +
- " operator not followed by argument");
+ throw_(parse_exception,
+ tok.symbol << " operator not followed by argument");
tok = next_token(in, tflags);
if (tok.kind != token_t::RPAREN)
tok.unexpected(); // jww (2006-09-09): wanted )
@@ -767,7 +760,7 @@ xpath_t::parse_predicate_expr(std::istream& in, unsigned short tflags) const
node->set_left(prev.release());
node->set_right(parse_value_expr(in, tflags | XPATH_PARSE_PARTIAL));
if (! node->right)
- throw new parse_error("[ operator not followed by valid expression");
+ throw_(parse_exception, "[ operator not followed by valid expression");
tok = next_token(in, tflags);
if (tok.kind != token_t::RBRACKET)
@@ -801,7 +794,7 @@ xpath_t::parse_path_expr(std::istream& in, unsigned short tflags) const
node->set_left(prev.release());
node->set_right(parse_predicate_expr(in, tflags));
if (! node->right)
- throw new parse_error("/ operator not followed by a valid term");
+ throw_(parse_exception, "/ operator not followed by a valid term");
tok = next_token(in, tflags);
}
@@ -823,8 +816,8 @@ xpath_t::parse_unary_expr(std::istream& in, unsigned short tflags) const
case token_t::EXCLAM: {
std::auto_ptr<op_t> texpr(parse_path_expr(in, tflags));
if (! texpr.get())
- throw new parse_error(string(tok.symbol) +
- " operator not followed by argument");
+ throw_(parse_exception,
+ tok.symbol << " operator not followed by argument");
// A very quick optimization
if (texpr->kind == op_t::VALUE) {
*texpr->valuep = ! *texpr->valuep;
@@ -839,8 +832,8 @@ xpath_t::parse_unary_expr(std::istream& in, unsigned short tflags) const
case token_t::MINUS: {
std::auto_ptr<op_t> texpr(parse_path_expr(in, tflags));
if (! texpr.get())
- throw new parse_error(string(tok.symbol) +
- " operator not followed by argument");
+ throw_(parse_exception,
+ tok.symbol << " operator not followed by argument");
// A very quick optimization
if (texpr->kind == op_t::VALUE) {
texpr->valuep->in_place_negate();
@@ -856,8 +849,8 @@ xpath_t::parse_unary_expr(std::istream& in, unsigned short tflags) const
case token_t::PERCENT: {
std::auto_ptr<op_t> texpr(parse_path_expr(in, tflags));
if (! texpr.get())
- throw new parse_error(string(tok.symbol) +
- " operator not followed by argument");
+ throw_(parse_exception,
+ tok.symbol << " operator not followed by argument");
// A very quick optimization
if (texpr->kind == op_t::VALUE) {
static value_t perc("100.0%");
@@ -893,8 +886,8 @@ xpath_t::parse_union_expr(std::istream& in, unsigned short tflags) const
node->set_left(prev.release());
node->set_right(parse_union_expr(in, tflags));
if (! node->right)
- throw new parse_error(string(tok.symbol) +
- " operator not followed by argument");
+ throw_(parse_exception,
+ tok.symbol << " operator not followed by argument");
} else {
push_token(tok);
}
@@ -916,8 +909,8 @@ xpath_t::parse_mul_expr(std::istream& in, unsigned short tflags) const
node->set_left(prev.release());
node->set_right(parse_mul_expr(in, tflags));
if (! node->right)
- throw new parse_error(string(tok.symbol) +
- " operator not followed by argument");
+ throw_(parse_exception,
+ tok.symbol << " operator not followed by argument");
tok = next_token(in, tflags);
}
@@ -942,8 +935,8 @@ xpath_t::parse_add_expr(std::istream& in, unsigned short tflags) const
node->set_left(prev.release());
node->set_right(parse_add_expr(in, tflags));
if (! node->right)
- throw new parse_error(string(tok.symbol) +
- " operator not followed by argument");
+ throw_(parse_exception,
+ tok.symbol << " operator not followed by argument");
tok = next_token(in, tflags);
}
@@ -1012,11 +1005,11 @@ xpath_t::parse_logic_expr(std::istream& in, unsigned short tflags) const
if (! node->right) {
if (tok.kind == token_t::PLUS)
- throw new parse_error(string(tok.symbol) +
- " operator not followed by argument");
+ throw_(parse_exception,
+ tok.symbol << " operator not followed by argument");
else
- throw new parse_error(string(tok.symbol) +
- " operator not followed by argument");
+ throw_(parse_exception,
+ tok.symbol << " operator not followed by argument");
}
}
}
@@ -1037,8 +1030,8 @@ xpath_t::parse_and_expr(std::istream& in, unsigned short tflags) const
node->set_left(prev.release());
node->set_right(parse_and_expr(in, tflags));
if (! node->right)
- throw new parse_error(string(tok.symbol) +
- " operator not followed by argument");
+ throw_(parse_exception,
+ tok.symbol << " operator not followed by argument");
} else {
push_token(tok);
}
@@ -1059,8 +1052,8 @@ xpath_t::parse_or_expr(std::istream& in, unsigned short tflags) const
node->set_left(prev.release());
node->set_right(parse_or_expr(in, tflags));
if (! node->right)
- throw new parse_error(string(tok.symbol) +
- " operator not followed by argument");
+ throw_(parse_exception,
+ tok.symbol << " operator not followed by argument");
} else {
push_token(tok);
}
@@ -1082,15 +1075,15 @@ xpath_t::parse_querycolon_expr(std::istream& in, unsigned short tflags) const
node->set_right(new op_t(op_t::O_COLON));
node->right->set_left(parse_querycolon_expr(in, tflags));
if (! node->right)
- throw new parse_error(string(tok.symbol) +
- " operator not followed by argument");
+ throw_(parse_exception,
+ tok.symbol << " operator not followed by argument");
tok = next_token(in, tflags);
if (tok.kind != token_t::COLON)
tok.unexpected(); // jww (2006-09-09): wanted :
node->right->set_right(parse_querycolon_expr(in, tflags));
if (! node->right)
- throw new parse_error(string(tok.symbol) +
- " operator not followed by argument");
+ throw_(parse_exception,
+ tok.symbol << " operator not followed by argument");
} else {
push_token(tok);
}
@@ -1111,8 +1104,8 @@ xpath_t::parse_value_expr(std::istream& in, unsigned short tflags) const
node->set_left(prev.release());
node->set_right(parse_value_expr(in, tflags));
if (! node->right)
- throw new parse_error(string(tok.symbol) +
- " operator not followed by argument");
+ throw_(parse_exception,
+ tok.symbol << " operator not followed by argument");
tok = next_token(in, tflags);
}
@@ -1124,7 +1117,7 @@ xpath_t::parse_value_expr(std::istream& in, unsigned short tflags) const
}
}
else if (! (tflags & XPATH_PARSE_PARTIAL)) {
- throw new parse_error(string("Failed to parse value expression"));
+ throw_(parse_exception, "Failed to parse value expression");
}
return node.release();
@@ -1188,7 +1181,7 @@ void xpath_t::op_t::find_values(value_t * context, scope_t * scope,
}
}
} else {
- throw new calc_error("Recursive path selection on a non-node value");
+ throw_(calc_exception, "Recursive path selection on a non-node value");
}
}
}
@@ -1199,7 +1192,7 @@ bool xpath_t::op_t::test_value(value_t * context, scope_t * scope,
xpath_t expr(compile(context, scope, true));
if (expr->kind != VALUE)
- throw new calc_error("Predicate expression does not yield a constant value");
+ throw_(calc_exception, "Predicate expression does not yield a constant value");
switch (expr->valuep->type) {
case value_t::INTEGER:
@@ -1262,7 +1255,9 @@ void xpath_t::op_t::append_value(value_t& val,
xpath_t::op_t * xpath_t::op_t::compile(value_t * context, scope_t * scope,
bool resolve)
{
+#if 0
try {
+#endif
switch (kind) {
case VALUE:
return acquire();
@@ -1274,25 +1269,25 @@ xpath_t::op_t * xpath_t::op_t::compile(value_t * context, scope_t * scope,
case document_t::PARENT:
if (context->type != value_t::XML_NODE)
- throw new compile_error("Referencing parent node from a non-node value");
+ throw_(compile_exception, "Referencing parent node from a non-node value");
else if (context->to_xml_node()->parent)
return wrap_value(context->to_xml_node()->parent)->acquire();
else
- throw new compile_error("Referencing parent node from the root node");
+ throw_(compile_exception, "Referencing parent node from the root node");
case document_t::ROOT:
if (context->type != value_t::XML_NODE)
- throw new compile_error("Referencing root node from a non-node value");
+ throw_(compile_exception, "Referencing root node from a non-node value");
else
return wrap_value(context->to_xml_node()->document->top)->acquire();
case document_t::ALL: {
if (context->type != value_t::XML_NODE)
- throw new compile_error("Referencing child nodes from a non-node value");
+ throw_(compile_exception, "Referencing child nodes from a non-node value");
node_t * ptr = context->to_xml_node();
if (! (ptr->flags & XML_NODE_IS_PARENT))
- throw new compile_error("Request for child nodes of a leaf node");
+ throw_(compile_exception, "Request for child nodes of a leaf node");
parent_node_t * parent = static_cast<parent_node_t *>(ptr);
@@ -1366,7 +1361,7 @@ xpath_t::op_t * xpath_t::op_t::compile(value_t * context, scope_t * scope,
if (arg_index < scope->args.to_sequence()->size())
return wrap_value((*scope->args.to_sequence())[arg_index])->acquire();
else
- throw new compile_error("Reference to non-existing argument");
+ throw_(compile_exception, "Reference to non-existing argument");
} else {
return acquire();
}
@@ -1650,7 +1645,7 @@ xpath_t::op_t * xpath_t::op_t::compile(value_t * context, scope_t * scope,
}
if (lexpr->valuep->type != value_t::STRING)
- throw new compile_error("Left operand of mask operator is not a string");
+ throw_(compile_exception, "Left operand of mask operator is not a string");
assert(rexpr->mask);
@@ -1759,8 +1754,7 @@ xpath_t::op_t * xpath_t::op_t::compile(value_t * context, scope_t * scope,
return func->compile(context, call_args.get(), resolve);
}
else {
- throw new calc_error(string("Unknown function name '") +
- *left->name + "'");
+ throw_(calc_exception, "Unknown function name '" << *left->name << "'");
}
}
else if (left->kind == FUNCTOR) {
@@ -1815,7 +1809,7 @@ xpath_t::op_t * xpath_t::op_t::compile(value_t * context, scope_t * scope,
i++, index++) {
assert((*i).type != value_t::SEQUENCE);
if ((*i).type != value_t::XML_NODE)
- throw new compile_error("Attempting to apply path selection "
+ throw_(compile_exception, "Attempting to apply path selection "
"to non-node(s)");
function_scope_t xpath_fscope(seq, &(*i), index, scope);
@@ -1831,8 +1825,8 @@ xpath_t::op_t * xpath_t::op_t::compile(value_t * context, scope_t * scope,
}
default:
- throw new compile_error("Attempting to apply path selection "
- "to non-node(s)");
+ throw_(compile_exception, "Attempting to apply path selection "
+ "to non-node(s)");
}
if (result_seq->size() == 1)
@@ -1863,6 +1857,7 @@ xpath_t::op_t * xpath_t::op_t::compile(value_t * context, scope_t * scope,
assert(0);
break;
}
+#if 0
}
catch (error * err) {
#if 0
@@ -1873,6 +1868,7 @@ xpath_t::op_t * xpath_t::op_t::compile(value_t * context, scope_t * scope,
#endif
throw err;
}
+#endif
assert(0);
return NULL;
@@ -1880,7 +1876,9 @@ xpath_t::op_t * xpath_t::op_t::compile(value_t * context, scope_t * scope,
void xpath_t::calc(value_t& result, node_t * node, scope_t * scope) const
{
+#if 0
try {
+#endif
if (node) {
value_t context_node(node);
xpath_t final(ptr->compile(&context_node, scope, true));
@@ -1893,6 +1891,7 @@ void xpath_t::calc(value_t& result, node_t * node, scope_t * scope) const
xpath_t final(ptr->compile(&context_node, scope, true));
final->get_value(result);
}
+#if 0
}
catch (error * err) {
if (err->context.empty() ||
@@ -1908,8 +1907,10 @@ void xpath_t::calc(value_t& result, node_t * node, scope_t * scope) const
#endif
throw err;
}
+#endif
}
+#if 0
xpath_t::context::context(const xpath_t& _xpath,
const op_t * _err_node,
const string& desc) throw()
@@ -1952,6 +1953,7 @@ void xpath_t::context::describe(std::ostream& out) const throw()
out << std::endl;
}
}
+#endif
bool xpath_t::op_t::write(std::ostream& out,
const bool relaxed,
diff --git a/xpath.h b/xpath.h
index 85ad11d9..54edf81c 100644
--- a/xpath.h
+++ b/xpath.h
@@ -11,30 +11,11 @@ class xpath_t
public:
struct op_t;
- class parse_error : public error {
- public:
- parse_error(const string& _reason,
- error_context * _ctxt = NULL) throw()
- : error(_reason, _ctxt) {}
- virtual ~parse_error() throw() {}
- };
-
- class compile_error : public error {
- public:
- compile_error(const string& _reason,
- error_context * _ctxt = NULL) throw()
- : error(_reason, _ctxt) {}
- virtual ~compile_error() throw() {}
- };
-
- class calc_error : public error {
- public:
- calc_error(const string& _reason,
- error_context * _ctxt = NULL) throw()
- : error(_reason, _ctxt) {}
- virtual ~calc_error() throw() {}
- };
+ DECLARE_EXCEPTION(parse_exception);
+ DECLARE_EXCEPTION(compile_exception);
+ DECLARE_EXCEPTION(calc_exception);
+#if 0
class context : public error_context {
public:
const xpath_t& xpath;
@@ -47,6 +28,7 @@ public:
virtual void describe(std::ostream& out) const throw();
};
+#endif
public:
class scope_t;
@@ -439,21 +421,21 @@ public:
}
void release() const {
- DEBUG_PRINT("ledger.xpath.memory",
+ DEBUG_("ledger.xpath.memory",
"Releasing " << this << ", refc now " << refc - 1);
assert(refc > 0);
if (--refc == 0)
delete this;
}
op_t * acquire() {
- DEBUG_PRINT("ledger.xpath.memory",
+ DEBUG_("ledger.xpath.memory",
"Acquiring " << this << ", refc now " << refc + 1);
assert(refc >= 0);
refc++;
return this;
}
const op_t * acquire() const {
- DEBUG_PRINT("ledger.xpath.memory",
+ DEBUG_("ledger.xpath.memory",
"Acquiring " << this << ", refc now " << refc + 1);
assert(refc >= 0);
refc++;
@@ -580,8 +562,11 @@ public:
unsigned short tflags = XPATH_PARSE_RELAXED) const
{
std::istringstream stream(str);
+#if 0
try {
+#endif
return parse_expr(stream, tflags);
+#if 0
}
catch (error * err) {
err->context.push_back
@@ -589,6 +574,7 @@ public:
"While parsing value expression:"));
throw err;
}
+#endif
}
op_t * parse_expr(const char * p,
@@ -749,6 +735,11 @@ public:
friend class scope_t;
};
+inline std::ostream& operator<<(std::ostream& out, const xpath_t::op_t& op) {
+ op.write(out);
+ return out;
+};
+
} // namespace xml
template <typename T>
@@ -770,7 +761,6 @@ class xml_command : public xml::xpath_t::functor_t
doc->write(*out);
}
-
};
} // namespace ledger