diff options
author | John Wiegley <johnw@newartisans.com> | 2006-02-16 21:10:50 +0000 |
---|---|---|
committer | John Wiegley <johnw@newartisans.com> | 2008-04-13 02:41:24 -0400 |
commit | 2df14a5b86371cd8008c72f9d16421c1a404a4a8 (patch) | |
tree | 247b3e1f9628fd62e19f0758d8f7265308b1d8e2 | |
parent | 085420dd28802b8b5962c785dd31e0c28571147d (diff) | |
download | fork-ledger-2df14a5b86371cd8008c72f9d16421c1a404a4a8.tar.gz fork-ledger-2df14a5b86371cd8008c72f9d16421c1a404a4a8.tar.bz2 fork-ledger-2df14a5b86371cd8008c72f9d16421c1a404a4a8.zip |
Transactions now track their beginning and ending position, as do
entries. The new format strings %xB %xE %xb %xe can be used to
display those values relative to a transaction. The Emacs module now
relies on this support to exactly determine where a transaction is,
rather than the Elisp logic it relied on previously.
-rw-r--r-- | binary.cc | 12 | ||||
-rw-r--r-- | emacs.cc | 3 | ||||
-rw-r--r-- | format.cc | 48 | ||||
-rw-r--r-- | format.h | 12 | ||||
-rw-r--r-- | gnucash.cc | 5 | ||||
-rw-r--r-- | journal.h | 31 | ||||
-rw-r--r-- | ledger.el | 25 | ||||
-rw-r--r-- | textual.cc | 9 |
8 files changed, 98 insertions, 47 deletions
@@ -12,9 +12,9 @@ namespace ledger { static unsigned long binary_magic_number = 0xFFEED765; #ifdef DEBUG_ENABLED -static unsigned long format_version = 0x00020501; +static unsigned long format_version = 0x00020503; #else -static unsigned long format_version = 0x00020500; +static unsigned long format_version = 0x00020502; #endif static account_t ** accounts; @@ -198,6 +198,10 @@ 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); xact->data = NULL; } @@ -564,6 +568,10 @@ 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); } void write_binary_entry_base(std::ostream& out, entry_base_t * entry) @@ -47,7 +47,8 @@ void format_emacs_transactions::operator()(transaction_t& xact) out << "\n"; } - out << " (\"" << xact_account(xact)->fullname() << "\" \"" + out << " (" << (((unsigned long)xact.beg_pos) + 1) << " "; + out << "\"" << xact_account(xact)->fullname() << "\" \"" << xact.amount << "\""; switch (xact.state) { @@ -191,6 +191,17 @@ element_t * format_t::parse_elements(const std::string& fmt) break; } + case 'x': + switch (*++p) { + case 'B': current->type = element_t::XACT_BEG_POS; break; + case 'b': current->type = element_t::XACT_BEG_LINE; break; + case 'E': current->type = element_t::XACT_END_POS; break; + case 'e': current->type = element_t::XACT_END_LINE; break; + case '\0': + goto END; + } + break; + case 'd': current->type = element_t::COMPLETE_DATE_STRING; current->chars = format_t::date_format; @@ -201,10 +212,10 @@ element_t * format_t::parse_elements(const std::string& fmt) break; case 'S': current->type = element_t::SOURCE; break; - case 'B': current->type = element_t::BEG_POS; break; - case 'b': current->type = element_t::BEG_LINE; break; - case 'E': current->type = element_t::END_POS; break; - case 'e': current->type = element_t::END_LINE; break; + case 'B': current->type = element_t::ENTRY_BEG_POS; break; + case 'b': current->type = element_t::ENTRY_BEG_LINE; break; + case 'E': current->type = element_t::ENTRY_END_POS; break; + case 'e': current->type = element_t::ENTRY_END_LINE; break; case 'X': current->type = element_t::CLEARED; break; case 'Y': current->type = element_t::ENTRY_CLEARED; break; case 'C': current->type = element_t::CODE; break; @@ -222,6 +233,7 @@ element_t * format_t::parse_elements(const std::string& fmt) } } + END: if (q != buf) { if (! result.get()) { result.reset(new element_t); @@ -389,26 +401,46 @@ void format_t::format(std::ostream& out_str, const details_t& details) const } break; - case element_t::BEG_POS: + case element_t::ENTRY_BEG_POS: if (details.entry) out << (unsigned long)details.entry->beg_pos; break; - case element_t::BEG_LINE: + case element_t::ENTRY_BEG_LINE: if (details.entry) out << details.entry->beg_line; break; - case element_t::END_POS: + case element_t::ENTRY_END_POS: if (details.entry) out << (unsigned long)details.entry->end_pos; break; - case element_t::END_LINE: + case element_t::ENTRY_END_LINE: if (details.entry) out << details.entry->end_line; break; + case element_t::XACT_BEG_POS: + if (details.xact) + out << (unsigned long)details.xact->beg_pos; + break; + + case element_t::XACT_BEG_LINE: + if (details.xact) + out << details.xact->beg_line; + break; + + case element_t::XACT_END_POS: + if (details.xact) + out << (unsigned long)details.xact->end_pos; + break; + + case element_t::XACT_END_LINE: + if (details.xact) + out << details.xact->end_line; + break; + case element_t::DATE_STRING: { std::time_t date = 0; if (details.xact) @@ -19,10 +19,14 @@ struct element_t STRING, VALUE_EXPR, SOURCE, - BEG_POS, - BEG_LINE, - END_POS, - END_LINE, + ENTRY_BEG_POS, + ENTRY_BEG_LINE, + ENTRY_END_POS, + ENTRY_END_LINE, + XACT_BEG_POS, + XACT_BEG_LINE, + XACT_END_POS, + XACT_END_LINE, DATE_STRING, COMPLETE_DATE_STRING, CLEARED, @@ -189,6 +189,11 @@ static void endElement(void *userData, const char *name) if (value != curr_value) xact->cost = new amount_t(curr_value); + xact->beg_pos = beg_pos; + xact->beg_line = beg_line; + xact->end_pos = instreamp->tellg(); + xact->end_line = XML_GetCurrentLineNumber(parser) - offset; + // Clear the relevant variables for the next run curr_state = transaction_t::UNCLEARED; curr_value = amount_t(); @@ -31,23 +31,27 @@ class transaction_t public: enum state_t { UNCLEARED, CLEARED, PENDING }; - entry_t * entry; - std::time_t _date; - std::time_t _date_eff; - account_t * account; - amount_t amount; - amount_t * cost; - state_t state; - unsigned short flags; - std::string note; - mutable void * data; + entry_t * entry; + std::time_t _date; + std::time_t _date_eff; + account_t * account; + amount_t amount; + amount_t * cost; + state_t state; + unsigned short flags; + std::string note; + istream_pos_type beg_pos; + unsigned long beg_line; + istream_pos_type end_pos; + unsigned long end_line; + mutable void * data; static bool use_effective_date; transaction_t(account_t * _account = NULL) : entry(NULL), _date(0), _date_eff(0), account(_account), cost(NULL), state(UNCLEARED), flags(TRANSACTION_NORMAL), - data(NULL) { + data(NULL), beg_pos(0), beg_line(0), end_pos(0), end_line(0) { DEBUG_PRINT("ledger.memory.ctors", "ctor transaction_t"); } @@ -57,7 +61,8 @@ 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), data(NULL) { + note(_note), data(NULL), beg_pos(0), beg_line(0), end_pos(0), + end_line(0) { DEBUG_PRINT("ledger.memory.ctors", "ctor transaction_t"); } @@ -66,7 +71,7 @@ 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), - data(NULL) { + data(NULL), beg_pos(0), beg_line(0), end_pos(0), end_line(0) { DEBUG_PRINT("ledger.memory.ctors", "ctor transaction_t"); } @@ -372,15 +372,9 @@ dropped." ;; attempt to auto-reconcile in the background (with-temp-buffer (let ((exit-code - (ledger-run-ledger - buffer "--format" "%B\\n" "--reconcile" - (with-temp-buffer - (insert balance) - (goto-char (point-min)) - (while (re-search-forward "\\([&$]\\)" nil t) - (replace-match "\\\\\\1")) - (buffer-string)) - "--reconcile-date" date "register" account))) + (ledger-run-ledger buffer "--format" "%xB\\n" + "--reconcile" balance "--reconcile-date" date + "register" account))) (if (/= 0 exit-code) (error "Failed to reconcile account '%s' to balance '%s'" account balance) @@ -494,18 +488,11 @@ dropped." (nth 0 item) (if ledger-clear-whole-entries (copy-marker (nth 1 item)) - (save-excursion - (goto-char (nth 1 item)) - (let ((i 0)) - (while (< i index) - (re-search-forward - account (cdr (ledger-current-entry-bounds))) - (setq i (1+ i)))) - (point-marker))))))) + (copy-marker (nth 0 xact))))))) (insert (format "%s %-30s %-25s %15s\n" (format-time-string "%m/%d" (nth 2 item)) - (nth 4 item) (nth 0 xact) (nth 1 xact))) - (if (nth 2 xact) + (nth 4 item) (nth 1 xact) (nth 2 xact))) + (if (nth 3 xact) (set-text-properties beg (1- (point)) (list 'face 'bold 'where where)) @@ -384,6 +384,9 @@ entry_t * parse_entry(std::istream& in, char * line, account_t * master, TIMER_START(entry_xacts); while (! in.eof() && (in.peek() == ' ' || in.peek() == '\t')) { + istream_pos_type beg_pos = in.tellg(); + unsigned long beg_line = linenum; + line[0] = '\0'; in.getline(line, MAX_LINE); if (in.eof() && line[0] == '\0') @@ -400,6 +403,12 @@ entry_t * parse_entry(std::istream& in, char * line, account_t * master, if (state != transaction_t::UNCLEARED && xact->state == transaction_t::UNCLEARED) xact->state = state; + + xact->beg_pos = beg_pos; + xact->beg_line = beg_line; + xact->end_pos = in.tellg(); + xact->end_line = linenum; + curr->add_transaction(xact); } |