diff options
author | John Wiegley <johnw@newartisans.com> | 2006-02-25 10:55:49 +0000 |
---|---|---|
committer | John Wiegley <johnw@newartisans.com> | 2008-04-13 02:41:26 -0400 |
commit | f2a167e0ed4e0f23ddc0ffc68ec2a549b65670ac (patch) | |
tree | cd0dd475208cb9af1e8f2c95530d7ca4b73ad766 | |
parent | 9545b22b41e06dcbee1a1368eddf709218458eb2 (diff) | |
download | fork-ledger-f2a167e0ed4e0f23ddc0ffc68ec2a549b65670ac.tar.gz fork-ledger-f2a167e0ed4e0f23ddc0ffc68ec2a549b65670ac.tar.bz2 fork-ledger-f2a167e0ed4e0f23ddc0ffc68ec2a549b65670ac.zip |
*** empty log message ***
-rw-r--r-- | Makefile.am | 5 | ||||
-rw-r--r-- | NEWS | 6 | ||||
-rwxr-xr-x | acprep | 4 | ||||
-rw-r--r-- | binary.cc | 243 | ||||
-rw-r--r-- | configure.in | 9 | ||||
-rw-r--r-- | format.cc | 2 | ||||
-rw-r--r-- | gnucash.cc | 10 | ||||
-rw-r--r-- | journal.h | 19 | ||||
-rw-r--r-- | ledger.el | 1 | ||||
-rw-r--r-- | main.cc | 15 | ||||
-rw-r--r-- | parser.cc | 11 | ||||
-rw-r--r-- | qif.cc | 8 | ||||
-rw-r--r-- | textual.cc | 30 |
13 files changed, 273 insertions, 90 deletions
diff --git a/Makefile.am b/Makefile.am index 8c52b263..2fc919af 100644 --- a/Makefile.am +++ b/Makefile.am @@ -7,7 +7,6 @@ libledger_la_SOURCES = \ config.cc \ datetime.cc \ derive.cc \ - emacs.cc \ format.cc \ journal.cc \ mask.cc \ @@ -21,6 +20,10 @@ libledger_la_SOURCES = \ valexpr.cc \ value.cc \ walk.cc +if USE_EDITOR +libledger_la_CXXFLAGS += -DUSE_EDITOR=1 +libledger_la_SOURCES += emacs.cc +endif if HAVE_EXPAT libledger_la_CXXFLAGS += -DHAVE_EXPAT=1 libledger_la_SOURCES += gnucash.cc xml.cc @@ -3,6 +3,12 @@ * 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 value expression regexp command: @@ -23,13 +23,13 @@ LIBDIRS="-L/sw/lib -L/usr/local/lib" if [ "$1" = "--debug" ]; then ./configure CPPFLAGS="$INCDIRS" LDFLAGS="$LIBDIRS" CXXFLAGS="-g" \ - --enable-debug + --enable-debug --disable-emacs elif [ "$1" = "--opt" ]; then ./configure CPPFLAGS="$INCDIRS" LDFLAGS="$LIBDIRS" \ CXXFLAGS="-fomit-frame-pointer -O3 -mcpu=7450 -fPIC" elif [ "$1" = "--flat-opt" ]; then ./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 ./configure CPPFLAGS="$INCDIRS" LDFLAGS="$LIBDIRS" \ CXXFLAGS="-fomit-frame-pointer -O3 -mcpu=7450 -fPIC -DDEBUG_LEVEL=1" @@ -11,11 +11,19 @@ namespace ledger { 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 static unsigned long format_version = 0x00020503; #else static unsigned long format_version = 0x00020502; #endif +#endif static account_t ** accounts; static account_t ** accounts_next; @@ -46,12 +54,43 @@ inline void read_binary_number(std::istream& in, T& 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> inline T read_binary_number(std::istream& in) { T num; read_binary_number(in, 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) { read_binary_guard(in, 0x3001); @@ -93,12 +132,42 @@ inline void read_binary_number(char *& data, T& num) { } 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> inline T read_binary_number(char *& data) { T num; read_binary_number(data, 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) { #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) { commodity_t::ident_t ident; - read_binary_number(data, ident); + read_binary_long(data, ident); if (ident == 0xffffffff) amt.commodity_ = NULL; 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) { - read_binary_number(data, xact->_date); - read_binary_number(data, xact->_date_eff); - xact->account = accounts[read_binary_number<account_t::ident_t>(data) - 1]; + read_binary_long(data, xact->_date); + read_binary_long(data, xact->_date_eff); + xact->account = accounts[read_binary_long<account_t::ident_t>(data) - 1]; read_binary_amount(data, xact->amount); if (*data++ == 1) { @@ -198,10 +267,13 @@ inline void read_binary_transaction(char *& data, transaction_t * xact) read_binary_number(data, xact->flags); xact->flags |= TRANSACTION_BULK_ALLOC; read_binary_string(data, &xact->note); - read_binary_number(data, xact->beg_pos); - read_binary_number(data, xact->beg_line); - read_binary_number(data, xact->end_pos); - read_binary_number(data, xact->end_line); + +#ifdef USE_EDITOR + xact->beg_pos = read_binary_long<unsigned long>(data); + 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; } @@ -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, transaction_t *& xact_pool) { - read_binary_number(data, entry->src_idx); - read_binary_number(data, entry->beg_pos); - read_binary_number(data, entry->beg_line); - read_binary_number(data, entry->end_pos); - read_binary_number(data, entry->end_line); +#ifdef USE_EDITOR + read_binary_long(data, entry->src_idx); + entry->beg_pos = read_binary_long<unsigned long>(data); + read_binary_long(data, entry->beg_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++) { 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) { read_binary_entry_base(data, entry, xact_pool); - read_binary_number(data, entry->_date); - read_binary_number(data, entry->_date_eff); + read_binary_long(data, entry->_date); + read_binary_long(data, entry->_date_eff); read_binary_string(data, &entry->code); 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_number(data, commodity->precision); read_binary_number(data, commodity->flags); - read_binary_number(data, commodity->ident); + read_binary_long(data, commodity->ident); return commodity; } @@ -272,11 +346,11 @@ inline void read_binary_commodity_extra(char *& data, { 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++) { std::time_t when; - read_binary_number(data, when); + read_binary_long(data, when); amount_t 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)); } if (commodity->history) - read_binary_number(data, commodity->history->last_lookup); + read_binary_long(data, commodity->history->last_lookup); unsigned char flag; @@ -314,11 +388,11 @@ account_t * read_binary_account(char *& data, journal_t * journal, account_t * acct = new account_t(NULL); *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; account_t::ident_t id; - read_binary_number(data, id); // parent id + read_binary_long(data, id); // parent id if (id == 0xffffffff) acct->parent = NULL; else @@ -338,7 +412,7 @@ account_t * read_binary_account(char *& data, journal_t * journal, } 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++) { account_t * child = read_binary_account(data, journal); @@ -370,7 +444,7 @@ unsigned int read_binary_journal(std::istream& in, return 0; std::time_t old_mtime; - read_binary_number(in, old_mtime); + read_binary_long(in, old_mtime); struct stat info; stat(path.c_str(), &info); 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 - 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]; journal->master = read_binary_account(data, journal, master); 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 // one large block, which is then chopped up and custom constructed // as necessary. - unsigned long count = read_binary_number<unsigned long>(data); - unsigned long auto_count = read_binary_number<unsigned long>(data); - unsigned long period_count = read_binary_number<unsigned long>(data); + unsigned long count = read_binary_long<unsigned long>(data); + unsigned long auto_count = read_binary_long<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 bigint_count = read_binary_number<unsigned long>(data); @@ -428,7 +502,7 @@ unsigned int read_binary_journal(std::istream& in, // 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]; for (commodity_t::ident_t i = 0; i < c_count; i++) { 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); commodity_t::ident_t ident; - read_binary_number(data, ident); + read_binary_long(data, ident); if (ident == 0xffffffff || ident == 0) commodity_t::default_commodity = NULL; else @@ -490,7 +564,7 @@ unsigned int read_binary_journal(std::istream& in, bool binary_parser_t::test(std::istream& in) const { 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; in.clear(); @@ -522,6 +596,34 @@ inline void write_binary_number(std::ostream& out, T 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) { 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) { if (amt.commodity_) - write_binary_number(out, amt.commodity().ident); + write_binary_long(out, amt.commodity().ident); else - write_binary_number<commodity_t::ident_t>(out, 0xffffffff); + write_binary_long<commodity_t::ident_t>(out, 0xffffffff); amt.write_quantity(out); } void write_binary_transaction(std::ostream& out, transaction_t * xact) { - write_binary_number(out, xact->_date); - write_binary_number(out, xact->_date_eff); - write_binary_number(out, xact->account->ident); + write_binary_long(out, xact->_date); + write_binary_long(out, xact->_date_eff); + write_binary_long(out, xact->account->ident); write_binary_amount(out, xact->amount); 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->flags); 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); - write_binary_number<istream_pos_type>(out, xact->end_pos); - write_binary_number<unsigned long>(out, xact->end_line); + +#ifdef USE_EDITOR + write_binary_long(out, xact->beg_pos); + 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) { - write_binary_number<unsigned long>(out, entry->src_idx); - write_binary_number<istream_pos_type>(out, entry->beg_pos); - write_binary_number<unsigned long>(out, entry->beg_line); - write_binary_number<istream_pos_type>(out, entry->end_pos); - write_binary_number<unsigned long>(out, entry->end_line); +#ifdef USE_EDITOR + write_binary_long(out, entry->src_idx); + write_binary_long(out, entry->beg_pos); + write_binary_long(out, entry->beg_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(); i != entry->transactions.end(); 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) { write_binary_entry_base(out, entry); - write_binary_number(out, entry->_date); - write_binary_number(out, entry->_date_eff); + write_binary_long(out, entry->_date); + write_binary_long(out, entry->_date_eff); write_binary_string(out, entry->code); 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->flags); 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) { if (! commodity->history) { - write_binary_number<unsigned long>(out, 0); + write_binary_long<unsigned long>(out, 0); } 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(); i != commodity->history->prices.end(); i++) { - write_binary_number(out, (*i).first); + write_binary_long(out, (*i).first); 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) { @@ -668,17 +775,17 @@ void write_binary_account(std::ostream& out, account_t * account) { account->ident = ++account_index; - write_binary_number(out, account->ident); + write_binary_long(out, account->ident); if (account->parent) - write_binary_number(out, account->parent->ident); + write_binary_long(out, account->parent->ident); 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->note); 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(); i != account->accounts.end(); i++) @@ -691,7 +798,7 @@ void write_binary_journal(std::ostream& out, journal_t * journal) commodity_index = 0; 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 // 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); struct stat 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 @@ -719,21 +826,21 @@ void write_binary_journal(std::ostream& out, journal_t * journal) // 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); if (journal->basket) { write_binary_number<bool>(out, true); - write_binary_number(out, journal->basket->ident); + write_binary_long(out, journal->basket->ident); } else { write_binary_number<bool>(out, false); } // Write out the number of entries, transactions, and amounts - write_binary_number<unsigned long>(out, journal->entries.size()); - write_binary_number<unsigned long>(out, journal->auto_entries.size()); - write_binary_number<unsigned long>(out, journal->period_entries.size()); + write_binary_long<unsigned long>(out, journal->entries.size()); + write_binary_long<unsigned long>(out, journal->auto_entries.size()); + write_binary_long<unsigned long>(out, journal->period_entries.size()); 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_binary_number<commodity_t::ident_t> + write_binary_long<commodity_t::ident_t> (out, commodity_t::commodities.size() - 1); 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); if (commodity_t::default_commodity) - write_binary_number(out, commodity_t::default_commodity->ident); + write_binary_long(out, commodity_t::default_commodity->ident); 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 diff --git a/configure.in b/configure.in index 88acb260..ce50acc5 100644 --- a/configure.in +++ b/configure.in @@ -200,6 +200,15 @@ AC_ARG_ENABLE(debug, esac],[debug=false]) 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. AC_STDC_HEADERS AC_HAVE_HEADERS(sys/stat.h) @@ -388,6 +388,7 @@ void format_t::format(std::ostream& out_str, const details_t& details) const } break; +#ifdef USE_EDITOR case element_t::SOURCE: if (details.entry && details.entry->journal) { 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) out << details.xact->end_line; break; +#endif case element_t::DATE_STRING: { std::time_t date = 0; @@ -45,9 +45,11 @@ static std::istream * instreamp; static unsigned int offset; static XML_Parser parser; static std::string path; +#ifdef USE_EDITOR static unsigned int src_idx; static istream_pos_type beg_pos; static unsigned long beg_line; +#endif 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"; delete curr_entry; } else { +#ifdef USE_EDITOR curr_entry->src_idx = src_idx; curr_entry->beg_pos = beg_pos; curr_entry->beg_line = beg_line; curr_entry->end_pos = instreamp->tellg(); curr_entry->end_line = XML_GetCurrentLineNumber(parser) - offset; +#endif count++; } @@ -189,10 +193,12 @@ static void endElement(void *userData, const char *name) if (value != curr_value) xact->cost = new amount_t(curr_value); +#ifdef USE_EDITOR xact->beg_pos = beg_pos; xact->beg_line = beg_line; xact->end_pos = instreamp->tellg(); xact->end_line = XML_GetCurrentLineNumber(parser) - offset; +#endif // Clear the relevant variables for the next run curr_state = transaction_t::UNCLEARED; @@ -376,7 +382,9 @@ unsigned int gnucash_parser_t::parse(std::istream& in, instreamp = ∈ path = original_file ? *original_file : "<gnucash>"; +#ifdef USE_EDITOR src_idx = journal->sources.size() - 1; +#endif // GnuCash uses the USD commodity without defining it, which really // means $. @@ -393,8 +401,10 @@ unsigned int gnucash_parser_t::parse(std::istream& in, XML_SetCharacterDataHandler(parser, dataHandler); while (in.good() && ! in.eof()) { +#ifdef USE_EDITOR beg_pos = in.tellg(); beg_line = (XML_GetCurrentLineNumber(parser) - offset) + 1; +#endif in.getline(buf, BUFSIZ - 1); std::strcat(buf, "\n"); @@ -40,10 +40,12 @@ class transaction_t state_t state; unsigned short flags; std::string note; +#ifdef USE_EDITOR istream_pos_type beg_pos; unsigned long beg_line; istream_pos_type end_pos; unsigned long end_line; +#endif mutable void * data; static bool use_effective_date; @@ -51,7 +53,10 @@ class transaction_t transaction_t(account_t * _account = NULL) : entry(NULL), _date(0), _date_eff(0), account(_account), 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"); } @@ -61,7 +66,10 @@ class transaction_t const std::string& _note = "") : entry(NULL), _date(0), _date_eff(0), account(_account), 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) { DEBUG_PRINT("ledger.memory.ctors", "ctor transaction_t"); } @@ -71,7 +79,10 @@ class transaction_t account(xact.account), amount(xact.amount), cost(xact.cost ? new amount_t(*xact.cost) : NULL), 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"); } @@ -108,11 +119,13 @@ class entry_base_t { public: journal_t * journal; +#ifdef USE_EDITOR unsigned long src_idx; istream_pos_type beg_pos; unsigned long beg_line; istream_pos_type end_pos; unsigned long end_line; +#endif transactions_list transactions; entry_base_t() : journal(NULL) { @@ -229,7 +229,6 @@ dropped." (forward-line) (while (looking-at "[ \t]") (skip-chars-forward " \t") - (assert (not (looking-at "[!*]"))) (insert cleared " ") (if (search-forward " " (line-end-position) t) (delete-char 2)) @@ -28,6 +28,7 @@ namespace { TIMER_DEF_(process); TIMER_DEF_(walk); TIMER_DEF_(cleanup); + TIMER_DEF_(cache_write); } 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"; else if (command == "output") command = "w"; +#ifdef USE_EDITOR else if (command == "emacs") command = "x"; +#endif else if (command == "xml") command = "X"; else if (command == "entry") @@ -244,8 +247,10 @@ int parse_and_report(int argc, char * argv[], char * envp[]) formatter = new set_account_value; else if (command == "p" || command == "e") formatter = new format_entries(*out, *format); +#ifdef USE_EDITOR else if (command == "x") formatter = new format_emacs_transactions(*out); +#endif else if (command == "X") { #if defined(HAVE_EXPAT) || defined(HAVE_XMLPARSE) 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); if (command == "w") { +#ifdef USE_EDITOR write_textual_journal(*journal, first_arg, *formatter, config.write_hdr_format, *out); +#endif } else { formatter = config.chain_xact_handlers(command, formatter, journal.get(), journal->master, formatter_ptrs); @@ -318,13 +325,19 @@ int parse_and_report(int argc, char * argv[], char * envp[]) formatter_ptrs.clear(); #endif + TIMER_STOP(cleanup); + // Write out the binary cache, if need be + TIMER_START(cache_write); + if (config.use_cache && config.cache_dirty && ! config.cache_file.empty()) { std::ofstream stream(config.cache_file.c_str()); write_binary_journal(stream, journal.get()); } + TIMER_STOP(cache_write); + #ifdef HAVE_UNIX_PIPES if (! config.pager.empty()) { delete out; @@ -337,8 +350,6 @@ int parse_and_report(int argc, char * argv[], char * envp[]) } #endif - TIMER_STOP(cleanup); - return 0; } @@ -129,8 +129,7 @@ unsigned int parse_ledger_data(config_t& config, ! config.data_file.empty()) { DEBUG_PRINT("ledger.config.cache", "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) { std::ifstream stream(config.cache_file.c_str()); 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; entry_count += cache_parser->parse(stream, config, journal, NULL, &config.data_file); - if (entry_count > 0) { - if (config.cache_dirty) - config.cache_dirty = false; - } else { + if (entry_count > 0) + config.cache_dirty = false; + else journal->price_db = price_db_orig; - } } } } @@ -63,6 +63,7 @@ unsigned int qif_parser_t::parse(std::istream& in, src_idx = journal->sources.size() - 1; linenum = 1; +#ifdef USE_EDITOR istream_pos_type beg_pos = 0; unsigned long beg_line = 0; @@ -71,6 +72,9 @@ unsigned int qif_parser_t::parse(std::istream& in, beg_pos = in.tellg(); \ beg_line = linenum; \ } +#else +#define SET_BEG_POS_AND_LINE() +#endif while (in.good() && ! in.eof()) { char c; @@ -217,11 +221,13 @@ unsigned int qif_parser_t::parse(std::istream& in, } if (journal->add_entry(entry.get())) { +#ifdef USE_EDITOR entry->src_idx = src_idx; entry->beg_pos = beg_pos; entry->beg_line = beg_line; entry->end_pos = in.tellg(); entry->end_line = linenum; +#endif entry.release(); count++; } @@ -234,7 +240,9 @@ unsigned int qif_parser_t::parse(std::istream& in, saw_splits = false; saw_category = false; total = NULL; +#ifdef USE_EDITOR beg_line = 0; +#endif break; } @@ -335,6 +335,7 @@ bool parse_transactions(std::istream& in, } namespace { + TIMER_DEF(parsing_total, "total parsing time"); TIMER_DEF(entry_xacts, "parsing transactions"); TIMER_DEF(entry_details, "parsing entry details"); TIMER_DEF(entry_date, "parsing entry date"); @@ -401,8 +402,10 @@ entry_t * parse_entry(std::istream& in, char * line, account_t * master, TIMER_START(entry_xacts); while (! in.eof() && (in.peek() == ' ' || in.peek() == '\t')) { +#ifdef USE_EDITOR istream_pos_type beg_pos = in.tellg(); unsigned long beg_line = linenum; +#endif line[0] = '\0'; 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 = state; +#ifdef USE_EDITOR xact->beg_pos = beg_pos; xact->beg_line = beg_line; xact->end_pos = in.tellg(); xact->end_line = linenum; +#endif curr->add_transaction(xact); } @@ -524,6 +529,8 @@ unsigned int textual_parser_t::parse(std::istream& in, unsigned int count = 0; unsigned int errors = 0; + TIMER_START(parsing_total); + std::list<account_t *> account_stack; 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()) { try { +#ifdef USE_EDITOR istream_pos_type beg_pos = in.tellg(); unsigned long beg_line = linenum; +#endif in.getline(line, MAX_LINE); 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)); if (parse_transactions(in, account_stack.front(), *ae, "automated")) { journal->auto_entries.push_back(ae); +#ifdef USE_EDITOR ae->src_idx = src_idx; ae->beg_pos = beg_pos; ae->beg_line = beg_line; ae->end_pos = in.tellg(); ae->end_line = linenum; +#endif } break; } @@ -712,11 +723,13 @@ unsigned int textual_parser_t::parse(std::istream& in, if (pe->finalize()) { extend_entry_base(journal, *pe); journal->period_entries.push_back(pe); +#ifdef USE_EDITOR pe->src_idx = src_idx; pe->beg_pos = beg_pos; pe->beg_line = beg_line; pe->end_pos = in.tellg(); pe->end_line = linenum; +#endif } else { 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(), *this)) { if (journal->add_entry(entry)) { +#ifdef USE_EDITOR entry->src_idx = src_idx; entry->beg_pos = beg_pos; entry->beg_line = beg_line; entry->end_pos = in.tellg(); entry->end_line = linenum; +#endif count++; } else { print_entry(std::cerr, *entry); @@ -832,9 +847,13 @@ unsigned int textual_parser_t::parse(std::istream& in, if (errors > 0) throw error(std::string("Errors parsing file '") + path + "'"); + TIMER_STOP(parsing_total); + return count; } +#ifdef USE_EDITOR + void write_textual_journal(journal_t& journal, std::string path, item_handler<transaction_t>& formatter, const std::string& write_hdr_format, @@ -885,18 +904,15 @@ void write_textual_journal(journal_t& journal, std::string path, while (! in.eof()) { entry_base_t * base = NULL; - if (el != journal.entries.end() && - pos == (*el)->beg_pos) { + if (el != journal.entries.end() && pos == (*el)->beg_pos) { hdr_fmt.format(out, details_t(**el)); base = *el++; } - else if (al != journal.auto_entries.end() && - pos == (*al)->beg_pos) { + else if (al != journal.auto_entries.end() && pos == (*al)->beg_pos) { out << "= " << (*al)->predicate_string << '\n'; base = *al++; } - else if (pl != journal.period_entries.end() && - pos == (*pl)->beg_pos) { + else if (pl != journal.period_entries.end() && pos == (*pl)->beg_pos) { out << "~ " << (*pl)->period_string << '\n'; base = *pl++; } @@ -924,4 +940,6 @@ void write_textual_journal(journal_t& journal, std::string path, } } +#endif // USE_EDITOR + } // namespace ledger |