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/refman.pdf
|
||||
/doc/report/
|
||||
/doc/*.aux
|
||||
/doc/*.cp
|
||||
/doc/*.fn
|
||||
/doc/*.ky
|
||||
/doc/*.log
|
||||
/doc/*.pdf
|
||||
/doc/*.pg
|
||||
/doc/*.toc
|
||||
/doc/*.tp
|
||||
/doc/*.vr
|
||||
/expr_tests
|
||||
/libtool
|
||||
/math_tests
|
||||
|
|
|
|||
|
|
@ -5,7 +5,7 @@
|
|||
|
||||
@dircategory User Applications
|
||||
@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
|
||||
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.
|
||||
@end copying
|
||||
|
||||
@documentencoding iso-8859-1
|
||||
@documentencoding utf-8
|
||||
|
||||
@iftex
|
||||
@finalout
|
||||
|
|
@ -4107,4 +4107,19 @@ parser_t
|
|||
|
||||
@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
|
||||
|
|
|
|||
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 'pcomplete)
|
||||
|
||||
(defvar ledger-version "1.2"
|
||||
(defvar ledger-version "1.3"
|
||||
"The version of ledger.el currently loaded")
|
||||
|
||||
(defgroup ledger nil
|
||||
|
|
@ -1226,7 +1226,7 @@ the default."
|
|||
"Align amounts in the current region.
|
||||
This is done so that the last digit falls in COLUMN, which defaults to 52."
|
||||
(interactive "p")
|
||||
(if (= column 1)
|
||||
(if (or (null column) (= column 1))
|
||||
(setq column 52))
|
||||
(save-excursion
|
||||
(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
|
||||
* 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
|
||||
* 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
|
||||
* 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
|
||||
* 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
|
||||
* 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
|
||||
* 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
|
||||
* 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
|
||||
* 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
|
||||
* 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
|
||||
* 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
|
||||
* 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
|
||||
* 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
|
||||
* modification, are permitted provided that the following conditions are
|
||||
|
|
@ -112,10 +112,12 @@ post_handler_ptr chain_post_handlers(report_t& report,
|
|||
else
|
||||
handler.reset(new sort_posts(handler, report.HANDLER(sort_).str()));
|
||||
}
|
||||
#if 0
|
||||
else if (! report.HANDLED(period_) &&
|
||||
! report.HANDLED(unsorted)) {
|
||||
handler.reset(new sort_posts(handler, "date"));
|
||||
}
|
||||
#endif
|
||||
|
||||
// collapse_posts causes xacts with multiple posts to appear as xacts
|
||||
// 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_)) {
|
||||
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,
|
||||
report.session.journal->master, pivot,
|
||||
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
|
||||
* 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
|
||||
* 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
|
||||
* 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
|
||||
* 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
|
||||
* 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
|
||||
* modification, are permitted provided that the following conditions are
|
||||
|
|
@ -38,7 +38,8 @@
|
|||
#include "journal.h"
|
||||
#include "session.h"
|
||||
#include "report.h"
|
||||
#include "output.h"
|
||||
#include "lookup.h"
|
||||
#include "print.h"
|
||||
|
||||
namespace ledger {
|
||||
|
||||
|
|
@ -240,20 +241,27 @@ void draft_t::parse_args(const value_t& args)
|
|||
xact_t * draft_t::insert(journal_t& journal)
|
||||
{
|
||||
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);
|
||||
|
||||
for (xacts_list::reverse_iterator j = journal.xacts.rbegin();
|
||||
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;
|
||||
xacts_iterator xi(journal);
|
||||
if (xact_t * xact = lookup_probable_account(tmpl->payee_mask.str(), xi).first) {
|
||||
DEBUG("derive.xact", "Found payee by lookup: transaction on line "
|
||||
<< xact->pos->beg_line);
|
||||
matching = xact;
|
||||
} else {
|
||||
for (xacts_list::reverse_iterator j = journal.xacts.rbegin();
|
||||
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) {
|
||||
added->payee = matching->payee;
|
||||
added->code = matching->code;
|
||||
added->note = matching->note;
|
||||
//added->code = matching->code;
|
||||
//added->note = matching->note;
|
||||
|
||||
#if defined(DEBUG_ON)
|
||||
DEBUG("derive.xact", "Setting payee from match: " << added->payee);
|
||||
if (added->code)
|
||||
DEBUG("derive.xact", "Setting code from match: " << *added->code);
|
||||
if (added->note)
|
||||
DEBUG("derive.xact", "Setting note from match: " << *added->note);
|
||||
//if (added->code)
|
||||
// DEBUG("derive.xact", "Setting code from match: " << *added->code);
|
||||
//if (added->note)
|
||||
// DEBUG("derive.xact", "Setting note from match: " << *added->note);
|
||||
#endif
|
||||
} else {
|
||||
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
|
||||
report.HANDLER(limit_).on(string("#xact"), "actual");
|
||||
|
||||
report.xact_report(post_handler_ptr
|
||||
(new format_posts(report,
|
||||
report.HANDLER(print_format_).str())),
|
||||
*new_xact);
|
||||
report.xact_report(post_handler_ptr(new print_xacts(report)), *new_xact);
|
||||
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
|
||||
* 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
|
||||
* 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
|
||||
* 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
|
||||
* 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
|
||||
* 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
|
||||
* 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
|
||||
* 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
|
||||
* 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
|
||||
* modification, are permitted provided that the following conditions are
|
||||
|
|
@ -107,6 +107,9 @@ void truncate_xacts::flush()
|
|||
|
||||
void truncate_xacts::operator()(post_t& post)
|
||||
{
|
||||
if (completed)
|
||||
return;
|
||||
|
||||
if (last_xact != post.xact) {
|
||||
if (last_xact)
|
||||
xacts_seen++;
|
||||
|
|
@ -114,8 +117,11 @@ void truncate_xacts::operator()(post_t& post)
|
|||
}
|
||||
|
||||
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;
|
||||
}
|
||||
|
||||
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
|
||||
* modification, are permitted provided that the following conditions are
|
||||
|
|
@ -125,8 +125,9 @@ public:
|
|||
|
||||
class truncate_xacts : public item_handler<post_t>
|
||||
{
|
||||
int head_count;
|
||||
int tail_count;
|
||||
int head_count;
|
||||
int tail_count;
|
||||
bool completed;
|
||||
|
||||
posts_list posts;
|
||||
std::size_t xacts_seen;
|
||||
|
|
@ -139,7 +140,7 @@ public:
|
|||
int _head_count, int _tail_count)
|
||||
: item_handler<post_t>(handler),
|
||||
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");
|
||||
}
|
||||
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
|
||||
* 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
|
||||
* 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
|
||||
* 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
|
||||
* 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
|
||||
* 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
|
||||
* 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
|
||||
* modification, are permitted provided that the following conditions
|
||||
|
|
@ -110,7 +110,7 @@ public:
|
|||
out <<
|
||||
"Ledger " << ledger::version << _(", the command-line accounting tool");
|
||||
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\
|
||||
See LICENSE file included with the distribution for details and disclaimer.");
|
||||
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
|
||||
* 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
|
||||
* 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
|
||||
* 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 (! value_mask)
|
||||
return true;
|
||||
else if (data.second)
|
||||
return value_mask->match(*data.second);
|
||||
else if (data.second.first)
|
||||
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);
|
||||
if (i != metadata->end()) {
|
||||
DEBUG("item.meta", "Found the item!");
|
||||
return (*i).second;
|
||||
return (*i).second.first;
|
||||
}
|
||||
}
|
||||
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) {
|
||||
if (tag_mask.match(data.first) &&
|
||||
(! value_mask ||
|
||||
(data.second && value_mask->match(*data.second))))
|
||||
return data.second;
|
||||
(data.second.first && value_mask->match(*data.second.first))))
|
||||
return data.second.first;
|
||||
}
|
||||
}
|
||||
return none;
|
||||
}
|
||||
|
||||
void item_t::set_tag(const string& tag,
|
||||
const optional<string>& value)
|
||||
item_t::string_map::iterator
|
||||
item_t::set_tag(const string& tag,
|
||||
const optional<string>& value,
|
||||
const bool overwrite_existing)
|
||||
{
|
||||
assert(! tag.empty());
|
||||
|
||||
if (! metadata)
|
||||
metadata = string_map();
|
||||
|
||||
DEBUG("item.meta", "Setting tag '" << tag << "' to value '"
|
||||
<< (value ? *value : string("<none>")) << "'");
|
||||
|
||||
std::pair<string_map::iterator, bool> result
|
||||
= metadata->insert(string_map::value_type(tag, value));
|
||||
assert(result.second);
|
||||
optional<string> data = value;
|
||||
if (data && data->empty())
|
||||
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)
|
||||
{
|
||||
if (const char * b = std::strchr(p, '[')) {
|
||||
|
|
@ -149,15 +165,18 @@ void item_t::parse_tags(const char * p,
|
|||
q = std::strtok(NULL, " \t")) {
|
||||
const string::size_type len = std::strlen(q);
|
||||
if (! tag.empty()) {
|
||||
if (! has_tag(tag))
|
||||
set_tag(tag, string(p + (q - buf.get())));
|
||||
string_map::iterator i = set_tag(tag, string(p + (q - buf.get())),
|
||||
overwrite_existing);
|
||||
(*i).second.second = true;
|
||||
break;
|
||||
}
|
||||
else if (q[0] == ':' && q[len - 1] == ':') { // a series of tags
|
||||
for (char * r = std::strtok(q + 1, ":");
|
||||
r;
|
||||
r = std::strtok(NULL, ":"))
|
||||
set_tag(r);
|
||||
r = std::strtok(NULL, ":")) {
|
||||
string_map::iterator i = set_tag(r, none, overwrite_existing);
|
||||
(*i).second.second = true;
|
||||
}
|
||||
}
|
||||
else if (q[len - 1] == ':') { // a metadata setting
|
||||
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)
|
||||
{
|
||||
if (note) {
|
||||
|
|
@ -175,7 +194,7 @@ void item_t::append_note(const char * p,
|
|||
note = p;
|
||||
}
|
||||
|
||||
parse_tags(p, current_year);
|
||||
parse_tags(p, overwrite_existing, current_year);
|
||||
}
|
||||
|
||||
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
|
||||
* modification, are permitted provided that the following conditions are
|
||||
|
|
@ -106,7 +106,8 @@ public:
|
|||
|
||||
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;
|
||||
optional<date_t> _date;
|
||||
|
|
@ -156,12 +157,14 @@ public:
|
|||
virtual optional<string> get_tag(const mask_t& tag_mask,
|
||||
const optional<mask_t>& value_mask = none) const;
|
||||
|
||||
virtual void set_tag(const string& tag,
|
||||
const optional<string>& value = none);
|
||||
virtual string_map::iterator
|
||||
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);
|
||||
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);
|
||||
|
||||
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
|
||||
* 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
|
||||
* 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
|
||||
* 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
|
||||
* modification, are permitted provided that the following conditions are
|
||||
|
|
@ -44,6 +44,7 @@
|
|||
|
||||
#include "utils.h"
|
||||
#include "times.h"
|
||||
#include "mask.h"
|
||||
|
||||
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<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
|
||||
{
|
||||
public:
|
||||
|
|
@ -110,6 +116,8 @@ public:
|
|||
period_xacts_list period_xacts;
|
||||
std::list<fileinfo_t> sources;
|
||||
bool was_loaded;
|
||||
payee_mappings_t payee_mappings;
|
||||
account_mappings_t account_mappings;
|
||||
|
||||
journal_t();
|
||||
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
|
||||
* 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
|
||||
* modification, are permitted provided that the following conditions are
|
||||
|
|
@ -52,4 +52,38 @@ mask_t& mask_t::operator=(const string& pat)
|
|||
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
|
||||
|
|
|
|||
|
|
@ -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
|
||||
* modification, are permitted provided that the following conditions are
|
||||
|
|
@ -73,7 +73,11 @@ public:
|
|||
}
|
||||
|
||||
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 {
|
||||
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
|
||||
* 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
|
||||
* 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
|
||||
* 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
|
||||
* 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
|
||||
* modification, are permitted provided that the following conditions are
|
||||
|
|
@ -42,10 +42,8 @@ namespace ledger {
|
|||
|
||||
format_posts::format_posts(report_t& _report,
|
||||
const string& format,
|
||||
bool _print_raw,
|
||||
const optional<string>& _prepend_format)
|
||||
: report(_report), last_xact(NULL), last_post(NULL),
|
||||
print_raw(_print_raw)
|
||||
: report(_report), last_xact(NULL), last_post(NULL)
|
||||
{
|
||||
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);
|
||||
|
||||
if (print_raw) {
|
||||
if (! post.has_xdata() ||
|
||||
! 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)) {
|
||||
if (! post.has_xdata() ||
|
||||
! post.xdata().has_flags(POST_EXT_DISPLAYED)) {
|
||||
bind_scope_t bound_scope(report, post);
|
||||
|
||||
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
|
||||
* modification, are permitted provided that the following conditions are
|
||||
|
|
@ -63,11 +63,9 @@ protected:
|
|||
format_t prepend_format;
|
||||
xact_t * last_xact;
|
||||
post_t * last_post;
|
||||
bool print_raw;
|
||||
|
||||
public:
|
||||
format_posts(report_t& _report, const string& format,
|
||||
bool _print_raw = false,
|
||||
const optional<string>& _prepend_format = none);
|
||||
virtual ~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
|
||||
* 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
|
||||
* 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
|
||||
* 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
|
||||
* 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
|
||||
* 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) {
|
||||
push_xml y(out, "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, "key");
|
||||
|
|
@ -584,7 +584,7 @@ void to_xml(std::ostream& out, const post_t& post)
|
|||
}
|
||||
{
|
||||
push_xml z(out, "value");
|
||||
out << y.guard(*pair.second);
|
||||
out << y.guard(*pair.second.first);
|
||||
}
|
||||
} else {
|
||||
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
|
||||
* modification, are permitted provided that the following conditions are
|
||||
|
|
@ -52,10 +52,11 @@ class account_t;
|
|||
class post_t : public item_t
|
||||
{
|
||||
public:
|
||||
#define POST_VIRTUAL 0x10 // the account was specified with (parens)
|
||||
#define POST_MUST_BALANCE 0x20 // posting must balance in the transaction
|
||||
#define POST_CALCULATED 0x40 // posting's amount was calculated
|
||||
#define POST_COST_CALCULATED 0x80 // posting's cost was calculated
|
||||
#define POST_VIRTUAL 0x08 // the account was specified with (parens)
|
||||
#define POST_MUST_BALANCE 0x10 // posting must balance in the transaction
|
||||
#define POST_CALCULATED 0x20 // posting's amount 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
|
||||
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
|
||||
* 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
|
||||
* 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
|
||||
* 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
|
||||
* 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
|
||||
* 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
|
||||
* 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
|
||||
* 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
|
||||
* 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
|
||||
* 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
|
||||
* 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
|
||||
* 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
|
||||
* 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
|
||||
* 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
|
||||
* 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
|
||||
* 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
|
||||
* 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
|
||||
* 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
|
||||
* 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
|
||||
* 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
|
||||
* 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
|
||||
* 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
|
||||
* 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
|
||||
* 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
|
||||
* 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
|
||||
* 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
|
||||
* 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
|
||||
* 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