diff --git a/Makefile.am b/Makefile.am index 832806a6..ba96fd9b 100644 --- a/Makefile.am +++ b/Makefile.am @@ -20,7 +20,6 @@ libledger_la_SOURCES = \ config.cc \ derive.cc \ emacs.cc \ - error.cc \ format.cc \ journal.cc \ mask.cc \ diff --git a/error.h b/error.h index d12a3399..c4b3bb88 100644 --- a/error.h +++ b/error.h @@ -39,31 +39,6 @@ class file_context : public error_context } }; -namespace ledger { class value_t; } -class value_context : public error_context -{ - ledger::value_t * bal; - public: - value_context(const ledger::value_t& _bal, - const std::string& desc = "") throw(); - virtual ~value_context() throw(); - - virtual void describe(std::ostream& out) const throw(); -}; - -namespace ledger { class value_expr_t; } -class valexpr_context : public error_context { - public: - const ledger::value_expr_t * expr; - const ledger::value_expr_t * error_node; - - valexpr_context(const ledger::value_expr_t * _expr, - const std::string& desc = "") throw(); - virtual ~valexpr_context() throw(); - - virtual void describe(std::ostream& out) const throw(); -}; - class line_context : public error_context { public: std::string line; @@ -74,46 +49,18 @@ class line_context : public error_context { : line(_line), pos(_pos), error_context(desc) {} virtual ~line_context() throw() {} - virtual void describe(std::ostream& out) const throw(); -}; - -class include_context : public file_context { - public: - include_context(const std::string& file, unsigned long line, - const std::string& desc = "") throw() - : file_context(file, line, desc) {} - virtual ~include_context() throw() {} - virtual void describe(std::ostream& out) const throw() { if (! desc.empty()) - out << desc << ": "; - out << "\"" << file << "\", line " << line << ":" << std::endl; + out << desc << std::endl; + + out << " " << line << std::endl << " "; + long idx = pos < 0 ? line.length() - 1 : pos; + for (int i = 0; i < idx; i++) + out << " "; + out << "^" << std::endl; } }; -namespace ledger { class entry_base_t; } -class entry_context : public error_context { - public: - const ledger::entry_base_t& entry; - - entry_context(const ledger::entry_base_t& _entry, - const std::string& desc = "") throw() - : entry(_entry), error_context(desc) {} - virtual ~entry_context() throw() {} - - virtual void describe(std::ostream& out) const throw(); -}; - -namespace ledger { class transaction_t; } -class xact_context : public file_context { - public: - const ledger::transaction_t& xact; - - xact_context(const ledger::transaction_t& _xact, - const std::string& desc = "") throw(); - virtual ~xact_context() throw() {} -}; - ////////////////////////////////////////////////////////////////////// class str_exception : public std::exception { @@ -175,59 +122,4 @@ class fatal_assert : public fatal { virtual ~fatal_assert() throw() {} }; -namespace ledger { - -class compute_error : public error { - public: - compute_error(const std::string& reason, error_context * ctxt = NULL) throw() - : error(reason, ctxt) {} - virtual ~compute_error() throw() {} -}; - -class value_expr_error : public error { - public: - value_expr_error(const std::string& reason, - error_context * ctxt = NULL) throw() - : error(reason, ctxt) {} - virtual ~value_expr_error() throw() {} -}; - -class interval_expr_error : public error { - public: - interval_expr_error(const std::string& reason, - error_context * ctxt = NULL) throw() - : error(reason, ctxt) {} - virtual ~interval_expr_error() throw() {} -}; - -class format_error : public error { - public: - format_error(const std::string& reason, error_context * ctxt = NULL) throw() - : error(reason, ctxt) {} - virtual ~format_error() throw() {} -}; - -class parse_error : public error { - public: - parse_error(const std::string& reason, error_context * ctxt = NULL) throw() - : error(reason, ctxt) {} - virtual ~parse_error() throw() {} -}; - -class value_error : public error { - public: - value_error(const std::string& reason, error_context * ctxt = NULL) throw() - : error(reason, ctxt) {} - virtual ~value_error() throw() {} -}; - -class balance_error : public error { - public: - balance_error(const std::string& reason, error_context * ctxt = NULL) throw() - : error(reason, ctxt) {} - virtual ~balance_error() throw() {} -}; - -} // namespace ledger - #endif // _ERROR_H diff --git a/format.h b/format.h index e125bcb9..e245b9aa 100644 --- a/format.h +++ b/format.h @@ -189,6 +189,13 @@ class format_equity : public item_handler virtual void operator()(account_t& account); }; +class format_error : public error { + public: + format_error(const std::string& reason, error_context * ctxt = NULL) throw() + : error(reason, ctxt) {} + virtual ~format_error() throw() {} +}; + } // namespace ledger #endif // _FORMAT_H diff --git a/journal.cc b/journal.cc index 54d2a82a..b1292907 100644 --- a/journal.cc +++ b/journal.cc @@ -2,7 +2,7 @@ #include "datetime.h" #include "valexpr.h" #include "mask.h" -#include "error.h" +#include "format.h" #include "acconf.h" #include @@ -546,4 +546,28 @@ bool journal_t::valid() const return true; } +void entry_context::describe(std::ostream& out) const throw() +{ + if (! desc.empty()) + out << desc << std::endl; + + print_entry(out, entry, " "); +} + +xact_context::xact_context(const ledger::transaction_t& _xact, + const std::string& desc) throw() + : xact(_xact), file_context("", 0, desc) +{ + const ledger::strings_list& sources(xact.entry->journal->sources); + int x = 0; + for (ledger::strings_list::const_iterator i = sources.begin(); + i != sources.end(); + i++, x++) + if (x == xact.entry->src_idx) { + file = *i; + break; + } + line = xact.beg_line; +} + } // namespace ledger diff --git a/journal.h b/journal.h index 6d0103dc..7096e8bb 100644 --- a/journal.h +++ b/journal.h @@ -97,6 +97,15 @@ class transaction_t bool valid() const; }; +class xact_context : public file_context { + public: + const transaction_t& xact; + + xact_context(const transaction_t& _xact, + const std::string& desc = "") throw(); + virtual ~xact_context() throw() {} +}; + class journal_t; typedef std::list transactions_list; @@ -193,6 +202,25 @@ struct entry_finalizer_t { virtual bool operator()(entry_t& entry) = 0; }; +class entry_context : public error_context { + public: + const entry_base_t& entry; + + entry_context(const entry_base_t& _entry, + const std::string& desc = "") throw() + : entry(_entry), error_context(desc) {} + virtual ~entry_context() throw() {} + + virtual void describe(std::ostream& out) const throw(); +}; + +class balance_error : public error { + public: + balance_error(const std::string& reason, error_context * ctxt = NULL) throw() + : error(reason, ctxt) {} + virtual ~balance_error() throw() {} +}; + template class item_predicate; diff --git a/parser.h b/parser.h index 396f0fe6..6178d293 100644 --- a/parser.h +++ b/parser.h @@ -4,6 +4,8 @@ #include #include +#include "error.h" + namespace ledger { class account_t; @@ -48,6 +50,13 @@ unsigned int parse_ledger_data(config_t& config, void initialize_parser_support(); void shutdown_parser_support(); +class parse_error : public error { + public: + parse_error(const std::string& reason, error_context * ctxt = NULL) throw() + : error(reason, ctxt) {} + virtual ~parse_error() throw() {} +}; + } // namespace ledger #endif // _PARSER_H diff --git a/textual.h b/textual.h index 473f0294..8ad653c5 100644 --- a/textual.h +++ b/textual.h @@ -27,6 +27,20 @@ void write_textual_journal(journal_t& journal, std::string path, const std::string& write_hdr_format, std::ostream& out); +class include_context : public file_context { + public: + include_context(const std::string& file, unsigned long line, + const std::string& desc = "") throw() + : file_context(file, line, desc) {} + virtual ~include_context() throw() {} + + virtual void describe(std::ostream& out) const throw() { + if (! desc.empty()) + out << desc << ": "; + out << "\"" << file << "\", line " << line << ":" << std::endl; + } +}; + } // namespace ledger #endif // _TEXTUAL_H diff --git a/valexpr.cc b/valexpr.cc index 020be32e..00ab8f87 100644 --- a/valexpr.cc +++ b/valexpr.cc @@ -1492,6 +1492,39 @@ value_expr_t * parse_value_expr(std::istream& in, scope_t * scope, return node.release(); } +valexpr_context::valexpr_context(const ledger::value_expr_t * _expr, + const std::string& desc) throw() + : expr(NULL), error_node(_expr), error_context(desc) +{ + error_node->acquire(); +} + +valexpr_context::~valexpr_context() throw() +{ + if (expr) expr->release(); + if (error_node) error_node->release(); +} + +void valexpr_context::describe(std::ostream& out) const throw() +{ + if (! expr) { + out << "Valexpr_context expr not set!" << std::endl; + return; + } + + if (! desc.empty()) + out << desc << std::endl; + + out << " "; + unsigned long start = out.tellp(); + unsigned long pos = ledger::write_value_expr(out, expr, + error_node, start); + out << std::endl << " "; + for (int i = 0; i < pos - start; i++) + out << " "; + out << "^" << std::endl; +} + unsigned long write_value_expr(std::ostream& out, const value_expr_t * node, const value_expr_t * node_to_find, diff --git a/valexpr.h b/valexpr.h index 10e7fe5d..461a8497 100644 --- a/valexpr.h +++ b/valexpr.h @@ -188,6 +188,33 @@ struct value_expr_t } }; +class valexpr_context : public error_context { + public: + const ledger::value_expr_t * expr; + const ledger::value_expr_t * error_node; + + valexpr_context(const ledger::value_expr_t * _expr, + const std::string& desc = "") throw(); + virtual ~valexpr_context() throw(); + + virtual void describe(std::ostream& out) const throw(); +}; + +class compute_error : public error { + public: + compute_error(const std::string& reason, error_context * ctxt = NULL) throw() + : error(reason, ctxt) {} + virtual ~compute_error() throw() {} +}; + +class value_expr_error : public error { + public: + value_expr_error(const std::string& reason, + error_context * ctxt = NULL) throw() + : error(reason, ctxt) {} + virtual ~value_expr_error() throw() {} +}; + struct scope_t { scope_t * parent; diff --git a/value.cc b/value.cc index 758a9c9b..a60de5bd 100644 --- a/value.cc +++ b/value.cc @@ -1331,6 +1331,55 @@ value_t& value_t::add(const amount_t& amount, const amount_t * cost) return *this; } +value_context::value_context(const value_t& _bal, + const std::string& desc) throw() + : bal(new value_t(_bal)), error_context(desc) {} + +value_context::~value_context() throw() +{ + delete bal; +} + +void value_context::describe(std::ostream& out) const throw() +{ + if (! desc.empty()) + out << desc << std::endl; + + ledger::balance_t * ptr = NULL; + + out << std::right; + out.width(20); + + switch (bal->type) { + case ledger::value_t::BOOLEAN: + out << (*((bool *) bal->data) ? "true" : "false"); + break; + case ledger::value_t::INTEGER: + out << *((long *) bal->data); + break; + case ledger::value_t::DATETIME: + out << *((datetime_t *) bal->data); + break; + case ledger::value_t::AMOUNT: + out << *((ledger::amount_t *) bal->data); + break; + case ledger::value_t::BALANCE: + ptr = (ledger::balance_t *) bal->data; + // fall through... + + case ledger::value_t::BALANCE_PAIR: + if (! ptr) + ptr = &((ledger::balance_pair_t *) bal->data)->quantity; + + ptr->write(out, 20); + break; + default: + assert(0); + break; + } + out << std::endl; +} + } // namespace ledger #ifdef USE_BOOST_PYTHON diff --git a/value.h b/value.h index 9417b8da..b9565430 100644 --- a/value.h +++ b/value.h @@ -3,6 +3,7 @@ #include "amount.h" #include "balance.h" +#include "error.h" #include @@ -412,6 +413,24 @@ inline std::ostream& operator<<(std::ostream& out, const value_t& value) { return out; } +class value_context : public error_context +{ + value_t * bal; + public: + value_context(const value_t& _bal, + const std::string& desc = "") throw(); + virtual ~value_context() throw(); + + virtual void describe(std::ostream& out) const throw(); +}; + +class value_error : public error { + public: + value_error(const std::string& reason, error_context * ctxt = NULL) throw() + : error(reason, ctxt) {} + virtual ~value_error() throw() {} +}; + } // namespace ledger #endif // _VALUE_H diff --git a/walk.h b/walk.h index 69da7bd2..a7dc3c08 100644 --- a/walk.h +++ b/walk.h @@ -423,6 +423,14 @@ class subtotal_transactions : public item_handler virtual void operator()(transaction_t& xact); }; +class interval_expr_error : public error { + public: + interval_expr_error(const std::string& reason, + error_context * ctxt = NULL) throw() + : error(reason, ctxt) {} + virtual ~interval_expr_error() throw() {} +}; + class interval_transactions : public subtotal_transactions { interval_t interval;