*** no comment ***
This commit is contained in:
parent
793dbf26d9
commit
13f375ae58
13 changed files with 273 additions and 90 deletions
|
|
@ -7,7 +7,6 @@ libledger_la_SOURCES = \
|
||||||
config.cc \
|
config.cc \
|
||||||
datetime.cc \
|
datetime.cc \
|
||||||
derive.cc \
|
derive.cc \
|
||||||
emacs.cc \
|
|
||||||
format.cc \
|
format.cc \
|
||||||
journal.cc \
|
journal.cc \
|
||||||
mask.cc \
|
mask.cc \
|
||||||
|
|
@ -21,6 +20,10 @@ libledger_la_SOURCES = \
|
||||||
valexpr.cc \
|
valexpr.cc \
|
||||||
value.cc \
|
value.cc \
|
||||||
walk.cc
|
walk.cc
|
||||||
|
if USE_EDITOR
|
||||||
|
libledger_la_CXXFLAGS += -DUSE_EDITOR=1
|
||||||
|
libledger_la_SOURCES += emacs.cc
|
||||||
|
endif
|
||||||
if HAVE_EXPAT
|
if HAVE_EXPAT
|
||||||
libledger_la_CXXFLAGS += -DHAVE_EXPAT=1
|
libledger_la_CXXFLAGS += -DHAVE_EXPAT=1
|
||||||
libledger_la_SOURCES += gnucash.cc xml.cc
|
libledger_la_SOURCES += gnucash.cc xml.cc
|
||||||
|
|
|
||||||
6
NEWS
6
NEWS
|
|
@ -3,6 +3,12 @@
|
||||||
|
|
||||||
* 2.5
|
* 2.5
|
||||||
|
|
||||||
|
- A new configure option "--disable-emacs" will disable generation of
|
||||||
|
transaction and entry location info, which is used by ledger.el and
|
||||||
|
the "write" command. If you use neither of these, then disabling
|
||||||
|
them will cut textual parsing time in half, and binary loading time
|
||||||
|
by a third.
|
||||||
|
|
||||||
- Added a new "csv" command, for outputting results in CSV format.
|
- Added a new "csv" command, for outputting results in CSV format.
|
||||||
|
|
||||||
- Added a new value expression regexp command:
|
- Added a new value expression regexp command:
|
||||||
|
|
|
||||||
4
acprep
4
acprep
|
|
@ -23,13 +23,13 @@ LIBDIRS="-L/sw/lib -L/usr/local/lib"
|
||||||
|
|
||||||
if [ "$1" = "--debug" ]; then
|
if [ "$1" = "--debug" ]; then
|
||||||
./configure CPPFLAGS="$INCDIRS" LDFLAGS="$LIBDIRS" CXXFLAGS="-g" \
|
./configure CPPFLAGS="$INCDIRS" LDFLAGS="$LIBDIRS" CXXFLAGS="-g" \
|
||||||
--enable-debug
|
--enable-debug --disable-emacs
|
||||||
elif [ "$1" = "--opt" ]; then
|
elif [ "$1" = "--opt" ]; then
|
||||||
./configure CPPFLAGS="$INCDIRS" LDFLAGS="$LIBDIRS" \
|
./configure CPPFLAGS="$INCDIRS" LDFLAGS="$LIBDIRS" \
|
||||||
CXXFLAGS="-fomit-frame-pointer -O3 -mcpu=7450 -fPIC"
|
CXXFLAGS="-fomit-frame-pointer -O3 -mcpu=7450 -fPIC"
|
||||||
elif [ "$1" = "--flat-opt" ]; then
|
elif [ "$1" = "--flat-opt" ]; then
|
||||||
./configure CPPFLAGS="$INCDIRS" LDFLAGS="$LIBDIRS" \
|
./configure CPPFLAGS="$INCDIRS" LDFLAGS="$LIBDIRS" \
|
||||||
CXXFLAGS="-fomit-frame-pointer -O3 -mcpu=7450"
|
CXXFLAGS="-fomit-frame-pointer -O3 -mcpu=7450" --disable-emacs
|
||||||
elif [ "$1" = "--safe-opt" ]; then
|
elif [ "$1" = "--safe-opt" ]; then
|
||||||
./configure CPPFLAGS="$INCDIRS" LDFLAGS="$LIBDIRS" \
|
./configure CPPFLAGS="$INCDIRS" LDFLAGS="$LIBDIRS" \
|
||||||
CXXFLAGS="-fomit-frame-pointer -O3 -mcpu=7450 -fPIC -DDEBUG_LEVEL=1"
|
CXXFLAGS="-fomit-frame-pointer -O3 -mcpu=7450 -fPIC -DDEBUG_LEVEL=1"
|
||||||
|
|
|
||||||
243
binary.cc
243
binary.cc
|
|
@ -11,11 +11,19 @@
|
||||||
namespace ledger {
|
namespace ledger {
|
||||||
|
|
||||||
static unsigned long binary_magic_number = 0xFFEED765;
|
static unsigned long binary_magic_number = 0xFFEED765;
|
||||||
|
#ifdef USE_EDITOR
|
||||||
|
#ifdef DEBUG_ENABLED
|
||||||
|
static unsigned long format_version = 0x00020583;
|
||||||
|
#else
|
||||||
|
static unsigned long format_version = 0x00020582;
|
||||||
|
#endif
|
||||||
|
#else
|
||||||
#ifdef DEBUG_ENABLED
|
#ifdef DEBUG_ENABLED
|
||||||
static unsigned long format_version = 0x00020503;
|
static unsigned long format_version = 0x00020503;
|
||||||
#else
|
#else
|
||||||
static unsigned long format_version = 0x00020502;
|
static unsigned long format_version = 0x00020502;
|
||||||
#endif
|
#endif
|
||||||
|
#endif
|
||||||
|
|
||||||
static account_t ** accounts;
|
static account_t ** accounts;
|
||||||
static account_t ** accounts_next;
|
static account_t ** accounts_next;
|
||||||
|
|
@ -45,6 +53,30 @@ inline void read_binary_number(std::istream& in, T& num) {
|
||||||
in.read((char *)&num, sizeof(num));
|
in.read((char *)&num, sizeof(num));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline void read_binary_long(std::istream& in, T& num) {
|
||||||
|
unsigned char len;
|
||||||
|
in.read((char *)&len, sizeof(unsigned char));
|
||||||
|
|
||||||
|
num = 0;
|
||||||
|
unsigned char temp;
|
||||||
|
if (len > 3) {
|
||||||
|
in.read((char *)&temp, sizeof(unsigned char));
|
||||||
|
num |= ((unsigned long)temp) << 24;
|
||||||
|
}
|
||||||
|
if (len > 2) {
|
||||||
|
in.read((char *)&temp, sizeof(unsigned char));
|
||||||
|
num |= ((unsigned long)temp) << 16;
|
||||||
|
}
|
||||||
|
if (len > 1) {
|
||||||
|
in.read((char *)&temp, sizeof(unsigned char));
|
||||||
|
num |= ((unsigned long)temp) << 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
in.read((char *)&temp, sizeof(unsigned char));
|
||||||
|
num |= ((unsigned long)temp);
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline T read_binary_number(std::istream& in) {
|
inline T read_binary_number(std::istream& in) {
|
||||||
T num;
|
T num;
|
||||||
|
|
@ -52,6 +84,13 @@ inline T read_binary_number(std::istream& in) {
|
||||||
return num;
|
return num;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline T read_binary_long(std::istream& in) {
|
||||||
|
T num;
|
||||||
|
read_binary_long(in, num);
|
||||||
|
return num;
|
||||||
|
}
|
||||||
|
|
||||||
inline void read_binary_string(std::istream& in, std::string& str)
|
inline void read_binary_string(std::istream& in, std::string& str)
|
||||||
{
|
{
|
||||||
read_binary_guard(in, 0x3001);
|
read_binary_guard(in, 0x3001);
|
||||||
|
|
@ -92,6 +131,29 @@ inline void read_binary_number(char *& data, T& num) {
|
||||||
data += sizeof(T);
|
data += sizeof(T);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline void read_binary_long(char *& data, T& num) {
|
||||||
|
unsigned char len = *((unsigned char *)data++);
|
||||||
|
|
||||||
|
num = 0;
|
||||||
|
unsigned char temp;
|
||||||
|
if (len > 3) {
|
||||||
|
temp = *((unsigned char *)data++);
|
||||||
|
num |= ((unsigned long)temp) << 24;
|
||||||
|
}
|
||||||
|
if (len > 2) {
|
||||||
|
temp = *((unsigned char *)data++);
|
||||||
|
num |= ((unsigned long)temp) << 16;
|
||||||
|
}
|
||||||
|
if (len > 1) {
|
||||||
|
temp = *((unsigned char *)data++);
|
||||||
|
num |= ((unsigned long)temp) << 8;
|
||||||
|
}
|
||||||
|
|
||||||
|
temp = *((unsigned char *)data++);
|
||||||
|
num |= ((unsigned long)temp);
|
||||||
|
}
|
||||||
|
|
||||||
template <typename T>
|
template <typename T>
|
||||||
inline T read_binary_number(char *& data) {
|
inline T read_binary_number(char *& data) {
|
||||||
T num;
|
T num;
|
||||||
|
|
@ -99,6 +161,13 @@ inline T read_binary_number(char *& data) {
|
||||||
return num;
|
return num;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline T read_binary_long(char *& data) {
|
||||||
|
T num;
|
||||||
|
read_binary_long(data, num);
|
||||||
|
return num;
|
||||||
|
}
|
||||||
|
|
||||||
inline void read_binary_string(char *& data, std::string& str)
|
inline void read_binary_string(char *& data, std::string& str)
|
||||||
{
|
{
|
||||||
#if DEBUG_LEVEL >= ALPHA
|
#if DEBUG_LEVEL >= ALPHA
|
||||||
|
|
@ -169,7 +238,7 @@ inline void read_binary_string(char *& data, std::string * str)
|
||||||
inline void read_binary_amount(char *& data, amount_t& amt)
|
inline void read_binary_amount(char *& data, amount_t& amt)
|
||||||
{
|
{
|
||||||
commodity_t::ident_t ident;
|
commodity_t::ident_t ident;
|
||||||
read_binary_number(data, ident);
|
read_binary_long(data, ident);
|
||||||
if (ident == 0xffffffff)
|
if (ident == 0xffffffff)
|
||||||
amt.commodity_ = NULL;
|
amt.commodity_ = NULL;
|
||||||
else if (ident == 0)
|
else if (ident == 0)
|
||||||
|
|
@ -182,9 +251,9 @@ inline void read_binary_amount(char *& data, amount_t& amt)
|
||||||
|
|
||||||
inline void read_binary_transaction(char *& data, transaction_t * xact)
|
inline void read_binary_transaction(char *& data, transaction_t * xact)
|
||||||
{
|
{
|
||||||
read_binary_number(data, xact->_date);
|
read_binary_long(data, xact->_date);
|
||||||
read_binary_number(data, xact->_date_eff);
|
read_binary_long(data, xact->_date_eff);
|
||||||
xact->account = accounts[read_binary_number<account_t::ident_t>(data) - 1];
|
xact->account = accounts[read_binary_long<account_t::ident_t>(data) - 1];
|
||||||
read_binary_amount(data, xact->amount);
|
read_binary_amount(data, xact->amount);
|
||||||
|
|
||||||
if (*data++ == 1) {
|
if (*data++ == 1) {
|
||||||
|
|
@ -198,10 +267,13 @@ inline void read_binary_transaction(char *& data, transaction_t * xact)
|
||||||
read_binary_number(data, xact->flags);
|
read_binary_number(data, xact->flags);
|
||||||
xact->flags |= TRANSACTION_BULK_ALLOC;
|
xact->flags |= TRANSACTION_BULK_ALLOC;
|
||||||
read_binary_string(data, &xact->note);
|
read_binary_string(data, &xact->note);
|
||||||
read_binary_number(data, xact->beg_pos);
|
|
||||||
read_binary_number(data, xact->beg_line);
|
#ifdef USE_EDITOR
|
||||||
read_binary_number(data, xact->end_pos);
|
xact->beg_pos = read_binary_long<unsigned long>(data);
|
||||||
read_binary_number(data, xact->end_line);
|
read_binary_long(data, xact->beg_line);
|
||||||
|
xact->end_pos = read_binary_long<unsigned long>(data);
|
||||||
|
read_binary_long(data, xact->end_line);
|
||||||
|
#endif
|
||||||
|
|
||||||
xact->data = NULL;
|
xact->data = NULL;
|
||||||
}
|
}
|
||||||
|
|
@ -209,13 +281,15 @@ inline void read_binary_transaction(char *& data, transaction_t * xact)
|
||||||
inline void read_binary_entry_base(char *& data, entry_base_t * entry,
|
inline void read_binary_entry_base(char *& data, entry_base_t * entry,
|
||||||
transaction_t *& xact_pool)
|
transaction_t *& xact_pool)
|
||||||
{
|
{
|
||||||
read_binary_number(data, entry->src_idx);
|
#ifdef USE_EDITOR
|
||||||
read_binary_number(data, entry->beg_pos);
|
read_binary_long(data, entry->src_idx);
|
||||||
read_binary_number(data, entry->beg_line);
|
entry->beg_pos = read_binary_long<unsigned long>(data);
|
||||||
read_binary_number(data, entry->end_pos);
|
read_binary_long(data, entry->beg_line);
|
||||||
read_binary_number(data, entry->end_line);
|
entry->end_pos = read_binary_long<unsigned long>(data);
|
||||||
|
read_binary_long(data, entry->end_line);
|
||||||
|
#endif
|
||||||
|
|
||||||
for (unsigned long i = 0, count = read_binary_number<unsigned long>(data);
|
for (unsigned long i = 0, count = read_binary_long<unsigned long>(data);
|
||||||
i < count;
|
i < count;
|
||||||
i++) {
|
i++) {
|
||||||
DEBUG_PRINT("ledger.memory.ctors", "ctor transaction_t");
|
DEBUG_PRINT("ledger.memory.ctors", "ctor transaction_t");
|
||||||
|
|
@ -228,8 +302,8 @@ inline void read_binary_entry(char *& data, entry_t * entry,
|
||||||
transaction_t *& xact_pool)
|
transaction_t *& xact_pool)
|
||||||
{
|
{
|
||||||
read_binary_entry_base(data, entry, xact_pool);
|
read_binary_entry_base(data, entry, xact_pool);
|
||||||
read_binary_number(data, entry->_date);
|
read_binary_long(data, entry->_date);
|
||||||
read_binary_number(data, entry->_date_eff);
|
read_binary_long(data, entry->_date_eff);
|
||||||
read_binary_string(data, &entry->code);
|
read_binary_string(data, &entry->code);
|
||||||
read_binary_string(data, &entry->payee);
|
read_binary_string(data, &entry->payee);
|
||||||
}
|
}
|
||||||
|
|
@ -262,7 +336,7 @@ inline commodity_t * read_binary_commodity(char *& data)
|
||||||
read_binary_string(data, commodity->note);
|
read_binary_string(data, commodity->note);
|
||||||
read_binary_number(data, commodity->precision);
|
read_binary_number(data, commodity->precision);
|
||||||
read_binary_number(data, commodity->flags);
|
read_binary_number(data, commodity->flags);
|
||||||
read_binary_number(data, commodity->ident);
|
read_binary_long(data, commodity->ident);
|
||||||
|
|
||||||
return commodity;
|
return commodity;
|
||||||
}
|
}
|
||||||
|
|
@ -272,11 +346,11 @@ inline void read_binary_commodity_extra(char *& data,
|
||||||
{
|
{
|
||||||
commodity_t * commodity = commodities[ident];
|
commodity_t * commodity = commodities[ident];
|
||||||
|
|
||||||
for (unsigned long i = 0, count = read_binary_number<unsigned long>(data);
|
for (unsigned long i = 0, count = read_binary_long<unsigned long>(data);
|
||||||
i < count;
|
i < count;
|
||||||
i++) {
|
i++) {
|
||||||
std::time_t when;
|
std::time_t when;
|
||||||
read_binary_number(data, when);
|
read_binary_long(data, when);
|
||||||
amount_t amt;
|
amount_t amt;
|
||||||
read_binary_amount(data, amt);
|
read_binary_amount(data, amt);
|
||||||
|
|
||||||
|
|
@ -288,7 +362,7 @@ inline void read_binary_commodity_extra(char *& data,
|
||||||
commodity->history->prices.insert(history_pair(when, amt));
|
commodity->history->prices.insert(history_pair(when, amt));
|
||||||
}
|
}
|
||||||
if (commodity->history)
|
if (commodity->history)
|
||||||
read_binary_number(data, commodity->history->last_lookup);
|
read_binary_long(data, commodity->history->last_lookup);
|
||||||
|
|
||||||
unsigned char flag;
|
unsigned char flag;
|
||||||
|
|
||||||
|
|
@ -314,11 +388,11 @@ account_t * read_binary_account(char *& data, journal_t * journal,
|
||||||
account_t * acct = new account_t(NULL);
|
account_t * acct = new account_t(NULL);
|
||||||
*accounts_next++ = acct;
|
*accounts_next++ = acct;
|
||||||
|
|
||||||
acct->ident = read_binary_number<account_t::ident_t>(data);
|
acct->ident = read_binary_long<account_t::ident_t>(data);
|
||||||
acct->journal = journal;
|
acct->journal = journal;
|
||||||
|
|
||||||
account_t::ident_t id;
|
account_t::ident_t id;
|
||||||
read_binary_number(data, id); // parent id
|
read_binary_long(data, id); // parent id
|
||||||
if (id == 0xffffffff)
|
if (id == 0xffffffff)
|
||||||
acct->parent = NULL;
|
acct->parent = NULL;
|
||||||
else
|
else
|
||||||
|
|
@ -338,7 +412,7 @@ account_t * read_binary_account(char *& data, journal_t * journal,
|
||||||
}
|
}
|
||||||
|
|
||||||
for (account_t::ident_t i = 0,
|
for (account_t::ident_t i = 0,
|
||||||
count = read_binary_number<account_t::ident_t>(data);
|
count = read_binary_long<account_t::ident_t>(data);
|
||||||
i < count;
|
i < count;
|
||||||
i++) {
|
i++) {
|
||||||
account_t * child = read_binary_account(data, journal);
|
account_t * child = read_binary_account(data, journal);
|
||||||
|
|
@ -370,7 +444,7 @@ unsigned int read_binary_journal(std::istream& in,
|
||||||
return 0;
|
return 0;
|
||||||
|
|
||||||
std::time_t old_mtime;
|
std::time_t old_mtime;
|
||||||
read_binary_number(in, old_mtime);
|
read_binary_long(in, old_mtime);
|
||||||
struct stat info;
|
struct stat info;
|
||||||
stat(path.c_str(), &info);
|
stat(path.c_str(), &info);
|
||||||
if (std::difftime(info.st_mtime, old_mtime) > 0)
|
if (std::difftime(info.st_mtime, old_mtime) > 0)
|
||||||
|
|
@ -397,19 +471,19 @@ unsigned int read_binary_journal(std::istream& in,
|
||||||
|
|
||||||
// Read in the accounts
|
// Read in the accounts
|
||||||
|
|
||||||
account_t::ident_t a_count = read_binary_number<account_t::ident_t>(data);
|
account_t::ident_t a_count = read_binary_long<account_t::ident_t>(data);
|
||||||
accounts = accounts_next = new account_t *[a_count];
|
accounts = accounts_next = new account_t *[a_count];
|
||||||
journal->master = read_binary_account(data, journal, master);
|
journal->master = read_binary_account(data, journal, master);
|
||||||
if (read_binary_number<bool>(data))
|
if (read_binary_number<bool>(data))
|
||||||
journal->basket = accounts[read_binary_number<account_t::ident_t>(data) - 1];
|
journal->basket = accounts[read_binary_long<account_t::ident_t>(data) - 1];
|
||||||
|
|
||||||
// Allocate the memory needed for the entries and transactions in
|
// Allocate the memory needed for the entries and transactions in
|
||||||
// one large block, which is then chopped up and custom constructed
|
// one large block, which is then chopped up and custom constructed
|
||||||
// as necessary.
|
// as necessary.
|
||||||
|
|
||||||
unsigned long count = read_binary_number<unsigned long>(data);
|
unsigned long count = read_binary_long<unsigned long>(data);
|
||||||
unsigned long auto_count = read_binary_number<unsigned long>(data);
|
unsigned long auto_count = read_binary_long<unsigned long>(data);
|
||||||
unsigned long period_count = read_binary_number<unsigned long>(data);
|
unsigned long period_count = read_binary_long<unsigned long>(data);
|
||||||
unsigned long xact_count = read_binary_number<unsigned long>(data);
|
unsigned long xact_count = read_binary_number<unsigned long>(data);
|
||||||
unsigned long bigint_count = read_binary_number<unsigned long>(data);
|
unsigned long bigint_count = read_binary_number<unsigned long>(data);
|
||||||
|
|
||||||
|
|
@ -428,7 +502,7 @@ unsigned int read_binary_journal(std::istream& in,
|
||||||
|
|
||||||
// Read in the commodities
|
// Read in the commodities
|
||||||
|
|
||||||
commodity_t::ident_t c_count = read_binary_number<commodity_t::ident_t>(data);
|
commodity_t::ident_t c_count = read_binary_long<commodity_t::ident_t>(data);
|
||||||
commodities = commodities_next = new commodity_t *[c_count];
|
commodities = commodities_next = new commodity_t *[c_count];
|
||||||
for (commodity_t::ident_t i = 0; i < c_count; i++) {
|
for (commodity_t::ident_t i = 0; i < c_count; i++) {
|
||||||
commodity_t * commodity = read_binary_commodity(data);
|
commodity_t * commodity = read_binary_commodity(data);
|
||||||
|
|
@ -446,7 +520,7 @@ unsigned int read_binary_journal(std::istream& in,
|
||||||
read_binary_commodity_extra(data, i);
|
read_binary_commodity_extra(data, i);
|
||||||
|
|
||||||
commodity_t::ident_t ident;
|
commodity_t::ident_t ident;
|
||||||
read_binary_number(data, ident);
|
read_binary_long(data, ident);
|
||||||
if (ident == 0xffffffff || ident == 0)
|
if (ident == 0xffffffff || ident == 0)
|
||||||
commodity_t::default_commodity = NULL;
|
commodity_t::default_commodity = NULL;
|
||||||
else
|
else
|
||||||
|
|
@ -490,7 +564,7 @@ unsigned int read_binary_journal(std::istream& in,
|
||||||
bool binary_parser_t::test(std::istream& in) const
|
bool binary_parser_t::test(std::istream& in) const
|
||||||
{
|
{
|
||||||
if (read_binary_number<unsigned long>(in) == binary_magic_number &&
|
if (read_binary_number<unsigned long>(in) == binary_magic_number &&
|
||||||
read_binary_number<unsigned long>(in) == format_version)
|
read_binary_long<unsigned long>(in) == format_version)
|
||||||
return true;
|
return true;
|
||||||
|
|
||||||
in.clear();
|
in.clear();
|
||||||
|
|
@ -522,6 +596,34 @@ inline void write_binary_number(std::ostream& out, T num) {
|
||||||
out.write((char *)&num, sizeof(num));
|
out.write((char *)&num, sizeof(num));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
template <typename T>
|
||||||
|
inline void write_binary_long(std::ostream& out, T num) {
|
||||||
|
unsigned char len = 4;
|
||||||
|
if (((unsigned long)num) < 0x00000100UL)
|
||||||
|
len = 1;
|
||||||
|
else if (((unsigned long)num) < 0x00010000UL)
|
||||||
|
len = 2;
|
||||||
|
else if (((unsigned long)num) < 0x01000000UL)
|
||||||
|
len = 3;
|
||||||
|
out.write((char *)&len, sizeof(unsigned char));
|
||||||
|
|
||||||
|
if (len > 3) {
|
||||||
|
unsigned char temp = (((unsigned long)num) & 0xFF000000UL) >> 24;
|
||||||
|
out.write((char *)&temp, sizeof(unsigned char));
|
||||||
|
}
|
||||||
|
if (len > 2) {
|
||||||
|
unsigned char temp = (((unsigned long)num) & 0x00FF0000UL) >> 16;
|
||||||
|
out.write((char *)&temp, sizeof(unsigned char));
|
||||||
|
}
|
||||||
|
if (len > 1) {
|
||||||
|
unsigned char temp = (((unsigned long)num) & 0x0000FF00UL) >> 8;
|
||||||
|
out.write((char *)&temp, sizeof(unsigned char));
|
||||||
|
}
|
||||||
|
|
||||||
|
unsigned char temp = (((unsigned long)num) & 0x000000FFUL);
|
||||||
|
out.write((char *)&temp, sizeof(unsigned char));
|
||||||
|
}
|
||||||
|
|
||||||
inline void write_binary_string(std::ostream& out, const std::string& str)
|
inline void write_binary_string(std::ostream& out, const std::string& str)
|
||||||
{
|
{
|
||||||
write_binary_guard(out, 0x3001);
|
write_binary_guard(out, 0x3001);
|
||||||
|
|
@ -544,18 +646,18 @@ inline void write_binary_string(std::ostream& out, const std::string& str)
|
||||||
void write_binary_amount(std::ostream& out, const amount_t& amt)
|
void write_binary_amount(std::ostream& out, const amount_t& amt)
|
||||||
{
|
{
|
||||||
if (amt.commodity_)
|
if (amt.commodity_)
|
||||||
write_binary_number(out, amt.commodity().ident);
|
write_binary_long(out, amt.commodity().ident);
|
||||||
else
|
else
|
||||||
write_binary_number<commodity_t::ident_t>(out, 0xffffffff);
|
write_binary_long<commodity_t::ident_t>(out, 0xffffffff);
|
||||||
|
|
||||||
amt.write_quantity(out);
|
amt.write_quantity(out);
|
||||||
}
|
}
|
||||||
|
|
||||||
void write_binary_transaction(std::ostream& out, transaction_t * xact)
|
void write_binary_transaction(std::ostream& out, transaction_t * xact)
|
||||||
{
|
{
|
||||||
write_binary_number(out, xact->_date);
|
write_binary_long(out, xact->_date);
|
||||||
write_binary_number(out, xact->_date_eff);
|
write_binary_long(out, xact->_date_eff);
|
||||||
write_binary_number(out, xact->account->ident);
|
write_binary_long(out, xact->account->ident);
|
||||||
write_binary_amount(out, xact->amount);
|
write_binary_amount(out, xact->amount);
|
||||||
|
|
||||||
if (xact->cost) {
|
if (xact->cost) {
|
||||||
|
|
@ -568,21 +670,26 @@ void write_binary_transaction(std::ostream& out, transaction_t * xact)
|
||||||
write_binary_number(out, xact->state);
|
write_binary_number(out, xact->state);
|
||||||
write_binary_number(out, xact->flags);
|
write_binary_number(out, xact->flags);
|
||||||
write_binary_string(out, xact->note);
|
write_binary_string(out, xact->note);
|
||||||
write_binary_number<istream_pos_type>(out, xact->beg_pos);
|
|
||||||
write_binary_number<unsigned long>(out, xact->beg_line);
|
#ifdef USE_EDITOR
|
||||||
write_binary_number<istream_pos_type>(out, xact->end_pos);
|
write_binary_long(out, xact->beg_pos);
|
||||||
write_binary_number<unsigned long>(out, xact->end_line);
|
write_binary_long(out, xact->beg_line);
|
||||||
|
write_binary_long(out, xact->end_pos);
|
||||||
|
write_binary_long(out, xact->end_line);
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
void write_binary_entry_base(std::ostream& out, entry_base_t * entry)
|
void write_binary_entry_base(std::ostream& out, entry_base_t * entry)
|
||||||
{
|
{
|
||||||
write_binary_number<unsigned long>(out, entry->src_idx);
|
#ifdef USE_EDITOR
|
||||||
write_binary_number<istream_pos_type>(out, entry->beg_pos);
|
write_binary_long(out, entry->src_idx);
|
||||||
write_binary_number<unsigned long>(out, entry->beg_line);
|
write_binary_long(out, entry->beg_pos);
|
||||||
write_binary_number<istream_pos_type>(out, entry->end_pos);
|
write_binary_long(out, entry->beg_line);
|
||||||
write_binary_number<unsigned long>(out, entry->end_line);
|
write_binary_long(out, entry->end_pos);
|
||||||
|
write_binary_long(out, entry->end_line);
|
||||||
|
#endif
|
||||||
|
|
||||||
write_binary_number<unsigned long>(out, entry->transactions.size());
|
write_binary_long(out, entry->transactions.size());
|
||||||
for (transactions_list::const_iterator i = entry->transactions.begin();
|
for (transactions_list::const_iterator i = entry->transactions.begin();
|
||||||
i != entry->transactions.end();
|
i != entry->transactions.end();
|
||||||
i++)
|
i++)
|
||||||
|
|
@ -592,8 +699,8 @@ void write_binary_entry_base(std::ostream& out, entry_base_t * entry)
|
||||||
void write_binary_entry(std::ostream& out, entry_t * entry)
|
void write_binary_entry(std::ostream& out, entry_t * entry)
|
||||||
{
|
{
|
||||||
write_binary_entry_base(out, entry);
|
write_binary_entry_base(out, entry);
|
||||||
write_binary_number(out, entry->_date);
|
write_binary_long(out, entry->_date);
|
||||||
write_binary_number(out, entry->_date_eff);
|
write_binary_long(out, entry->_date_eff);
|
||||||
write_binary_string(out, entry->code);
|
write_binary_string(out, entry->code);
|
||||||
write_binary_string(out, entry->payee);
|
write_binary_string(out, entry->payee);
|
||||||
}
|
}
|
||||||
|
|
@ -619,22 +726,22 @@ void write_binary_commodity(std::ostream& out, commodity_t * commodity)
|
||||||
write_binary_number(out, commodity->precision);
|
write_binary_number(out, commodity->precision);
|
||||||
write_binary_number(out, commodity->flags);
|
write_binary_number(out, commodity->flags);
|
||||||
commodity->ident = ++commodity_index;
|
commodity->ident = ++commodity_index;
|
||||||
write_binary_number(out, commodity->ident);
|
write_binary_long(out, commodity->ident);
|
||||||
}
|
}
|
||||||
|
|
||||||
void write_binary_commodity_extra(std::ostream& out, commodity_t * commodity)
|
void write_binary_commodity_extra(std::ostream& out, commodity_t * commodity)
|
||||||
{
|
{
|
||||||
if (! commodity->history) {
|
if (! commodity->history) {
|
||||||
write_binary_number<unsigned long>(out, 0);
|
write_binary_long<unsigned long>(out, 0);
|
||||||
} else {
|
} else {
|
||||||
write_binary_number<unsigned long>(out, commodity->history->prices.size());
|
write_binary_long<unsigned long>(out, commodity->history->prices.size());
|
||||||
for (history_map::const_iterator i = commodity->history->prices.begin();
|
for (history_map::const_iterator i = commodity->history->prices.begin();
|
||||||
i != commodity->history->prices.end();
|
i != commodity->history->prices.end();
|
||||||
i++) {
|
i++) {
|
||||||
write_binary_number(out, (*i).first);
|
write_binary_long(out, (*i).first);
|
||||||
write_binary_amount(out, (*i).second);
|
write_binary_amount(out, (*i).second);
|
||||||
}
|
}
|
||||||
write_binary_number(out, commodity->history->last_lookup);
|
write_binary_long(out, commodity->history->last_lookup);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (commodity->smaller) {
|
if (commodity->smaller) {
|
||||||
|
|
@ -668,17 +775,17 @@ void write_binary_account(std::ostream& out, account_t * account)
|
||||||
{
|
{
|
||||||
account->ident = ++account_index;
|
account->ident = ++account_index;
|
||||||
|
|
||||||
write_binary_number(out, account->ident);
|
write_binary_long(out, account->ident);
|
||||||
if (account->parent)
|
if (account->parent)
|
||||||
write_binary_number(out, account->parent->ident);
|
write_binary_long(out, account->parent->ident);
|
||||||
else
|
else
|
||||||
write_binary_number<account_t::ident_t>(out, 0xffffffff);
|
write_binary_long<account_t::ident_t>(out, 0xffffffff);
|
||||||
|
|
||||||
write_binary_string(out, account->name);
|
write_binary_string(out, account->name);
|
||||||
write_binary_string(out, account->note);
|
write_binary_string(out, account->note);
|
||||||
write_binary_number(out, account->depth);
|
write_binary_number(out, account->depth);
|
||||||
|
|
||||||
write_binary_number<account_t::ident_t>(out, account->accounts.size());
|
write_binary_long<account_t::ident_t>(out, account->accounts.size());
|
||||||
for (accounts_map::iterator i = account->accounts.begin();
|
for (accounts_map::iterator i = account->accounts.begin();
|
||||||
i != account->accounts.end();
|
i != account->accounts.end();
|
||||||
i++)
|
i++)
|
||||||
|
|
@ -691,7 +798,7 @@ void write_binary_journal(std::ostream& out, journal_t * journal)
|
||||||
commodity_index = 0;
|
commodity_index = 0;
|
||||||
|
|
||||||
write_binary_number(out, binary_magic_number);
|
write_binary_number(out, binary_magic_number);
|
||||||
write_binary_number(out, format_version);
|
write_binary_long(out, format_version);
|
||||||
|
|
||||||
// Write out the files that participated in this journal, so that
|
// Write out the files that participated in this journal, so that
|
||||||
// they can be checked for changes on reading.
|
// they can be checked for changes on reading.
|
||||||
|
|
@ -706,7 +813,7 @@ void write_binary_journal(std::ostream& out, journal_t * journal)
|
||||||
write_binary_string(out, *i);
|
write_binary_string(out, *i);
|
||||||
struct stat info;
|
struct stat info;
|
||||||
stat((*i).c_str(), &info);
|
stat((*i).c_str(), &info);
|
||||||
write_binary_number(out, std::time_t(info.st_mtime));
|
write_binary_long(out, std::time_t(info.st_mtime));
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write out the price database that relates to this data file, so
|
// Write out the price database that relates to this data file, so
|
||||||
|
|
@ -719,21 +826,21 @@ void write_binary_journal(std::ostream& out, journal_t * journal)
|
||||||
|
|
||||||
// Write out the accounts
|
// Write out the accounts
|
||||||
|
|
||||||
write_binary_number<account_t::ident_t>(out, count_accounts(journal->master));
|
write_binary_long<account_t::ident_t>(out, count_accounts(journal->master));
|
||||||
write_binary_account(out, journal->master);
|
write_binary_account(out, journal->master);
|
||||||
|
|
||||||
if (journal->basket) {
|
if (journal->basket) {
|
||||||
write_binary_number<bool>(out, true);
|
write_binary_number<bool>(out, true);
|
||||||
write_binary_number(out, journal->basket->ident);
|
write_binary_long(out, journal->basket->ident);
|
||||||
} else {
|
} else {
|
||||||
write_binary_number<bool>(out, false);
|
write_binary_number<bool>(out, false);
|
||||||
}
|
}
|
||||||
|
|
||||||
// Write out the number of entries, transactions, and amounts
|
// Write out the number of entries, transactions, and amounts
|
||||||
|
|
||||||
write_binary_number<unsigned long>(out, journal->entries.size());
|
write_binary_long<unsigned long>(out, journal->entries.size());
|
||||||
write_binary_number<unsigned long>(out, journal->auto_entries.size());
|
write_binary_long<unsigned long>(out, journal->auto_entries.size());
|
||||||
write_binary_number<unsigned long>(out, journal->period_entries.size());
|
write_binary_long<unsigned long>(out, journal->period_entries.size());
|
||||||
|
|
||||||
ostream_pos_type xacts_val = out.tellp();
|
ostream_pos_type xacts_val = out.tellp();
|
||||||
|
|
||||||
|
|
@ -744,7 +851,7 @@ void write_binary_journal(std::ostream& out, journal_t * journal)
|
||||||
|
|
||||||
// Write out the commodities
|
// Write out the commodities
|
||||||
|
|
||||||
write_binary_number<commodity_t::ident_t>
|
write_binary_long<commodity_t::ident_t>
|
||||||
(out, commodity_t::commodities.size() - 1);
|
(out, commodity_t::commodities.size() - 1);
|
||||||
|
|
||||||
for (commodities_map::const_iterator i = commodity_t::commodities.begin();
|
for (commodities_map::const_iterator i = commodity_t::commodities.begin();
|
||||||
|
|
@ -762,9 +869,9 @@ void write_binary_journal(std::ostream& out, journal_t * journal)
|
||||||
write_binary_commodity_extra(out, (*i).second);
|
write_binary_commodity_extra(out, (*i).second);
|
||||||
|
|
||||||
if (commodity_t::default_commodity)
|
if (commodity_t::default_commodity)
|
||||||
write_binary_number(out, commodity_t::default_commodity->ident);
|
write_binary_long(out, commodity_t::default_commodity->ident);
|
||||||
else
|
else
|
||||||
write_binary_number<commodity_t::ident_t>(out, 0xffffffff);
|
write_binary_long<commodity_t::ident_t>(out, 0xffffffff);
|
||||||
|
|
||||||
// Write out the entries and transactions
|
// Write out the entries and transactions
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -200,6 +200,15 @@ AC_ARG_ENABLE(debug,
|
||||||
esac],[debug=false])
|
esac],[debug=false])
|
||||||
AM_CONDITIONAL(DEBUG, test x$debug = xtrue)
|
AM_CONDITIONAL(DEBUG, test x$debug = xtrue)
|
||||||
|
|
||||||
|
AC_ARG_ENABLE(emacs,
|
||||||
|
[ --enable-emacs Turn on Emacs support],
|
||||||
|
[case "${enableval}" in
|
||||||
|
yes) emacs=true ;;
|
||||||
|
no) emacs=false ;;
|
||||||
|
*) AC_MSG_ERROR(bad value ${enableval} for --enable-emacs) ;;
|
||||||
|
esac],[emacs=true])
|
||||||
|
AM_CONDITIONAL(USE_EDITOR, test x$emacs = xtrue)
|
||||||
|
|
||||||
# Checks for header files.
|
# Checks for header files.
|
||||||
AC_STDC_HEADERS
|
AC_STDC_HEADERS
|
||||||
AC_HAVE_HEADERS(sys/stat.h)
|
AC_HAVE_HEADERS(sys/stat.h)
|
||||||
|
|
|
||||||
|
|
@ -388,6 +388,7 @@ void format_t::format(std::ostream& out_str, const details_t& details) const
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
#ifdef USE_EDITOR
|
||||||
case element_t::SOURCE:
|
case element_t::SOURCE:
|
||||||
if (details.entry && details.entry->journal) {
|
if (details.entry && details.entry->journal) {
|
||||||
int idx = details.entry->src_idx;
|
int idx = details.entry->src_idx;
|
||||||
|
|
@ -440,6 +441,7 @@ void format_t::format(std::ostream& out_str, const details_t& details) const
|
||||||
if (details.xact)
|
if (details.xact)
|
||||||
out << details.xact->end_line;
|
out << details.xact->end_line;
|
||||||
break;
|
break;
|
||||||
|
#endif
|
||||||
|
|
||||||
case element_t::DATE_STRING: {
|
case element_t::DATE_STRING: {
|
||||||
std::time_t date = 0;
|
std::time_t date = 0;
|
||||||
|
|
|
||||||
10
gnucash.cc
10
gnucash.cc
|
|
@ -45,9 +45,11 @@ static std::istream * instreamp;
|
||||||
static unsigned int offset;
|
static unsigned int offset;
|
||||||
static XML_Parser parser;
|
static XML_Parser parser;
|
||||||
static std::string path;
|
static std::string path;
|
||||||
|
#ifdef USE_EDITOR
|
||||||
static unsigned int src_idx;
|
static unsigned int src_idx;
|
||||||
static istream_pos_type beg_pos;
|
static istream_pos_type beg_pos;
|
||||||
static unsigned long beg_line;
|
static unsigned long beg_line;
|
||||||
|
#endif
|
||||||
|
|
||||||
static transaction_t::state_t curr_state;
|
static transaction_t::state_t curr_state;
|
||||||
|
|
||||||
|
|
@ -146,11 +148,13 @@ static void endElement(void *userData, const char *name)
|
||||||
have_error = "The above entry does not balance";
|
have_error = "The above entry does not balance";
|
||||||
delete curr_entry;
|
delete curr_entry;
|
||||||
} else {
|
} else {
|
||||||
|
#ifdef USE_EDITOR
|
||||||
curr_entry->src_idx = src_idx;
|
curr_entry->src_idx = src_idx;
|
||||||
curr_entry->beg_pos = beg_pos;
|
curr_entry->beg_pos = beg_pos;
|
||||||
curr_entry->beg_line = beg_line;
|
curr_entry->beg_line = beg_line;
|
||||||
curr_entry->end_pos = instreamp->tellg();
|
curr_entry->end_pos = instreamp->tellg();
|
||||||
curr_entry->end_line = XML_GetCurrentLineNumber(parser) - offset;
|
curr_entry->end_line = XML_GetCurrentLineNumber(parser) - offset;
|
||||||
|
#endif
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -189,10 +193,12 @@ static void endElement(void *userData, const char *name)
|
||||||
if (value != curr_value)
|
if (value != curr_value)
|
||||||
xact->cost = new amount_t(curr_value);
|
xact->cost = new amount_t(curr_value);
|
||||||
|
|
||||||
|
#ifdef USE_EDITOR
|
||||||
xact->beg_pos = beg_pos;
|
xact->beg_pos = beg_pos;
|
||||||
xact->beg_line = beg_line;
|
xact->beg_line = beg_line;
|
||||||
xact->end_pos = instreamp->tellg();
|
xact->end_pos = instreamp->tellg();
|
||||||
xact->end_line = XML_GetCurrentLineNumber(parser) - offset;
|
xact->end_line = XML_GetCurrentLineNumber(parser) - offset;
|
||||||
|
#endif
|
||||||
|
|
||||||
// Clear the relevant variables for the next run
|
// Clear the relevant variables for the next run
|
||||||
curr_state = transaction_t::UNCLEARED;
|
curr_state = transaction_t::UNCLEARED;
|
||||||
|
|
@ -376,7 +382,9 @@ unsigned int gnucash_parser_t::parse(std::istream& in,
|
||||||
|
|
||||||
instreamp = ∈
|
instreamp = ∈
|
||||||
path = original_file ? *original_file : "<gnucash>";
|
path = original_file ? *original_file : "<gnucash>";
|
||||||
|
#ifdef USE_EDITOR
|
||||||
src_idx = journal->sources.size() - 1;
|
src_idx = journal->sources.size() - 1;
|
||||||
|
#endif
|
||||||
|
|
||||||
// GnuCash uses the USD commodity without defining it, which really
|
// GnuCash uses the USD commodity without defining it, which really
|
||||||
// means $.
|
// means $.
|
||||||
|
|
@ -393,8 +401,10 @@ unsigned int gnucash_parser_t::parse(std::istream& in,
|
||||||
XML_SetCharacterDataHandler(parser, dataHandler);
|
XML_SetCharacterDataHandler(parser, dataHandler);
|
||||||
|
|
||||||
while (in.good() && ! in.eof()) {
|
while (in.good() && ! in.eof()) {
|
||||||
|
#ifdef USE_EDITOR
|
||||||
beg_pos = in.tellg();
|
beg_pos = in.tellg();
|
||||||
beg_line = (XML_GetCurrentLineNumber(parser) - offset) + 1;
|
beg_line = (XML_GetCurrentLineNumber(parser) - offset) + 1;
|
||||||
|
#endif
|
||||||
|
|
||||||
in.getline(buf, BUFSIZ - 1);
|
in.getline(buf, BUFSIZ - 1);
|
||||||
std::strcat(buf, "\n");
|
std::strcat(buf, "\n");
|
||||||
|
|
|
||||||
19
journal.h
19
journal.h
|
|
@ -40,10 +40,12 @@ class transaction_t
|
||||||
state_t state;
|
state_t state;
|
||||||
unsigned short flags;
|
unsigned short flags;
|
||||||
std::string note;
|
std::string note;
|
||||||
|
#ifdef USE_EDITOR
|
||||||
istream_pos_type beg_pos;
|
istream_pos_type beg_pos;
|
||||||
unsigned long beg_line;
|
unsigned long beg_line;
|
||||||
istream_pos_type end_pos;
|
istream_pos_type end_pos;
|
||||||
unsigned long end_line;
|
unsigned long end_line;
|
||||||
|
#endif
|
||||||
mutable void * data;
|
mutable void * data;
|
||||||
|
|
||||||
static bool use_effective_date;
|
static bool use_effective_date;
|
||||||
|
|
@ -51,7 +53,10 @@ class transaction_t
|
||||||
transaction_t(account_t * _account = NULL)
|
transaction_t(account_t * _account = NULL)
|
||||||
: entry(NULL), _date(0), _date_eff(0), account(_account),
|
: entry(NULL), _date(0), _date_eff(0), account(_account),
|
||||||
cost(NULL), state(UNCLEARED), flags(TRANSACTION_NORMAL),
|
cost(NULL), state(UNCLEARED), flags(TRANSACTION_NORMAL),
|
||||||
beg_pos(0), beg_line(0), end_pos(0), end_line(0), data(NULL) {
|
#ifdef USE_EDITOR
|
||||||
|
beg_pos(0), beg_line(0), end_pos(0), end_line(0),
|
||||||
|
#endif
|
||||||
|
data(NULL) {
|
||||||
DEBUG_PRINT("ledger.memory.ctors", "ctor transaction_t");
|
DEBUG_PRINT("ledger.memory.ctors", "ctor transaction_t");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -61,7 +66,10 @@ class transaction_t
|
||||||
const std::string& _note = "")
|
const std::string& _note = "")
|
||||||
: entry(NULL), _date(0), _date_eff(0), account(_account),
|
: entry(NULL), _date(0), _date_eff(0), account(_account),
|
||||||
amount(_amount), cost(NULL), state(UNCLEARED), flags(_flags),
|
amount(_amount), cost(NULL), state(UNCLEARED), flags(_flags),
|
||||||
note(_note), beg_pos(0), beg_line(0), end_pos(0), end_line(0),
|
note(_note),
|
||||||
|
#ifdef USE_EDITOR
|
||||||
|
beg_pos(0), beg_line(0), end_pos(0), end_line(0),
|
||||||
|
#endif
|
||||||
data(NULL) {
|
data(NULL) {
|
||||||
DEBUG_PRINT("ledger.memory.ctors", "ctor transaction_t");
|
DEBUG_PRINT("ledger.memory.ctors", "ctor transaction_t");
|
||||||
}
|
}
|
||||||
|
|
@ -71,7 +79,10 @@ class transaction_t
|
||||||
account(xact.account), amount(xact.amount),
|
account(xact.account), amount(xact.amount),
|
||||||
cost(xact.cost ? new amount_t(*xact.cost) : NULL),
|
cost(xact.cost ? new amount_t(*xact.cost) : NULL),
|
||||||
state(xact.state), flags(xact.flags), note(xact.note),
|
state(xact.state), flags(xact.flags), note(xact.note),
|
||||||
beg_pos(0), beg_line(0), end_pos(0), end_line(0), data(NULL) {
|
#ifdef USE_EDITOR
|
||||||
|
beg_pos(0), beg_line(0), end_pos(0), end_line(0),
|
||||||
|
#endif
|
||||||
|
data(NULL) {
|
||||||
DEBUG_PRINT("ledger.memory.ctors", "ctor transaction_t");
|
DEBUG_PRINT("ledger.memory.ctors", "ctor transaction_t");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -108,11 +119,13 @@ class entry_base_t
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
journal_t * journal;
|
journal_t * journal;
|
||||||
|
#ifdef USE_EDITOR
|
||||||
unsigned long src_idx;
|
unsigned long src_idx;
|
||||||
istream_pos_type beg_pos;
|
istream_pos_type beg_pos;
|
||||||
unsigned long beg_line;
|
unsigned long beg_line;
|
||||||
istream_pos_type end_pos;
|
istream_pos_type end_pos;
|
||||||
unsigned long end_line;
|
unsigned long end_line;
|
||||||
|
#endif
|
||||||
transactions_list transactions;
|
transactions_list transactions;
|
||||||
|
|
||||||
entry_base_t() : journal(NULL) {
|
entry_base_t() : journal(NULL) {
|
||||||
|
|
|
||||||
|
|
@ -229,7 +229,6 @@ dropped."
|
||||||
(forward-line)
|
(forward-line)
|
||||||
(while (looking-at "[ \t]")
|
(while (looking-at "[ \t]")
|
||||||
(skip-chars-forward " \t")
|
(skip-chars-forward " \t")
|
||||||
(assert (not (looking-at "[!*]")))
|
|
||||||
(insert cleared " ")
|
(insert cleared " ")
|
||||||
(if (search-forward " " (line-end-position) t)
|
(if (search-forward " " (line-end-position) t)
|
||||||
(delete-char 2))
|
(delete-char 2))
|
||||||
|
|
|
||||||
15
main.cc
15
main.cc
|
|
@ -28,6 +28,7 @@ namespace {
|
||||||
TIMER_DEF_(process);
|
TIMER_DEF_(process);
|
||||||
TIMER_DEF_(walk);
|
TIMER_DEF_(walk);
|
||||||
TIMER_DEF_(cleanup);
|
TIMER_DEF_(cleanup);
|
||||||
|
TIMER_DEF_(cache_write);
|
||||||
}
|
}
|
||||||
|
|
||||||
int parse_and_report(int argc, char * argv[], char * envp[])
|
int parse_and_report(int argc, char * argv[], char * envp[])
|
||||||
|
|
@ -105,8 +106,10 @@ int parse_and_report(int argc, char * argv[], char * envp[])
|
||||||
command = "p";
|
command = "p";
|
||||||
else if (command == "output")
|
else if (command == "output")
|
||||||
command = "w";
|
command = "w";
|
||||||
|
#ifdef USE_EDITOR
|
||||||
else if (command == "emacs")
|
else if (command == "emacs")
|
||||||
command = "x";
|
command = "x";
|
||||||
|
#endif
|
||||||
else if (command == "xml")
|
else if (command == "xml")
|
||||||
command = "X";
|
command = "X";
|
||||||
else if (command == "entry")
|
else if (command == "entry")
|
||||||
|
|
@ -244,8 +247,10 @@ int parse_and_report(int argc, char * argv[], char * envp[])
|
||||||
formatter = new set_account_value;
|
formatter = new set_account_value;
|
||||||
else if (command == "p" || command == "e")
|
else if (command == "p" || command == "e")
|
||||||
formatter = new format_entries(*out, *format);
|
formatter = new format_entries(*out, *format);
|
||||||
|
#ifdef USE_EDITOR
|
||||||
else if (command == "x")
|
else if (command == "x")
|
||||||
formatter = new format_emacs_transactions(*out);
|
formatter = new format_emacs_transactions(*out);
|
||||||
|
#endif
|
||||||
else if (command == "X") {
|
else if (command == "X") {
|
||||||
#if defined(HAVE_EXPAT) || defined(HAVE_XMLPARSE)
|
#if defined(HAVE_EXPAT) || defined(HAVE_XMLPARSE)
|
||||||
formatter = new format_xml_entries(*out, config.show_totals);
|
formatter = new format_xml_entries(*out, config.show_totals);
|
||||||
|
|
@ -256,8 +261,10 @@ int parse_and_report(int argc, char * argv[], char * envp[])
|
||||||
formatter = new format_transactions(*out, *format);
|
formatter = new format_transactions(*out, *format);
|
||||||
|
|
||||||
if (command == "w") {
|
if (command == "w") {
|
||||||
|
#ifdef USE_EDITOR
|
||||||
write_textual_journal(*journal, first_arg, *formatter,
|
write_textual_journal(*journal, first_arg, *formatter,
|
||||||
config.write_hdr_format, *out);
|
config.write_hdr_format, *out);
|
||||||
|
#endif
|
||||||
} else {
|
} else {
|
||||||
formatter = config.chain_xact_handlers(command, formatter, journal.get(),
|
formatter = config.chain_xact_handlers(command, formatter, journal.get(),
|
||||||
journal->master, formatter_ptrs);
|
journal->master, formatter_ptrs);
|
||||||
|
|
@ -318,13 +325,19 @@ int parse_and_report(int argc, char * argv[], char * envp[])
|
||||||
formatter_ptrs.clear();
|
formatter_ptrs.clear();
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
|
TIMER_STOP(cleanup);
|
||||||
|
|
||||||
// Write out the binary cache, if need be
|
// Write out the binary cache, if need be
|
||||||
|
|
||||||
|
TIMER_START(cache_write);
|
||||||
|
|
||||||
if (config.use_cache && config.cache_dirty && ! config.cache_file.empty()) {
|
if (config.use_cache && config.cache_dirty && ! config.cache_file.empty()) {
|
||||||
std::ofstream stream(config.cache_file.c_str());
|
std::ofstream stream(config.cache_file.c_str());
|
||||||
write_binary_journal(stream, journal.get());
|
write_binary_journal(stream, journal.get());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
TIMER_STOP(cache_write);
|
||||||
|
|
||||||
#ifdef HAVE_UNIX_PIPES
|
#ifdef HAVE_UNIX_PIPES
|
||||||
if (! config.pager.empty()) {
|
if (! config.pager.empty()) {
|
||||||
delete out;
|
delete out;
|
||||||
|
|
@ -337,8 +350,6 @@ int parse_and_report(int argc, char * argv[], char * envp[])
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
TIMER_STOP(cleanup);
|
|
||||||
|
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
11
parser.cc
11
parser.cc
|
|
@ -129,8 +129,7 @@ unsigned int parse_ledger_data(config_t& config,
|
||||||
! config.data_file.empty()) {
|
! config.data_file.empty()) {
|
||||||
DEBUG_PRINT("ledger.config.cache",
|
DEBUG_PRINT("ledger.config.cache",
|
||||||
"using_cache " << config.cache_file);
|
"using_cache " << config.cache_file);
|
||||||
if (config.cache_dirty)
|
config.cache_dirty = true;
|
||||||
config.cache_dirty = true;
|
|
||||||
if (access(config.cache_file.c_str(), R_OK) != -1) {
|
if (access(config.cache_file.c_str(), R_OK) != -1) {
|
||||||
std::ifstream stream(config.cache_file.c_str());
|
std::ifstream stream(config.cache_file.c_str());
|
||||||
if (cache_parser && cache_parser->test(stream)) {
|
if (cache_parser && cache_parser->test(stream)) {
|
||||||
|
|
@ -138,12 +137,10 @@ unsigned int parse_ledger_data(config_t& config,
|
||||||
journal->price_db = config.price_db;
|
journal->price_db = config.price_db;
|
||||||
entry_count += cache_parser->parse(stream, config, journal,
|
entry_count += cache_parser->parse(stream, config, journal,
|
||||||
NULL, &config.data_file);
|
NULL, &config.data_file);
|
||||||
if (entry_count > 0) {
|
if (entry_count > 0)
|
||||||
if (config.cache_dirty)
|
config.cache_dirty = false;
|
||||||
config.cache_dirty = false;
|
else
|
||||||
} else {
|
|
||||||
journal->price_db = price_db_orig;
|
journal->price_db = price_db_orig;
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
8
qif.cc
8
qif.cc
|
|
@ -63,6 +63,7 @@ unsigned int qif_parser_t::parse(std::istream& in,
|
||||||
src_idx = journal->sources.size() - 1;
|
src_idx = journal->sources.size() - 1;
|
||||||
linenum = 1;
|
linenum = 1;
|
||||||
|
|
||||||
|
#ifdef USE_EDITOR
|
||||||
istream_pos_type beg_pos = 0;
|
istream_pos_type beg_pos = 0;
|
||||||
unsigned long beg_line = 0;
|
unsigned long beg_line = 0;
|
||||||
|
|
||||||
|
|
@ -71,6 +72,9 @@ unsigned int qif_parser_t::parse(std::istream& in,
|
||||||
beg_pos = in.tellg(); \
|
beg_pos = in.tellg(); \
|
||||||
beg_line = linenum; \
|
beg_line = linenum; \
|
||||||
}
|
}
|
||||||
|
#else
|
||||||
|
#define SET_BEG_POS_AND_LINE()
|
||||||
|
#endif
|
||||||
|
|
||||||
while (in.good() && ! in.eof()) {
|
while (in.good() && ! in.eof()) {
|
||||||
char c;
|
char c;
|
||||||
|
|
@ -217,11 +221,13 @@ unsigned int qif_parser_t::parse(std::istream& in,
|
||||||
}
|
}
|
||||||
|
|
||||||
if (journal->add_entry(entry.get())) {
|
if (journal->add_entry(entry.get())) {
|
||||||
|
#ifdef USE_EDITOR
|
||||||
entry->src_idx = src_idx;
|
entry->src_idx = src_idx;
|
||||||
entry->beg_pos = beg_pos;
|
entry->beg_pos = beg_pos;
|
||||||
entry->beg_line = beg_line;
|
entry->beg_line = beg_line;
|
||||||
entry->end_pos = in.tellg();
|
entry->end_pos = in.tellg();
|
||||||
entry->end_line = linenum;
|
entry->end_line = linenum;
|
||||||
|
#endif
|
||||||
entry.release();
|
entry.release();
|
||||||
count++;
|
count++;
|
||||||
}
|
}
|
||||||
|
|
@ -234,7 +240,9 @@ unsigned int qif_parser_t::parse(std::istream& in,
|
||||||
saw_splits = false;
|
saw_splits = false;
|
||||||
saw_category = false;
|
saw_category = false;
|
||||||
total = NULL;
|
total = NULL;
|
||||||
|
#ifdef USE_EDITOR
|
||||||
beg_line = 0;
|
beg_line = 0;
|
||||||
|
#endif
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
30
textual.cc
30
textual.cc
|
|
@ -335,6 +335,7 @@ bool parse_transactions(std::istream& in,
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
TIMER_DEF(parsing_total, "total parsing time");
|
||||||
TIMER_DEF(entry_xacts, "parsing transactions");
|
TIMER_DEF(entry_xacts, "parsing transactions");
|
||||||
TIMER_DEF(entry_details, "parsing entry details");
|
TIMER_DEF(entry_details, "parsing entry details");
|
||||||
TIMER_DEF(entry_date, "parsing entry date");
|
TIMER_DEF(entry_date, "parsing entry date");
|
||||||
|
|
@ -401,8 +402,10 @@ entry_t * parse_entry(std::istream& in, char * line, account_t * master,
|
||||||
TIMER_START(entry_xacts);
|
TIMER_START(entry_xacts);
|
||||||
|
|
||||||
while (! in.eof() && (in.peek() == ' ' || in.peek() == '\t')) {
|
while (! in.eof() && (in.peek() == ' ' || in.peek() == '\t')) {
|
||||||
|
#ifdef USE_EDITOR
|
||||||
istream_pos_type beg_pos = in.tellg();
|
istream_pos_type beg_pos = in.tellg();
|
||||||
unsigned long beg_line = linenum;
|
unsigned long beg_line = linenum;
|
||||||
|
#endif
|
||||||
|
|
||||||
line[0] = '\0';
|
line[0] = '\0';
|
||||||
in.getline(line, MAX_LINE);
|
in.getline(line, MAX_LINE);
|
||||||
|
|
@ -421,10 +424,12 @@ entry_t * parse_entry(std::istream& in, char * line, account_t * master,
|
||||||
xact->state == transaction_t::UNCLEARED)
|
xact->state == transaction_t::UNCLEARED)
|
||||||
xact->state = state;
|
xact->state = state;
|
||||||
|
|
||||||
|
#ifdef USE_EDITOR
|
||||||
xact->beg_pos = beg_pos;
|
xact->beg_pos = beg_pos;
|
||||||
xact->beg_line = beg_line;
|
xact->beg_line = beg_line;
|
||||||
xact->end_pos = in.tellg();
|
xact->end_pos = in.tellg();
|
||||||
xact->end_line = linenum;
|
xact->end_line = linenum;
|
||||||
|
#endif
|
||||||
|
|
||||||
curr->add_transaction(xact);
|
curr->add_transaction(xact);
|
||||||
}
|
}
|
||||||
|
|
@ -524,6 +529,8 @@ unsigned int textual_parser_t::parse(std::istream& in,
|
||||||
unsigned int count = 0;
|
unsigned int count = 0;
|
||||||
unsigned int errors = 0;
|
unsigned int errors = 0;
|
||||||
|
|
||||||
|
TIMER_START(parsing_total);
|
||||||
|
|
||||||
std::list<account_t *> account_stack;
|
std::list<account_t *> account_stack;
|
||||||
auto_entry_finalizer_t auto_entry_finalizer(journal);
|
auto_entry_finalizer_t auto_entry_finalizer(journal);
|
||||||
|
|
||||||
|
|
@ -538,8 +545,10 @@ unsigned int textual_parser_t::parse(std::istream& in,
|
||||||
|
|
||||||
while (in.good() && ! in.eof()) {
|
while (in.good() && ! in.eof()) {
|
||||||
try {
|
try {
|
||||||
|
#ifdef USE_EDITOR
|
||||||
istream_pos_type beg_pos = in.tellg();
|
istream_pos_type beg_pos = in.tellg();
|
||||||
unsigned long beg_line = linenum;
|
unsigned long beg_line = linenum;
|
||||||
|
#endif
|
||||||
|
|
||||||
in.getline(line, MAX_LINE);
|
in.getline(line, MAX_LINE);
|
||||||
if (in.eof())
|
if (in.eof())
|
||||||
|
|
@ -693,11 +702,13 @@ unsigned int textual_parser_t::parse(std::istream& in,
|
||||||
auto_entry_t * ae = new auto_entry_t(skip_ws(line + 1));
|
auto_entry_t * ae = new auto_entry_t(skip_ws(line + 1));
|
||||||
if (parse_transactions(in, account_stack.front(), *ae, "automated")) {
|
if (parse_transactions(in, account_stack.front(), *ae, "automated")) {
|
||||||
journal->auto_entries.push_back(ae);
|
journal->auto_entries.push_back(ae);
|
||||||
|
#ifdef USE_EDITOR
|
||||||
ae->src_idx = src_idx;
|
ae->src_idx = src_idx;
|
||||||
ae->beg_pos = beg_pos;
|
ae->beg_pos = beg_pos;
|
||||||
ae->beg_line = beg_line;
|
ae->beg_line = beg_line;
|
||||||
ae->end_pos = in.tellg();
|
ae->end_pos = in.tellg();
|
||||||
ae->end_line = linenum;
|
ae->end_line = linenum;
|
||||||
|
#endif
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -712,11 +723,13 @@ unsigned int textual_parser_t::parse(std::istream& in,
|
||||||
if (pe->finalize()) {
|
if (pe->finalize()) {
|
||||||
extend_entry_base(journal, *pe);
|
extend_entry_base(journal, *pe);
|
||||||
journal->period_entries.push_back(pe);
|
journal->period_entries.push_back(pe);
|
||||||
|
#ifdef USE_EDITOR
|
||||||
pe->src_idx = src_idx;
|
pe->src_idx = src_idx;
|
||||||
pe->beg_pos = beg_pos;
|
pe->beg_pos = beg_pos;
|
||||||
pe->beg_line = beg_line;
|
pe->beg_line = beg_line;
|
||||||
pe->end_pos = in.tellg();
|
pe->end_pos = in.tellg();
|
||||||
pe->end_line = linenum;
|
pe->end_line = linenum;
|
||||||
|
#endif
|
||||||
} else {
|
} else {
|
||||||
throw parse_error(path, linenum, "Period entry failed to balance");
|
throw parse_error(path, linenum, "Period entry failed to balance");
|
||||||
}
|
}
|
||||||
|
|
@ -781,11 +794,13 @@ unsigned int textual_parser_t::parse(std::istream& in,
|
||||||
if (entry_t * entry = parse_entry(in, line, account_stack.front(),
|
if (entry_t * entry = parse_entry(in, line, account_stack.front(),
|
||||||
*this)) {
|
*this)) {
|
||||||
if (journal->add_entry(entry)) {
|
if (journal->add_entry(entry)) {
|
||||||
|
#ifdef USE_EDITOR
|
||||||
entry->src_idx = src_idx;
|
entry->src_idx = src_idx;
|
||||||
entry->beg_pos = beg_pos;
|
entry->beg_pos = beg_pos;
|
||||||
entry->beg_line = beg_line;
|
entry->beg_line = beg_line;
|
||||||
entry->end_pos = in.tellg();
|
entry->end_pos = in.tellg();
|
||||||
entry->end_line = linenum;
|
entry->end_line = linenum;
|
||||||
|
#endif
|
||||||
count++;
|
count++;
|
||||||
} else {
|
} else {
|
||||||
print_entry(std::cerr, *entry);
|
print_entry(std::cerr, *entry);
|
||||||
|
|
@ -832,9 +847,13 @@ unsigned int textual_parser_t::parse(std::istream& in,
|
||||||
if (errors > 0)
|
if (errors > 0)
|
||||||
throw error(std::string("Errors parsing file '") + path + "'");
|
throw error(std::string("Errors parsing file '") + path + "'");
|
||||||
|
|
||||||
|
TIMER_STOP(parsing_total);
|
||||||
|
|
||||||
return count;
|
return count;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#ifdef USE_EDITOR
|
||||||
|
|
||||||
void write_textual_journal(journal_t& journal, std::string path,
|
void write_textual_journal(journal_t& journal, std::string path,
|
||||||
item_handler<transaction_t>& formatter,
|
item_handler<transaction_t>& formatter,
|
||||||
const std::string& write_hdr_format,
|
const std::string& write_hdr_format,
|
||||||
|
|
@ -885,18 +904,15 @@ void write_textual_journal(journal_t& journal, std::string path,
|
||||||
|
|
||||||
while (! in.eof()) {
|
while (! in.eof()) {
|
||||||
entry_base_t * base = NULL;
|
entry_base_t * base = NULL;
|
||||||
if (el != journal.entries.end() &&
|
if (el != journal.entries.end() && pos == (*el)->beg_pos) {
|
||||||
pos == (*el)->beg_pos) {
|
|
||||||
hdr_fmt.format(out, details_t(**el));
|
hdr_fmt.format(out, details_t(**el));
|
||||||
base = *el++;
|
base = *el++;
|
||||||
}
|
}
|
||||||
else if (al != journal.auto_entries.end() &&
|
else if (al != journal.auto_entries.end() && pos == (*al)->beg_pos) {
|
||||||
pos == (*al)->beg_pos) {
|
|
||||||
out << "= " << (*al)->predicate_string << '\n';
|
out << "= " << (*al)->predicate_string << '\n';
|
||||||
base = *al++;
|
base = *al++;
|
||||||
}
|
}
|
||||||
else if (pl != journal.period_entries.end() &&
|
else if (pl != journal.period_entries.end() && pos == (*pl)->beg_pos) {
|
||||||
pos == (*pl)->beg_pos) {
|
|
||||||
out << "~ " << (*pl)->period_string << '\n';
|
out << "~ " << (*pl)->period_string << '\n';
|
||||||
base = *pl++;
|
base = *pl++;
|
||||||
}
|
}
|
||||||
|
|
@ -924,4 +940,6 @@ void write_textual_journal(journal_t& journal, std::string path,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#endif // USE_EDITOR
|
||||||
|
|
||||||
} // namespace ledger
|
} // namespace ledger
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue