cleanup; fully switched to autoconf -- use scripts/acprep

This commit is contained in:
John Wiegley 2004-08-24 02:11:32 -04:00
parent 73e2abd1b2
commit 1fd37a432d
22 changed files with 234 additions and 259 deletions

View file

@ -1,11 +1,19 @@
noinst_LIBRARIES = libledger.a noinst_LIBRARIES = libledger.a
libledger_a_CXXFLAGS = -DDEBUG_LEVEL=4 -DDO_CLEANUP
libledger_a_SOURCES = account.cc amount.cc autoxact.cc balance.cc binary.cc \ libledger_a_SOURCES = account.cc amount.cc autoxact.cc balance.cc binary.cc \
config.cc datetime.cc debug.cc format.cc ledger.cc option.cc \ config.cc datetime.cc format.cc ledger.cc option.cc parser.cc qif.cc \
parser.cc qif.cc quotes.cc textual.cc valexpr.cc value.cc walk.cc quotes.cc textual.cc valexpr.cc value.cc walk.cc
if DEBUG
libledger_a_CXXFLAGS = -DDEBUG_LEVEL=4
libledger_a_SOURCES += debug.cc
endif
if READ_GNUCASH
libledger_a_SOURCES += gnucash.cc
endif
bin_PROGRAMS = ledger bin_PROGRAMS = ledger
if DEBUG
ledger_CXXFLAGS = -DDEBUG_LEVEL=4 -DDO_CLEANUP ledger_CXXFLAGS = -DDEBUG_LEVEL=4 -DDO_CLEANUP
endif
ledger_SOURCES = main.cc ledger_SOURCES = main.cc
ledger_LDADD = $(LIBOBJS) libledger.a ledger_LDADD = $(LIBOBJS) libledger.a

View file

@ -1,82 +0,0 @@
CODE = account.cc \
amount.cc \
autoxact.cc \
balance.cc \
binary.cc \
config.cc \
datetime.cc \
debug.cc \
format.cc \
ledger.cc \
option.cc \
parser.cc \
qif.cc \
quotes.cc \
textual.cc \
valexpr.cc \
value.cc \
walk.cc
OBJS = $(patsubst %.cc,%.o,$(CODE))
#CXX = cc
CXX = g++
CFLAGS = -Wall -ansi -pedantic
#DFLAGS = -O3 -fomit-frame-pointer -DDEBUG_LEVEL=0
DFLAGS = -g -DDEBUG_LEVEL=4 -DDO_CLEANUP
#DFLAGS = -g -DDEBUG_LEVEL=2 -pg
INCS = -I/sw/include \
-I/usr/include/gcc/darwin/3.3/c++ \
-I/usr/include/gcc/darwin/3.3/c++/ppc-darwin
LIBS = -L/sw/lib -lgmp -lpcre
ifdef GNUCASH
CODE := $(CODE) gnucash.cc
OBJS := $(OBJS) gnucash.o
CFLAGS := $(CFLAGS) -DREAD_GNUCASH=1
INCS := $(INCS) -I/usr/include/httpd/xml
LIBS := $(LIBS) -L/sw/lib -lxmlparse
endif
all: make.deps ledger
docs: ledger.info ledger.pdf
libledger.a: $(OBJS)
ar rv $@ $?
ranlib $@
ledger: libledger.a main.o
$(CXX) $(CFLAGS) $(INCS) $(DFLAGS) -o $@ main.o -L. -lledger $(LIBS)
valexpr: libledger.a valexpr.cc
$(CXX) $(CFLAGS) $(INCS) $(DFLAGS) -DTEST -o $@ valexpr.cc \
-L. -lledger $(LIBS)
ledger.info: ledger.texi
makeinfo $<
ledger.pdf: ledger.texi
texi2pdf $<
%.o: %.cc
$(CXX) $(CFLAGS) $(INCS) $(DFLAGS) -c -o $@ $<
clean:
rm -f ledger valexpr libledger.a *.o *.elc *~ .\#*
rm -f *.aux *.cp *.fn *.ky *.log *.pg *.toc *.tp *.vr
rm -f .gdb_history gmon.out out
distclean fullclean: clean
rm -f *.info *.html *.pdf *.elc make.deps TAGS
rebuild: clean deps all
deps: make.deps
make.deps: Makefile.old
cc -M $(INCS) $(CODE) main.cc > $@
include make.deps

View file

@ -5,8 +5,6 @@
namespace ledger { namespace ledger {
#ifdef DO_CLEANUP
account_t::~account_t() account_t::~account_t()
{ {
DEBUG_PRINT("ledger.memory.ctors", "dtor account_t"); DEBUG_PRINT("ledger.memory.ctors", "dtor account_t");
@ -18,8 +16,6 @@ account_t::~account_t()
delete (*i).second; delete (*i).second;
} }
#endif // DO_CLEANUP
account_t * account_t::find_account(const std::string& name, account_t * account_t::find_account(const std::string& name,
const bool auto_create) const bool auto_create)
{ {

View file

@ -5,6 +5,7 @@
#include "debug.h" #include "debug.h"
#include <deque> #include <deque>
#include <sstream>
#include "gmp.h" #include "gmp.h"
@ -43,21 +44,37 @@ static mpz_t temp;
static mpz_t divisor; static mpz_t divisor;
static mpz_t true_value; static mpz_t true_value;
static struct init_amounts { commodity_t::updater_t * commodity_t::updater;
init_amounts() { commodities_map commodity_t::commodities;
mpz_init(temp); commodity_t * commodity_t::null_commodity;
mpz_init(divisor);
mpz_init(true_value); void initialize_amounts()
mpz_set_ui(true_value, 1); {
} mpz_init(temp);
#ifdef DO_CLEANUP mpz_init(divisor);
~init_amounts() { mpz_init(true_value);
mpz_clear(true_value); mpz_set_ui(true_value, 1);
mpz_clear(divisor);
mpz_clear(temp); commodity_t::updater = NULL;
} commodity_t::null_commodity = commodity_t::find_commodity("", true);
#endif }
} _init;
void shutdown_amounts()
{
mpz_clear(true_value);
mpz_clear(divisor);
mpz_clear(temp);
if (commodity_t::updater)
delete commodity_t::updater;
for (commodities_map::iterator i = commodity_t::commodities.begin();
i != commodity_t::commodities.end();
i++)
delete (*i).second;
commodity_t::commodities.clear();
}
static void mpz_round(mpz_t out, mpz_t value, int value_prec, int round_prec) static void mpz_round(mpz_t out, mpz_t value, int value_prec, int round_prec)
{ {
@ -549,6 +566,12 @@ amount_t& amount_t::operator*=(const amount_t& amt)
mpz_mul(MPZ(quantity), MPZ(quantity), MPZ(amt.quantity)); mpz_mul(MPZ(quantity), MPZ(quantity), MPZ(amt.quantity));
quantity->prec += amt.quantity->prec; quantity->prec += amt.quantity->prec;
if (quantity->prec > commodity->precision + 6U) {
mpz_round(MPZ(quantity), MPZ(quantity),
quantity->prec, commodity->precision + 6U);
quantity->prec = commodity->precision + 6U;
}
return *this; return *this;
} }
@ -568,6 +591,12 @@ amount_t& amount_t::operator/=(const amount_t& amt)
mpz_tdiv_q(MPZ(quantity), MPZ(quantity), MPZ(amt.quantity)); mpz_tdiv_q(MPZ(quantity), MPZ(quantity), MPZ(amt.quantity));
quantity->prec += 6; quantity->prec += 6;
if (quantity->prec > commodity->precision + 6U) {
mpz_round(MPZ(quantity), MPZ(quantity),
quantity->prec, commodity->precision + 6U);
quantity->prec = commodity->precision + 6U;
}
return *this; return *this;
} }
@ -712,6 +741,10 @@ std::ostream& operator<<(std::ostream& _out, const amount_t& amt)
mpz_clear(rquotient); mpz_clear(rquotient);
mpz_clear(remainder); mpz_clear(remainder);
// Things are output to a string first, so that if anyone has
// specified a width or fill for _out, it will be applied to the
// entire amount string, and not just the first part.
_out << out.str(); _out << out.str();
return _out; return _out;
@ -831,6 +864,12 @@ void amount_t::parse(std::istream& in)
delete[] buf; delete[] buf;
} }
void amount_t::parse(const std::string& str)
{
std::istringstream stream(str);
parse(stream);
}
static char buf[4096]; static char buf[4096];
static int index = 0; static int index = 0;
@ -912,27 +951,6 @@ void amount_t::read_quantity(std::istream& in)
} }
commodity_t::updater_t * commodity_t::updater = NULL;
commodities_map commodity_t::commodities;
commodity_t * commodity_t::null_commodity =
commodity_t::find_commodity("", true);
#ifdef DO_CLEANUP
static struct cleanup_t
{
~cleanup_t() {
if (commodity_t::updater)
delete commodity_t::updater;
for (commodities_map::iterator i
= commodity_t::commodities.begin();
i != commodity_t::commodities.end();
i++)
delete (*i).second;
}
} _cleanup;
#endif
commodity_t * commodity_t::find_commodity(const std::string& symbol, commodity_t * commodity_t::find_commodity(const std::string& symbol,
bool auto_create) bool auto_create)
{ {

View file

@ -5,7 +5,6 @@
#include <string> #include <string>
#include <ctime> #include <ctime>
#include <iostream> #include <iostream>
#include <sstream>
#include "debug.h" #include "debug.h"
@ -163,10 +162,7 @@ class amount_t
} }
void parse(std::istream& in); void parse(std::istream& in);
void parse(const std::string& str) { void parse(const std::string& str);
std::istringstream stream(str);
parse(stream);
}
void write_quantity(std::ostream& out) const; void write_quantity(std::ostream& out) const;
void read_quantity(std::istream& in); void read_quantity(std::istream& in);

View file

@ -296,14 +296,12 @@ unsigned int read_binary_journal(std::istream& in,
journal->entries.push_back(entry_pool++); journal->entries.push_back(entry_pool++);
} }
#ifdef DO_CLEANUP
journal->item_pool = item_pool; journal->item_pool = item_pool;
journal->item_pool_end = item_pool + pool_size; journal->item_pool_end = item_pool + pool_size;
accounts.clear(); accounts.clear();
commodities.clear(); commodities.clear();
bigints.clear(); bigints.clear();
#endif
return count; return count;
} }

View file

@ -7,8 +7,7 @@ config_t * config = NULL;
std::string bal_fmt = "%20T %2_%-n\n"; std::string bal_fmt = "%20T %2_%-n\n";
std::string reg_fmt std::string reg_fmt
= "%D %-.20P %-.22N %12.66t %12.80T\n\ = "%D %-.20P %-.22N %12.66t %12.80T\n%/%32|%-.22N %12.66t %12.80T\n";
%/ %-.22N %12.66t %12.80T\n";
std::string plot_value_fmt = "%D %t\n"; std::string plot_value_fmt = "%D %t\n";
std::string plot_total_fmt = "%D %T\n"; std::string plot_total_fmt = "%D %T\n";
std::string print_fmt std::string print_fmt

View file

@ -13,9 +13,26 @@ AC_PROG_MAKE_SET
AC_PROG_RANLIB AC_PROG_RANLIB
# Checks for libraries. # Checks for libraries.
AC_CHECK_LIB([gmp], [__gmpz_add],, [AC_MSG_FAILURE("Could not find libgmp!")]) AC_CHECK_LIB([gmp], [__gmpz_add], [],
AC_CHECK_LIB([pcre], [pcre_compile],, [AC_MSG_FAILURE("Could not find libpcre!")]) AC_MSG_FAILURE("Could not find gmp (GNU multi-precision) library"))
AC_CHECK_LIB([xmlparse], [XML_ParserCreate]) AC_CHECK_LIB([pcre], [pcre_compile], [],
AC_MSG_FAILURE("Could not find pcre (Perl regular expression) library"))
AC_CHECK_LIB([xmlparse], [XML_ParserCreate],
[AC_DEFINE([READ_GNUCASH], [1], [Support reading gnucash files])
AM_CONDITIONAL(READ_GNUCASH, true)
AC_SUBST(LIBS, "-lxmlparse -lxmltok $LIBS")],
AC_MSG_NOTICE([Could not find xmlparse library; gnucash support disabled]),
[-lxmltok])
# Check for options
AC_ARG_ENABLE(debug,
[ --enable-debug Turn on debugging],
[case "${enableval}" in
yes) debug=true ;;
no) debug=false ;;
*) AC_MSG_ERROR(bad value ${enableval} for --enable-debug) ;;
esac],[debug=false])
AM_CONDITIONAL(DEBUG, test x$debug = xtrue)
# Checks for header files. # Checks for header files.
AC_STDC_HEADERS AC_STDC_HEADERS

View file

@ -86,8 +86,11 @@ static void parse_inclusion_specifier(const std::string& word,
if (when.tm_mday == -1) if (when.tm_mday == -1)
when.tm_mday = 1; when.tm_mday = 1;
*begin = std::mktime(&when); if (begin)
*end = interval_t(0, saw_mon ? 1 : 0, saw_year ? 1 : 0).increment(*begin); *begin = std::mktime(&when);
if (end)
*end = interval_t(0, saw_mon ? 1 : 0,
saw_year ? 1 : 0).increment(*begin);
} }
interval_t interval_t::parse(std::istream& in, interval_t interval_t::parse(std::istream& in,
@ -166,20 +169,28 @@ interval_t interval_t::parse(std::istream& in,
if (type == "last") { if (type == "last") {
if (mon_spec) { if (mon_spec) {
*begin = interval_t(0, -1, 0).increment(*begin); if (begin)
*end = interval_t(0, -1, 0).increment(*end); *begin = interval_t(0, -1, 0).increment(*begin);
if (end)
*end = interval_t(0, -1, 0).increment(*end);
} else { } else {
*begin = interval_t(0, 0, -1).increment(*begin); if (begin)
*end = interval_t(0, 0, -1).increment(*end); *begin = interval_t(0, 0, -1).increment(*begin);
if (end)
*end = interval_t(0, 0, -1).increment(*end);
} }
} }
else if (type == "next") { else if (type == "next") {
if (mon_spec) { if (mon_spec) {
*begin = interval_t(0, 1, 0).increment(*begin); if (begin)
*end = interval_t(0, 1, 0).increment(*end); *begin = interval_t(0, 1, 0).increment(*begin);
if (end)
*end = interval_t(0, 1, 0).increment(*end);
} else { } else {
*begin = interval_t(0, 0, 1).increment(*begin); if (begin)
*end = interval_t(0, 0, 1).increment(*end); *begin = interval_t(0, 0, 1).increment(*begin);
if (end)
*end = interval_t(0, 0, 1).increment(*end);
} }
} }
} }

View file

@ -25,61 +25,59 @@ std::map<void *, int> ptrs;
void * operator new(std::size_t size) throw (std::bad_alloc) { void * operator new(std::size_t size) throw (std::bad_alloc) {
void * ptr = std::malloc(size); void * ptr = std::malloc(size);
if (DEBUG("ledger.debug.alloc")) { if (DEBUG("debug.alloc")) {
PRINT_INC("void * operator new(std::size_t size) throw (std::bad_alloc)\n"); PRINT_INC("void * operator new(std::size_t size) throw (std::bad_alloc)\n");
} }
return ptr; return ptr;
} }
void * operator new[](std::size_t size) throw (std::bad_alloc) { void * operator new[](std::size_t size) throw (std::bad_alloc) {
void * ptr = std::malloc(size); void * ptr = std::malloc(size);
if (DEBUG("ledger.debug.alloc")) { if (DEBUG("debug.alloc")) {
PRINT_INC("void * operator new[](std::size_t) throw (std::bad_alloc)\n"); PRINT_INC("void * operator new[](std::size_t) throw (std::bad_alloc)\n");
} }
return ptr; return ptr;
} }
void * operator new(std::size_t size, const std::nothrow_t&) throw() { void * operator new(std::size_t size, const std::nothrow_t&) throw() {
void * ptr = std::malloc(size); void * ptr = std::malloc(size);
if (DEBUG("ledger.debug.alloc")) { if (DEBUG("debug.alloc")) {
PRINT_INC("void * operator new(std::size_t size, const std::nothrow_t&) throw()\n"); PRINT_INC("void * operator new(std::size_t size, const std::nothrow_t&) throw()\n");
} }
return ptr; return ptr;
} }
void * operator new[](std::size_t size, const std::nothrow_t&) throw() { void * operator new[](std::size_t size, const std::nothrow_t&) throw() {
void * ptr = std::malloc(size); void * ptr = std::malloc(size);
if (DEBUG("ledger.debug.alloc")) { if (DEBUG("debug.alloc")) {
PRINT_INC("void * operator new[](std::size_t size, const std::nothrow_t&) throw()\n"); PRINT_INC("void * operator new[](std::size_t size, const std::nothrow_t&) throw()\n");
} }
return ptr; return ptr;
} }
void operator delete(void * ptr) throw() { void operator delete(void * ptr) throw() {
if (DEBUG("ledger.debug.alloc")) { if (DEBUG("debug.alloc")) {
PRINT_DEC("void operator delete(void * ptr) throw()\n"); PRINT_DEC("void operator delete(void * ptr) throw()\n");
} }
std::free(ptr); std::free(ptr);
} }
void operator delete[](void * ptr) throw() { void operator delete[](void * ptr) throw() {
if (DEBUG("ledger.debug.alloc")) { if (DEBUG("debug.alloc")) {
PRINT_DEC("void operator delete[](void * ptr) throw()\n"); PRINT_DEC("void operator delete[](void * ptr) throw()\n");
} }
std::free(ptr); std::free(ptr);
} }
void operator delete(void * ptr, const std::nothrow_t&) throw() { void operator delete(void * ptr, const std::nothrow_t&) throw() {
if (DEBUG("ledger.debug.alloc")) { if (DEBUG("debug.alloc")) {
PRINT_DEC("void operator delete(void * ptr, const std::nothrow_t&) throw()\n"); PRINT_DEC("void operator delete(void * ptr, const std::nothrow_t&) throw()\n");
} }
std::free(ptr); std::free(ptr);
} }
void operator delete[](void * ptr, const std::nothrow_t&) throw() { void operator delete[](void * ptr, const std::nothrow_t&) throw() {
if (DEBUG("ledger.debug.alloc")) { if (DEBUG("debug.alloc")) {
PRINT_DEC("void operator delete[](void * ptr, const std::nothrow_t&) throw()\n"); PRINT_DEC("void operator delete[](void * ptr, const std::nothrow_t&) throw()\n");
} }
std::free(ptr); std::free(ptr);
} }
namespace ledger { std::ostream * _debug_stream = &std::cerr;
bool _free_debug_stream = false;
std::ostream * debug_stream = &std::cerr;
bool free_debug_stream = false;
bool _debug_active(const char * const cls) { bool _debug_active(const char * const cls) {
if (char * debug = std::getenv("DEBUG_CLASS")) { if (char * debug = std::getenv("DEBUG_CLASS")) {
@ -99,18 +97,16 @@ static struct init_streams {
// If debugging is enabled and DEBUG_FILE is set, all debugging // If debugging is enabled and DEBUG_FILE is set, all debugging
// output goes to that file. // output goes to that file.
if (const char * p = std::getenv("DEBUG_FILE")) { if (const char * p = std::getenv("DEBUG_FILE")) {
debug_stream = new std::ofstream(p); _debug_stream = new std::ofstream(p);
free_debug_stream = true; _free_debug_stream = true;
} }
} }
~init_streams() { ~init_streams() {
if (free_debug_stream && debug_stream) { if (_free_debug_stream && _debug_stream) {
delete debug_stream; delete _debug_stream;
debug_stream = NULL; _debug_stream = NULL;
} }
} }
} _debug_init; } _debug_init;
} // namespace ledger
#endif // DEBUG_ENABLED #endif // DEBUG_ENABLED

67
debug.h
View file

@ -11,26 +11,13 @@
#define DEBUG_LEVEL RELEASE #define DEBUG_LEVEL RELEASE
#endif #endif
#if DEBUG_LEVEL >= ALPHA
#include <cstdlib> // for `getenv'
#include <cstring> // for `strcmp'
#endif
#if DEBUG_LEVEL >= BETA #if DEBUG_LEVEL >= BETA
#include <cassert> #include <cassert>
#endif #endif
#if DEBUG_LEVEL >= RELEASE
#include <iostream>
#endif
#include <sstream> // used for constructing exceptions
namespace ledger {
////////////////////////////////////////////////////////////////////// //////////////////////////////////////////////////////////////////////
// //
// Debugging facilities for Ledger // General debugging facilities
// //
// - In developer level, all checking and debugging facilities are // - In developer level, all checking and debugging facilities are
// active. // active.
@ -47,37 +34,30 @@ namespace ledger {
// - Running with no seatbelt disables all checking except for normal // - Running with no seatbelt disables all checking except for normal
// syntax and semantic error checking. // syntax and semantic error checking.
#define WARN(x) \
if (ledger::warning_stream) \
*ledger::warning_stream << "Warning: "<< x << std::endl
#define ERR(exc, x) { \
std::ostringstream s; \
s << x; \
throw exc(s.str().c_str()); \
}
#if DEBUG_LEVEL >= ALPHA #if DEBUG_LEVEL >= ALPHA
#include <pcre.h> #include <pcre.h>
#include <cstring> #include <cstring>
#include <new>
#include <iostream>
#include <cstdlib>
#include <ctime>
#define DEBUG_ENABLED #define DEBUG_ENABLED
extern std::ostream * warning_stream; extern std::ostream * _debug_stream;
extern std::ostream * debug_stream; extern bool _free_debug_stream;
extern bool free_debug_stream;
bool _debug_active(const char * const cls); bool _debug_active(const char * const cls);
#define DEBUG_CLASS(cls) static const char * const _debug_cls = (cls) #define DEBUG_CLASS(cls) static const char * const _debug_cls = (cls)
#define DEBUG(cls) (ledger::_debug_active(cls)) #define DEBUG(cls) (_debug_active(cls))
#define DEBUG_() DEBUG(_debug_cls) #define DEBUG_() DEBUG(_debug_cls)
#define DEBUG_PRINT(cls, x) \ #define DEBUG_PRINT(cls, x) \
if (ledger::debug_stream && ledger::_debug_active(cls)) { \ if (_debug_stream && _debug_active(cls)) { \
*ledger::debug_stream << x << std::endl; \ *_debug_stream << x << std::endl; \
} }
#define DEBUG_PRINT_(x) DEBUG_PRINT(_debug_cls, x) #define DEBUG_PRINT_(x) DEBUG_PRINT(_debug_cls, x)
@ -97,6 +77,15 @@ bool _debug_active(const char * const cls);
#define VALIDATE(x) #define VALIDATE(x)
#endif #endif
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();
#else // DEBUG_LEVEL #else // DEBUG_LEVEL
#define DEBUG_CLASS(cls) #define DEBUG_CLASS(cls)
@ -117,7 +106,6 @@ bool _debug_active(const char * const cls);
#elif DEBUG_LEVEL >= RELEASE #elif DEBUG_LEVEL >= RELEASE
extern std::ostream * warning_stream;
#define CONFIRM(x) #define CONFIRM(x)
#elif DEBUG_LEVEL >= BETA #elif DEBUG_LEVEL >= BETA
@ -128,19 +116,4 @@ extern std::ostream * warning_stream;
#endif // DEBUG_LEVEL #endif // DEBUG_LEVEL
} // namespace ledger
#ifdef DEBUG_ENABLED
void * operator new(std::size_t) throw (std::bad_alloc);
void * operator new[](std::size_t) throw (std::bad_alloc);
void operator delete(void*) throw();
void operator delete[](void*) throw();
void * operator new(std::size_t, const std::nothrow_t&) throw();
void * operator new[](std::size_t, const std::nothrow_t&) throw();
void operator delete(void*, const std::nothrow_t&) throw();
void operator delete[](void*, const std::nothrow_t&) throw();
#endif // DEBUG_ENABLED
#endif // _DEBUG_H #endif // _DEBUG_H

View file

@ -5,6 +5,7 @@
#include <exception> #include <exception>
#include <string> #include <string>
#include <sstream>
namespace ledger { namespace ledger {

View file

@ -33,20 +33,24 @@ std::string partial_account_name(const account_t * account)
return name; return name;
} }
std::string format_t::date_format = "%Y/%m/%d"; std::string format_t::date_format;
value_expr_t * format_t::value_expr = NULL; value_expr_t * format_t::value_expr;
value_expr_t * format_t::total_expr = NULL; value_expr_t * format_t::total_expr;
#ifdef DO_CLEANUP void initialize_formats()
static struct cleanup_t { {
~cleanup_t() { format_t::date_format = "%Y/%m/%d";
if (format_t::value_expr) format_t::value_expr = NULL;
delete format_t::value_expr; format_t::total_expr = NULL;
if (format_t::total_expr) }
delete format_t::total_expr;
} void shutdown_formats()
} _cleanup; {
#endif if (format_t::value_expr)
delete format_t::value_expr;
if (format_t::total_expr)
delete format_t::total_expr;
}
element_t * format_t::parse_elements(const std::string& fmt) element_t * format_t::parse_elements(const std::string& fmt)
{ {
@ -164,7 +168,8 @@ element_t * format_t::parse_elements(const std::string& fmt)
case 'o': current->type = element_t::OPT_AMOUNT; break; case 'o': current->type = element_t::OPT_AMOUNT; break;
case 't': current->type = element_t::VALUE; break; case 't': current->type = element_t::VALUE; break;
case 'T': current->type = element_t::TOTAL; break; case 'T': current->type = element_t::TOTAL; break;
case '_': current->type = element_t::SPACER; break; case '|': current->type = element_t::SPACER; break;
case '_': current->type = element_t::DEPTH_SPACER; break;
} }
} }
@ -348,6 +353,10 @@ void format_t::format_elements(std::ostream& out,
break; break;
case element_t::SPACER: case element_t::SPACER:
out << " ";
break;
case element_t::DEPTH_SPACER:
for (const account_t * acct = details.account; for (const account_t * acct = details.account;
acct; acct;
acct = acct->parent) acct = acct->parent)

View file

@ -26,7 +26,8 @@ struct element_t
OPT_AMOUNT, OPT_AMOUNT,
VALUE, VALUE,
TOTAL, TOTAL,
SPACER SPACER,
DEPTH_SPACER
}; };
bool align_left; bool align_left;

View file

@ -1,5 +1,7 @@
#include "gnucash.h"
#include "ledger.h" #include "ledger.h"
#include <iostream>
#include <sstream> #include <sstream>
#include <cstring> #include <cstring>

View file

@ -8,8 +8,6 @@ namespace ledger {
const std::string version = "2.0b"; const std::string version = "2.0b";
#ifdef DO_CLEANUP
journal_t::~journal_t() journal_t::~journal_t()
{ {
DEBUG_PRINT("ledger.memory.dtors", "dtor journal_t"); DEBUG_PRINT("ledger.memory.dtors", "dtor journal_t");
@ -30,8 +28,6 @@ journal_t::~journal_t()
delete[] item_pool; delete[] item_pool;
} }
#endif // DO_CLEANUP
bool journal_t::add_entry(entry_t * entry) bool journal_t::add_entry(entry_t * entry)
{ {
entries.push_back(entry); entries.push_back(entry);
@ -184,4 +180,21 @@ entry_t * journal_t::derive_entry(strings_list::iterator i,
return added.release(); return added.release();
} }
void initialize_amounts();
void shutdown_amounts();
void initialize_formats();
void shutdown_formats();
void initialize()
{
initialize_amounts();
initialize_formats();
}
void shutdown()
{
shutdown_formats();
}
} // namespace ledger } // namespace ledger

View file

@ -54,13 +54,11 @@ class transaction_t
cost(NULL), flags(_flags), note(_note), data(NULL) { cost(NULL), flags(_flags), note(_note), data(NULL) {
} }
#ifdef DO_CLEANUP
~transaction_t() { ~transaction_t() {
//assert(! data); //assert(! data);
if (cost) if (cost)
delete cost; delete cost;
} }
#endif
}; };
@ -80,14 +78,12 @@ class entry_t
transactions_list transactions; transactions_list transactions;
entry_t() : date(-1), state(UNCLEARED) {} entry_t() : date(-1), state(UNCLEARED) {}
#ifdef DO_CLEANUP
~entry_t() { ~entry_t() {
for (transactions_list::iterator i = transactions.begin(); for (transactions_list::iterator i = transactions.begin();
i != transactions.end(); i != transactions.end();
i++) i++)
delete *i; delete *i;
} }
#endif
void add_transaction(transaction_t * xact) { void add_transaction(transaction_t * xact) {
xact->entry = this; xact->entry = this;
@ -124,9 +120,7 @@ class account_t
: parent(_parent), name(_name), note(_note), : parent(_parent), name(_name), note(_note),
depth(parent ? parent->depth + 1 : 0), data(NULL), ident(0) {} depth(parent ? parent->depth + 1 : 0), data(NULL), ident(0) {}
#ifdef DO_CLEANUP
~account_t(); ~account_t();
#endif
std::string fullname() const; std::string fullname() const;
@ -169,22 +163,16 @@ class journal_t
account_t * master; account_t * master;
entries_list entries; entries_list entries;
strings_list sources; strings_list sources;
#ifdef DO_CLEANUP
char * item_pool; char * item_pool;
char * item_pool_end; char * item_pool_end;
#endif
mutable accounts_map accounts_cache; mutable accounts_map accounts_cache;
journal_t() { journal_t() {
master = new account_t(NULL, ""); master = new account_t(NULL, "");
#ifdef DO_CLEANUP
item_pool = NULL; item_pool = NULL;
#endif
} }
#ifdef DO_CLEANUP
~journal_t(); ~journal_t();
#endif
void add_account(account_t * acct) { void add_account(account_t * acct) {
master->add_account(acct); master->add_account(acct);
@ -217,6 +205,9 @@ class journal_t
extern const std::string version; extern const std::string version;
void initialize();
void shutdown();
} // namespace ledger } // namespace ledger
#endif // _LEDGER_H #endif // _LEDGER_H

View file

@ -550,6 +550,10 @@ Inserts the results of the value expression specified by @samp{-T}.
If @samp{-T} was not specified, the current report style's value If @samp{-T} was not specified, the current report style's value
expression is used. expression is used.
@item |
Inserts a single space. This is useful if a width is specified, for
inserting a certain number of spaces.
@item _ @item _
Inserts a space for each level of an account's depth. That is, if an Inserts a space for each level of an account's depth. That is, if an
account has two parents, this construct will insert two spaces. If a account has two parents, this construct will insert two spaces. If a

12
main.cc
View file

@ -3,6 +3,7 @@
#include "textual.h" #include "textual.h"
#include "binary.h" #include "binary.h"
#include "qif.h" #include "qif.h"
#include "acconf.h"
#ifdef READ_GNUCASH #ifdef READ_GNUCASH
#include "gnucash.h" #include "gnucash.h"
#endif #endif
@ -140,6 +141,10 @@ regexps_to_predicate(std::list<std::string>::const_iterator begin,
int main(int argc, char * argv[], char * envp[]) int main(int argc, char * argv[], char * envp[])
{ {
#ifdef DO_CLEANUP
initialize();
#endif
std::auto_ptr<journal_t> journal(new journal_t); std::auto_ptr<journal_t> journal(new journal_t);
// Initialize the global configuration object for this run // Initialize the global configuration object for this run
@ -189,6 +194,9 @@ int main(int argc, char * argv[], char * envp[])
// Setup the parsers // Setup the parsers
std::auto_ptr<binary_parser_t> bin_parser(new binary_parser_t); std::auto_ptr<binary_parser_t> bin_parser(new binary_parser_t);
#ifdef READ_GNUCASH
std::auto_ptr<gnucash_parser_t> gnucash_parser(new gnucash_parser_t);
#endif
std::auto_ptr<qif_parser_t> qif_parser(new qif_parser_t); std::auto_ptr<qif_parser_t> qif_parser(new qif_parser_t);
std::auto_ptr<textual_parser_t> text_parser(new textual_parser_t); std::auto_ptr<textual_parser_t> text_parser(new textual_parser_t);
@ -626,6 +634,10 @@ int main(int argc, char * argv[], char * envp[])
TIMER_STOP(write_cache); TIMER_STOP(write_cache);
#ifdef DO_CLEANUP
shutdown();
#endif
return 0; return 0;
} }

12
scripts/acprep Executable file
View file

@ -0,0 +1,12 @@
#!/bin/sh
aclocal
if [ "$1" = "--dist" ]; then
automake -acfi
else
automake -acf
fi
autoheader
autoconf

View file

@ -370,21 +370,21 @@ inline value_expr_t * parse_value_term(const char * p) {
value_expr_t * parse_value_term(std::istream& in) value_expr_t * parse_value_term(std::istream& in)
{ {
static char buf[256];
std::auto_ptr<value_expr_t> node; std::auto_ptr<value_expr_t> node;
char c = peek_next_nonws(in); char c = peek_next_nonws(in);
if (std::isdigit(c)) { if (std::isdigit(c)) {
static char buf[2048]; READ_INTO(in, buf, 255, c, std::isdigit(c));
READ_INTO(in, buf, 2048, c, std::isdigit(c));
node.reset(new value_expr_t(value_expr_t::CONSTANT_I)); node.reset(new value_expr_t(value_expr_t::CONSTANT_I));
node->constant_i = std::atol(buf); node->constant_i = std::atol(buf);
return node.release(); return node.release();
} }
else if (c == '{') { else if (c == '{') {
static char buf[2048];
in.get(c); in.get(c);
READ_INTO(in, buf, 2048, c, c != '}'); READ_INTO(in, buf, 255, c, c != '}');
if (c == '}') if (c == '}')
in.get(c); in.get(c);
else else
@ -488,8 +488,7 @@ value_expr_t * parse_value_term(std::istream& in)
} }
} }
static char buf[4096]; READ_INTO(in, buf, 255, c, c != '/');
READ_INTO(in, buf, 4096, c, c != '/');
if (c != '/') if (c != '/')
throw value_expr_error("Missing closing '/'"); throw value_expr_error("Missing closing '/'");
@ -511,15 +510,16 @@ value_expr_t * parse_value_term(std::istream& in)
break; break;
case '[': { case '[': {
static char buf[1024]; READ_INTO(in, buf, 255, c, c != ']');
READ_INTO(in, buf, 1024, c, c != ']');
if (c != ']') if (c != ']')
throw value_expr_error("Missing ']'"); throw value_expr_error("Missing ']'");
in.get(c); in.get(c);
node.reset(new value_expr_t(value_expr_t::CONSTANT_T)); node.reset(new value_expr_t(value_expr_t::CONSTANT_T));
if (! parse_date(buf, &node->constant_t))
throw value_expr_error("Failed to parse date"); std::string datespec = buf;
std::istringstream stream(datespec);
interval_t::parse(stream, &node->constant_t, NULL);
break; break;
} }

View file

@ -165,10 +165,10 @@ class item_predicate
predicate = parse_value_expr(_predicate); predicate = parse_value_expr(_predicate);
#ifdef DEBUG_ENABLED #ifdef DEBUG_ENABLED
if (DEBUG_() && ledger::debug_stream) { if (DEBUG_() && _debug_stream) {
*ledger::debug_stream << "dump: "; *_debug_stream << "dump: ";
dump_value_expr(*ledger::debug_stream, predicate); dump_value_expr(*_debug_stream, predicate);
*ledger::debug_stream << std::endl; *_debug_stream << std::endl;
} }
#endif #endif
} }