Merge branch 'next'
This commit is contained in:
commit
7ca8149ec5
137 changed files with 2256 additions and 349 deletions
10
.gitignore
vendored
10
.gitignore
vendored
|
|
@ -53,6 +53,16 @@
|
||||||
/doc/ledger.info
|
/doc/ledger.info
|
||||||
/doc/refman.pdf
|
/doc/refman.pdf
|
||||||
/doc/report/
|
/doc/report/
|
||||||
|
/doc/*.aux
|
||||||
|
/doc/*.cp
|
||||||
|
/doc/*.fn
|
||||||
|
/doc/*.ky
|
||||||
|
/doc/*.log
|
||||||
|
/doc/*.pdf
|
||||||
|
/doc/*.pg
|
||||||
|
/doc/*.toc
|
||||||
|
/doc/*.tp
|
||||||
|
/doc/*.vr
|
||||||
/expr_tests
|
/expr_tests
|
||||||
/libtool
|
/libtool
|
||||||
/math_tests
|
/math_tests
|
||||||
|
|
|
||||||
|
|
@ -5,7 +5,7 @@
|
||||||
|
|
||||||
@dircategory User Applications
|
@dircategory User Applications
|
||||||
@copying
|
@copying
|
||||||
Copyright (c) 2003-2009, John Wiegley. All rights reserved.
|
Copyright (c) 2003-2010, John Wiegley. All rights reserved.
|
||||||
|
|
||||||
Redistribution and use in source and binary forms, with or without
|
Redistribution and use in source and binary forms, with or without
|
||||||
modification, are permitted provided that the following conditions are
|
modification, are permitted provided that the following conditions are
|
||||||
|
|
@ -35,7 +35,7 @@ THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
@end copying
|
@end copying
|
||||||
|
|
||||||
@documentencoding iso-8859-1
|
@documentencoding utf-8
|
||||||
|
|
||||||
@iftex
|
@iftex
|
||||||
@finalout
|
@finalout
|
||||||
|
|
@ -4107,4 +4107,19 @@ parser_t
|
||||||
|
|
||||||
@section General Utility
|
@section General Utility
|
||||||
|
|
||||||
|
@c data: foo
|
||||||
|
@smallexample
|
||||||
|
2004/05/01 * Checking balance
|
||||||
|
Assets:Bank:Checking $1,000.00
|
||||||
|
Equity:Opening Balances
|
||||||
|
@end smallexample
|
||||||
|
|
||||||
|
@c smex utility-1: $LEDGER -f $foo bal
|
||||||
|
@smallexample
|
||||||
|
$1,000.00 Assets:Bank:Checking
|
||||||
|
$-1,000.00 Equity:Opening Balances
|
||||||
|
--------------------
|
||||||
|
0
|
||||||
|
@end smallexample
|
||||||
|
|
||||||
@bye
|
@bye
|
||||||
|
|
|
||||||
122
lisp/ldg-post.el
Normal file
122
lisp/ldg-post.el
Normal file
|
|
@ -0,0 +1,122 @@
|
||||||
|
(require 'ldg-regex)
|
||||||
|
|
||||||
|
(defgroup ledger-post nil
|
||||||
|
""
|
||||||
|
:group 'ledger)
|
||||||
|
|
||||||
|
(defcustom ledger-post-auto-adjust-amounts t
|
||||||
|
"If non-nil, ."
|
||||||
|
:type 'boolean
|
||||||
|
:group 'ledger-post)
|
||||||
|
|
||||||
|
(declare-function iswitchb-read-buffer "iswitchb"
|
||||||
|
(prompt &optional default require-match start matches-set))
|
||||||
|
(defvar iswitchb-temp-buflist)
|
||||||
|
|
||||||
|
(defvar ledger-post-current-list nil)
|
||||||
|
|
||||||
|
(defun ledger-post-find-all ()
|
||||||
|
(let ((origin (point))
|
||||||
|
(ledger-post-list nil)
|
||||||
|
account-path elements)
|
||||||
|
(save-excursion
|
||||||
|
(goto-char (point-min))
|
||||||
|
(while (re-search-forward
|
||||||
|
"^[ \t]+\\([*!]\\s-+\\)?[[(]?\\(.+?\\)\\(\t\\|\n\\| [ \t]\\)" nil t)
|
||||||
|
(unless (and (>= origin (match-beginning 0))
|
||||||
|
(< origin (match-end 0)))
|
||||||
|
(setq account-path (match-string-no-properties 2))
|
||||||
|
(unless (string-match "\\`\\s-*;" account-path)
|
||||||
|
(add-to-list 'ledger-post-list account-path))))
|
||||||
|
(setq ledger-post-current-list
|
||||||
|
(nreverse ledger-post-list)))))
|
||||||
|
|
||||||
|
(defun ledger-post-completing-read (prompt choices)
|
||||||
|
"Use iswitchb as a completing-read replacement to choose from choices.
|
||||||
|
PROMPT is a string to prompt with. CHOICES is a list of strings
|
||||||
|
to choose from."
|
||||||
|
(let* ((iswitchb-use-virtual-buffers nil)
|
||||||
|
(iswitchb-make-buflist-hook
|
||||||
|
(lambda ()
|
||||||
|
(setq iswitchb-temp-buflist choices))))
|
||||||
|
(iswitchb-read-buffer prompt)))
|
||||||
|
|
||||||
|
(defun ledger-post-pick-account ()
|
||||||
|
(interactive)
|
||||||
|
(let* ((account
|
||||||
|
(ledger-post-completing-read "Account: "
|
||||||
|
(or ledger-post-current-list
|
||||||
|
(ledger-post-find-all))))
|
||||||
|
(account-len (length account))
|
||||||
|
(pos (point)))
|
||||||
|
(goto-char (line-beginning-position))
|
||||||
|
(when (re-search-forward ledger-regex-post-line (line-end-position) t)
|
||||||
|
(let ((existing-len (length (match-string 3))))
|
||||||
|
(goto-char (match-beginning 3))
|
||||||
|
(delete-region (match-beginning 3) (match-end 3))
|
||||||
|
(insert account)
|
||||||
|
(cond
|
||||||
|
((> existing-len account-len)
|
||||||
|
(insert (make-string (- existing-len account-len) ? )))
|
||||||
|
((< existing-len account-len)
|
||||||
|
(dotimes (n (- account-len existing-len))
|
||||||
|
(if (looking-at "[ \t]\\( [ \t]\\|\t\\)")
|
||||||
|
(delete-char 1)))))))
|
||||||
|
(goto-char pos)))
|
||||||
|
|
||||||
|
(defun ledger-post-align-amount ()
|
||||||
|
(interactive)
|
||||||
|
(save-excursion
|
||||||
|
(set-mark (line-beginning-position))
|
||||||
|
(goto-char (1+ (line-end-position)))
|
||||||
|
(ledger-align-amounts)))
|
||||||
|
|
||||||
|
(defun ledger-post-maybe-align (beg end len)
|
||||||
|
(save-excursion
|
||||||
|
(goto-char beg)
|
||||||
|
(when (< end (line-end-position))
|
||||||
|
(goto-char (line-beginning-position))
|
||||||
|
(if (looking-at ledger-regex-post-line)
|
||||||
|
(ledger-post-align-amount)))))
|
||||||
|
|
||||||
|
(defun ledger-post-edit-amount ()
|
||||||
|
(interactive)
|
||||||
|
(goto-char (line-beginning-position))
|
||||||
|
(when (re-search-forward ledger-regex-post-line (line-end-position) t)
|
||||||
|
(goto-char (match-end 3))
|
||||||
|
(when (re-search-forward "[-.,0-9]+" (line-end-position) t)
|
||||||
|
(let ((val (match-string 0)))
|
||||||
|
(goto-char (match-beginning 0))
|
||||||
|
(delete-region (match-beginning 0) (match-end 0))
|
||||||
|
(calc)
|
||||||
|
(while (string-match "," val)
|
||||||
|
(setq val (replace-match "" nil nil val)))
|
||||||
|
(calc-eval val 'push)))))
|
||||||
|
|
||||||
|
(defun ledger-post-prev-xact ()
|
||||||
|
(interactive)
|
||||||
|
(backward-paragraph)
|
||||||
|
(when (re-search-backward ledger-regex-xact-line nil t)
|
||||||
|
(goto-char (match-beginning 0))
|
||||||
|
(re-search-forward ledger-regex-post-line)
|
||||||
|
(goto-char (match-end 3))))
|
||||||
|
|
||||||
|
(defun ledger-post-next-xact ()
|
||||||
|
(interactive)
|
||||||
|
(when (re-search-forward ledger-regex-xact-line nil t)
|
||||||
|
(goto-char (match-beginning 0))
|
||||||
|
(re-search-forward ledger-regex-post-line)
|
||||||
|
(goto-char (match-end 3))))
|
||||||
|
|
||||||
|
(defun ledger-post-setup ()
|
||||||
|
(let ((map (current-local-map)))
|
||||||
|
(define-key map [(meta ?p)] 'ledger-post-prev-xact)
|
||||||
|
(define-key map [(meta ?n)] 'ledger-post-next-xact)
|
||||||
|
(define-key map [(control ?c) (control ?c)] 'ledger-post-pick-account)
|
||||||
|
(define-key map [(control ?c) (control ?e)] 'ledger-post-edit-amount))
|
||||||
|
(if ledger-post-auto-adjust-amounts
|
||||||
|
(add-hook 'after-change-functions 'ledger-post-maybe-align t t)))
|
||||||
|
|
||||||
|
(add-hook 'ledger-mode-hook 'ledger-post-setup)
|
||||||
|
|
||||||
|
(provide 'ldg-post)
|
||||||
167
lisp/ldg-regex.el
Normal file
167
lisp/ldg-regex.el
Normal file
|
|
@ -0,0 +1,167 @@
|
||||||
|
(require 'rx)
|
||||||
|
|
||||||
|
(defconst ledger-regex-date
|
||||||
|
(let ((sep '(or ?- (any ?. ?/)))) ; can't do (any ?- ?. ?/) due to bug
|
||||||
|
(rx (group
|
||||||
|
(and (? (= 4 num)
|
||||||
|
(eval sep))
|
||||||
|
(and num (? num))
|
||||||
|
(eval sep)
|
||||||
|
(and num (? num))))))
|
||||||
|
"Match a single date, in its 'written' form.")
|
||||||
|
|
||||||
|
(defconst ledger-regex-date-group 1)
|
||||||
|
(defconst ledger-regex-date-group--count 1)
|
||||||
|
|
||||||
|
(defconst ledger-regex-full-date
|
||||||
|
(macroexpand
|
||||||
|
`(rx (and (regexp ,ledger-regex-date)
|
||||||
|
(? (and ?= (regexp ,ledger-regex-date))))))
|
||||||
|
"Match a compound date, of the form ACTUAL=EFFECTIVE")
|
||||||
|
|
||||||
|
(defconst ledger-regex-full-date-group-actual
|
||||||
|
ledger-regex-date-group)
|
||||||
|
(defconst ledger-regex-full-date-group-effective
|
||||||
|
(+ ledger-regex-date-group--count
|
||||||
|
ledger-regex-date-group))
|
||||||
|
(defconst ledger-regex-full-date-group--count
|
||||||
|
(* 2 ledger-regex-date-group--count))
|
||||||
|
|
||||||
|
(defconst ledger-regex-state
|
||||||
|
(rx (group (any ?! ?*))))
|
||||||
|
|
||||||
|
(defconst ledger-regex-state-group 1)
|
||||||
|
(defconst ledger-regex-state-group--count 1)
|
||||||
|
|
||||||
|
(defconst ledger-regex-code
|
||||||
|
(rx (and ?\( (group (+? (not (any ?\))))) ?\))))
|
||||||
|
|
||||||
|
(defconst ledger-regex-code-group 1)
|
||||||
|
(defconst ledger-regex-code-group--count 1)
|
||||||
|
|
||||||
|
(defconst ledger-regex-long-space
|
||||||
|
(rx (and (*? space)
|
||||||
|
(or (and ? (or ? ?\t)) ?\t))))
|
||||||
|
|
||||||
|
(defconst ledger-regex-note
|
||||||
|
(rx (group (+ nonl))))
|
||||||
|
|
||||||
|
(defconst ledger-regex-note-group 1)
|
||||||
|
(defconst ledger-regex-note-group--count 1)
|
||||||
|
|
||||||
|
(defconst ledger-regex-end-note
|
||||||
|
(macroexpand `(rx (and (regexp ,ledger-regex-long-space) ?\;
|
||||||
|
(regexp ,ledger-regex-note)))))
|
||||||
|
|
||||||
|
(defconst ledger-regex-end-note-group
|
||||||
|
ledger-regex-note-group)
|
||||||
|
(defconst ledger-regex-end-note-group--count
|
||||||
|
ledger-regex-note-group--count)
|
||||||
|
|
||||||
|
(defconst ledger-regex-full-note
|
||||||
|
(macroexpand `(rx (and line-start (+ space)
|
||||||
|
?\; (regexp ,ledger-regex-note)))))
|
||||||
|
|
||||||
|
(defconst ledger-regex-full-note-group
|
||||||
|
ledger-regex-note-group)
|
||||||
|
(defconst ledger-regex-full-note-group--count
|
||||||
|
ledger-regex-note-group--count)
|
||||||
|
|
||||||
|
(defconst ledger-regex-xact-line
|
||||||
|
(macroexpand
|
||||||
|
`(rx (and line-start
|
||||||
|
(regexp ,ledger-regex-full-date)
|
||||||
|
(? (and (+ space) (regexp ,ledger-regex-state)))
|
||||||
|
(? (and (+ space) (regexp ,ledger-regex-code)))
|
||||||
|
(+ space) (+? nonl)
|
||||||
|
(? (regexp ,ledger-regex-end-note))
|
||||||
|
line-end))))
|
||||||
|
|
||||||
|
(defconst ledger-regex-xact-line-group-actual-date
|
||||||
|
ledger-regex-full-date-group-actual)
|
||||||
|
(defconst ledger-regex-xact-line-group-effective-date
|
||||||
|
ledger-regex-full-date-group-effective)
|
||||||
|
(defconst ledger-regex-xact-line-group-state
|
||||||
|
(+ ledger-regex-full-date-group--count
|
||||||
|
ledger-regex-state-group))
|
||||||
|
(defconst ledger-regex-xact-line-group-code
|
||||||
|
(+ ledger-regex-full-date-group--count
|
||||||
|
ledger-regex-state-group--count
|
||||||
|
ledger-regex-code-group))
|
||||||
|
(defconst ledger-regex-xact-line-group-note
|
||||||
|
(+ ledger-regex-full-date-group--count
|
||||||
|
ledger-regex-state-group--count
|
||||||
|
ledger-regex-code-group--count
|
||||||
|
ledger-regex-note-group))
|
||||||
|
(defconst ledger-regex-full-note-group--count
|
||||||
|
(+ ledger-regex-full-date-group--count
|
||||||
|
ledger-regex-state-group--count
|
||||||
|
ledger-regex-code-group--count
|
||||||
|
ledger-regex-note-group--count))
|
||||||
|
|
||||||
|
(defun ledger-regex-xact-line-actual-date
|
||||||
|
(&optional string)
|
||||||
|
(match-string ledger-regex-xact-line-group-actual-date string))
|
||||||
|
|
||||||
|
(defconst ledger-regex-account
|
||||||
|
(rx (group (and (not (any ?:)) (*? nonl)))))
|
||||||
|
|
||||||
|
(defconst ledger-regex-full-account
|
||||||
|
(macroexpand
|
||||||
|
`(rx (and (group (? (any ?\[ ?\))))
|
||||||
|
(regexp ,ledger-regex-account)
|
||||||
|
(? (any ?\] ?\)))))))
|
||||||
|
|
||||||
|
(defconst ledger-regex-commodity
|
||||||
|
(rx (or (and ?\" (+ (not (any ?\"))) ?\")
|
||||||
|
(not (any space ?\n
|
||||||
|
digit
|
||||||
|
?- ?\[ ?\]
|
||||||
|
?. ?, ?\; ?+ ?* ?/ ?^ ?? ?: ?& ?| ?! ?=
|
||||||
|
?\< ?\> ?\{ ?\} ?\( ?\) ?@)))))
|
||||||
|
|
||||||
|
(defconst ledger-regex-amount
|
||||||
|
(rx (and (? ?-)
|
||||||
|
(and (+ digit)
|
||||||
|
(*? (and (any ?. ?,) (+ digit))))
|
||||||
|
(? (and (any ?. ?,) (+ digit))))))
|
||||||
|
|
||||||
|
(defconst ledger-regex-commoditized-amount
|
||||||
|
(macroexpand
|
||||||
|
`(rx (or (and (regexp ,ledger-regex-commodity)
|
||||||
|
(*? space)
|
||||||
|
(regexp ,ledger-regex-amount))
|
||||||
|
(and (regexp ,ledger-regex-amount)
|
||||||
|
(*? space)
|
||||||
|
(regexp ,ledger-regex-commodity))))))
|
||||||
|
|
||||||
|
(defconst ledger-regex-commodity-annotations
|
||||||
|
(macroexpand
|
||||||
|
`(rx (* (+ space)
|
||||||
|
(or (and ?\{ (regexp ,ledger-regex-commoditized-amount) ?\})
|
||||||
|
(and ?\[ (regexp ,ledger-regex-date) ?\])
|
||||||
|
(and ?\( (not (any ?\))) ?\)))))))
|
||||||
|
|
||||||
|
(defconst ledger-regex-cost
|
||||||
|
(macroexpand
|
||||||
|
`(rx (and (or "@" "@@") (+ space)
|
||||||
|
(regexp ,ledger-regex-commoditized-amount)))))
|
||||||
|
|
||||||
|
(defconst ledger-regex-balance-assertion
|
||||||
|
(macroexpand
|
||||||
|
`(rx (and ?= (+ space)
|
||||||
|
(regexp ,ledger-regex-commoditized-amount)))))
|
||||||
|
|
||||||
|
(defconst ledger-regex-full-amount
|
||||||
|
(macroexpand `(rx (group (+? (not (any ?\;)))))))
|
||||||
|
|
||||||
|
(defconst ledger-regex-post-line
|
||||||
|
(macroexpand
|
||||||
|
`(rx (and line-start
|
||||||
|
(? (and (+ space) (regexp ,ledger-regex-state)))
|
||||||
|
(+ space) (regexp ,ledger-regex-full-account)
|
||||||
|
(+ space) (regexp ,ledger-regex-full-amount)
|
||||||
|
(? (regexp ,ledger-regex-end-note))
|
||||||
|
line-end))))
|
||||||
|
|
||||||
|
(provide 'ldg-regex)
|
||||||
121
lisp/ldg-texi.el
Normal file
121
lisp/ldg-texi.el
Normal file
|
|
@ -0,0 +1,121 @@
|
||||||
|
(defvar ledger-path "/Users/johnw/bin/ledger")
|
||||||
|
(defvar ledger-sample-doc-path "/Users/johnw/src/ledger/doc/sample.dat")
|
||||||
|
(defvar ledger-normalization-args "--args-only --columns 80")
|
||||||
|
|
||||||
|
(defun ledger-texi-write-test (name command input output &optional category)
|
||||||
|
(let ((buf (current-buffer)))
|
||||||
|
(with-current-buffer (find-file-noselect
|
||||||
|
(expand-file-name (concat name ".test") category))
|
||||||
|
(erase-buffer)
|
||||||
|
(let ((case-fold-search nil))
|
||||||
|
(if (string-match "\\$LEDGER\\s-+" command)
|
||||||
|
(setq command (replace-match "" t t command)))
|
||||||
|
(if (string-match " -f \\$\\([-a-z]+\\)" command)
|
||||||
|
(setq command (replace-match "" t t command))))
|
||||||
|
(insert command ?\n)
|
||||||
|
(insert "<<<" ?\n)
|
||||||
|
(insert input)
|
||||||
|
(insert ">>>1" ?\n)
|
||||||
|
(insert output)
|
||||||
|
(insert ">>>2" ?\n)
|
||||||
|
(insert "=== 0" ?\n)
|
||||||
|
(save-buffer)
|
||||||
|
(unless (eq buf (current-buffer))
|
||||||
|
(kill-buffer (current-buffer))))))
|
||||||
|
|
||||||
|
(defun ledger-texi-update-test ()
|
||||||
|
(interactive)
|
||||||
|
(let ((details (ledger-texi-test-details))
|
||||||
|
(name (file-name-sans-extension
|
||||||
|
(file-name-nondirectory (buffer-file-name)))))
|
||||||
|
(ledger-texi-write-test
|
||||||
|
name (nth 0 details)
|
||||||
|
(nth 1 details)
|
||||||
|
(ledger-texi-invoke-command
|
||||||
|
(ledger-texi-expand-command
|
||||||
|
(nth 0 details)
|
||||||
|
(ledger-texi-write-test-data name (nth 1 details)))))))
|
||||||
|
|
||||||
|
(defun ledger-texi-test-details ()
|
||||||
|
(goto-char (point-min))
|
||||||
|
(let ((command (buffer-substring (point) (line-end-position)))
|
||||||
|
input output)
|
||||||
|
(re-search-forward "^<<<")
|
||||||
|
(let ((input-beg (1+ (match-end 0))))
|
||||||
|
(re-search-forward "^>>>1")
|
||||||
|
(let ((output-beg (1+ (match-end 0))))
|
||||||
|
(setq input (buffer-substring input-beg (match-beginning 0)))
|
||||||
|
(re-search-forward "^>>>2")
|
||||||
|
(setq output (buffer-substring output-beg (match-beginning 0)))
|
||||||
|
(list command input output)))))
|
||||||
|
|
||||||
|
(defun ledger-texi-expand-command (command data-file)
|
||||||
|
(if (string-match "\\$LEDGER" command)
|
||||||
|
(replace-match (format "%s -f \"%s\" %s" ledger-path
|
||||||
|
data-file ledger-normalization-args) t t command)
|
||||||
|
(concat (format "%s -f \"%s\" %s " ledger-path
|
||||||
|
data-file ledger-normalization-args) command)))
|
||||||
|
|
||||||
|
(defun ledger-texi-invoke-command (command)
|
||||||
|
(with-temp-buffer (shell-command command t (current-buffer))
|
||||||
|
(if (= (point-min) (point-max))
|
||||||
|
(progn
|
||||||
|
(push-mark nil t)
|
||||||
|
(message "Command '%s' yielded no result at %d" command (point))
|
||||||
|
(ding))
|
||||||
|
(buffer-string))))
|
||||||
|
|
||||||
|
(defun ledger-texi-write-test-data (name input)
|
||||||
|
(let ((path (expand-file-name name temporary-file-directory)))
|
||||||
|
(with-current-buffer (find-file-noselect path)
|
||||||
|
(erase-buffer)
|
||||||
|
(insert input)
|
||||||
|
(save-buffer))
|
||||||
|
path))
|
||||||
|
|
||||||
|
(defun ledger-texi-update-examples ()
|
||||||
|
(interactive)
|
||||||
|
(save-excursion
|
||||||
|
(goto-char (point-min))
|
||||||
|
(while (re-search-forward "^@c \\(\\(?:sm\\)?ex\\) \\(\\S-+\\): \\(.*\\)" nil t)
|
||||||
|
(let ((section (match-string 1))
|
||||||
|
(example-name (match-string 2))
|
||||||
|
(command (match-string 3)) expanded-command
|
||||||
|
(data-file ledger-sample-doc-path)
|
||||||
|
input output)
|
||||||
|
(goto-char (match-end 0))
|
||||||
|
(forward-line)
|
||||||
|
(when (looking-at "@\\(\\(?:small\\)?example\\)")
|
||||||
|
(let ((beg (point)))
|
||||||
|
(re-search-forward "^@end \\(\\(?:small\\)?example\\)")
|
||||||
|
(delete-region beg (1+ (point)))))
|
||||||
|
|
||||||
|
(when (let ((case-fold-search nil))
|
||||||
|
(string-match " -f \\$\\([-a-z]+\\)" command))
|
||||||
|
(let ((label (match-string 1 command)))
|
||||||
|
(setq command (replace-match "" t t command))
|
||||||
|
(save-excursion
|
||||||
|
(goto-char (point-min))
|
||||||
|
(search-forward (format "@c data: %s" label))
|
||||||
|
(re-search-forward "@\\(\\(?:small\\)?example\\)")
|
||||||
|
(forward-line)
|
||||||
|
(let ((beg (point)))
|
||||||
|
(re-search-forward "@end \\(\\(?:small\\)?example\\)")
|
||||||
|
(setq data-file (ledger-texi-write-test-data
|
||||||
|
(format "%s.dat" label)
|
||||||
|
(buffer-substring-no-properties
|
||||||
|
beg (match-beginning 0))))))))
|
||||||
|
|
||||||
|
(let ((section-name (if (string= section "smex")
|
||||||
|
"smallexample"
|
||||||
|
"example"))
|
||||||
|
(output (ledger-texi-invoke-command
|
||||||
|
(ledger-texi-expand-command command data-file))))
|
||||||
|
(insert "@" section-name ?\n output
|
||||||
|
"@end " section-name ?\n))
|
||||||
|
|
||||||
|
;; Update the regression test associated with this example
|
||||||
|
(ledger-texi-write-test example-name command input output
|
||||||
|
"../test/manual")))))
|
||||||
|
|
||||||
|
(provide 'ldg-texi)
|
||||||
|
|
@ -73,7 +73,7 @@
|
||||||
(require 'esh-arg)
|
(require 'esh-arg)
|
||||||
(require 'pcomplete)
|
(require 'pcomplete)
|
||||||
|
|
||||||
(defvar ledger-version "1.2"
|
(defvar ledger-version "1.3"
|
||||||
"The version of ledger.el currently loaded")
|
"The version of ledger.el currently loaded")
|
||||||
|
|
||||||
(defgroup ledger nil
|
(defgroup ledger nil
|
||||||
|
|
@ -1226,7 +1226,7 @@ the default."
|
||||||
"Align amounts in the current region.
|
"Align amounts in the current region.
|
||||||
This is done so that the last digit falls in COLUMN, which defaults to 52."
|
This is done so that the last digit falls in COLUMN, which defaults to 52."
|
||||||
(interactive "p")
|
(interactive "p")
|
||||||
(if (= column 1)
|
(if (or (null column) (= column 1))
|
||||||
(setq column 52))
|
(setq column 52))
|
||||||
(save-excursion
|
(save-excursion
|
||||||
(let* ((mark-first (< (mark) (point)))
|
(let* ((mark-first (< (mark) (point)))
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2003-2009, John Wiegley. All rights reserved.
|
* Copyright (c) 2003-2010, John Wiegley. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2003-2009, John Wiegley. All rights reserved.
|
* Copyright (c) 2003-2010, John Wiegley. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2003-2009, John Wiegley. All rights reserved.
|
* Copyright (c) 2003-2010, John Wiegley. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2003-2009, John Wiegley. All rights reserved.
|
* Copyright (c) 2003-2010, John Wiegley. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions
|
* modification, are permitted provided that the following conditions
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2003-2009, John Wiegley. All rights reserved.
|
* Copyright (c) 2003-2010, John Wiegley. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2003-2009, John Wiegley. All rights reserved.
|
* Copyright (c) 2003-2010, John Wiegley. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions
|
* modification, are permitted provided that the following conditions
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2003-2009, John Wiegley. All rights reserved.
|
* Copyright (c) 2003-2010, John Wiegley. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2003-2009, John Wiegley. All rights reserved.
|
* Copyright (c) 2003-2010, John Wiegley. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2003-2009, John Wiegley. All rights reserved.
|
* Copyright (c) 2003-2010, John Wiegley. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2003-2009, John Wiegley. All rights reserved.
|
* Copyright (c) 2003-2010, John Wiegley. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2003-2009, John Wiegley. All rights reserved.
|
* Copyright (c) 2003-2010, John Wiegley. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2003-2009, John Wiegley. All rights reserved.
|
* Copyright (c) 2003-2010, John Wiegley. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2003-2009, John Wiegley. All rights reserved.
|
* Copyright (c) 2003-2010, John Wiegley. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
|
|
@ -112,10 +112,12 @@ post_handler_ptr chain_post_handlers(report_t& report,
|
||||||
else
|
else
|
||||||
handler.reset(new sort_posts(handler, report.HANDLER(sort_).str()));
|
handler.reset(new sort_posts(handler, report.HANDLER(sort_).str()));
|
||||||
}
|
}
|
||||||
|
#if 0
|
||||||
else if (! report.HANDLED(period_) &&
|
else if (! report.HANDLED(period_) &&
|
||||||
! report.HANDLED(unsorted)) {
|
! report.HANDLED(unsorted)) {
|
||||||
handler.reset(new sort_posts(handler, "date"));
|
handler.reset(new sort_posts(handler, "date"));
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
// collapse_posts causes xacts with multiple posts to appear as xacts
|
// collapse_posts causes xacts with multiple posts to appear as xacts
|
||||||
// with a subtotaled post for each commodity used.
|
// with a subtotaled post for each commodity used.
|
||||||
|
|
@ -167,7 +169,7 @@ post_handler_ptr chain_post_handlers(report_t& report,
|
||||||
}
|
}
|
||||||
else if (report.HANDLED(pivot_)) {
|
else if (report.HANDLED(pivot_)) {
|
||||||
string pivot = report.HANDLER(pivot_).str();
|
string pivot = report.HANDLER(pivot_).str();
|
||||||
pivot = string("\"") + pivot + ":\" + tag(/" + pivot + "/)";
|
pivot = string("\"") + pivot + ":\" + tag(\"" + pivot + "\")";
|
||||||
handler.reset(new transfer_details(handler, transfer_details::SET_ACCOUNT,
|
handler.reset(new transfer_details(handler, transfer_details::SET_ACCOUNT,
|
||||||
report.session.journal->master, pivot,
|
report.session.journal->master, pivot,
|
||||||
report));
|
report));
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2003-2009, John Wiegley. All rights reserved.
|
* Copyright (c) 2003-2010, John Wiegley. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2003-2009, John Wiegley. All rights reserved.
|
* Copyright (c) 2003-2010, John Wiegley. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2003-2009, John Wiegley. All rights reserved.
|
* Copyright (c) 2003-2010, John Wiegley. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2003-2009, John Wiegley. All rights reserved.
|
* Copyright (c) 2003-2010, John Wiegley. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2003-2009, John Wiegley. All rights reserved.
|
* Copyright (c) 2003-2010, John Wiegley. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
|
|
|
||||||
156
src/convert.cc
Normal file
156
src/convert.cc
Normal file
|
|
@ -0,0 +1,156 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2003-2010, John Wiegley. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
*
|
||||||
|
* - Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* - Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* - Neither the name of New Artisans LLC nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived from
|
||||||
|
* this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <system.hh>
|
||||||
|
|
||||||
|
#include "convert.h"
|
||||||
|
#include "csv.h"
|
||||||
|
#include "scope.h"
|
||||||
|
#include "interactive.h"
|
||||||
|
#include "iterators.h"
|
||||||
|
#include "report.h"
|
||||||
|
#include "xact.h"
|
||||||
|
#include "print.h"
|
||||||
|
#include "lookup.h"
|
||||||
|
|
||||||
|
namespace ledger {
|
||||||
|
|
||||||
|
value_t convert_command(call_scope_t& scope)
|
||||||
|
{
|
||||||
|
interactive_t args(scope, "s");
|
||||||
|
report_t& report(find_scope<report_t>(scope));
|
||||||
|
journal_t& journal(*report.session.journal.get());
|
||||||
|
|
||||||
|
string bucket_name;
|
||||||
|
if (report.HANDLED(account_))
|
||||||
|
bucket_name = report.HANDLER(account_).str();
|
||||||
|
else
|
||||||
|
bucket_name = "Equity:Unknown";
|
||||||
|
|
||||||
|
account_t * bucket = journal.master->find_account(bucket_name);
|
||||||
|
account_t * unknown = journal.master->find_account(_("Expenses:Unknown"));
|
||||||
|
|
||||||
|
// Make an amounts mapping for the account under consideration
|
||||||
|
|
||||||
|
typedef std::map<value_t, std::list<post_t *> > post_map_t;
|
||||||
|
post_map_t post_map;
|
||||||
|
|
||||||
|
xacts_iterator journal_iter(journal);
|
||||||
|
while (xact_t * xact = journal_iter()) {
|
||||||
|
post_t * post = NULL;
|
||||||
|
xact_posts_iterator xact_iter(*xact);
|
||||||
|
while ((post = xact_iter()) != NULL) {
|
||||||
|
if (post->account == bucket)
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (post) {
|
||||||
|
post_map_t::iterator i = post_map.find(post->amount);
|
||||||
|
if (i == post_map.end()) {
|
||||||
|
std::list<post_t *> post_list;
|
||||||
|
post_list.push_back(post);
|
||||||
|
post_map.insert(post_map_t::value_type(post->amount, post_list));
|
||||||
|
} else {
|
||||||
|
(*i).second.push_back(post);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
// Create a flat list o
|
||||||
|
xacts_list current_xacts(journal.xacts_begin(), journal.xacts_end());
|
||||||
|
|
||||||
|
// Read in the series of transactions from the CSV file
|
||||||
|
|
||||||
|
print_xacts formatter(report);
|
||||||
|
ifstream data(path(args.get<string>(0)));
|
||||||
|
csv_reader reader(data);
|
||||||
|
|
||||||
|
while (xact_t * xact = reader.read_xact(journal, bucket)) {
|
||||||
|
bool matched = false;
|
||||||
|
post_map_t::iterator i = post_map.find(- xact->posts.front()->amount);
|
||||||
|
if (i != post_map.end()) {
|
||||||
|
std::list<post_t *>& post_list((*i).second);
|
||||||
|
foreach (post_t * post, post_list) {
|
||||||
|
if (xact->code && post->xact->code &&
|
||||||
|
*xact->code == *post->xact->code) {
|
||||||
|
matched = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
else if (xact->actual_date() == post->actual_date()) {
|
||||||
|
matched = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (matched) {
|
||||||
|
DEBUG("convert.csv", "Ignored xact with code: " << *xact->code);
|
||||||
|
delete xact; // ignore it
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
if (xact->posts.front()->account == NULL) {
|
||||||
|
xacts_iterator xi;
|
||||||
|
xi.xacts_i = current_xacts.begin();
|
||||||
|
xi.xacts_end = current_xacts.end();
|
||||||
|
xi.xacts_uninitialized = false;
|
||||||
|
|
||||||
|
// jww (2010-03-07): Bind this logic to an option: --auto-match
|
||||||
|
if (account_t * acct =
|
||||||
|
lookup_probable_account(xact->payee, xi, bucket).second)
|
||||||
|
xact->posts.front()->account = acct;
|
||||||
|
else
|
||||||
|
xact->posts.front()->account = unknown;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! journal.add_xact(xact)) {
|
||||||
|
delete xact;
|
||||||
|
throw_(std::runtime_error,
|
||||||
|
_("Failed to finalize derived transaction (check commodities)"));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
xact_posts_iterator xact_iter(*xact);
|
||||||
|
while (post_t * post = xact_iter())
|
||||||
|
formatter(*post);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
formatter.flush();
|
||||||
|
|
||||||
|
// If not, transform the payee according to regexps
|
||||||
|
|
||||||
|
// Set the account to a default vaule, then transform the account according
|
||||||
|
// to the payee
|
||||||
|
|
||||||
|
// Print out the final form of the transaction
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace ledger
|
||||||
55
src/convert.h
Normal file
55
src/convert.h
Normal file
|
|
@ -0,0 +1,55 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2003-2010, John Wiegley. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
*
|
||||||
|
* - Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* - Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* - Neither the name of New Artisans LLC nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived from
|
||||||
|
* this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @addtogroup data
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file convert.h
|
||||||
|
* @author John Wiegley
|
||||||
|
*
|
||||||
|
* @ingroup data
|
||||||
|
*/
|
||||||
|
#ifndef _CONVERT_H
|
||||||
|
#define _CONVERT_H
|
||||||
|
|
||||||
|
#include "value.h"
|
||||||
|
|
||||||
|
namespace ledger {
|
||||||
|
|
||||||
|
class call_scope_t;
|
||||||
|
|
||||||
|
value_t convert_command(call_scope_t& scope);
|
||||||
|
|
||||||
|
} // namespace ledger
|
||||||
|
|
||||||
|
#endif // _CONVERT_H
|
||||||
298
src/csv.cc
Normal file
298
src/csv.cc
Normal file
|
|
@ -0,0 +1,298 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2003-2010, John Wiegley. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
*
|
||||||
|
* - Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* - Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* - Neither the name of New Artisans LLC nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived from
|
||||||
|
* this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <system.hh>
|
||||||
|
|
||||||
|
#include "csv.h"
|
||||||
|
#include "xact.h"
|
||||||
|
#include "post.h"
|
||||||
|
#include "account.h"
|
||||||
|
#include "journal.h"
|
||||||
|
#include "pool.h"
|
||||||
|
|
||||||
|
namespace ledger {
|
||||||
|
|
||||||
|
string csv_reader::read_field(std::istream& in)
|
||||||
|
{
|
||||||
|
string field;
|
||||||
|
|
||||||
|
char c;
|
||||||
|
if (in.peek() == '"' || in.peek() == '|') {
|
||||||
|
in.get(c);
|
||||||
|
char x;
|
||||||
|
while (in.good() && ! in.eof()) {
|
||||||
|
in.get(x);
|
||||||
|
if (x == '\\') {
|
||||||
|
in.get(x);
|
||||||
|
}
|
||||||
|
else if (x == '"' && in.peek() == '"') {
|
||||||
|
in.get(x);
|
||||||
|
}
|
||||||
|
else if (x == c) {
|
||||||
|
if (x == '|')
|
||||||
|
in.unget();
|
||||||
|
else if (in.peek() == ',')
|
||||||
|
in.get(c);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
if (x != '\0')
|
||||||
|
field += x;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
while (in.good() && ! in.eof()) {
|
||||||
|
in.get(c);
|
||||||
|
if (c == ',')
|
||||||
|
break;
|
||||||
|
if (c != '\0')
|
||||||
|
field += c;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
trim(field);
|
||||||
|
return field;
|
||||||
|
}
|
||||||
|
|
||||||
|
char * csv_reader::next_line(std::istream& in)
|
||||||
|
{
|
||||||
|
static char linebuf[MAX_LINE + 1];
|
||||||
|
|
||||||
|
while (in.good() && ! in.eof() && in.peek() == '#')
|
||||||
|
in.getline(linebuf, MAX_LINE);
|
||||||
|
|
||||||
|
if (! in.good() || in.eof())
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
in.getline(linebuf, MAX_LINE);
|
||||||
|
|
||||||
|
return linebuf;
|
||||||
|
}
|
||||||
|
|
||||||
|
void csv_reader::read_index(std::istream& in)
|
||||||
|
{
|
||||||
|
char * line = next_line(in);
|
||||||
|
if (! line)
|
||||||
|
return;
|
||||||
|
|
||||||
|
std::istringstream instr(line);
|
||||||
|
|
||||||
|
while (instr.good() && ! instr.eof()) {
|
||||||
|
string field = read_field(instr);
|
||||||
|
names.push_back(field);
|
||||||
|
|
||||||
|
if (date_mask.match(field))
|
||||||
|
index.push_back(FIELD_DATE);
|
||||||
|
else if (date_eff_mask.match(field))
|
||||||
|
index.push_back(FIELD_DATE_EFF);
|
||||||
|
else if (code_mask.match(field))
|
||||||
|
index.push_back(FIELD_CODE);
|
||||||
|
else if (payee_mask.match(field))
|
||||||
|
index.push_back(FIELD_PAYEE);
|
||||||
|
else if (amount_mask.match(field))
|
||||||
|
index.push_back(FIELD_AMOUNT);
|
||||||
|
else if (cost_mask.match(field))
|
||||||
|
index.push_back(FIELD_COST);
|
||||||
|
else if (total_mask.match(field))
|
||||||
|
index.push_back(FIELD_TOTAL);
|
||||||
|
else if (note_mask.match(field))
|
||||||
|
index.push_back(FIELD_NOTE);
|
||||||
|
else
|
||||||
|
index.push_back(FIELD_UNKNOWN);
|
||||||
|
|
||||||
|
DEBUG("csv.parse", "Header field: " << field);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
xact_t * csv_reader::read_xact(journal_t& journal, account_t * bucket)
|
||||||
|
{
|
||||||
|
restart:
|
||||||
|
char * line = next_line(in);
|
||||||
|
if (! line || index.empty())
|
||||||
|
return NULL;
|
||||||
|
|
||||||
|
std::istringstream instr(line);
|
||||||
|
|
||||||
|
std::auto_ptr<xact_t> xact(new xact_t);
|
||||||
|
std::auto_ptr<post_t> post(new post_t);
|
||||||
|
|
||||||
|
xact->set_state(item_t::CLEARED);
|
||||||
|
|
||||||
|
xact->pos = position_t();
|
||||||
|
xact->pos->pathname = "jww (2010-03-05): unknown";
|
||||||
|
xact->pos->beg_pos = in.tellg();
|
||||||
|
xact->pos->beg_line = 0;
|
||||||
|
xact->pos->sequence = 0;
|
||||||
|
|
||||||
|
post->xact = xact.get();
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
post->pos = position_t();
|
||||||
|
post->pos->pathname = pathname;
|
||||||
|
post->pos->beg_pos = line_beg_pos;
|
||||||
|
post->pos->beg_line = linenum;
|
||||||
|
post->pos->sequence = context.sequence++;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
post->set_state(item_t::CLEARED);
|
||||||
|
post->account = NULL;
|
||||||
|
|
||||||
|
int n = 0;
|
||||||
|
amount_t amt;
|
||||||
|
string total;
|
||||||
|
|
||||||
|
while (instr.good() && ! instr.eof()) {
|
||||||
|
string field = read_field(instr);
|
||||||
|
|
||||||
|
switch (index[n]) {
|
||||||
|
case FIELD_DATE:
|
||||||
|
if (field.empty())
|
||||||
|
goto restart;
|
||||||
|
try {
|
||||||
|
xact->_date = parse_date(field);
|
||||||
|
}
|
||||||
|
catch (date_error&) {
|
||||||
|
goto restart;
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FIELD_DATE_EFF:
|
||||||
|
xact->_date_eff = parse_date(field);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FIELD_CODE:
|
||||||
|
if (! field.empty())
|
||||||
|
xact->code = field;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FIELD_PAYEE: {
|
||||||
|
bool found = false;
|
||||||
|
foreach (payee_mapping_t& value, journal.payee_mappings) {
|
||||||
|
DEBUG("csv.mappings", "Looking for payee mapping: " << value.first);
|
||||||
|
if (value.first.match(field)) {
|
||||||
|
xact->payee = value.second;
|
||||||
|
found = true;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
if (! found)
|
||||||
|
xact->payee = field;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case FIELD_AMOUNT: {
|
||||||
|
std::istringstream amount_str(field);
|
||||||
|
amt.parse(amount_str, PARSE_NO_REDUCE);
|
||||||
|
if (! amt.has_commodity() &&
|
||||||
|
commodity_pool_t::current_pool->default_commodity)
|
||||||
|
amt.set_commodity(*commodity_pool_t::current_pool->default_commodity);
|
||||||
|
post->amount = amt;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case FIELD_COST: {
|
||||||
|
std::istringstream amount_str(field);
|
||||||
|
amt.parse(amount_str, PARSE_NO_REDUCE);
|
||||||
|
if (! amt.has_commodity() &&
|
||||||
|
commodity_pool_t::current_pool->default_commodity)
|
||||||
|
amt.set_commodity
|
||||||
|
(*commodity_pool_t::current_pool->default_commodity);
|
||||||
|
post->cost = amt;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
case FIELD_TOTAL:
|
||||||
|
total = field;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FIELD_NOTE:
|
||||||
|
xact->note = field;
|
||||||
|
break;
|
||||||
|
|
||||||
|
case FIELD_UNKNOWN:
|
||||||
|
if (! names[n].empty() && ! field.empty())
|
||||||
|
xact->set_tag(names[n], field);
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
n++;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
xact->set_tag(_("Imported"),
|
||||||
|
string(format_date(CURRENT_DATE(), FMT_WRITTEN)));
|
||||||
|
xact->set_tag(_("Original"), string(line));
|
||||||
|
xact->set_tag(_("SHA1"), string(sha1sum(line)));
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// Translate the account name, if we have enough information to do so
|
||||||
|
|
||||||
|
foreach (account_mapping_t& value, journal.account_mappings) {
|
||||||
|
if (value.first.match(xact->payee)) {
|
||||||
|
post->account = value.second;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
xact->add_post(post.release());
|
||||||
|
|
||||||
|
// Create the "balancing post", which refers to the account for this data
|
||||||
|
|
||||||
|
post.reset(new post_t);
|
||||||
|
|
||||||
|
post->xact = xact.get();
|
||||||
|
|
||||||
|
#if 0
|
||||||
|
post->pos = position_t();
|
||||||
|
post->pos->pathname = pathname;
|
||||||
|
post->pos->beg_pos = line_beg_pos;
|
||||||
|
post->pos->beg_line = linenum;
|
||||||
|
post->pos->sequence = context.sequence++;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
post->set_state(item_t::CLEARED);
|
||||||
|
post->account = bucket;
|
||||||
|
|
||||||
|
if (! amt.is_null())
|
||||||
|
post->amount = - amt;
|
||||||
|
|
||||||
|
if (! total.empty()) {
|
||||||
|
std::istringstream assigned_amount_str(total);
|
||||||
|
amt.parse(assigned_amount_str, PARSE_NO_REDUCE);
|
||||||
|
if (! amt.has_commodity() &&
|
||||||
|
commodity_pool_t::current_pool->default_commodity)
|
||||||
|
amt.set_commodity(*commodity_pool_t::current_pool->default_commodity);
|
||||||
|
post->assigned_amount = amt;
|
||||||
|
}
|
||||||
|
|
||||||
|
xact->add_post(post.release());
|
||||||
|
|
||||||
|
return xact.release();
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace ledger
|
||||||
110
src/csv.h
Normal file
110
src/csv.h
Normal file
|
|
@ -0,0 +1,110 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2003-2010, John Wiegley. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
*
|
||||||
|
* - Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* - Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* - Neither the name of New Artisans LLC nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived from
|
||||||
|
* this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @addtogroup data
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file csv.h
|
||||||
|
* @author John Wiegley
|
||||||
|
*
|
||||||
|
* @ingroup data
|
||||||
|
*/
|
||||||
|
#ifndef _CSV_H
|
||||||
|
#define _CSV_H
|
||||||
|
|
||||||
|
#include "value.h"
|
||||||
|
|
||||||
|
namespace ledger {
|
||||||
|
|
||||||
|
class xact_t;
|
||||||
|
class journal_t;
|
||||||
|
class account_t;
|
||||||
|
|
||||||
|
class csv_reader
|
||||||
|
{
|
||||||
|
static const std::size_t MAX_LINE = 1024;
|
||||||
|
|
||||||
|
std::istream& in;
|
||||||
|
|
||||||
|
enum headers_t {
|
||||||
|
FIELD_DATE = 0,
|
||||||
|
FIELD_DATE_EFF,
|
||||||
|
FIELD_CODE,
|
||||||
|
FIELD_PAYEE,
|
||||||
|
FIELD_AMOUNT,
|
||||||
|
FIELD_COST,
|
||||||
|
FIELD_TOTAL,
|
||||||
|
FIELD_NOTE,
|
||||||
|
|
||||||
|
FIELD_UNKNOWN
|
||||||
|
};
|
||||||
|
|
||||||
|
mask_t date_mask;
|
||||||
|
mask_t date_eff_mask;
|
||||||
|
mask_t code_mask;
|
||||||
|
mask_t payee_mask;
|
||||||
|
mask_t amount_mask;
|
||||||
|
mask_t cost_mask;
|
||||||
|
mask_t total_mask;
|
||||||
|
mask_t note_mask;
|
||||||
|
|
||||||
|
std::vector<int> index;
|
||||||
|
std::vector<string> names;
|
||||||
|
std::vector<string> fields;
|
||||||
|
|
||||||
|
typedef std::map<string, string> string_map;
|
||||||
|
|
||||||
|
public:
|
||||||
|
csv_reader(std::istream& _in)
|
||||||
|
: in(_in),
|
||||||
|
date_mask("date"),
|
||||||
|
date_eff_mask("posted( ?date)?"),
|
||||||
|
code_mask("code"),
|
||||||
|
payee_mask("(payee|desc(ription)?|title)"),
|
||||||
|
amount_mask("amount"),
|
||||||
|
cost_mask("cost"),
|
||||||
|
total_mask("total"),
|
||||||
|
note_mask("note") {
|
||||||
|
read_index(in);
|
||||||
|
}
|
||||||
|
|
||||||
|
string read_field(std::istream& in);
|
||||||
|
char * next_line(std::istream& in);
|
||||||
|
void read_index(std::istream& in);
|
||||||
|
|
||||||
|
xact_t * read_xact(journal_t& journal, account_t * bucket);
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace ledger
|
||||||
|
|
||||||
|
#endif // _CSV_H
|
||||||
49
src/draft.cc
49
src/draft.cc
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2003-2009, John Wiegley. All rights reserved.
|
* Copyright (c) 2003-2010, John Wiegley. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
|
|
@ -38,7 +38,8 @@
|
||||||
#include "journal.h"
|
#include "journal.h"
|
||||||
#include "session.h"
|
#include "session.h"
|
||||||
#include "report.h"
|
#include "report.h"
|
||||||
#include "output.h"
|
#include "lookup.h"
|
||||||
|
#include "print.h"
|
||||||
|
|
||||||
namespace ledger {
|
namespace ledger {
|
||||||
|
|
||||||
|
|
@ -240,20 +241,27 @@ void draft_t::parse_args(const value_t& args)
|
||||||
xact_t * draft_t::insert(journal_t& journal)
|
xact_t * draft_t::insert(journal_t& journal)
|
||||||
{
|
{
|
||||||
if (tmpl->payee_mask.empty())
|
if (tmpl->payee_mask.empty())
|
||||||
throw std::runtime_error(_("xact' command requires at least a payee"));
|
throw std::runtime_error(_("'xact' command requires at least a payee"));
|
||||||
|
|
||||||
xact_t * matching = NULL;
|
xact_t * matching = NULL;
|
||||||
|
|
||||||
std::auto_ptr<xact_t> added(new xact_t);
|
std::auto_ptr<xact_t> added(new xact_t);
|
||||||
|
|
||||||
for (xacts_list::reverse_iterator j = journal.xacts.rbegin();
|
xacts_iterator xi(journal);
|
||||||
j != journal.xacts.rend();
|
if (xact_t * xact = lookup_probable_account(tmpl->payee_mask.str(), xi).first) {
|
||||||
j++) {
|
DEBUG("derive.xact", "Found payee by lookup: transaction on line "
|
||||||
if (tmpl->payee_mask.match((*j)->payee)) {
|
<< xact->pos->beg_line);
|
||||||
matching = *j;
|
matching = xact;
|
||||||
DEBUG("derive.xact",
|
} else {
|
||||||
"Found payee match: transaction on line " << (*j)->pos->beg_line);
|
for (xacts_list::reverse_iterator j = journal.xacts.rbegin();
|
||||||
break;
|
j != journal.xacts.rend();
|
||||||
|
j++) {
|
||||||
|
if (tmpl->payee_mask.match((*j)->payee)) {
|
||||||
|
matching = *j;
|
||||||
|
DEBUG("derive.xact",
|
||||||
|
"Found payee match: transaction on line " << (*j)->pos->beg_line);
|
||||||
|
break;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -269,15 +277,15 @@ xact_t * draft_t::insert(journal_t& journal)
|
||||||
|
|
||||||
if (matching) {
|
if (matching) {
|
||||||
added->payee = matching->payee;
|
added->payee = matching->payee;
|
||||||
added->code = matching->code;
|
//added->code = matching->code;
|
||||||
added->note = matching->note;
|
//added->note = matching->note;
|
||||||
|
|
||||||
#if defined(DEBUG_ON)
|
#if defined(DEBUG_ON)
|
||||||
DEBUG("derive.xact", "Setting payee from match: " << added->payee);
|
DEBUG("derive.xact", "Setting payee from match: " << added->payee);
|
||||||
if (added->code)
|
//if (added->code)
|
||||||
DEBUG("derive.xact", "Setting code from match: " << *added->code);
|
// DEBUG("derive.xact", "Setting code from match: " << *added->code);
|
||||||
if (added->note)
|
//if (added->note)
|
||||||
DEBUG("derive.xact", "Setting note from match: " << *added->note);
|
// DEBUG("derive.xact", "Setting note from match: " << *added->note);
|
||||||
#endif
|
#endif
|
||||||
} else {
|
} else {
|
||||||
added->payee = tmpl->payee_mask.str();
|
added->payee = tmpl->payee_mask.str();
|
||||||
|
|
@ -520,10 +528,7 @@ value_t xact_command(call_scope_t& args)
|
||||||
// Only consider actual postings for the "xact" command
|
// Only consider actual postings for the "xact" command
|
||||||
report.HANDLER(limit_).on(string("#xact"), "actual");
|
report.HANDLER(limit_).on(string("#xact"), "actual");
|
||||||
|
|
||||||
report.xact_report(post_handler_ptr
|
report.xact_report(post_handler_ptr(new print_xacts(report)), *new_xact);
|
||||||
(new format_posts(report,
|
|
||||||
report.HANDLER(print_format_).str())),
|
|
||||||
*new_xact);
|
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2003-2009, John Wiegley. All rights reserved.
|
* Copyright (c) 2003-2010, John Wiegley. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2003-2009, John Wiegley. All rights reserved.
|
* Copyright (c) 2003-2010, John Wiegley. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2003-2009, John Wiegley. All rights reserved.
|
* Copyright (c) 2003-2010, John Wiegley. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2003-2009, John Wiegley. All rights reserved.
|
* Copyright (c) 2003-2010, John Wiegley. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2003-2009, John Wiegley. All rights reserved.
|
* Copyright (c) 2003-2010, John Wiegley. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2003-2009, John Wiegley. All rights reserved.
|
* Copyright (c) 2003-2010, John Wiegley. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2003-2009, John Wiegley. All rights reserved.
|
* Copyright (c) 2003-2010, John Wiegley. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2003-2009, John Wiegley. All rights reserved.
|
* Copyright (c) 2003-2010, John Wiegley. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2003-2009, John Wiegley. All rights reserved.
|
* Copyright (c) 2003-2010, John Wiegley. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
|
|
@ -107,6 +107,9 @@ void truncate_xacts::flush()
|
||||||
|
|
||||||
void truncate_xacts::operator()(post_t& post)
|
void truncate_xacts::operator()(post_t& post)
|
||||||
{
|
{
|
||||||
|
if (completed)
|
||||||
|
return;
|
||||||
|
|
||||||
if (last_xact != post.xact) {
|
if (last_xact != post.xact) {
|
||||||
if (last_xact)
|
if (last_xact)
|
||||||
xacts_seen++;
|
xacts_seen++;
|
||||||
|
|
@ -114,8 +117,11 @@ void truncate_xacts::operator()(post_t& post)
|
||||||
}
|
}
|
||||||
|
|
||||||
if (tail_count == 0 && head_count > 0 &&
|
if (tail_count == 0 && head_count > 0 &&
|
||||||
static_cast<int>(xacts_seen) >= head_count)
|
static_cast<int>(xacts_seen) >= head_count) {
|
||||||
|
flush();
|
||||||
|
completed = true;
|
||||||
return;
|
return;
|
||||||
|
}
|
||||||
|
|
||||||
posts.push_back(&post);
|
posts.push_back(&post);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2003-2009, John Wiegley. All rights reserved.
|
* Copyright (c) 2003-2010, John Wiegley. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
|
|
@ -125,8 +125,9 @@ public:
|
||||||
|
|
||||||
class truncate_xacts : public item_handler<post_t>
|
class truncate_xacts : public item_handler<post_t>
|
||||||
{
|
{
|
||||||
int head_count;
|
int head_count;
|
||||||
int tail_count;
|
int tail_count;
|
||||||
|
bool completed;
|
||||||
|
|
||||||
posts_list posts;
|
posts_list posts;
|
||||||
std::size_t xacts_seen;
|
std::size_t xacts_seen;
|
||||||
|
|
@ -139,7 +140,7 @@ public:
|
||||||
int _head_count, int _tail_count)
|
int _head_count, int _tail_count)
|
||||||
: item_handler<post_t>(handler),
|
: item_handler<post_t>(handler),
|
||||||
head_count(_head_count), tail_count(_tail_count),
|
head_count(_head_count), tail_count(_tail_count),
|
||||||
xacts_seen(0), last_xact(NULL) {
|
completed(false), xacts_seen(0), last_xact(NULL) {
|
||||||
TRACE_CTOR(truncate_xacts, "post_handler_ptr, int, int");
|
TRACE_CTOR(truncate_xacts, "post_handler_ptr, int, int");
|
||||||
}
|
}
|
||||||
virtual ~truncate_xacts() {
|
virtual ~truncate_xacts() {
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2003-2009, John Wiegley. All rights reserved.
|
* Copyright (c) 2003-2010, John Wiegley. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2003-2009, John Wiegley. All rights reserved.
|
* Copyright (c) 2003-2010, John Wiegley. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2003-2009, John Wiegley. All rights reserved.
|
* Copyright (c) 2003-2010, John Wiegley. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2003-2009, John Wiegley. All rights reserved.
|
* Copyright (c) 2003-2010, John Wiegley. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2003-2009, John Wiegley. All rights reserved.
|
* Copyright (c) 2003-2010, John Wiegley. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2003-2009, John Wiegley. All rights reserved.
|
* Copyright (c) 2003-2010, John Wiegley. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2003-2009, John Wiegley. All rights reserved.
|
* Copyright (c) 2003-2010, John Wiegley. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions
|
* modification, are permitted provided that the following conditions
|
||||||
|
|
@ -110,7 +110,7 @@ public:
|
||||||
out <<
|
out <<
|
||||||
"Ledger " << ledger::version << _(", the command-line accounting tool");
|
"Ledger " << ledger::version << _(", the command-line accounting tool");
|
||||||
out <<
|
out <<
|
||||||
_("\n\nCopyright (c) 2003-2009, John Wiegley. All rights reserved.\n\n\
|
_("\n\nCopyright (c) 2003-2010, John Wiegley. All rights reserved.\n\n\
|
||||||
This program is made available under the terms of the BSD Public License.\n\
|
This program is made available under the terms of the BSD Public License.\n\
|
||||||
See LICENSE file included with the distribution for details and disclaimer.");
|
See LICENSE file included with the distribution for details and disclaimer.");
|
||||||
out << std::endl;
|
out << std::endl;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2003-2009, John Wiegley. All rights reserved.
|
* Copyright (c) 2003-2010, John Wiegley. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2003-2009, John Wiegley. All rights reserved.
|
* Copyright (c) 2003-2010, John Wiegley. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
|
|
|
||||||
55
src/item.cc
55
src/item.cc
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2003-2009, John Wiegley. All rights reserved.
|
* Copyright (c) 2003-2010, John Wiegley. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
|
|
@ -65,8 +65,8 @@ bool item_t::has_tag(const mask_t& tag_mask,
|
||||||
if (tag_mask.match(data.first)) {
|
if (tag_mask.match(data.first)) {
|
||||||
if (! value_mask)
|
if (! value_mask)
|
||||||
return true;
|
return true;
|
||||||
else if (data.second)
|
else if (data.second.first)
|
||||||
return value_mask->match(*data.second);
|
return value_mask->match(*data.second.first);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -81,7 +81,7 @@ optional<string> item_t::get_tag(const string& tag) const
|
||||||
string_map::const_iterator i = metadata->find(tag);
|
string_map::const_iterator i = metadata->find(tag);
|
||||||
if (i != metadata->end()) {
|
if (i != metadata->end()) {
|
||||||
DEBUG("item.meta", "Found the item!");
|
DEBUG("item.meta", "Found the item!");
|
||||||
return (*i).second;
|
return (*i).second.first;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return none;
|
return none;
|
||||||
|
|
@ -94,28 +94,44 @@ optional<string> item_t::get_tag(const mask_t& tag_mask,
|
||||||
foreach (const string_map::value_type& data, *metadata) {
|
foreach (const string_map::value_type& data, *metadata) {
|
||||||
if (tag_mask.match(data.first) &&
|
if (tag_mask.match(data.first) &&
|
||||||
(! value_mask ||
|
(! value_mask ||
|
||||||
(data.second && value_mask->match(*data.second))))
|
(data.second.first && value_mask->match(*data.second.first))))
|
||||||
return data.second;
|
return data.second.first;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return none;
|
return none;
|
||||||
}
|
}
|
||||||
|
|
||||||
void item_t::set_tag(const string& tag,
|
item_t::string_map::iterator
|
||||||
const optional<string>& value)
|
item_t::set_tag(const string& tag,
|
||||||
|
const optional<string>& value,
|
||||||
|
const bool overwrite_existing)
|
||||||
{
|
{
|
||||||
|
assert(! tag.empty());
|
||||||
|
|
||||||
if (! metadata)
|
if (! metadata)
|
||||||
metadata = string_map();
|
metadata = string_map();
|
||||||
|
|
||||||
DEBUG("item.meta", "Setting tag '" << tag << "' to value '"
|
DEBUG("item.meta", "Setting tag '" << tag << "' to value '"
|
||||||
<< (value ? *value : string("<none>")) << "'");
|
<< (value ? *value : string("<none>")) << "'");
|
||||||
|
|
||||||
std::pair<string_map::iterator, bool> result
|
optional<string> data = value;
|
||||||
= metadata->insert(string_map::value_type(tag, value));
|
if (data && data->empty())
|
||||||
assert(result.second);
|
data = none;
|
||||||
|
|
||||||
|
string_map::iterator i = metadata->find(tag);
|
||||||
|
if (i == metadata->end()) {
|
||||||
|
std::pair<string_map::iterator, bool> result
|
||||||
|
= metadata->insert(string_map::value_type(tag, tag_data_t(data, false)));
|
||||||
|
assert(result.second);
|
||||||
|
return result.first;
|
||||||
|
} else {
|
||||||
|
if (overwrite_existing)
|
||||||
|
(*i).second = tag_data_t(data, false);
|
||||||
|
return i;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void item_t::parse_tags(const char * p,
|
void item_t::parse_tags(const char * p, bool overwrite_existing,
|
||||||
optional<date_t::year_type> current_year)
|
optional<date_t::year_type> current_year)
|
||||||
{
|
{
|
||||||
if (const char * b = std::strchr(p, '[')) {
|
if (const char * b = std::strchr(p, '[')) {
|
||||||
|
|
@ -149,15 +165,18 @@ void item_t::parse_tags(const char * p,
|
||||||
q = std::strtok(NULL, " \t")) {
|
q = std::strtok(NULL, " \t")) {
|
||||||
const string::size_type len = std::strlen(q);
|
const string::size_type len = std::strlen(q);
|
||||||
if (! tag.empty()) {
|
if (! tag.empty()) {
|
||||||
if (! has_tag(tag))
|
string_map::iterator i = set_tag(tag, string(p + (q - buf.get())),
|
||||||
set_tag(tag, string(p + (q - buf.get())));
|
overwrite_existing);
|
||||||
|
(*i).second.second = true;
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
else if (q[0] == ':' && q[len - 1] == ':') { // a series of tags
|
else if (q[0] == ':' && q[len - 1] == ':') { // a series of tags
|
||||||
for (char * r = std::strtok(q + 1, ":");
|
for (char * r = std::strtok(q + 1, ":");
|
||||||
r;
|
r;
|
||||||
r = std::strtok(NULL, ":"))
|
r = std::strtok(NULL, ":")) {
|
||||||
set_tag(r);
|
string_map::iterator i = set_tag(r, none, overwrite_existing);
|
||||||
|
(*i).second.second = true;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
else if (q[len - 1] == ':') { // a metadata setting
|
else if (q[len - 1] == ':') { // a metadata setting
|
||||||
tag = string(q, len - 1);
|
tag = string(q, len - 1);
|
||||||
|
|
@ -165,7 +184,7 @@ void item_t::parse_tags(const char * p,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void item_t::append_note(const char * p,
|
void item_t::append_note(const char * p, bool overwrite_existing,
|
||||||
optional<date_t::year_type> current_year)
|
optional<date_t::year_type> current_year)
|
||||||
{
|
{
|
||||||
if (note) {
|
if (note) {
|
||||||
|
|
@ -175,7 +194,7 @@ void item_t::append_note(const char * p,
|
||||||
note = p;
|
note = p;
|
||||||
}
|
}
|
||||||
|
|
||||||
parse_tags(p, current_year);
|
parse_tags(p, overwrite_existing, current_year);
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
|
|
|
||||||
15
src/item.h
15
src/item.h
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2003-2009, John Wiegley. All rights reserved.
|
* Copyright (c) 2003-2010, John Wiegley. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
|
|
@ -106,7 +106,8 @@ public:
|
||||||
|
|
||||||
enum state_t { UNCLEARED = 0, CLEARED, PENDING };
|
enum state_t { UNCLEARED = 0, CLEARED, PENDING };
|
||||||
|
|
||||||
typedef std::map<string, optional<string> > string_map;
|
typedef std::pair<optional<string>, bool> tag_data_t;
|
||||||
|
typedef std::map<string, tag_data_t> string_map;
|
||||||
|
|
||||||
state_t _state;
|
state_t _state;
|
||||||
optional<date_t> _date;
|
optional<date_t> _date;
|
||||||
|
|
@ -156,12 +157,14 @@ public:
|
||||||
virtual optional<string> get_tag(const mask_t& tag_mask,
|
virtual optional<string> get_tag(const mask_t& tag_mask,
|
||||||
const optional<mask_t>& value_mask = none) const;
|
const optional<mask_t>& value_mask = none) const;
|
||||||
|
|
||||||
virtual void set_tag(const string& tag,
|
virtual string_map::iterator
|
||||||
const optional<string>& value = none);
|
set_tag(const string& tag,
|
||||||
|
const optional<string>& value = none,
|
||||||
|
const bool overwrite_existing = true);
|
||||||
|
|
||||||
virtual void parse_tags(const char * p,
|
virtual void parse_tags(const char * p, bool overwrite_existing = true,
|
||||||
optional<date_t::year_type> current_year = none);
|
optional<date_t::year_type> current_year = none);
|
||||||
virtual void append_note(const char * p,
|
virtual void append_note(const char * p, bool overwrite_existing = true,
|
||||||
optional<date_t::year_type> current_year = none);
|
optional<date_t::year_type> current_year = none);
|
||||||
|
|
||||||
static bool use_effective_date;
|
static bool use_effective_date;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2003-2009, John Wiegley. All rights reserved.
|
* Copyright (c) 2003-2010, John Wiegley. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2003-2009, John Wiegley. All rights reserved.
|
* Copyright (c) 2003-2010, John Wiegley. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2003-2009, John Wiegley. All rights reserved.
|
* Copyright (c) 2003-2010, John Wiegley. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2003-2009, John Wiegley. All rights reserved.
|
* Copyright (c) 2003-2010, John Wiegley. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
|
|
@ -44,6 +44,7 @@
|
||||||
|
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "times.h"
|
#include "times.h"
|
||||||
|
#include "mask.h"
|
||||||
|
|
||||||
namespace ledger {
|
namespace ledger {
|
||||||
|
|
||||||
|
|
@ -58,6 +59,11 @@ typedef std::list<xact_t *> xacts_list;
|
||||||
typedef std::list<auto_xact_t *> auto_xacts_list;
|
typedef std::list<auto_xact_t *> auto_xacts_list;
|
||||||
typedef std::list<period_xact_t *> period_xacts_list;
|
typedef std::list<period_xact_t *> period_xacts_list;
|
||||||
|
|
||||||
|
typedef std::pair<mask_t, string> payee_mapping_t;
|
||||||
|
typedef std::list<payee_mapping_t> payee_mappings_t;
|
||||||
|
typedef std::pair<mask_t, account_t *> account_mapping_t;
|
||||||
|
typedef std::list<account_mapping_t> account_mappings_t;
|
||||||
|
|
||||||
class journal_t : public noncopyable
|
class journal_t : public noncopyable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
|
|
@ -110,6 +116,8 @@ public:
|
||||||
period_xacts_list period_xacts;
|
period_xacts_list period_xacts;
|
||||||
std::list<fileinfo_t> sources;
|
std::list<fileinfo_t> sources;
|
||||||
bool was_loaded;
|
bool was_loaded;
|
||||||
|
payee_mappings_t payee_mappings;
|
||||||
|
account_mappings_t account_mappings;
|
||||||
|
|
||||||
journal_t();
|
journal_t();
|
||||||
journal_t(const path& pathname);
|
journal_t(const path& pathname);
|
||||||
|
|
|
||||||
283
src/lookup.cc
Normal file
283
src/lookup.cc
Normal file
|
|
@ -0,0 +1,283 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2003-2010, John Wiegley. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
*
|
||||||
|
* - Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* - Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* - Neither the name of New Artisans LLC nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived from
|
||||||
|
* this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <system.hh>
|
||||||
|
|
||||||
|
#include "lookup.h"
|
||||||
|
#include "unistring.h"
|
||||||
|
|
||||||
|
namespace ledger {
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
typedef std::pair<xact_t *, int> score_entry_t;
|
||||||
|
typedef std::deque<score_entry_t> scorecard_t;
|
||||||
|
typedef std::map<uint32_t, std::size_t> char_positions_map;
|
||||||
|
|
||||||
|
struct score_sorter {
|
||||||
|
bool operator()(const score_entry_t& left,
|
||||||
|
const score_entry_t& right) const {
|
||||||
|
return left.second > right.second;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
typedef std::map<account_t *, int> account_use_map;
|
||||||
|
typedef std::pair<account_t *, int> account_use_pair;
|
||||||
|
|
||||||
|
struct usage_sorter {
|
||||||
|
bool operator()(const account_use_pair& left,
|
||||||
|
const account_use_pair& right) const {
|
||||||
|
return left.second > right.second;
|
||||||
|
}
|
||||||
|
};
|
||||||
|
}
|
||||||
|
|
||||||
|
std::pair<xact_t *, account_t *>
|
||||||
|
lookup_probable_account(const string& ident,
|
||||||
|
xacts_iterator& iter_func,
|
||||||
|
account_t * ref_account)
|
||||||
|
{
|
||||||
|
scorecard_t scores;
|
||||||
|
|
||||||
|
#if !defined(HAVE_BOOST_REGEX_UNICODE)
|
||||||
|
string lident = ident;
|
||||||
|
to_lower(lident);
|
||||||
|
unistring lowered_ident(lident);
|
||||||
|
#else
|
||||||
|
// jww (2010-03-07): Not yet implemented
|
||||||
|
unistring lowered_ident(ident);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
DEBUG("lookup.account",
|
||||||
|
"Looking up identifier '" << lowered_ident.extract() << "'");
|
||||||
|
#if defined(DEBUG_ON)
|
||||||
|
if (ref_account != NULL)
|
||||||
|
DEBUG("lookup.account",
|
||||||
|
" with reference account: " << ref_account->fullname());
|
||||||
|
#endif
|
||||||
|
|
||||||
|
while (xact_t * xact = iter_func()) {
|
||||||
|
#if 0
|
||||||
|
// Only consider transactions from the last two years (jww (2010-03-07):
|
||||||
|
// make this an option)
|
||||||
|
if ((CURRENT_DATE() - xact->date()).days() > 700)
|
||||||
|
continue;
|
||||||
|
#endif
|
||||||
|
|
||||||
|
// An exact match is worth a score of 100 and terminates the search
|
||||||
|
if (ident == xact->payee) {
|
||||||
|
DEBUG("lookup", " we have an exact match, score = 100");
|
||||||
|
scores.push_back(score_entry_t(xact, 100));
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if !defined(HAVE_BOOST_REGEX_UNICODE)
|
||||||
|
string payee = xact->payee;
|
||||||
|
to_lower(payee);
|
||||||
|
unistring value_key(payee);
|
||||||
|
#else
|
||||||
|
// jww (2010-03-07): Not yet implemented
|
||||||
|
unistring value_key(xact->payee);
|
||||||
|
#endif
|
||||||
|
|
||||||
|
DEBUG("lookup", "Considering payee: " << value_key.extract());
|
||||||
|
|
||||||
|
std::size_t index = 0;
|
||||||
|
std::size_t last_match_pos = unistring::npos;
|
||||||
|
int bonus = 0;
|
||||||
|
int score = 0;
|
||||||
|
std::size_t pos;
|
||||||
|
char_positions_map positions;
|
||||||
|
|
||||||
|
// Walk each letter in the source identifier
|
||||||
|
foreach (const uint32_t& ch, lowered_ident.utf32chars) {
|
||||||
|
int addend = 0;
|
||||||
|
bool added_bonus = false;
|
||||||
|
std::size_t value_len = value_key.length();
|
||||||
|
|
||||||
|
pos = value_key.find(ch);
|
||||||
|
|
||||||
|
// Ensure that a letter which has been matched is not matched twice, so
|
||||||
|
// that the two x's of Exxon don't both match to the single x in Oxford.
|
||||||
|
// This part of the loop is very expensive, but avoids a lot of bogus
|
||||||
|
// matches.
|
||||||
|
|
||||||
|
char_positions_map::iterator pi = positions.find(ch);
|
||||||
|
while (pi != positions.end() &&
|
||||||
|
pos != unistring::npos && pos <= (*pi).second &&
|
||||||
|
(*pi).second + 1 < value_len)
|
||||||
|
pos = value_key.find(ch, (*pi).second + 1);
|
||||||
|
|
||||||
|
if (pos != unistring::npos) {
|
||||||
|
if (pi != positions.end())
|
||||||
|
(*pi).second = pos;
|
||||||
|
else
|
||||||
|
positions.insert(char_positions_map::value_type(ch, pos));
|
||||||
|
|
||||||
|
// If it occurs in the same order as the source identifier -- that is,
|
||||||
|
// without intervening letters to break the pattern -- it's worth 10
|
||||||
|
// points. Plus, an extra point is added for every letter in chains
|
||||||
|
// of 3 or more.
|
||||||
|
|
||||||
|
if (last_match_pos == unistring::npos ?
|
||||||
|
index == 0 && pos == 0 : pos == last_match_pos + 1) {
|
||||||
|
DEBUG("lookup",
|
||||||
|
" char " << index << " in-sequence match with bonus " << bonus);
|
||||||
|
addend += 10;
|
||||||
|
if (bonus > 2)
|
||||||
|
addend += bonus - 2;
|
||||||
|
bonus++;
|
||||||
|
added_bonus = true;
|
||||||
|
|
||||||
|
last_match_pos = pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If it occurs in the same general sequence as the source identifier,
|
||||||
|
// it's worth 5 points, plus an extra point if it's within the next 3
|
||||||
|
// characters, and an extra point if it's preceded by a non-alphabetic
|
||||||
|
// character.
|
||||||
|
//
|
||||||
|
// If the letter occurs at all in the target identifier, it's worth 1
|
||||||
|
// point, plus an extra point if it's within 3 characters, and an
|
||||||
|
// extra point if it's preceded by a non-alphabetic character.
|
||||||
|
|
||||||
|
else {
|
||||||
|
bool in_order_match = (last_match_pos != unistring::npos &&
|
||||||
|
pos > last_match_pos);
|
||||||
|
DEBUG("lookup", " char " << index << " " <<
|
||||||
|
(in_order_match ? "in-order" : "out-of-order")
|
||||||
|
<< " match" << (in_order_match && pos - index < 3 ?
|
||||||
|
" with proximity bonus of 1" : ""));
|
||||||
|
|
||||||
|
if (pos < index)
|
||||||
|
addend += 1;
|
||||||
|
else
|
||||||
|
addend += 5;
|
||||||
|
|
||||||
|
if (in_order_match && pos - index < 3)
|
||||||
|
addend++;
|
||||||
|
|
||||||
|
#if !defined(HAVE_BOOST_REGEX_UNICODE)
|
||||||
|
if (pos == 0 || (pos > 0 && !std::isalnum(value_key[pos - 1])))
|
||||||
|
addend++;
|
||||||
|
#else
|
||||||
|
// jww (2010-03-07): Not yet implemented
|
||||||
|
#endif
|
||||||
|
|
||||||
|
last_match_pos = pos;
|
||||||
|
}
|
||||||
|
|
||||||
|
// If the letter does not appear at all, decrease the score by 1
|
||||||
|
|
||||||
|
} else {
|
||||||
|
last_match_pos = unistring::npos;
|
||||||
|
|
||||||
|
DEBUG("lookup", " char " << index << " does not match");
|
||||||
|
addend--;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Finally, decay what is to be added to the score based on its position
|
||||||
|
// in the word. Since credit card payees in particular often share
|
||||||
|
// information at the end (such as the location where the purchase was
|
||||||
|
// made), we want to give much more credence to what occurs at the
|
||||||
|
// beginning. Every 5 character positions from the beginning becomes a
|
||||||
|
// divisor for the addend.
|
||||||
|
|
||||||
|
if ((int(index / 5) + 1) > 1) {
|
||||||
|
DEBUG("lookup",
|
||||||
|
" discounting the addend by / " << (int(index / 5) + 1));
|
||||||
|
addend = int(double(addend) / (int(index / 5) + 1));
|
||||||
|
}
|
||||||
|
|
||||||
|
DEBUG("lookup", " final addend is " << addend);
|
||||||
|
score += addend;
|
||||||
|
DEBUG("lookup", " score is " << score);
|
||||||
|
|
||||||
|
if (! added_bonus)
|
||||||
|
bonus = 0;
|
||||||
|
|
||||||
|
index++;
|
||||||
|
}
|
||||||
|
|
||||||
|
// Only consider payees with a score of 30 or greater
|
||||||
|
if (score >= 30)
|
||||||
|
scores.push_back(score_entry_t(xact, score));
|
||||||
|
}
|
||||||
|
|
||||||
|
// Sort the results by descending score, then look at every account ever
|
||||||
|
// used among the top five. Rank these by number of times used. Lastly,
|
||||||
|
// "decay" any latter accounts, so that we give recently used accounts a
|
||||||
|
// slightly higher rating in case of a tie.
|
||||||
|
|
||||||
|
std::stable_sort(scores.begin(), scores.end(), score_sorter());
|
||||||
|
|
||||||
|
scorecard_t::iterator si = scores.begin();
|
||||||
|
int decay = 0;
|
||||||
|
xact_t * best_xact = si != scores.end() ? (*si).first : NULL;
|
||||||
|
account_use_map account_usage;
|
||||||
|
|
||||||
|
for (int i = 0; i < 5 && si != scores.end(); i++, si++) {
|
||||||
|
DEBUG("lookup.account",
|
||||||
|
"Payee: " << std::setw(5) << std::right << (*si).second <<
|
||||||
|
" - " << (*si).first->payee);
|
||||||
|
|
||||||
|
foreach (post_t * post, (*si).first->posts) {
|
||||||
|
if (! post->has_flags(ITEM_TEMP | ITEM_GENERATED) &&
|
||||||
|
post->account != ref_account &&
|
||||||
|
! post->account->has_flags(ACCOUNT_TEMP | ACCOUNT_GENERATED)) {
|
||||||
|
account_use_map::iterator x = account_usage.find(post->account);
|
||||||
|
if (x == account_usage.end())
|
||||||
|
account_usage.insert(account_use_pair(post->account,
|
||||||
|
((*si).second - decay)));
|
||||||
|
else
|
||||||
|
(*x).second += ((*si).second - decay);
|
||||||
|
}
|
||||||
|
decay++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (account_usage.size() > 0) {
|
||||||
|
#if defined(DEBUG_ON)
|
||||||
|
if (SHOW_DEBUG("lookup.account")) {
|
||||||
|
foreach (const account_use_pair& value, account_usage) {
|
||||||
|
DEBUG("lookup.account",
|
||||||
|
"Account: " << value.second << " - " << value.first->fullname());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
return std::pair<xact_t *, account_t *>
|
||||||
|
(best_xact, (*std::max_element(account_usage.begin(), account_usage.end(),
|
||||||
|
usage_sorter())).first);
|
||||||
|
} else {
|
||||||
|
return std::pair<xact_t *, account_t *>(best_xact, NULL);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace ledger
|
||||||
56
src/lookup.h
Normal file
56
src/lookup.h
Normal file
|
|
@ -0,0 +1,56 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2003-2010, John Wiegley. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
*
|
||||||
|
* - Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* - Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* - Neither the name of New Artisans LLC nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived from
|
||||||
|
* this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @addtogroup data
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file lookup.h
|
||||||
|
* @author John Wiegley
|
||||||
|
*
|
||||||
|
* @ingroup data
|
||||||
|
*/
|
||||||
|
#ifndef _LOOKUP_H
|
||||||
|
#define _LOOKUP_H
|
||||||
|
|
||||||
|
#include "iterators.h"
|
||||||
|
|
||||||
|
namespace ledger {
|
||||||
|
|
||||||
|
std::pair<xact_t *, account_t *>
|
||||||
|
lookup_probable_account(const string& ident,
|
||||||
|
xacts_iterator& iter_func,
|
||||||
|
account_t * ref_account = NULL);
|
||||||
|
|
||||||
|
} // namespace ledger
|
||||||
|
|
||||||
|
#endif // _LOOKUP_H
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2003-2009, John Wiegley. All rights reserved.
|
* Copyright (c) 2003-2010, John Wiegley. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
|
|
|
||||||
36
src/mask.cc
36
src/mask.cc
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2003-2009, John Wiegley. All rights reserved.
|
* Copyright (c) 2003-2010, John Wiegley. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
|
|
@ -52,4 +52,38 @@ mask_t& mask_t::operator=(const string& pat)
|
||||||
return *this;
|
return *this;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
mask_t& mask_t::assign_glob(const string& pat)
|
||||||
|
{
|
||||||
|
string re_pat = "";
|
||||||
|
string::size_type len = pat.length();
|
||||||
|
for (string::size_type i = 0; i < len; i++) {
|
||||||
|
switch (pat[i]) {
|
||||||
|
case '?':
|
||||||
|
re_pat += '.';
|
||||||
|
break;
|
||||||
|
case '*':
|
||||||
|
re_pat += ".*";
|
||||||
|
break;
|
||||||
|
case '[':
|
||||||
|
while (i < len && pat[i] != ']')
|
||||||
|
re_pat += pat[i++];
|
||||||
|
if (i < len)
|
||||||
|
re_pat += pat[i];
|
||||||
|
break;
|
||||||
|
|
||||||
|
case '\\':
|
||||||
|
if (i + 1 < len) {
|
||||||
|
re_pat += pat[++i];
|
||||||
|
break;
|
||||||
|
} else {
|
||||||
|
// fallthrough...
|
||||||
|
}
|
||||||
|
default:
|
||||||
|
re_pat += pat[i];
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
return (*this = re_pat);
|
||||||
|
}
|
||||||
|
|
||||||
} // namespace ledger
|
} // namespace ledger
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2003-2009, John Wiegley. All rights reserved.
|
* Copyright (c) 2003-2010, John Wiegley. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
|
|
@ -73,7 +73,11 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
mask_t& operator=(const string& other);
|
mask_t& operator=(const string& other);
|
||||||
|
mask_t& assign_glob(const string& other);
|
||||||
|
|
||||||
|
bool operator<(const mask_t& other) const {
|
||||||
|
return expr < other.expr;
|
||||||
|
}
|
||||||
bool operator==(const mask_t& other) const {
|
bool operator==(const mask_t& other) const {
|
||||||
return expr == other.expr;
|
return expr == other.expr;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2003-2009, John Wiegley. All rights reserved.
|
* Copyright (c) 2003-2010, John Wiegley. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
|
|
|
||||||
2
src/op.h
2
src/op.h
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2003-2009, John Wiegley. All rights reserved.
|
* Copyright (c) 2003-2010, John Wiegley. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2003-2009, John Wiegley. All rights reserved.
|
* Copyright (c) 2003-2010, John Wiegley. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2003-2009, John Wiegley. All rights reserved.
|
* Copyright (c) 2003-2010, John Wiegley. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2003-2009, John Wiegley. All rights reserved.
|
* Copyright (c) 2003-2010, John Wiegley. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
|
|
@ -42,10 +42,8 @@ namespace ledger {
|
||||||
|
|
||||||
format_posts::format_posts(report_t& _report,
|
format_posts::format_posts(report_t& _report,
|
||||||
const string& format,
|
const string& format,
|
||||||
bool _print_raw,
|
|
||||||
const optional<string>& _prepend_format)
|
const optional<string>& _prepend_format)
|
||||||
: report(_report), last_xact(NULL), last_post(NULL),
|
: report(_report), last_xact(NULL), last_post(NULL)
|
||||||
print_raw(_print_raw)
|
|
||||||
{
|
{
|
||||||
TRACE_CTOR(format_posts, "report&, const string&, bool");
|
TRACE_CTOR(format_posts, "report&, const string&, bool");
|
||||||
|
|
||||||
|
|
@ -80,24 +78,8 @@ void format_posts::operator()(post_t& post)
|
||||||
{
|
{
|
||||||
std::ostream& out(report.output_stream);
|
std::ostream& out(report.output_stream);
|
||||||
|
|
||||||
if (print_raw) {
|
if (! post.has_xdata() ||
|
||||||
if (! post.has_xdata() ||
|
! post.xdata().has_flags(POST_EXT_DISPLAYED)) {
|
||||||
! post.xdata().has_flags(POST_EXT_DISPLAYED)) {
|
|
||||||
if (last_xact != post.xact) {
|
|
||||||
if (last_xact) {
|
|
||||||
bind_scope_t xact_scope(report, *last_xact);
|
|
||||||
out << between_format(xact_scope);
|
|
||||||
}
|
|
||||||
print_item(out, *post.xact);
|
|
||||||
out << '\n';
|
|
||||||
last_xact = post.xact;
|
|
||||||
}
|
|
||||||
post.xdata().add_flags(POST_EXT_DISPLAYED);
|
|
||||||
last_post = &post;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
else if (! post.has_xdata() ||
|
|
||||||
! post.xdata().has_flags(POST_EXT_DISPLAYED)) {
|
|
||||||
bind_scope_t bound_scope(report, post);
|
bind_scope_t bound_scope(report, post);
|
||||||
|
|
||||||
if (prepend_format)
|
if (prepend_format)
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2003-2009, John Wiegley. All rights reserved.
|
* Copyright (c) 2003-2010, John Wiegley. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
|
|
@ -63,11 +63,9 @@ protected:
|
||||||
format_t prepend_format;
|
format_t prepend_format;
|
||||||
xact_t * last_xact;
|
xact_t * last_xact;
|
||||||
post_t * last_post;
|
post_t * last_post;
|
||||||
bool print_raw;
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
format_posts(report_t& _report, const string& format,
|
format_posts(report_t& _report, const string& format,
|
||||||
bool _print_raw = false,
|
|
||||||
const optional<string>& _prepend_format = none);
|
const optional<string>& _prepend_format = none);
|
||||||
virtual ~format_posts() {
|
virtual ~format_posts() {
|
||||||
TRACE_DTOR(format_posts);
|
TRACE_DTOR(format_posts);
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2003-2009, John Wiegley. All rights reserved.
|
* Copyright (c) 2003-2010, John Wiegley. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2003-2009, John Wiegley. All rights reserved.
|
* Copyright (c) 2003-2010, John Wiegley. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2003-2009, John Wiegley. All rights reserved.
|
* Copyright (c) 2003-2010, John Wiegley. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2003-2009, John Wiegley. All rights reserved.
|
* Copyright (c) 2003-2010, John Wiegley. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2003-2009, John Wiegley. All rights reserved.
|
* Copyright (c) 2003-2010, John Wiegley. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
|
|
@ -576,7 +576,7 @@ void to_xml(std::ostream& out, const post_t& post)
|
||||||
if (post.metadata) {
|
if (post.metadata) {
|
||||||
push_xml y(out, "metadata");
|
push_xml y(out, "metadata");
|
||||||
foreach (const item_t::string_map::value_type& pair, *post.metadata) {
|
foreach (const item_t::string_map::value_type& pair, *post.metadata) {
|
||||||
if (pair.second) {
|
if (pair.second.first) {
|
||||||
push_xml z(out, "variable");
|
push_xml z(out, "variable");
|
||||||
{
|
{
|
||||||
push_xml z(out, "key");
|
push_xml z(out, "key");
|
||||||
|
|
@ -584,7 +584,7 @@ void to_xml(std::ostream& out, const post_t& post)
|
||||||
}
|
}
|
||||||
{
|
{
|
||||||
push_xml z(out, "value");
|
push_xml z(out, "value");
|
||||||
out << y.guard(*pair.second);
|
out << y.guard(*pair.second.first);
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
push_xml z(out, "tag");
|
push_xml z(out, "tag");
|
||||||
|
|
|
||||||
11
src/post.h
11
src/post.h
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2003-2009, John Wiegley. All rights reserved.
|
* Copyright (c) 2003-2010, John Wiegley. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
|
|
@ -52,10 +52,11 @@ class account_t;
|
||||||
class post_t : public item_t
|
class post_t : public item_t
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
#define POST_VIRTUAL 0x10 // the account was specified with (parens)
|
#define POST_VIRTUAL 0x08 // the account was specified with (parens)
|
||||||
#define POST_MUST_BALANCE 0x20 // posting must balance in the transaction
|
#define POST_MUST_BALANCE 0x10 // posting must balance in the transaction
|
||||||
#define POST_CALCULATED 0x40 // posting's amount was calculated
|
#define POST_CALCULATED 0x20 // posting's amount was calculated
|
||||||
#define POST_COST_CALCULATED 0x80 // posting's cost was calculated
|
#define POST_COST_CALCULATED 0x40 // posting's cost was calculated
|
||||||
|
#define POST_COST_IN_FULL 0x80 // cost specified using @@
|
||||||
|
|
||||||
xact_t * xact; // only set for posts of regular xacts
|
xact_t * xact; // only set for posts of regular xacts
|
||||||
account_t * account;
|
account_t * account;
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2003-2009, John Wiegley. All rights reserved.
|
* Copyright (c) 2003-2010, John Wiegley. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2003-2009, John Wiegley. All rights reserved.
|
* Copyright (c) 2003-2010, John Wiegley. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2003-2009, John Wiegley. All rights reserved.
|
* Copyright (c) 2003-2010, John Wiegley. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2003-2009, John Wiegley. All rights reserved.
|
* Copyright (c) 2003-2010, John Wiegley. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
|
|
|
||||||
208
src/print.cc
Normal file
208
src/print.cc
Normal file
|
|
@ -0,0 +1,208 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2003-2010, John Wiegley. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
*
|
||||||
|
* - Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* - Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* - Neither the name of New Artisans LLC nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived from
|
||||||
|
* this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <system.hh>
|
||||||
|
|
||||||
|
#include "print.h"
|
||||||
|
#include "xact.h"
|
||||||
|
#include "post.h"
|
||||||
|
#include "account.h"
|
||||||
|
#include "session.h"
|
||||||
|
#include "report.h"
|
||||||
|
|
||||||
|
namespace ledger {
|
||||||
|
|
||||||
|
print_xacts::print_xacts(report_t& _report,
|
||||||
|
bool _print_raw)
|
||||||
|
: report(_report), print_raw(_print_raw)
|
||||||
|
{
|
||||||
|
TRACE_CTOR(print_xacts, "report&, bool");
|
||||||
|
}
|
||||||
|
|
||||||
|
namespace {
|
||||||
|
void print_note(std::ostream& out, const string& note)
|
||||||
|
{
|
||||||
|
if (note.length() > 15)
|
||||||
|
out << "\n ;";
|
||||||
|
else
|
||||||
|
out << " ;";
|
||||||
|
|
||||||
|
bool need_separator = false;
|
||||||
|
for (const char * p = note.c_str(); *p; p++) {
|
||||||
|
if (*p == '\n') {
|
||||||
|
need_separator = true;
|
||||||
|
} else {
|
||||||
|
if (need_separator) {
|
||||||
|
out << "\n ;";
|
||||||
|
need_separator = false;
|
||||||
|
}
|
||||||
|
out << *p;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_xact(report_t& report, std::ostream& out, xact_t& xact)
|
||||||
|
{
|
||||||
|
out << format_date(item_t::use_effective_date ?
|
||||||
|
xact.date() : xact.actual_date(),
|
||||||
|
FMT_WRITTEN);
|
||||||
|
if (! item_t::use_effective_date && xact.effective_date())
|
||||||
|
out << '=' << format_date(*xact.effective_date(), FMT_WRITTEN);
|
||||||
|
out << ' ';
|
||||||
|
|
||||||
|
out << (xact.state() == item_t::CLEARED ? "* " :
|
||||||
|
(xact.state() == item_t::PENDING ? "! " : ""));
|
||||||
|
|
||||||
|
if (xact.code)
|
||||||
|
out << '(' << *xact.code << ") ";
|
||||||
|
|
||||||
|
out << xact.payee;
|
||||||
|
|
||||||
|
if (xact.note)
|
||||||
|
print_note(out, *xact.note);
|
||||||
|
out << '\n';
|
||||||
|
|
||||||
|
if (xact.metadata) {
|
||||||
|
foreach (const item_t::string_map::value_type& data, *xact.metadata) {
|
||||||
|
if (! data.second.second) {
|
||||||
|
out << " ; ";
|
||||||
|
if (data.second.first)
|
||||||
|
out << data.first << ": " << *data.second.first;
|
||||||
|
else
|
||||||
|
out << ':' << data.first << ":";
|
||||||
|
out << '\n';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (post_t * post, xact.posts) {
|
||||||
|
if (post->has_flags(ITEM_TEMP | ITEM_GENERATED) &&
|
||||||
|
! report.HANDLED(print_virtual))
|
||||||
|
continue;
|
||||||
|
|
||||||
|
out << " ";
|
||||||
|
|
||||||
|
std::ostringstream buf;
|
||||||
|
|
||||||
|
if (xact.state() == item_t::UNCLEARED)
|
||||||
|
buf << (post->state() == item_t::CLEARED ? "* " :
|
||||||
|
(post->state() == item_t::PENDING ? "! " : ""));
|
||||||
|
|
||||||
|
if (post->has_flags(POST_VIRTUAL)) {
|
||||||
|
if (post->has_flags(POST_MUST_BALANCE))
|
||||||
|
buf << '[';
|
||||||
|
else
|
||||||
|
buf << '(';
|
||||||
|
}
|
||||||
|
|
||||||
|
buf << post->account->fullname();
|
||||||
|
|
||||||
|
if (post->has_flags(POST_VIRTUAL)) {
|
||||||
|
if (post->has_flags(POST_MUST_BALANCE))
|
||||||
|
buf << ']';
|
||||||
|
else
|
||||||
|
buf << ')';
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! post->has_flags(POST_CALCULATED) || report.HANDLED(print_virtual)) {
|
||||||
|
unistring name(buf.str());
|
||||||
|
|
||||||
|
out << name.extract();
|
||||||
|
int slip = 36 - static_cast<int>(name.length());
|
||||||
|
if (slip > 0)
|
||||||
|
out << string(slip, ' ');
|
||||||
|
|
||||||
|
std::ostringstream amt_str;
|
||||||
|
report.scrub(post->amount).print(amt_str, 12, -1, true);
|
||||||
|
string amt = amt_str.str();
|
||||||
|
string trimmed_amt(amt);
|
||||||
|
trim_left(trimmed_amt);
|
||||||
|
int amt_slip = (static_cast<int>(amt.length()) -
|
||||||
|
static_cast<int>(trimmed_amt.length()));
|
||||||
|
if (slip + amt_slip < 2)
|
||||||
|
out << string(2 - (slip + amt_slip), ' ');
|
||||||
|
out << amt;
|
||||||
|
|
||||||
|
if (post->cost && ! post->has_flags(POST_CALCULATED)) {
|
||||||
|
if (post->has_flags(POST_COST_IN_FULL))
|
||||||
|
out << " @@ " << report.scrub(post->cost->abs());
|
||||||
|
else
|
||||||
|
out << " @ " << report.scrub((*post->cost / post->amount).abs());
|
||||||
|
}
|
||||||
|
|
||||||
|
if (post->assigned_amount)
|
||||||
|
out << " = " << report.scrub(*post->assigned_amount);
|
||||||
|
} else {
|
||||||
|
out << buf.str();
|
||||||
|
}
|
||||||
|
|
||||||
|
if (post->note)
|
||||||
|
print_note(out, *post->note);
|
||||||
|
out << '\n';
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_xacts::flush()
|
||||||
|
{
|
||||||
|
std::ostream& out(report.output_stream);
|
||||||
|
|
||||||
|
bool first = true;
|
||||||
|
foreach (xact_t * xact, xacts) {
|
||||||
|
if (first)
|
||||||
|
first = false;
|
||||||
|
else
|
||||||
|
out << '\n';
|
||||||
|
|
||||||
|
if (print_raw) {
|
||||||
|
print_item(out, *xact);
|
||||||
|
out << '\n';
|
||||||
|
} else {
|
||||||
|
print_xact(report, out, *xact);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
out.flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
void print_xacts::operator()(post_t& post)
|
||||||
|
{
|
||||||
|
if (! post.has_xdata() ||
|
||||||
|
! post.xdata().has_flags(POST_EXT_DISPLAYED)) {
|
||||||
|
if (xacts_present.find(post.xact) == xacts_present.end()) {
|
||||||
|
xacts_present.insert(xacts_present_map::value_type(post.xact, true));
|
||||||
|
xacts.push_back(post.xact);
|
||||||
|
}
|
||||||
|
post.xdata().add_flags(POST_EXT_DISPLAYED);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace ledger
|
||||||
79
src/print.h
Normal file
79
src/print.h
Normal file
|
|
@ -0,0 +1,79 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2003-2010, John Wiegley. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
*
|
||||||
|
* - Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* - Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* - Neither the name of New Artisans LLC nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived from
|
||||||
|
* this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @addtogroup data
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file convert.h
|
||||||
|
* @author John Wiegley
|
||||||
|
*
|
||||||
|
* @ingroup data
|
||||||
|
*/
|
||||||
|
#ifndef _PRINT_H
|
||||||
|
#define _PRINT_H
|
||||||
|
|
||||||
|
#include "chain.h"
|
||||||
|
#include "predicate.h"
|
||||||
|
#include "format.h"
|
||||||
|
|
||||||
|
namespace ledger {
|
||||||
|
|
||||||
|
class xact_t;
|
||||||
|
class post_t;
|
||||||
|
class report_t;
|
||||||
|
|
||||||
|
class print_xacts : public item_handler<post_t>
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
typedef std::list<xact_t *> xacts_list;
|
||||||
|
typedef std::map<xact_t *, bool> xacts_present_map;
|
||||||
|
|
||||||
|
report_t& report;
|
||||||
|
xacts_present_map xacts_present;
|
||||||
|
xacts_list xacts;
|
||||||
|
bool print_raw;
|
||||||
|
|
||||||
|
public:
|
||||||
|
print_xacts(report_t& _report, bool _print_raw = false);
|
||||||
|
virtual ~print_xacts() {
|
||||||
|
TRACE_DTOR(print_xacts);
|
||||||
|
}
|
||||||
|
|
||||||
|
virtual void flush();
|
||||||
|
virtual void operator()(post_t& post);
|
||||||
|
};
|
||||||
|
|
||||||
|
|
||||||
|
} // namespace ledger
|
||||||
|
|
||||||
|
#endif // _PRINT_H
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2003-2009, John Wiegley. All rights reserved.
|
* Copyright (c) 2003-2010, John Wiegley. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions
|
* modification, are permitted provided that the following conditions
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2003-2009, John Wiegley. All rights reserved.
|
* Copyright (c) 2003-2010, John Wiegley. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2003-2009, John Wiegley. All rights reserved.
|
* Copyright (c) 2003-2010, John Wiegley. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2003-2009, John Wiegley. All rights reserved.
|
* Copyright (c) 2003-2010, John Wiegley. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2003-2009, John Wiegley. All rights reserved.
|
* Copyright (c) 2003-2010, John Wiegley. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2003-2009, John Wiegley. All rights reserved.
|
* Copyright (c) 2003-2010, John Wiegley. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2003-2009, John Wiegley. All rights reserved.
|
* Copyright (c) 2003-2010, John Wiegley. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2003-2009, John Wiegley. All rights reserved.
|
* Copyright (c) 2003-2010, John Wiegley. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2003-2009, John Wiegley. All rights reserved.
|
* Copyright (c) 2003-2010, John Wiegley. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2003-2009, John Wiegley. All rights reserved.
|
* Copyright (c) 2003-2010, John Wiegley. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2003-2009, John Wiegley. All rights reserved.
|
* Copyright (c) 2003-2010, John Wiegley. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2003-2009, John Wiegley. All rights reserved.
|
* Copyright (c) 2003-2010, John Wiegley. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2003-2009, John Wiegley. All rights reserved.
|
* Copyright (c) 2003-2010, John Wiegley. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2003-2009, John Wiegley. All rights reserved.
|
* Copyright (c) 2003-2010, John Wiegley. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2003-2009, John Wiegley. All rights reserved.
|
* Copyright (c) 2003-2010, John Wiegley. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2003-2009, John Wiegley. All rights reserved.
|
* Copyright (c) 2003-2010, John Wiegley. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2003-2009, John Wiegley. All rights reserved.
|
* Copyright (c) 2003-2010, John Wiegley. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2003-2009, John Wiegley. All rights reserved.
|
* Copyright (c) 2003-2010, John Wiegley. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2003-2009, John Wiegley. All rights reserved.
|
* Copyright (c) 2003-2010, John Wiegley. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2003-2009, John Wiegley. All rights reserved.
|
* Copyright (c) 2003-2010, John Wiegley. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2003-2009, John Wiegley. All rights reserved.
|
* Copyright (c) 2003-2010, John Wiegley. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2003-2009, John Wiegley. All rights reserved.
|
* Copyright (c) 2003-2010, John Wiegley. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
|
|
|
||||||
|
|
@ -1,5 +1,5 @@
|
||||||
/*
|
/*
|
||||||
* Copyright (c) 2003-2009, John Wiegley. All rights reserved.
|
* Copyright (c) 2003-2010, John Wiegley. All rights reserved.
|
||||||
*
|
*
|
||||||
* Redistribution and use in source and binary forms, with or without
|
* Redistribution and use in source and binary forms, with or without
|
||||||
* modification, are permitted provided that the following conditions are
|
* modification, are permitted provided that the following conditions are
|
||||||
|
|
|
||||||
Some files were not shown because too many files have changed in this diff Show more
Loading…
Add table
Reference in a new issue