Merge commit 'af0da737fc4ef8f9ccebd3d43519610b8a8fcaa1' into next

Conflicts:
	lisp/ledger-reconcile.el
This commit is contained in:
Craig Earls 2015-02-25 22:01:33 -07:00
commit 1f803d6294
65 changed files with 1344 additions and 2235 deletions

View file

@ -1,8 +1,12 @@
((nil . ((tab-width . 2) ;;; Directory Local Variables
;;; For more information see (info "(emacs) Directory Variables")
((nil
(tab-width . 2)
(sentence-end-double-space . t) (sentence-end-double-space . t)
(bug-reference-url-format (bug-reference-url-format . "http://bugs.ledger-cli.org/show_bug.cgi?id=%s"))
. "http://bugs.ledger-cli.org/show_bug.cgi?id=%s"))) (c-mode
(c-mode . ((c-file-style . "ledger") (c-file-style . "ledger")
(c-style-alist (c-style-alist
("ledger" ("ledger"
(indent-tabs-mode) (indent-tabs-mode)
@ -24,7 +28,9 @@
(arglist-close . +) (arglist-close . +)
(inline-open . 0) (inline-open . 0)
(brace-list-open . 0) (brace-list-open . 0)
(topmost-intro-cont first c-lineup-topmost-intro-cont (topmost-intro-cont first c-lineup-topmost-intro-cont c-lineup-gnu-DEFUN-intro-cont))
c-lineup-gnu-DEFUN-intro-cont))
(c-special-indent-hook . c-gnu-impose-minimum) (c-special-indent-hook . c-gnu-impose-minimum)
(c-block-comment-prefix . "")))))) (c-block-comment-prefix . ""))))
(emacs-lisp-mode
(indent-tabs-mode)))

3
.gitignore vendored
View file

@ -43,17 +43,20 @@ doc/*.html
doc/*.info doc/*.info
doc/*.info-* doc/*.info-*
doc/*.ky doc/*.ky
doc/*.kys
doc/*.log doc/*.log
doc/*.pdf doc/*.pdf
doc/*.pg doc/*.pg
doc/*.toc doc/*.toc
doc/*.tp doc/*.tp
doc/*.vr doc/*.vr
doc/*.vrs
doc/.dirstamp doc/.dirstamp
doc/html/ doc/html/
doc/latex/ doc/latex/
doc/refman.pdf doc/refman.pdf
doc/report/ doc/report/
doc/version.texi
elisp-comp elisp-comp
install-sh install-sh
intl/ intl/

29
acprep
View file

@ -616,8 +616,8 @@ class PrepareBuild(CommandLineApp):
self.execute(*packages) self.execute(*packages)
if exists('/etc/redhat-release'): if exists('/etc/redhat-release'):
release = open('/etc/redhat-release') release = open('/etc/redhat-release').readline()
if release.readline().startswith('CentOS'): if release.startswith('CentOS'):
self.log.info('Looks like you are using YUM on CentOS') self.log.info('Looks like you are using YUM on CentOS')
packages = [ packages = [
'sudo', 'yum', 'install', 'sudo', 'yum', 'install',
@ -644,6 +644,31 @@ class PrepareBuild(CommandLineApp):
] ]
self.log.info('Executing: ' + ' '.join(packages)) self.log.info('Executing: ' + ' '.join(packages))
self.execute(*packages) self.execute(*packages)
elif release.startswith('Fedora release 20'):
self.log.info('Looks like you are using YUM on Fedora 20')
packages = [
'sudo', 'yum', 'install',
'boost-devel',
'bzip2-devel',
'cmake',
'doxygen',
'gcc',
'gcc-c++',
'gettext',
'gettext-devel',
'gmp-devel',
'lcov',
'libedit-devel',
'mpfr-devel',
'ninja-build',
'python-devel',
'sloccount',
'texinfo',
'zlib-devel'
]
self.log.info('Executing: ' + ' '.join(packages))
self.execute(*packages)
elif system.startswith('CYGWIN'): elif system.startswith('CYGWIN'):
self.log.info('Looks like you are using Cygwin') self.log.info('Looks like you are using Cygwin')
self.log.info('Please install the dependencies manually.') self.log.info('Please install the dependencies manually.')

View file

@ -1,5 +1,5 @@
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;; ;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
; Ledger ;; Ledger
;; Maybe later add this to the expense repo once it settles ;; Maybe later add this to the expense repo once it settles
(add-to-list 'load-path "/home/adamsrl/.emacs.d/addons/ledger") (add-to-list 'load-path "/home/adamsrl/.emacs.d/addons/ledger")

View file

@ -191,7 +191,8 @@ Show any gains (or losses) in commodity values over time.
Only show the top Only show the top
.Ar number .Ar number
postings. postings.
.\".It Fl \-historical Pq Fl H .It Fl \-historical Pq Fl H
Value commodities at the time of their acquisition.
.It Fl \-invert .It Fl \-invert
Invert the value of amounts shown. Invert the value of amounts shown.
.It Fl \-market Pq Fl V .It Fl \-market Pq Fl V
@ -366,7 +367,10 @@ Alias for
Ignore init files and environment variables for the Ignore init files and environment variables for the
.Nm .Nm
run. run.
.\".It Fl \-auto-match .It Fl \-auto-match
When generating a ledger transaction from a CSV file using the
.Ic convert
command, automatically match an account from the Ledger journal.
.It Fl \-aux-date .It Fl \-aux-date
Show auxiliary dates for all calculations. Show auxiliary dates for all calculations.
Alias for Alias for
@ -378,7 +382,9 @@ running totals.
Specify the format to use for the Specify the format to use for the
.Ic balance .Ic balance
report. report.
.\".It Fl \-base .It Fl \-base
Reduce convertible commodities down the bottom of the conversion, e.g.
display time in seconds.
.It Fl \-basis Pq Fl B .It Fl \-basis Pq Fl B
Report the cost basis on all posting. Report the cost basis on all posting.
Alias for Alias for
@ -401,7 +407,6 @@ Specify the format to use for the
report. report.
.It Fl \-by-payee Pq Fl P .It Fl \-by-payee Pq Fl P
Group postings in the register report by common payee names. Group postings in the register report by common payee names.
.\".It Fl \-cache Ar FILE
.It Fl \-check-payees .It Fl \-check-payees
Enable strict and pedantic checking for payees as well as accounts, Enable strict and pedantic checking for payees as well as accounts,
commodities and tags. commodities and tags.
@ -461,7 +466,12 @@ Print dates using
Refer to Refer to
.Xr strftime 3 .Xr strftime 3
for details on the format string syntax. for details on the format string syntax.
.\" .It Fl \-datetime-format Ar FMT .It Fl \-datetime-format Ar DATETIMEFMT
Print datetimes using
.Ar DATETIMEFMT .
Refer to
.Xr strftime 3
for details on the format string syntax.
.It Fl \-date-width Ar INT .It Fl \-date-width Ar INT
Specify the width, in characters, of the date column in the Specify the width, in characters, of the date column in the
.Ic register .Ic register
@ -501,6 +511,12 @@ but not
.Sy Expenses:Entertainment:Dining . .Sy Expenses:Entertainment:Dining .
This is a display predicate, which means it only affects display, This is a display predicate, which means it only affects display,
not the total calculations. not the total calculations.
.It Fl \-detail
Related to
.Ic convert
command. Synonym to
.Fl \-rich-data
option.
.It Fl \-deviation .It Fl \-deviation
Report each posting's deviation from the average. It is only meaningful Report each posting's deviation from the average. It is only meaningful
in the in the
@ -551,7 +567,9 @@ Related to the
.Ic equity .Ic equity
command. Gives current account balances in the form of a register command. Gives current account balances in the form of a register
report. report.
.\".It Fl \-exact .It Fl \-exact
Report beginning and ending of periods by the date of the first and last
posting occurring in that period.
.It Fl \-exchange Ar COMMODITY Oo , Ar COMMODITY, ... Oc Pq Fl X .It Fl \-exchange Ar COMMODITY Oo , Ar COMMODITY, ... Oc Pq Fl X
Display values in terms of the given Display values in terms of the given
.Ar COMMODITY . .Ar COMMODITY .
@ -560,7 +578,6 @@ The latest available price is used.
.It Fl \-file Ar FILE .It Fl \-file Ar FILE
Read journal data from Read journal data from
.Ar FILE . .Ar FILE .
.\".It Fl \-full-help
.It Fl \-first Ar INT .It Fl \-first Ar INT
Print the first Print the first
.Ar INT .Ar INT
@ -623,17 +640,13 @@ entries. Opposite of
Alias for Alias for
.Fl \-first .Fl \-first
.It Fl \-help .It Fl \-help
Print a summary of all the options, and what they are used for. This Print this man page.
can be a handy way to remember which options do what. This help screen
is also printed if
.Nm
is run without a command.
.\".It Fl \-help-calc
.\".It Fl \-help-comm
.\".It Fl \-help-disp
.It Fl \-immediate .It Fl \-immediate
Evaluate calculations immediately rather than lazily. Evaluate calculations immediately rather than lazily.
.\".It Fl \-import .It Fl \-import Ar FILE
Import
.Ar FILE
as Python module.
.It Fl \-init-file Ar FILE Pq Fl i .It Fl \-init-file Ar FILE Pq Fl i
Read Read
.Ar FILE .Ar FILE
@ -678,7 +691,9 @@ purchased.
.It Fl \-lots .It Fl \-lots
Report the date and price at which each commodity was purchased in Report the date and price at which each commodity was purchased in
a balance report. a balance report.
.\".It Fl \-lots-actual .It Fl \-lots-actual
Preserve the uniqueness of commodities so they aren't merged during
reporting without printing the lot annotations.
.It Fl \-market Pq Fl V .It Fl \-market Pq Fl V
Use the latest market value for all commodities. Use the latest market value for all commodities.
.It Fl \-master-account Ar STR .It Fl \-master-account Ar STR
@ -842,10 +857,27 @@ of the transaction.
Show all postings in a transaction, similar to Show all postings in a transaction, similar to
.Fl \-related .Fl \-related
but show both sides of each transaction. but show both sides of each transaction.
.\".It Fl \-revalued .It Fl \-revalued
.\".It Fl \-revalued-only Report discrepancy in values for manual reports by inserting
.\".It Fl \-revalued-total Ar EXPR <Revalued>
.\".It Fl \-rich-data postings.
This is implied when using
the
.Fl \-exchange Pq Fl X
or
.Fl \-market Pq Fl V
option.
.It Fl \-revalued-only
Show only
<Revalued>
postings.
.It Fl \-revalued-total
Display the sum of the revalued postings as the running total, which serves
to show unrealized capital in a gain/losses report.
.It Fl \-rich-data
When generating a ledger transaction from a CSV file using the
.Ic convert
command, add CSV, Imported, and UUID meta-data.
.It Fl \-seed Ar INT .It Fl \-seed Ar INT
Set the random seed to Set the random seed to
.Ar INT .Ar INT
@ -857,8 +889,9 @@ Execute a
.Nm .Nm
script. script.
.It Fl \-sort Ar EXPR Pq Fl S .It Fl \-sort Ar EXPR Pq Fl S
Sort the register report based on the value expression given to sort. Sort the register report based on the value expression
.\".It Fl \-sort-all .Ar EXPR .
.\".It Fl \-sort-all Ar EXPR
.It Fl \-sort-xacts .It Fl \-sort-xacts
Sort the posting within transactions using the given value expression. Sort the posting within transactions using the given value expression.
.It Fl \-start-of-week Ar STR .It Fl \-start-of-week Ar STR
@ -884,7 +917,10 @@ entries. Only useful on a register report. Alias for
.It Fl \-time-colon .It Fl \-time-colon
Display the value for commodities based on seconds as hours and minutes. Display the value for commodities based on seconds as hours and minutes.
Thus 8100s will be displayed as 2:15h instead of 2.25h. Thus 8100s will be displayed as 2:15h instead of 2.25h.
.\".It Fl \-time-report .It Fl \-time-report
Add two columns to the
.Ic balance
report to show the earliest checkin and checkout times for timelog entries.
.It Fl \-total Ar EXPR Pq Fl T .It Fl \-total Ar EXPR Pq Fl T
Define a value expression used to calculate the total in reports. Define a value expression used to calculate the total in reports.
.It Fl \-total-data Pq Fl J .It Fl \-total-data Pq Fl J
@ -936,7 +972,8 @@ precision.
Show the values used by each tag when used in combination with the Show the values used by each tag when used in combination with the
.Ic tags .Ic tags
command. command.
.\".It Fl \-value-expr Ar EXPR .It Fl \-value-expr Ar EXPR
Set a global value expression annotation.
.It Fl \-verbose .It Fl \-verbose
Print detailed information on the execution of Print detailed information on the execution of
.Nm . .Nm .
@ -946,7 +983,9 @@ slowdown. When combined with
.Fl \-debug Ar CODE .Fl \-debug Ar CODE
.Nm .Nm
will produce memory trace information. will produce memory trace information.
.\".It Fl \-verify-memory .It Fl \-verify-memory
Verify that every constructed object is properly destructed. This is for
debugging purposes only.
.It Fl \-version .It Fl \-version
Print version information and exit. Print version information and exit.
.It Fl \-weekly Pq Fl W .It Fl \-weekly Pq Fl W
@ -1117,6 +1156,12 @@ toward -infinity.
The name of the The name of the
.Nm .Nm
data file from whence the posting came. data file from whence the posting came.
.It Fn format string
Evaluate
.Ar string
as format just like the
.Fl \-format
option.
.It Fn format_date date format .It Fn format_date date format
Return the Return the
.Ar date .Ar date
@ -1125,18 +1170,56 @@ as a string using
Refer to Refer to
.Xr strftime 3 .Xr strftime 3
for format string details. for format string details.
.\".It Fn get_at .It Fn format_datetime datetime format
.\".It Fn has_meta Return the
.Ar datetime
as a string using
.Ar format .
Refer to
.Xr strftime 3
for format string details.
.It Fn get_at seq index
Return value at
.Ar index
from
.Ar seq .
Used internally to construct different reports.
.It Fn has_meta
Return true if the posting has metadata named
.Ar tag ,
false otherwise.
.It Fn has_tag tag .It Fn has_tag tag
Return true if the posting has metadata named Return true if the posting has metadata named
.Ar tag , .Ar tag ,
false otherwise. false otherwise.
.\".It Fn is_seq .It Fn is_seq value
Return true if
.Ar value
is a sequence. Used internally.
.It Fn join value .It Fn join value
Replace all newlines in Replace all newlines in
.Ar value .Ar value
with with
.Li \en . .Li \en .
.It Fn justify value first_width latter_width right_justify colorize
Right or left justify the string representing
.Ar value .
The width of the field in the first line is given by
.Ar first_width .
For subsequent lines the width is given by
.Ar latter_width .
If
.Ar latter_width
is -1,
.Ar first_width
is used for all lines.
If
.Ar right_justify
is true then the field is right justified within the width of the field. If it
is false, then the field is left justified and padded to the full width of the
field. If
.Ar colorize
is true, then ledger will honor color settings.
.It Fn market value datetime .It Fn market value datetime
Return the price of Return the price of
.Ar value .Ar value
@ -1146,8 +1229,13 @@ Note that
.Ar datetime .Ar datetime
must be surrounded by brackets in order to be parsed correctly, e.g. must be surrounded by brackets in order to be parsed correctly, e.g.
.Bq 2012/03/23 . .Bq 2012/03/23 .
.\".It Sy meta .It Fn meta
.I.\"t Sy note Return the value of metadata named
.Ar name .
.It Sy note
Return the note for the posting.
.It Sy now
Return the current datetime.
.\".It Sy null .\".It Sy null
.It Sy options .It Sy options
A variable that allows access to the values of the given command-line options A variable that allows access to the values of the given command-line options
@ -1173,7 +1261,11 @@ in relation to
.Ar value_b . .Ar value_b .
.\".It Sy post .\".It Sy post
.\" A variable scope .\" A variable scope
.\".It Sy print .It Fn print value
Print
.Ar value
to stdout.
Used internally for debugging.
.It Fn quantity value .It Fn quantity value
Return the quantity of Return the quantity of
.Ar value .Ar value
@ -1193,29 +1285,60 @@ Return
rounded to rounded to
.Ar n .Ar n
digits. Does not affect formatting. digits. Does not affect formatting.
.\".It Sy scrub .It Sy should_bold
Return true if expression given to
.Fl \-bold-if
evaluates to true. Internal use only!
.It Fn scrub value
Clean
.Ar value
using various transformations such as round,
stripping value annotations, and more.
.\".It Sy status .\".It Sy status
.\".It Sy strip .It Fn strip value
Strip value annotation from
.Ar value .
.\".It Sy subcount .\".It Sy subcount
.It Fn tag name .It Fn tag name
Return the value of tag named Return the value of tag named
.Ar name . .Ar name .
.\".It Fn to_amount value .It Fn to_amount value
.\".It Fn to_balance value Convert
.\".It Fn to_boolean value .Ar value
.\".It Fn to_date value to an amount. Internal use only!
.\".It Fn to_datetime value .It Fn to_balance value
Convert
.Ar value
to a balance. Internal use only!
.It Fn to_boolean value
Convert
.Ar value
to a boolean. Internal use only!
.It Fn to_date value
Convert
.Ar value
to a date. Internal use only!
.It Fn to_datetime value
Convert
.Ar value
to a datetime. Internal use only!
.It Fn to_int value .It Fn to_int value
Return the integer value for Return the integer value for
.Ar value . .Ar value .
.\".It Fn to_mask value .It Fn to_mask value
.\".It Fn to_sequence value Convert
.Ar value
to a mask. Internal use only!
.It Fn to_sequence value
Convert
.Ar value
to a sequence. Internal use only!
.It Fn to_string value .It Fn to_string value
Convert Convert
.Ar value .Ar value
to a character string. to a character string.
.It Sy today .It Sy today
Return todays date. Return today's date.
.It Sy total .It Sy total
Return the total of the posting. Return the total of the posting.
.It Sy total_expr .It Sy total_expr
@ -1225,7 +1348,14 @@ option.
.It Fn trim value .It Fn trim value
Trim leading and trailing whitespace from Trim leading and trailing whitespace from
.Ar value . .Ar value .
.\".It Fn truncate .It Fn truncated string, total_len, account_len
Truncate
.Ar string
to
.Ar total_len
enusring that each account is at least
.Ar account_len
long.
.\".It Sy uncleared .\".It Sy uncleared
.It Sy virtual .It Sy virtual
Return true if the transaction is virtual, e.g automated, false otherwise. Return true if the transaction is virtual, e.g automated, false otherwise.

View file

@ -88,6 +88,19 @@
@c $ 36.84 Expenses:Food:Dining @c $ 36.84 Expenses:Food:Dining
@c @end smallexample @c @end smallexample
@c @c
@c To pass additional input to ledger for certain commands, e.g. convert add
@c with_file:filename to the example command and add a file:UUID to an example
@c that holds the additional input, where UUID is the UUID of the command,
@c e.g.:
@c
@c @smallexample @c file:download.csv
@c 767718,12/13/2011,"Withdrawal","ACE HARDWARE 16335 S HOUGHTON RD",-8.80,,00001640.04,,
@c @end smallexample
@c
@c @smallexample @c command:94FD2B6,with_file:download.csv
@c $ ledger -f sample.dat convert download.csv
@c @end smallexample
@c
@c Additionally DocTests.py will pass --args-only and --columns 80 to ledger @c Additionally DocTests.py will pass --args-only and --columns 80 to ledger
@c to ignore any default arguments from the environment or .ledgerrc. @c to ignore any default arguments from the environment or .ledgerrc.
@c @c
@ -390,10 +403,11 @@ install` to install. If these intructions do not work for you can check the
@section Getting help @section Getting help
@findex help @findex help
Ledger has a complete online help system based on GNU Info. This Ledger has a complete online help system based on GNU Info. This manual
manual can be searched directly from the command-line using the can be searched directly from the command-line using @code{info ledger},
following options: @code{ledger --help} brings up this entire manual in which will bring up this entire manual in your TTY. Alternatively, the
your TTY. shorter man page can be accessed from the command-line either via
@code{man ledger} or @code{ledger --help}
If you need help on how to use Ledger, or run into problems, you can If you need help on how to use Ledger, or run into problems, you can
join the Ledger mailing list at join the Ledger mailing list at
@ -1142,6 +1156,8 @@ $ ledger --no-total balance Billable Project
-50.0m Project:XYZ -50.0m Project:XYZ
@end smallexample @end smallexample
@findex C
This example works because ledger already knows how to handle seconds, This example works because ledger already knows how to handle seconds,
minutes and hours, as part of its time tracking support. Defining minutes and hours, as part of its time tracking support. Defining
other equivalences is simple. The following is an example that other equivalences is simple. The following is an example that
@ -1383,7 +1399,7 @@ $ ledger --real --no-total bal
If more asset accounts are needed as the source of a posting, just If more asset accounts are needed as the source of a posting, just
list them as you would normally, for example: list them as you would normally, for example:
@smallexample @smallexample @c input:validate
2004/03/25 Payment for books (paid from Checking) 2004/03/25 Payment for books (paid from Checking)
Expenses:Books $100.00 Expenses:Books $100.00
Assets:Checking $-50.00 Assets:Checking $-50.00
@ -1599,7 +1615,7 @@ Beneath these top level accounts you can have any level of detail you
desire. For example, if you want to keep specific track of how much desire. For example, if you want to keep specific track of how much
you spend on burgers and fries, you could have the following: you spend on burgers and fries, you could have the following:
@smallexample @smallexample @c input:validate
Expenses:Food:Hamburgers and Fries Expenses:Food:Hamburgers and Fries
@end smallexample @end smallexample
@ -1885,14 +1901,14 @@ your function in Python, you can return something like
that value is always used, regardless of the commodity, the date, or that value is always used, regardless of the commodity, the date, or
the desired target commodity. For example, the desired target commodity. For example,
@smallexample @smallexample @c input:validate
define myfunc_seven(s, d, t) = 7 EUR define myfunc_seven(s, d, t) = 7 EUR
@end smallexample @end smallexample
In order to specify a fixed price, but still valuate that price into In order to specify a fixed price, but still valuate that price into
the target commodity, use something like this: the target commodity, use something like this:
@smallexample @smallexample @c input:validate
define myfunc_five(s, d, t) = market(5 EUR, d, t) define myfunc_five(s, d, t) = market(5 EUR, d, t)
@end smallexample @end smallexample
@ -1900,14 +1916,14 @@ The @code{value} directive sets the valuation used for all commodities
used in the rest of the data stream. This is the fallback, if nothing used in the rest of the data stream. This is the fallback, if nothing
more specific is found. more specific is found.
@smallexample @smallexample @c input:validate
value myfunc_seven value myfunc_seven
@end smallexample @end smallexample
You can set a specific valuation function on a per-commodity basis. You can set a specific valuation function on a per-commodity basis.
Instead of defining a function, you can also pass a lambda. Instead of defining a function, you can also pass a lambda.
@smallexample @smallexample @c input:validate
commodity $ commodity $
value s, d, t -> 6 EUR value s, d, t -> 6 EUR
@end smallexample @end smallexample
@ -1915,7 +1931,7 @@ commodity $
Each account can also provide a default valuation function for any Each account can also provide a default valuation function for any
commodities transferred to that account. commodities transferred to that account.
@smallexample @smallexample @c input:validate
account Expenses:Food5 account Expenses:Food5
value myfunc_five value myfunc_five
@end smallexample @end smallexample
@ -1923,7 +1939,7 @@ account Expenses:Food5
The metadata field @samp{Value}, if found, overrides the valuation The metadata field @samp{Value}, if found, overrides the valuation
function on a transaction-wide or per-posting basis. function on a transaction-wide or per-posting basis.
@smallexample @smallexample @c input:validate
= @@XACT and Food = @@XACT and Food
; Value:: 8 EUR ; Value:: 8 EUR
(Equity) $1 (Equity) $1
@ -2006,10 +2022,9 @@ In order to combat inconsistency you can define allowable accounts and
payees. For simplicity, create a separate text file and define accounts payees. For simplicity, create a separate text file and define accounts
and payees like and payees like
@smallexample @smallexample @c input:validate
account Expenses account Expenses
account Expenses:Utilities account Expenses:Utilities
...
@end smallexample @end smallexample
Using the @option{--strict} option will cause Ledger to complain if any Using the @option{--strict} option will cause Ledger to complain if any
@ -2025,7 +2040,7 @@ Warning: "FinanceData/Master.dat", line 15: Unknown account 'Allocation:Equities
If you have a large Ledger register already created use the If you have a large Ledger register already created use the
@command{accounts} command to get started: @command{accounts} command to get started:
@smallexample @smallexample @c command:validate
$ ledger accounts >> Accounts.dat $ ledger accounts >> Accounts.dat
@end smallexample @end smallexample
@ -2444,15 +2459,14 @@ payee KFC
The @code{alias} sub-directive provides a regex which, if it matches The @code{alias} sub-directive provides a regex which, if it matches
a parsed payee, the declared payee name is substituted: a parsed payee, the declared payee name is substituted:
@smallexample @smallexample @c input:validate
2012-02-27 KENTUCKY FRIED CHICKEN ; will be read as being 'KFC' 2012-02-27 KENTUCKY FRIED CHICKEN ; will be read as being 'KFC'
...
@end smallexample @end smallexample
The @code{uuid} sub-directive specifies that a transaction with exactly The @code{uuid} sub-directive specifies that a transaction with exactly
the uuid given should have the declared payee name substituted: the uuid given should have the declared payee name substituted:
@smallexample @smallexample @c input:validate
2014-05-13 UNHELPFUL PAYEE ; will be read as being 'KFC' 2014-05-13 UNHELPFUL PAYEE ; will be read as being 'KFC'
; UUID: 2a2e21d434356f886c84371eebac6e44f1337fda ; UUID: 2a2e21d434356f886c84371eebac6e44f1337fda
@end smallexample @end smallexample
@ -2513,7 +2527,7 @@ is the equivalent of:
@c TODO: the following paragraph seems to be false, the automated tests @c TODO: the following paragraph seems to be false, the automated tests
@c fail, if anything appears after end apply tag. @c fail, if anything appears after end apply tag.
@c Note that anything following @code{end apply tag} is ignored. placing @c Note that anything following @code{end apply tag} is ignored. Placing
@c the name of the tag that is being closed is a simple way to keep @c the name of the tag that is being closed is a simple way to keep
@c track. @c track.
@ -2580,7 +2594,7 @@ with a home currency, such as the dollar @samp{$}. It is recommended
that these pricing options be set in the price database file, which that these pricing options be set in the price database file, which
defaults to @file{~/.pricedb}. The syntax for this command is: defaults to @file{~/.pricedb}. The syntax for this command is:
@smallexample @smallexample @c input:validate
N SYMBOL N SYMBOL
@end smallexample @end smallexample
@ -2848,7 +2862,7 @@ default is uncleared. To mark a transaction cleared, put an asterisk
@end smallexample @end smallexample
@noindent @noindent
To mark it pending, use a !: To mark it pending, use a @samp{!}:
@smallexample @c input:validate @smallexample @c input:validate
2012-03-10 ! KFC 2012-03-10 ! KFC
@ -3002,7 +3016,7 @@ bank. On the bank statement, there is just one amount @samp{$400}, but
you can specify from whom each check came from, as shown by example you can specify from whom each check came from, as shown by example
below: below:
@smallexample @c input:validate @smallexample @c input:9B43E57
2010-06-17 Sample 2010-06-17 Sample
Assets:Bank $400.00 Assets:Bank $400.00
Income:Check1 $-100.00 ; Payee: Person One Income:Check1 $-100.00 ; Payee: Person One
@ -3011,9 +3025,15 @@ below:
Income:Check4 $-100.00 ; Payee: Person Four Income:Check4 $-100.00 ; Payee: Person Four
@end smallexample @end smallexample
When reporting this, it appears as: When reporting with
@smallexample @smallexample @c command:9B43E57
$ ledger reg
@end smallexample
it appears as:
@smallexample @c output:9B43E57
10-Jun-17 Sample Assets:Bank $400.00 $400.00 10-Jun-17 Sample Assets:Bank $400.00 $400.00
Person One Income:Check1 $-100.00 $300.00 Person One Income:Check1 $-100.00 $300.00
Person Two Income:Check2 $-100.00 $200.00 Person Two Income:Check2 $-100.00 $200.00
@ -3486,7 +3506,7 @@ sensitive to this difference.
If you buy a stock last year, and ask for its value today, Ledger will If you buy a stock last year, and ask for its value today, Ledger will
consult its price database to see what the most recent price for that consult its price database to see what the most recent price for that
stock is. You can short-circuit this lookup by ``fixing'' the price stock is. You can short-circuit this lookup by ``fixing'' the price
at the time of a transaction. This is done using @{=AMOUNT@}: at the time of a transaction. This is done using @samp{@{=AMOUNT@}}:
@smallexample @smallexample
2012-04-10 My Broker 2012-04-10 My Broker
@ -3572,13 +3592,13 @@ If you use the functional form, you can either specify a function
name, or a lambda expression. Here's a function that yields the price name, or a lambda expression. Here's a function that yields the price
as $10 in whatever commodity is being requested: as $10 in whatever commodity is being requested:
@smallexample @smallexample @c input:validate
define ten_dollars(s, date, t) = market($10, date, t) define ten_dollars(s, date, t) = market($10, date, t)
@end smallexample @end smallexample
I can now use that in a lot value expression as follows: I can now use that in a lot value expression as follows:
@smallexample @smallexample @c input:validate
2012-04-10 My Broker 2012-04-10 My Broker
Assets:Brokerage:Cash $375.00 Assets:Brokerage:Cash $375.00
Assets:Brokerage -5 AAPL @{$50.00@} ((ten_dollars)) @@@@ $375.00 Assets:Brokerage -5 AAPL @{$50.00@} ((ten_dollars)) @@@@ $375.00
@ -4190,8 +4210,7 @@ you want, or interface Ledger with other programs.
A query such as the following shows all expenses since last A query such as the following shows all expenses since last
October, sorted by total: October, sorted by total:
@c TODO: does not validate with @c command:validate, because "last oct" is split at the space @smallexample @c command:validate
@smallexample
$ ledger -b "last oct" -S T bal ^expenses $ ledger -b "last oct" -S T bal ^expenses
@end smallexample @end smallexample
@ -4296,7 +4315,7 @@ and a single bond issue is 100% bonds.
We track purchases of specific investments using the symbol of that We track purchases of specific investments using the symbol of that
investment as its commodity. How do we tell Ledger that a share of investment as its commodity. How do we tell Ledger that a share of
VTHRX is 24% Global equity etc.? Enter automatic transactions and VTHRX is 24% Domestic equity? Enter automatic transactions and
virtual accounts. virtual accounts.
At the top of our ledger we enter automatic transactions that describe At the top of our ledger we enter automatic transactions that describe
@ -4307,10 +4326,7 @@ actual balances.
For the three instruments listed above, those automatic transactions For the three instruments listed above, those automatic transactions
would look like: would look like:
@smallexample @c input:validate @smallexample @c input:582C8C2
;
; automatic calculations for asset allocation tracking
;
= expr ( commodity == 'VIFSX' ) = expr ( commodity == 'VIFSX' )
(Allocation:Equities:Domestic) 1.000 (Allocation:Equities:Domestic) 1.000
@ -4321,6 +4337,18 @@ would look like:
= expr ( commodity == 'VBMFX') = expr ( commodity == 'VBMFX')
(Allocation:Bonds/Cash) 1.000 (Allocation:Bonds/Cash) 1.000
2015-01-01 Buy VIFSX
Assets:Broker 100 VIFSX
Assets:Cash $-10000
2015-01-01 Buy VTHRX
Assets:Broker 10 VTHRX
Assets:Cash $-10000
2015-01-01 Buy VBMFX
Assets:Broker 1 VBMFX
Assets:Cash $-10000
@end smallexample @end smallexample
How do these work? First the @samp{=} sign at the beginning of the How do these work? First the @samp{=} sign at the beginning of the
@ -4339,23 +4367,21 @@ the various asset classes how do we get a report that tells us our
current allocation? Using the balance command and some tricky current allocation? Using the balance command and some tricky
formatting! formatting!
@c TODO: does not @c command:validate due to multiple lines @smallexample @c command:582C8C2
@smallexample
ledger bal Allocation --current --format "\ ledger bal Allocation --current --format "\
%-17((depth_spacer)+(partial_account))\ %-17((depth_spacer)+(partial_account))\
%10(percent(market(display_total), market(parent.total)))\ %10(percent(market(display_total), market(parent.total)))\
%16(market(display_total))\n%/" %16(market(display_total))\n%/"
@end smallexample @end smallexample
@noindent
Which yields: Which yields:
@smallexample @smallexample @c output:582C8C2
Allocation 100.00% $100000.00 Allocation 100.00% $30000
Bonds/Cash 38.94% $38940.00 Bonds/Cash 39.90% $11970
Equities 61.06% $61060.00 Equities 60.10% $18030
Domestic 95.31% $58196.29 Domestic 86.69% $15630
Global 4.69% $2863.71 Global 13.31% $2400
@end smallexample @end smallexample
Let's look at the Ledger invocation a bit closer. The command above is Let's look at the Ledger invocation a bit closer. The command above is
@ -4612,19 +4638,64 @@ Ledger will include @samp{; transid: 767718} in the first transaction
from the file above. from the file above.
@findex --invert @findex --invert
@findex --auto-match
@findex --account @var{STR} @findex --account @var{STR}
@findex --rich-data @findex --rich-data
The @command{convert} command accepts three options. They are The @command{convert} command accepts four options. They are
@option{--invert} which inverts the amount field, @option{--invert} which inverts the amount field, @option{--auto-match}
@option{--account @var{STR}} which you can use to specify the account to which automatically matches an account from the Ledger journal for every
balance against, and @option{--rich-data} which stores CSV line, @option{--account @var{STR}} which you can use to specify the
additional metadata as tags. There is, for example, account to balance against, and @option{--rich-data} which stores
a UUID field. If an entry with the same UUID tag is already included in additional tag/value pairs.
the normal ledger file (specified via @option{--file @var{FILE} (-f)} or
via the environment variable @env{LEDGER_FILE}) this entry will not be Using the two first lines of the above csv file,
@smallexample @c file:01B0350
,date,payee,note,amount,,,code,
767718,12/13/2011,"Withdrawal","ACE HARDWARE 16335 S HOUGHTON RD",-8.80,,00001640.04,,
767406,12/13/2011,"Withdrawal","ACE HARDWARE 16335 S HOUGHTON RD",-1.03,,00001648.84,,
@end smallexample
and launching the below command,
@smallexample @c command:01B0350,with_file:download.csv
$ ledger convert download.csv --input-date-format "%m/%d/%Y" \
--invert --account Assets:MyBank --rich-data \
--file sample.dat --now=2012/01/13
@end smallexample
you will get the result:
@smallexample @c output:01B0350
2011/12/13 * Withdrawal ;ACE HARDWARE 16335 S HOUGHTON RD
; CSV: 767718,12/13/2011,"Withdrawal","ACE HARDWARE 16335 S HOUGHTON RD",-8.80,,00001640.04,,
; Imported: 2012/01/13
; UUID: dfdc3c3d5c54c6967dd39d5b4e4fd1ea76e87233
Expenses:Unknown 8.8
Assets:MyBank
2011/12/13 * Withdrawal ;ACE HARDWARE 16335 S HOUGHTON RD
; CSV: 767406,12/13/2011,"Withdrawal","ACE HARDWARE 16335 S HOUGHTON RD",-1.03,,00001648.84,,
; Imported: 2012/01/13
; UUID: 63086448b1f29f7fd6efb11ea40660185a213f9d
Expenses:Unknown 1.03
Assets:MyBank
@end smallexample
The three added metadata are: @samp{CSV} as the original line from csv
file, @samp{Imported} as the date when the csv file was imported into
Ledger, and @samp{UUID} as a checksum of original csv line.
If an entry with the same @samp{UUID} tag is already included in the
normal ledger file (specified via @option{--file @var{FILE} (-f)} or via
the environment variable @env{LEDGER_FILE}) this entry will not be
printed again. printed again.
In the output above, the account is @samp{Expenses:Unknown} for CSV
lines. You can use the @option{--auto-match} option to automatically
match an account from your Ledger journal.
You can also use @command{convert} with @code{payee} and @code{account} You can also use @command{convert} with @code{payee} and @code{account}
directives. First, you can use the @code{payee} and @code{alias} directives. First, you can use the @code{payee} and @code{alias}
directive to rewrite the @code{payee} field based on some rules. Then directive to rewrite the @code{payee} field based on some rules. Then
@ -5236,8 +5307,10 @@ journal. Using the @option{--count} option will tell you how many
entries use each payee. To filter the payees displayed you must use the entries use each payee. To filter the payees displayed you must use the
prefix @@: prefix @@:
@smallexample @smallexample @c command:validate
$ ledger payees @@Nic $ ledger payees @@Nic
@end smallexample
@smallexample
Nicolas Nicolas
Nicolas BOILABUS Nicolas BOILABUS
Oudtshoorn Municipality Oudtshoorn Municipality
@ -5449,10 +5522,9 @@ Generate transactions based on previous postings.
@item --help @item --help
@itemx -h @itemx -h
Print summary of all options. Display the man page for @file{ledger}.
@item --version @item --version
@itemx -v
Print version information and exit. Print version information and exit.
@item --file @var{FILE} @item --file @var{FILE}
@ -5468,7 +5540,7 @@ Redirect output to @file{FILE}.
Specify an options file. Specify an options file.
@item --import @var{FILE} @item --import @var{FILE}
@value{FIXME:UNDOCUMENTED} Import @var{FILE} as Python module.
@item --account @var{STR} @item --account @var{STR}
@itemx -a @var{STR} @itemx -a @var{STR}
@ -5726,6 +5798,7 @@ Group postings together, similar to the balance report.
Use @file{FILE} for retrieving stored commodity prices. Use @file{FILE} for retrieving stored commodity prices.
@item --price-exp @var{INT} @item --price-exp @var{INT}
@itemx --leeway @var{INT}
@itemx -Z @var{INT} @itemx -Z @var{INT}
Set expected freshness of prices in @var{INT} minutes. Set expected freshness of prices in @var{INT} minutes.
@ -5733,8 +5806,9 @@ Set expected freshness of prices in @var{INT} minutes.
@itemx -Q @itemx -Q
Download quotes using the script named @file{getquote}. Download quotes using the script named @file{getquote}.
@item --getquote @var{FILE} @c FIXME: The option doesn't exist currently.
Sets the path to a user-defined script to download commodity prices. @c @item --getquote @var{FILE}
@c Sets the path to a user-defined script to download commodity prices.
@item --quantity @item --quantity
@itemx -O @itemx -O
@ -5791,7 +5865,7 @@ database.
@item --help @item --help
@itemx -h @itemx -h
Display the man page for ledger. Display the man page for @file{ledger}.
@item --init-file @var{FILE} @item --init-file @var{FILE}
Specify the location of the init file. The default is @file{~/.ledgerrc}. Specify the location of the init file. The default is @file{~/.ledgerrc}.
@ -5851,7 +5925,7 @@ produce memory trace information.
@value{FIXME:UNDOCUMENTED} @value{FIXME:UNDOCUMENTED}
@item --version @item --version
@value{FIXME:UNDOCUMENTED} Print version information and exit.
@end ftable @end ftable
@ -5867,9 +5941,6 @@ sessions with multiple reports per session.
@ftable @option @ftable @option
@item --cache @var{FIXME}
@value{FIXME:UNDOCUMENTED}
@item --check-payees @item --check-payees
Enable strict and pedantic checking for payees as well as accounts, Enable strict and pedantic checking for payees as well as accounts,
commodities and tags. This only works in conjunction with commodities and tags. This only works in conjunction with
@ -5887,7 +5958,6 @@ days by day.
@c @end smallexample @c @end smallexample
@c @smallexample @c output: @c @smallexample @c output:
@c @end smallexample @c @end smallexample
@value{FIXME:UNDOCUMENTED}
@item --decimal-comma @item --decimal-comma
Direct Ledger to parse journals using the European standard comma as Direct Ledger to parse journals using the European standard comma as
@ -5895,8 +5965,9 @@ a decimal separator, not the usual period.
@item --download @item --download
@itemx -Q @itemx -Q
Direct Ledger to download prices using the script defined via the option Direct Ledger to download prices.
@option{--getquote @var{FILE}}. @c using the script defined via the option
@c @option{--getquote @var{FILE}}.
@item --explicit @item --explicit
@c see test/baseline/opt-explicit.test @c see test/baseline/opt-explicit.test
@ -5906,11 +5977,12 @@ Direct Ledger to download prices using the script defined via the option
@itemx -f @var{FILE} @itemx -f @var{FILE}
Specify the input @file{FILE} for this invocation. Specify the input @file{FILE} for this invocation.
@item --getquote @var{FILE} @c FIXME: The option doesn't exist currently.
@cindex getquote @c @item --getquote @var{FILE}
@cindex download prices @c @cindex getquote
Tell ledger where to find the user defined script to download prices @c @cindex download prices
information. @c Tell ledger where to find the user defined script to download prices
@c information.
@item --input-date-format @var{DATE_FORMAT} @item --input-date-format @var{DATE_FORMAT}
Specify the input date format for journal entries. For example, Specify the input date format for journal entries. For example,
@ -5964,8 +6036,8 @@ Quiet balance assertions.
Specify the location of the price entry data file. Specify the location of the price entry data file.
@item --price-exp @var{INT} @item --price-exp @var{INT}
@itemx -Z @var{INT}
@itemx --leeway @var{INT} @itemx --leeway @var{INT}
@itemx -Z @var{INT}
Set the expected freshness of price quotes, in @var{INT} minutes. That Set the expected freshness of price quotes, in @var{INT} minutes. That
is, if the last known quote for any commodity is older than this value, is, if the last known quote for any commodity is older than this value,
and if @option{--download} is being used, then the Internet will be and if @option{--download} is being used, then the Internet will be
@ -5993,8 +6065,9 @@ based commodity as real hours and minutes.
For example 8100 seconds by default will be displayed as 2.25 whereas For example 8100 seconds by default will be displayed as 2.25 whereas
with the @option{--time-colon} option they will be displayed as 2:15. with the @option{--time-colon} option they will be displayed as 2:15.
@item --value-expr @var{FIXME} @item --value-expr @var{VEXPR}
@value{FIXME:UNDOCUMENTED} Set a global value expression annotation.
@c needs example
@end ftable @end ftable
@ -6054,9 +6127,9 @@ Set the width in characters of the amount column in the
Anonymize registry output, mostly for sending in bug reports. Anonymize registry output, mostly for sending in bug reports.
@item --auto-match @item --auto-match
@c Automatically match accounts from ledger journal when using convert command When generating a ledger transaction from a CSV file using the
@c see test/baseline/opt-auto-match.dat @command{convert} command, automatically match an account from the
@value{FIXME:UNDOCUMENTED} Ledger journal.
@item --aux-date @item --aux-date
@itemx --effective @itemx --effective
@ -6080,10 +6153,9 @@ Strings}). The default is:
@end smallexample @end smallexample
@item --base @item --base
@c Report commodity in the base commodity s instead of h Reduce convertible commodities down the bottom of the conversion, e.g.
@c Does this apply to other commodities too? display time in seconds. This also applies to custom commodity
@c see test/baseline/opt-base.test/ conversions (@pxref{Commodity equivalences}).
@value{FIXME:UNDOCUMENTED}
@item --basis @item --basis
@itemx -B @itemx -B
@ -6203,10 +6275,7 @@ Specify the width, in characters, of the date column in the
@command{register} report. @command{register} report.
@item --datetime-format @var{DATETIME_FORMAT} @item --datetime-format @var{DATETIME_FORMAT}
@c Specify the format ledger should use to print datetimes in Specify the format ledger should use to print datetimes.
@c @command{balance} @option{--timelog-report} reports.
@c see test/baseline/opt-datetime-format.test
@value{FIXME:UNDOCUMENTED}
@item --dc @item --dc
Display register or balance in debit/credit format If you use Display register or balance in debit/credit format If you use
@ -6314,7 +6383,8 @@ command}). Gives current account balances in the form of a register
report. report.
@item --exact @item --exact
@value{FIXME:UNDOCUMENTED} Report beginning and ending of periods by the date of the first and last
posting occurring in that period.
@item --exchange @var{COMMODITY} @item --exchange @var{COMMODITY}
@itemx -X @var{COMMODITY} @itemx -X @var{COMMODITY}
@ -6372,8 +6442,10 @@ Set the format for the headers that separates the report sections of
a grouped report. Only has an effect with a @option{--group-by a grouped report. Only has an effect with a @option{--group-by
@var{EXPR}} register report. @var{EXPR}} register report.
@smallexample @smallexample @c command:validate
$ ledger reg Expenses --group-by "payee" --group-title-format "------------------------ %-20(value) ---------------------\n" $ ledger reg Expenses --group-by "payee" --group-title-format "------------------------ %-20(value) ---------------------\n"
@end smallexample
@smallexample
------------------------ 7-Eleven --------------------- ------------------------ 7-Eleven ---------------------
2011/08/13 7-Eleven Expenses:Auto:Misc $ 5.80 $ 5.80 2011/08/13 7-Eleven Expenses:Auto:Misc $ 5.80 $ 5.80
@ -6392,10 +6464,10 @@ Print the first @var{INT} entries. Opposite of @option{--tail
@item --historical @item --historical
@itemx -H @itemx -H
@value{FIXME:UNDOCUMENTED} Value commodities at the time of their acquisition.
@item --immediate @item --immediate
@value{FIXME:UNDOCUMENTED} Evaluate calculations immediately rather than lazily.
@item --inject @item --inject
Use @code{Expected} amounts in calculations. In case you know Use @code{Expected} amounts in calculations. In case you know
@ -6436,8 +6508,8 @@ Report the date and price at which each commodity was purchased in
a balance report. a balance report.
@item --lots-actual @item --lots-actual
@c see test/baseline/opt-lots-actual.test Preserve the uniqueness of commodities so they aren't merged during
@value{FIXME:UNDOCUMENTED} reporting without printing the lot annotations.
@item --market @item --market
@itemx -V @itemx -V
@ -6520,8 +6592,10 @@ example, if you have multiple cars and track each fuel purchase in
identifying which car the purchase was for @samp{; Car: Prius}, then the identifying which car the purchase was for @samp{; Car: Prius}, then the
command: command:
@smallexample @smallexample @c command:validate
$ ledger bal Fuel --pivot "Car" --period "this year" $ ledger bal Fuel --pivot "Car" --period "this year"
@end smallexample
@smallexample
$ 3491.26 Car $ 3491.26 Car
$ 1084.22 M3:Expenses:Auto:Fuel $ 1084.22 M3:Expenses:Auto:Fuel
$ 149.65 MG V11:Expenses:Auto:Fuel $ 149.65 MG V11:Expenses:Auto:Fuel
@ -6592,22 +6666,21 @@ Show all postings in a transaction, similar to @option{--related} but
show both @emph{sides} of each transaction. show both @emph{sides} of each transaction.
@item --revalued @item --revalued
@c see test/baeline/opt-revalued.test Report discrepancy in values for manual reports by inserting @code{<Revalued>}
@value{FIXME:UNDOCUMENTED} postings. This is implied when using the @option{--exchange} or
@option{--market} option.
@item --revalued-only @item --revalued-only
@c see test/baeline/opt-revalued-only.test Show only @code{<Revalued>} postings.
@value{FIXME:UNDOCUMENTED}
@item --revalued-total @var{FIXME} @item --revalued-total @var{FIXME}
@value{FIXME:UNDOCUMENTED} Display the sum of the revalued postings as the running total, which serves
to show unrealized capital in a gain/losses report.
@item --rich-data @item --rich-data
@itemx --detail @itemx --detail
@c When generating ledger transaction from csv using the convert command When generating a ledger transaction from a CSV file using the
@c add CSV, Imported, and UUID meta-data. @command{convert} command, add CSV, Imported, and UUID metadata.
@c see test/baeline/opt-rich-data.test
@value{FIXME:UNDOCUMENTED}
@item --seed @var{INT} @item --seed @var{INT}
Set the random seed to @var{INT} for the @code{generate} command. Set the random seed to @var{INT} for the @code{generate} command.
@ -6640,9 +6713,8 @@ Report only the last @var{INT} entries. Only useful in
a @command{register} report. a @command{register} report.
@item --time-report @item --time-report
@c Display begin and end time for each timelog entry in balance reports Add two columns to the balance report to show the earliest checkin and
@c see test/baseline/opt-time-report.test checkout times for timelog entries.
@value{FIXME:UNDOCUMENTED}
@item --total @var{VEXPR} @item --total @var{VEXPR}
@itemx -T @var{VEXPR} @itemx -T @var{VEXPR}
@ -6716,8 +6788,7 @@ variables}), instead of using actual command-line options:
@item --help @item --help
@itemx -h @itemx -h
Print a summary of all the options, and what they are used for. This Display the man page for @file{ledger}.
can be a handy way to remember which options do what.
@item --version @item --version
Print the current version of ledger and exits. This is useful for Print the current version of ledger and exits. This is useful for
@ -6744,7 +6815,7 @@ settings. To specify options in the init file, use the same syntax as
on the command-line, but put each option on its own line. Here is an on the command-line, but put each option on its own line. Here is an
example init file: example init file:
@smallexample @smallexample @c input:validate
--price-db ~/finance/.pricedb --price-db ~/finance/.pricedb
--wide --wide
; ~/.ledgerrc ends here ; ~/.ledgerrc ends here
@ -7047,8 +7118,7 @@ register report, for example, but they will not be displayed. This is
useful for seeing last month's checking postings, against a running useful for seeing last month's checking postings, against a running
balance which includes all posting values: balance which includes all posting values:
@c TODO: does not @c command:validate due to space in "last month" @smallexample @c command:validate
@smallexample
$ ledger -d "d>=[last month]" reg checking $ ledger -d "d>=[last month]" reg checking
@end smallexample @end smallexample
@ -7056,8 +7126,7 @@ The output from this command is very different from the following,
whose running total includes only postings from the last month whose running total includes only postings from the last month
onward: onward:
@c TODO: does not @c command:validate due to space in "last month" @smallexample @c command:validate
@smallexample
$ ledger -p "last month" reg checking $ ledger -p "last month" reg checking
@end smallexample @end smallexample
@ -7213,7 +7282,7 @@ settings can be placed in this file manually, to prevent downloading
quotes for a specific commodity, for example. This is done by adding a quotes for a specific commodity, for example. This is done by adding a
line like the following: line like the following:
@smallexample @smallexample @c input:validate
; Don't download quotes for the dollar, or timelog values ; Don't download quotes for the dollar, or timelog values
N $ N $
N h N h
@ -7228,6 +7297,7 @@ The format of the file can be changed by telling ledger to use the
@option{--pricedb-format @var{FORMAT_STRING}} you define. @option{--pricedb-format @var{FORMAT_STRING}} you define.
@item --price-exp @var{INT} @item --price-exp @var{INT}
@itemx --leeway @var{INT}
@itemx -Z @var{INT} @itemx -Z @var{INT}
Set the expected freshness of price quotes, in @var{INT} minutes. That Set the expected freshness of price quotes, in @var{INT} minutes. That
is, if the last known quote for any commodity is older than this value, is, if the last known quote for any commodity is older than this value,
@ -7330,7 +7400,7 @@ they cannot have a different future value:
@end smallexample @end smallexample
This says the future valuation is the same as the valuation at the time This says the future valuation is the same as the valuation at the time
of posting. post.date equals the posting's date, while just 'date' is of posting. @code{post.date} equals the posting's date, while just 'date' is
the value of @option{--now @var{DATE}} (defaults to today). the value of @option{--now @var{DATE}} (defaults to today).
Or how about valuating miles based on a reimbursement rate during a Or how about valuating miles based on a reimbursement rate during a
@ -7451,7 +7521,7 @@ command-line always take precedence over environment variable settings, however.
Note that you may also permanently specify option values by placing Note that you may also permanently specify option values by placing
option settings in the file @file{~/.ledgerrc} one option per line, for example: option settings in the file @file{~/.ledgerrc} one option per line, for example:
@smallexample @smallexample @c input:validate
--pager /bin/cat --pager /bin/cat
@end smallexample @end smallexample
@ -7589,7 +7659,7 @@ These two periodic transactions give the usual monthly expenses, as well
as one typical yearly expense. For help on finding out what your as one typical yearly expense. For help on finding out what your
average monthly expenses are for any category, use a command like: average monthly expenses are for any category, use a command like:
@smallexample @smallexample @c command:validate
$ ledger -p "this year" --monthly --average balance ^expenses $ ledger -p "this year" --monthly --average balance ^expenses
@end smallexample @end smallexample
@ -7722,7 +7792,7 @@ constrain which transactions are printed. For example, the following
command shows only transactions from the beginning of the current month, command shows only transactions from the beginning of the current month,
while still calculating the running balance based on all transactions: while still calculating the running balance based on all transactions:
@smallexample @smallexample @c command:validate
$ ledger -d "d>[this month]" register checking $ ledger -d "d>[this month]" register checking
@end smallexample @end smallexample
@ -7731,7 +7801,7 @@ running total in terms of all transactions in the register. The
following, simpler command is similar, but totals only the displayed following, simpler command is similar, but totals only the displayed
postings: postings:
@smallexample @smallexample @c command:validate
$ ledger -b "this month" register checking $ ledger -b "this month" register checking
@end smallexample @end smallexample
@ -7937,7 +8007,7 @@ field. This searches only a posting's field, not the transaction's note
or comment field. For example, @code{ledger reg "expr" "comment =~ or comment field. For example, @code{ledger reg "expr" "comment =~
/landline/"} will match: /landline/"} will match:
@smallexample @smallexample @c input:validate
2014/1/29 Phone bill 2014/1/29 Phone bill
Assets:Checking $50.00 Assets:Checking $50.00
Expenses:Phone $-50.00 ; landline bill Expenses:Phone $-50.00 ; landline bill
@ -7945,7 +8015,7 @@ or comment field. For example, @code{ledger reg "expr" "comment =~
but will not match: but will not match:
@smallexample @smallexample @c input:validate
2014/1/29 Phone bill ; landline bill 2014/1/29 Phone bill ; landline bill
; landline bill ; landline bill
Assets:Checking $50.00 Assets:Checking $50.00
@ -7961,19 +8031,19 @@ This searches all comments in the transaction, including comments on
individual postings. Thus, @samp{ledger reg "expr" "note =~ /landline/"} individual postings. Thus, @samp{ledger reg "expr" "note =~ /landline/"}
will match both all the three examples below: will match both all the three examples below:
@smallexample @smallexample @c input:validate
2014/1/29 Phone bill 2014/1/29 Phone bill
Assets:Checking $50.00 Assets:Checking $50.00
Expenses:Phone $-50.00 ; landline bill Expenses:Phone $-50.00 ; landline bill
@end smallexample @end smallexample
@smallexample @smallexample @c input:validate
2014/1/29 Phone bill ; landline bill 2014/1/29 Phone bill ; landline bill
Assets:Checking $50.00 Assets:Checking $50.00
Expenses:Phone $-50.00 Expenses:Phone $-50.00
@end smallexample @end smallexample
@smallexample @smallexample @c input:validate
2014/1/29 Phone bill 2014/1/29 Phone bill
; landline bill ; landline bill
Assets:Checking $50.00 Assets:Checking $50.00
@ -8146,8 +8216,8 @@ Friday, January 16. 2015
Right or left justify the string representing @var{value}. The width Right or left justify the string representing @var{value}. The width
of the field in the first line is given by @var{first_width}. For of the field in the first line is given by @var{first_width}. For
subsequent lines the width is given by @var{latter_width}. If subsequent lines the width is given by @var{latter_width}. If
@var{latter_width=-1}, then @var{first_width} is use for all lines. @var{latter_width=-1}, then @var{first_width} is used for all lines.
If @var{right_justify=true} then the field is right justify within If @var{right_justify=true} then the field is right justified within
the width of the field. If it is @var{false}, then the field is left the width of the field. If it is @var{false}, then the field is left
justified and padded to the full width of the field. If justified and padded to the full width of the field. If
@var{colorize} is true, then ledger will honor color settings. @var{colorize} is true, then ledger will honor color settings.
@ -9703,6 +9773,7 @@ Enable tracing. The @var{INT} specifies the level of trace desired:
@ @
@item --verbose @item --verbose
@itemx -v
Print detailed information on the execution of Ledger. Print detailed information on the execution of Ledger.
@item --verify @item --verify
@ -9711,7 +9782,8 @@ slowdown. When combined with @option{--debug @var{CODE}} ledger will
produce memory trace information. produce memory trace information.
@item --verify-memory @item --verify-memory
@value{FIXME:UNDOCUMENTED} Verify that every constructed object is properly destructed. This is for
debugging purposes only.
@item --version @item --version
Print version information and exit. Print version information and exit.
@ -9748,8 +9820,10 @@ and apply it against a model transaction.
@item period @var{PERIOD_EXPRESSION} @item period @var{PERIOD_EXPRESSION}
Evaluate the given period and report how Ledger interprets it: Evaluate the given period and report how Ledger interprets it:
@smallexample @smallexample @c command:51F6A2C
$ ledger period "this year" $ ledger period "this year" --now 2011-01-01
@end smallexample
@smallexample @c output:51F6A2C
--- Period expression tokens --- --- Period expression tokens ---
TOK_THIS: this TOK_THIS: this
TOK_YEAR: year TOK_YEAR: year
@ -9772,8 +9846,10 @@ END_REACHED: <EOF>
Evaluate the given arguments and report how Ledger interprets it against Evaluate the given arguments and report how Ledger interprets it against
the following model transaction: the following model transaction:
@smallexample @smallexample @c command:validate
$ ledger query "/Book/" $ ledger query "/Book/"
@end smallexample
@smallexample
--- Input arguments --- --- Input arguments ---
("/Book/") ("/Book/")
@ -9901,7 +9977,7 @@ The test scripts take the remainder of the @code{test} line and use
it as command-line arguments for ledger, the text enclosed in @code{test} it as command-line arguments for ledger, the text enclosed in @code{test}
and @code{end test} is expected output, for example: and @code{end test} is expected output, for example:
@smallexample @smallexample @c input:validate
; This is the journal data ; This is the journal data
year 2014 year 2014
12/24 (C0d3) Santa Claus 12/24 (C0d3) Santa Claus

View file

@ -28,7 +28,6 @@ set(LEDGER_SOURCES
textual.cc textual.cc
temps.cc temps.cc
journal.cc journal.cc
archive.cc
account.cc account.cc
xact.cc xact.cc
post.cc post.cc
@ -80,7 +79,6 @@ set(LEDGER_INCLUDES
account.h account.h
amount.h amount.h
annotate.h annotate.h
archive.h
balance.h balance.h
chain.h chain.h
commodity.h commodity.h

View file

@ -289,26 +289,6 @@ public:
} }
bool children_with_xdata() const; bool children_with_xdata() const;
std::size_t children_with_flags(xdata_t::flags_t flags) const; std::size_t children_with_flags(xdata_t::flags_t flags) const;
#if HAVE_BOOST_SERIALIZATION
private:
/** Serialization. */
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive& ar, const unsigned int /* version */) {
ar & boost::serialization::base_object<supports_flags<> >(*this);
ar & boost::serialization::base_object<scope_t>(*this);
ar & parent;
ar & name;
ar & note;
ar & depth;
ar & accounts;
ar & posts;
ar & _fullname;
}
#endif // HAVE_BOOST_SERIALIZATION
}; };
std::ostream& operator<<(std::ostream& out, const account_t& account); std::ostream& operator<<(std::ostream& out, const account_t& account);

View file

@ -93,20 +93,6 @@ struct amount_t::bigint_t : public supports_flags<>
} }
return true; return true;
} }
#if HAVE_BOOST_SERIALIZATION
private:
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive& ar, const unsigned int /* version */)
{
ar & boost::serialization::base_object<supports_flags<> >(*this);
ar & val;
ar & prec;
ar & refc;
}
#endif // HAVE_BOOST_SERIALIZATION
}; };
bool amount_t::is_initialized = false; bool amount_t::is_initialized = false;
@ -1331,69 +1317,4 @@ void put_amount(property_tree::ptree& st, const amount_t& amt,
st.put("quantity", amt.quantity_string()); st.put("quantity", amt.quantity_string());
} }
#if HAVE_BOOST_SERIALIZATION
template<class Archive>
void amount_t::serialize(Archive& ar, const unsigned int /* version */)
{
ar & is_initialized;
ar & quantity;
ar & commodity_;
}
#endif // HAVE_BOOST_SERIALIZATION
} // namespace ledger } // namespace ledger
#if HAVE_BOOST_SERIALIZATION
namespace boost {
namespace serialization {
template <class Archive>
void serialize(Archive& ar, MP_INT& mpz, const unsigned int /* version */)
{
ar & mpz._mp_alloc;
ar & mpz._mp_size;
ar & mpz._mp_d;
}
template <class Archive>
void serialize(Archive& ar, MP_RAT& mpq, const unsigned int /* version */)
{
ar & mpq._mp_num;
ar & mpq._mp_den;
}
template <class Archive>
void serialize(Archive& ar, long unsigned int& integer,
const unsigned int /* version */)
{
ar & make_binary_object(&integer, sizeof(long unsigned int));
}
} // namespace serialization
} // namespace boost
BOOST_CLASS_EXPORT(ledger::annotated_commodity_t)
template void boost::serialization::serialize(boost::archive::binary_iarchive&,
MP_INT&, const unsigned int);
template void boost::serialization::serialize(boost::archive::binary_oarchive&,
MP_INT&, const unsigned int);
template void boost::serialization::serialize(boost::archive::binary_iarchive&,
MP_RAT&, const unsigned int);
template void boost::serialization::serialize(boost::archive::binary_oarchive&,
MP_RAT&, const unsigned int);
template void boost::serialization::serialize(boost::archive::binary_iarchive&,
long unsigned int&,
const unsigned int);
template void boost::serialization::serialize(boost::archive::binary_oarchive&,
long unsigned int&,
const unsigned int);
template void ledger::amount_t::serialize(boost::archive::binary_iarchive&,
const unsigned int);
template void ledger::amount_t::serialize(boost::archive::binary_oarchive&,
const unsigned int);
#endif // HAVE_BOOST_SERIALIZATION

View file

@ -743,16 +743,6 @@ public:
bool valid() const; bool valid() const;
#if HAVE_BOOST_SERIALIZATION
private:
/** Serialization. */
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive& ar, const unsigned int /* version */);
#endif // HAVE_BOOST_SERIALIZATION
/*@}*/ /*@}*/
}; };

View file

@ -107,21 +107,6 @@ struct annotation_t : public supports_flags<>,
assert(*this); assert(*this);
return true; return true;
} }
#if HAVE_BOOST_SERIALIZATION
private:
/** Serialization. */
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive& ar, const unsigned int /* version */) {
ar & boost::serialization::base_object<supports_flags<> >(*this);
ar & price;
ar & date;
ar & tag;
}
#endif // HAVE_BOOST_SERIALIZATION
}; };
void put_annotation(property_tree::ptree& pt, const annotation_t& details); void put_annotation(property_tree::ptree& pt, const annotation_t& details);
@ -162,21 +147,6 @@ struct keep_details_t
return keep_price || keep_date || keep_tag; return keep_price || keep_date || keep_tag;
} }
bool keep_any(const commodity_t& comm) const; bool keep_any(const commodity_t& comm) const;
#if HAVE_BOOST_SERIALIZATION
private:
/** Serialization. */
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive& ar, const unsigned int /* version */) {
ar & keep_price;
ar & keep_date;
ar & keep_tag;
ar & only_actuals;
}
#endif // HAVE_BOOST_SERIALIZATION
}; };
inline std::ostream& operator<<(std::ostream& out, inline std::ostream& operator<<(std::ostream& out,
@ -250,24 +220,6 @@ public:
virtual void write_annotations(std::ostream& out, virtual void write_annotations(std::ostream& out,
bool no_computed_annotations = false) const; bool no_computed_annotations = false) const;
#if HAVE_BOOST_SERIALIZATION
private:
explicit annotated_commodity_t() : ptr(NULL) {
TRACE_CTOR(annotated_commodity_t, "");
}
/** Serialization. */
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive& ar, const unsigned int /* version */) {
ar & boost::serialization::base_object<commodity_t>(*this);
ar & ptr;
ar & details;
}
#endif // HAVE_BOOST_SERIALIZATION
}; };
inline annotated_commodity_t& inline annotated_commodity_t&

View file

@ -1,295 +0,0 @@
/*
* Copyright (c) 2003-2015, 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>
#if HAVE_BOOST_SERIALIZATION
#include "archive.h"
#include "amount.h"
#include "commodity.h"
#include "pool.h"
#include "scope.h"
#include "account.h"
#include "post.h"
#include "xact.h"
#define LEDGER_MAGIC 0x4c454447
#define ARCHIVE_VERSION 0x03000006
//BOOST_IS_ABSTRACT(ledger::scope_t)
BOOST_CLASS_EXPORT(ledger::scope_t)
BOOST_CLASS_EXPORT(ledger::child_scope_t)
BOOST_CLASS_EXPORT(ledger::symbol_scope_t)
BOOST_CLASS_EXPORT(ledger::call_scope_t)
BOOST_CLASS_EXPORT(ledger::account_t)
BOOST_CLASS_EXPORT(ledger::item_t)
BOOST_CLASS_EXPORT(ledger::post_t)
BOOST_CLASS_EXPORT(ledger::xact_base_t)
BOOST_CLASS_EXPORT(ledger::xact_t)
BOOST_CLASS_EXPORT(ledger::auto_xact_t)
BOOST_CLASS_EXPORT(ledger::period_xact_t)
template void ledger::journal_t::serialize(boost::archive::binary_oarchive&,
const unsigned int);
template void ledger::journal_t::serialize(boost::archive::binary_iarchive&,
const unsigned int);
namespace ledger {
namespace {
bool read_header_bits(std::istream& in) {
uint32_t bytes;
assert(sizeof(uint32_t) == 4);
in.read(reinterpret_cast<char *>(&bytes), sizeof(uint32_t));
if (bytes != LEDGER_MAGIC) {
DEBUG("archive.journal", "Magic bytes not present");
return false;
}
in.read(reinterpret_cast<char *>(&bytes), sizeof(uint32_t));
if (bytes != ARCHIVE_VERSION) {
DEBUG("archive.journal", "Archive version mismatch");
return false;
}
return true;
}
void write_header_bits(std::ostream& out) {
uint32_t bytes;
assert(sizeof(uint32_t) == 4);
bytes = LEDGER_MAGIC;
out.write(reinterpret_cast<char *>(&bytes), sizeof(uint32_t));
bytes = ARCHIVE_VERSION;
out.write(reinterpret_cast<char *>(&bytes), sizeof(uint32_t));
}
}
bool archive_t::read_header()
{
uintmax_t size = file_size(file);
if (size < 8)
return false;
// Open the stream, read the version number and the list of sources
ifstream stream(file, std::ios::binary);
if (! read_header_bits(stream))
return false;
boost::archive::binary_iarchive iarchive(stream);
DEBUG("archive.journal", "Reading header from archive");
iarchive >> *this;
DEBUG("archive.journal",
"Version number: " << std::hex << ARCHIVE_VERSION << std::dec);
DEBUG("archive.journal", "Number of sources: " << sources.size());
#if DEBUG_ON
foreach (const journal_t::fileinfo_t& i, sources)
DEBUG("archive.journal", "Loaded source: " << *i.filename);
#endif
return true;
}
bool archive_t::should_load(const std::list<path>& data_files)
{
std::size_t found = 0;
DEBUG("archive.journal", "Should the archive be loaded?");
if (! exists(file)) {
DEBUG("archive.journal", "No, it does not exist");
return false;
}
if (! read_header()) {
DEBUG("archive.journal", "No, header failed to read");
return false;
}
if (data_files.empty()) {
DEBUG("archive.journal", "No, there were no data files!");
return false;
}
if (sources.empty()) {
DEBUG("archive.journal", "No, there were no sources!");
return false;
}
if (data_files.size() != sources.size()) {
DEBUG("archive.journal", "No, number of sources doesn't match: "
<< data_files.size() << " != " << sources.size());
return false;
}
foreach (const path& p, data_files) {
DEBUG("archive.journal", "Scanning for data file: " << p);
if (! exists(p)) {
DEBUG("archive.journal", "No, an input source no longer exists: " << p);
return false;
}
foreach (const journal_t::fileinfo_t& i, sources) {
assert(! i.from_stream);
assert(i.filename);
DEBUG("archive.journal", "Comparing against source file: " << *i.filename);
if (*i.filename == p) {
if (! exists(*i.filename)) {
DEBUG("archive.journal",
"No, a referent source no longer exists: " << *i.filename);
return false;
}
if (i.modtime != posix_time::from_time_t(last_write_time(p))) {
DEBUG("archive.journal", "No, a source's modtime has changed: " << p);
return false;
}
if (i.size != file_size(p)) {
DEBUG("archive.journal", "No, a source's size has changed: " << p);
return false;
}
found++;
}
}
}
if (found != data_files.size()) {
DEBUG("archive.journal", "No, not every source's name matched");
return false;
}
DEBUG("archive.journal", "Yes, it should be loaded!");
return true;
}
bool archive_t::should_save(journal_t& journal)
{
std::list<path> data_files;
DEBUG("archive.journal", "Should the archive be saved?");
if (journal.was_loaded) {
DEBUG("archive.journal", "No, it's one we loaded before");
return false;
}
if (journal.sources.empty()) {
DEBUG("archive.journal", "No, there were no sources!");
return false;
}
foreach (const journal_t::fileinfo_t& i, journal.sources) {
if (i.from_stream) {
DEBUG("archive.journal", "No, one source was from a stream");
return false;
}
if (! exists(*i.filename)) {
DEBUG("archive.journal",
"No, a source no longer exists: " << *i.filename);
return false;
}
data_files.push_back(*i.filename);
}
if (should_load(data_files)) {
DEBUG("archive.journal", "No, because it's still loadable");
return false;
}
DEBUG("archive.journal", "Yes, it should be saved!");
return true;
}
void archive_t::save(journal_t& journal)
{
INFO_START(archive, "Saved journal file cache");
ofstream stream(file, std::ios::binary);
write_header_bits(stream);
sources = journal.sources;
#if DEBUG_ON
foreach (const journal_t::fileinfo_t& i, sources)
DEBUG("archive.journal", "Saving source: " << *i.filename);
#endif
boost::archive::binary_oarchive oa(stream);
DEBUG("archive.journal", "Creating archive with version "
<< std::hex << ARCHIVE_VERSION << std::dec);
oa << *this;
DEBUG("archive.journal",
"Archiving journal with " << sources.size() << " sources");
oa << journal;
INFO_FINISH(archive);
}
bool archive_t::load(journal_t& journal)
{
INFO_START(archive, "Read cached journal file");
ifstream stream(file, std::ios::binary);
if (! read_header_bits(stream))
return false;
boost::archive::binary_iarchive iarchive(stream);
// Skip past the archive header, it was already read in before
archive_t temp;
iarchive >> temp;
iarchive >> journal;
journal.was_loaded = true;
INFO_FINISH(archive);
return true;
}
} // namespace ledger
#endif // HAVE_BOOST_SERIALIZATION

View file

@ -1,92 +0,0 @@
/*
* Copyright (c) 2003-2015, 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.
*/
/**
* @defgroup report Reporting
*/
/**
* @file archive.h
* @author John Wiegley
*
* @ingroup report
*/
#ifndef _ARCHIVE_H
#define _ARCHIVE_H
#include "journal.h"
namespace ledger {
class archive_t
{
path file;
std::list<journal_t::fileinfo_t> sources;
public:
archive_t() {
TRACE_CTOR(archive_t, "");
}
archive_t(const path& _file) : file(_file) {
TRACE_CTOR(archive_t, "const path&");
}
archive_t(const archive_t& ar) : file(ar.file) {
TRACE_CTOR(archive_t, "copy");
}
~archive_t() {
TRACE_DTOR(archive_t);
}
bool read_header();
bool should_load(const std::list<path>& data_files);
bool should_save(journal_t& journal);
void save(journal_t& journal);
bool load(journal_t& journal);
#if HAVE_BOOST_SERIALIZATION
private:
/** Serialization. */
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive& ar, const unsigned int /* version */) {
ar & sources;
}
#endif // HAVE_BOOST_SERIALIZATION
};
} // namespace ledger
#endif // _ARCHIVE_H

View file

@ -594,18 +594,6 @@ public:
} }
return true; return true;
} }
#if HAVE_BOOST_SERIALIZATION
private:
/** Serialization. */
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive& ar, const unsigned int /* version */) {
ar & amounts;
}
#endif // HAVE_BOOST_SERIALIZATION
}; };
inline std::ostream& operator<<(std::ostream& out, const balance_t& bal) { inline std::ostream& operator<<(std::ostream& out, const balance_t& bal) {

View file

@ -68,19 +68,6 @@ struct price_point_t
bool operator==(const price_point_t& other) const { bool operator==(const price_point_t& other) const {
return when == other.when && price == other.price; return when == other.when && price == other.price;
} }
#if HAVE_BOOST_SERIALIZATION
private:
/** Serialization. */
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive& ar, const unsigned int /* version */) {
ar & when;
ar & price;
}
#endif // HAVE_BOOST_SERIALIZATION
}; };
class commodity_t class commodity_t
@ -138,28 +125,6 @@ protected:
virtual ~base_t() { virtual ~base_t() {
TRACE_DTOR(commodity_t::base_t); TRACE_DTOR(commodity_t::base_t);
} }
#if HAVE_BOOST_SERIALIZATION
private:
base_t() {
TRACE_CTOR(base_t, "");
}
/** Serialization. */
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive& ar, const unsigned int /* version */) {
ar & boost::serialization::base_object<supports_flags<uint_least16_t> >(*this);
ar & symbol;
ar & precision;
ar & name;
ar & note;
ar & smaller;
ar & larger;
}
#endif // HAVE_BOOST_SERIALIZATION
}; };
shared_ptr<base_t> base; shared_ptr<base_t> base;
@ -315,32 +280,6 @@ public:
struct compare_by_commodity { struct compare_by_commodity {
bool operator()(const amount_t * left, const amount_t * right) const; bool operator()(const amount_t * left, const amount_t * right) const;
}; };
#if HAVE_BOOST_SERIALIZATION
private:
supports_flags<uint_least16_t> temp_flags;
protected:
explicit commodity_t()
: delegates_flags<uint_least16_t>(temp_flags), parent_(NULL),
annotated(false) {
TRACE_CTOR(commodity_t, "");
}
private:
/** Serialization. */
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive& ar, const unsigned int /* version */) {
ar & boost::serialization::base_object<delegates_flags<uint_least16_t> >(*this);
ar & base;
ar & parent_;
ar & qualified_symbol;
ar & annotated;
}
#endif // HAVE_BOOST_SERIALIZATION
}; };
inline std::ostream& operator<<(std::ostream& out, const commodity_t& comm) { inline std::ostream& operator<<(std::ostream& out, const commodity_t& comm) {

View file

@ -106,19 +106,6 @@ public:
virtual string context_to_str() const; virtual string context_to_str() const;
virtual void print(std::ostream& out) const; virtual void print(std::ostream& out) const;
virtual void dump(std::ostream& out) const; virtual void dump(std::ostream& out) const;
#if HAVE_BOOST_SERIALIZATION
private:
/** Serialization. */
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive& ar, const unsigned int /* version */) {
ar & boost::serialization::base_object<base_type>(*this);
ar & ptr;
}
#endif // HAVE_BOOST_SERIALIZATION
}; };
/** /**

View file

@ -231,21 +231,6 @@ public:
out << std::endl << _("--- Result value ---") << std::endl; out << std::endl << _("--- Result value ---") << std::endl;
return calc(); return calc();
} }
#if HAVE_BOOST_SERIALIZATION
private:
/** Serialization. */
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive& ar, const unsigned int /* version */) {
ar & context;
ar & str;
if (Archive::is_loading::value)
compiled = false;
}
#endif // HAVE_BOOST_SERIALIZATION
}; };
template <typename ResultType> template <typename ResultType>

View file

@ -90,17 +90,6 @@ public:
void drop_flags(const flags_t arg) { void drop_flags(const flags_t arg) {
_flags = static_cast<T>(static_cast<U>(_flags) & static_cast<U>(~arg)); _flags = static_cast<T>(static_cast<U>(_flags) & static_cast<U>(~arg));
} }
#if HAVE_BOOST_SERIALIZATION
private:
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive& ar, const unsigned int /* version */)
{
ar & _flags;
}
#endif // HAVE_BOOST_SERIALIZATION
}; };
template <typename T = boost::uint_least8_t, typename U = T> template <typename T = boost::uint_least8_t, typename U = T>
@ -193,17 +182,6 @@ public:
void drop_flags(const flags_t arg) { void drop_flags(const flags_t arg) {
_flags.drop_flags(arg); _flags.drop_flags(arg);
} }
#if HAVE_BOOST_SERIALIZATION
private:
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive& ar, const unsigned int /* version */)
{
ar & _flags;
}
#endif // HAVE_BOOST_SERIALIZATION
}; };
#endif // _FLAGS_H #endif // _FLAGS_H

View file

@ -316,9 +316,6 @@ option_t<global_scope_t> * global_scope_t::lookup_option(const char * p)
case 'd': case 'd':
OPT(debug_); OPT(debug_);
break; break;
case 'f':
OPT(full_help);
break;
case 'h': case 'h':
OPT_(help); OPT_(help);
break; break;

View file

@ -147,7 +147,6 @@ See LICENSE file included with the distribution for details and disclaimer.");
void visit_man_page() const; void visit_man_page() const;
OPTION_(global_scope_t, full_help, DO() { parent->visit_man_page(); }); // -H
OPTION_(global_scope_t, help, DO() { parent->visit_man_page(); }); // -h OPTION_(global_scope_t, help, DO() { parent->visit_man_page(); }); // -h
OPTION__ OPTION__

View file

@ -78,23 +78,6 @@ struct position_t
} }
return *this; return *this;
} }
#if HAVE_BOOST_SERIALIZATION
private:
/** Serialization. */
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive& ar, const unsigned int /* version */) {
ar & pathname;
ar & beg_pos;
ar & beg_line;
ar & end_pos;
ar & end_line;
ar & sequence;
}
#endif // HAVE_BOOST_SERIALIZATION
}; };
class item_t : public supports_flags<uint_least16_t>, public scope_t class item_t : public supports_flags<uint_least16_t>, public scope_t
@ -226,25 +209,6 @@ public:
const string& name); const string& name);
bool valid() const; bool valid() const;
#if HAVE_BOOST_SERIALIZATION
private:
/** Serialization. */
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive& ar, const unsigned int /* version */) {
ar & boost::serialization::base_object<supports_flags<uint_least16_t> >(*this);
ar & boost::serialization::base_object<scope_t>(*this);
ar & _state;
ar & _date;
ar & _date_aux;
ar & note;
ar & pos;
ar & metadata;
}
#endif // HAVE_BOOST_SERIALIZATION
}; };
value_t get_comment(item_t& item); value_t get_comment(item_t& item);

View file

@ -100,21 +100,6 @@ public:
~fileinfo_t() throw() { ~fileinfo_t() throw() {
TRACE_DTOR(journal_t::fileinfo_t); TRACE_DTOR(journal_t::fileinfo_t);
} }
#if HAVE_BOOST_SERIALIZATION
private:
/** Serialization. */
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive& ar, const unsigned int /* version */) {
ar & filename;
ar & size;
ar & modtime;
ar & from_stream;
}
#endif // HAVE_BOOST_SERIALIZATION
}; };
account_t * master; account_t * master;
@ -215,26 +200,6 @@ public:
private: private:
std::size_t read_textual(parse_context_stack_t& context); std::size_t read_textual(parse_context_stack_t& context);
#if HAVE_BOOST_SERIALIZATION
private:
/** Serialization. */
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive& ar, const unsigned int /* version */) {
ar & master;
ar & bucket;
ar & xacts;
ar & auto_xacts;
ar & period_xacts;
ar & sources;
ar & payee_mappings;
ar & account_mappings;
ar & checksum_map;
}
#endif // HAVE_BOOST_SERIALIZATION
}; };
} // namespace ledger } // namespace ledger

View file

@ -54,7 +54,7 @@ namespace {
struct usage_sorter { struct usage_sorter {
bool operator()(const account_use_pair& left, bool operator()(const account_use_pair& left,
const account_use_pair& right) const { const account_use_pair& right) const {
return left.second > right.second; return left.second < right.second;
} }
}; };
} }

View file

@ -124,25 +124,6 @@ public:
} }
return true; return true;
} }
#if HAVE_BOOST_SERIALIZATION
private:
/** Serialization. */
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive& ar, const unsigned int /* version */) {
string temp;
if (Archive::is_loading::value) {
ar & temp;
*this = temp;
} else {
temp = str();
ar & temp;
}
}
#endif // HAVE_BOOST_SERIALIZATION
}; };
inline std::ostream& operator<<(std::ostream& out, const mask_t& mask) { inline std::ostream& operator<<(std::ostream& out, const mask_t& mask) {

View file

@ -314,33 +314,6 @@ private:
value_t calc_call(scope_t& scope, ptr_op_t * locus, const int depth); value_t calc_call(scope_t& scope, ptr_op_t * locus, const int depth);
value_t calc_cons(scope_t& scope, ptr_op_t * locus, const int depth); value_t calc_cons(scope_t& scope, ptr_op_t * locus, const int depth);
value_t calc_seq(scope_t& scope, ptr_op_t * locus, const int depth); value_t calc_seq(scope_t& scope, ptr_op_t * locus, const int depth);
#if HAVE_BOOST_SERIALIZATION
private:
/** Serialization. */
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive& ar, const unsigned int /* version */) {
ar & refc;
ar & kind;
if (Archive::is_loading::value || ! left_ || ! left_->is_function()) {
ar & left_;
} else {
ptr_op_t temp_op;
ar & temp_op;
}
if (Archive::is_loading::value || is_value() || is_ident() ||
(kind > UNARY_OPERATORS &&
(! has_right() || ! right()->is_function()))) {
ar & data;
} else {
variant<ptr_op_t, value_t, string, expr_t::func_t> temp_data;
ar & temp_data;
}
}
#endif // HAVE_BOOST_SERIALIZATION
}; };
inline expr_t::ptr_op_t inline expr_t::ptr_op_t

View file

@ -132,26 +132,6 @@ public:
parse_price_expression(const std::string& str, parse_price_expression(const std::string& str,
const bool add_prices = true, const bool add_prices = true,
const optional<datetime_t>& moment = none); const optional<datetime_t>& moment = none);
#if HAVE_BOOST_SERIALIZATION
private:
/** Serialization. */
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive& ar, const unsigned int /* version */) {
ar & current_pool;
ar & commodities;
ar & annotated_commodities;
ar & null_commodity;
ar & default_commodity;
ar & keep_base;
ar & price_db;
ar & quote_leeway;
ar & get_quotes;
}
#endif // HAVE_BOOST_SERIALIZATION
}; };
} // namespace ledger } // namespace ledger

View file

@ -255,24 +255,6 @@ public:
} }
} }
}; };
#if HAVE_BOOST_SERIALIZATION
private:
/** Serialization. */
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive& ar, const unsigned int /* version */) {
ar & boost::serialization::base_object<item_t>(*this);
ar & xact;
ar & account;
ar & amount;
ar & amount_expr;
ar & cost;
ar & assigned_amount;
}
#endif // HAVE_BOOST_SERIALIZATION
}; };
class journal_t; class journal_t;

View file

@ -90,19 +90,6 @@ public:
.to_boolean() : .to_boolean() :
true); true);
} }
#if HAVE_BOOST_SERIALIZATION
private:
/** Serialization. */
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive& ar, const unsigned int /* version */) {
ar & boost::serialization::base_object<expr_t>(*this);
ar & what_to_keep;
}
#endif // HAVE_BOOST_SERIALIZATION
}; };
} // namespace ledger } // namespace ledger

View file

@ -83,20 +83,6 @@ struct symbol_t
bool operator==(const symbol_t& sym) const { bool operator==(const symbol_t& sym) const {
return kind == sym.kind || name == sym.name; return kind == sym.kind || name == sym.name;
} }
#if HAVE_BOOST_SERIALIZATION
private:
/** Serialization. */
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive& ar, const unsigned int /* version */) {
ar & kind;
ar & name;
ar & definition;
}
#endif // HAVE_BOOST_SERIALIZATION
}; };
class empty_scope_t; class empty_scope_t;
@ -127,16 +113,6 @@ public:
virtual bool type_required() const { virtual bool type_required() const {
return false; return false;
} }
#if HAVE_BOOST_SERIALIZATION
private:
/** Serialization. */
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive&, const unsigned int /* version */) {}
#endif // HAVE_BOOST_SERIALIZATION
}; };
class empty_scope_t : public scope_t class empty_scope_t : public scope_t
@ -184,19 +160,6 @@ public:
return parent->lookup(kind, name); return parent->lookup(kind, name);
return NULL; return NULL;
} }
#if HAVE_BOOST_SERIALIZATION
private:
/** Serialization. */
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive& ar, const unsigned int /* version */) {
ar & boost::serialization::base_object<scope_t>(*this);
ar & parent;
}
#endif // HAVE_BOOST_SERIALIZATION
}; };
class bind_scope_t : public child_scope_t class bind_scope_t : public child_scope_t
@ -233,19 +196,6 @@ public:
return def; return def;
return child_scope_t::lookup(kind, name); return child_scope_t::lookup(kind, name);
} }
#if HAVE_BOOST_SERIALIZATION
private:
/** Serialization. */
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive& ar, const unsigned int /* version */) {
ar & boost::serialization::base_object<child_scope_t>(*this);
ar & grandchild;
}
#endif // HAVE_BOOST_SERIALIZATION
}; };
template <typename T> template <typename T>
@ -323,19 +273,6 @@ public:
virtual expr_t::ptr_op_t lookup(const symbol_t::kind_t kind, virtual expr_t::ptr_op_t lookup(const symbol_t::kind_t kind,
const string& name); const string& name);
#if HAVE_BOOST_SERIALIZATION
private:
/** Serialization. */
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive& ar, const unsigned int /* version */) {
ar & boost::serialization::base_object<child_scope_t>(*this);
ar & symbols;
}
#endif // HAVE_BOOST_SERIALIZATION
}; };
class context_scope_t : public child_scope_t class context_scope_t : public child_scope_t
@ -365,24 +302,6 @@ public:
virtual bool type_required() const { virtual bool type_required() const {
return required; return required;
} }
#if HAVE_BOOST_SERIALIZATION
protected:
explicit context_scope_t() {
TRACE_CTOR(context_scope_t, "");
}
/** Serialization. */
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive& ar, const unsigned int /* version */) {
ar & boost::serialization::base_object<child_scope_t>(*this);
ar & value_type_context;
ar & required;
}
#endif // HAVE_BOOST_SERIALIZATION
}; };
class call_scope_t : public context_scope_t class call_scope_t : public context_scope_t
@ -480,24 +399,6 @@ public:
bool empty() const { bool empty() const {
return args.size() == 0; return args.size() == 0;
} }
#if HAVE_BOOST_SERIALIZATION
protected:
explicit call_scope_t() : depth(0) {
TRACE_CTOR(call_scope_t, "");
}
/** Serialization. */
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive& ar, const unsigned int /* version */) {
ar & boost::serialization::base_object<context_scope_t>(*this);
ar & args;
//ar & ptr;
}
#endif // HAVE_BOOST_SERIALIZATION
}; };
template <> template <>

View file

@ -37,7 +37,6 @@
#include "journal.h" #include "journal.h"
#include "iterators.h" #include "iterators.h"
#include "filters.h" #include "filters.h"
#include "archive.h"
namespace ledger { namespace ledger {
@ -128,16 +127,6 @@ std::size_t session_t::read_data(const string& master_account)
if (HANDLED(value_expr_)) if (HANDLED(value_expr_))
journal->value_expr = HANDLER(value_expr_).str(); journal->value_expr = HANDLER(value_expr_).str();
#if HAVE_BOOST_SERIALIZATION
optional<archive_t> cache;
if (HANDLED(cache_) && master_account.empty())
cache = archive_t(HANDLED(cache_).str());
if (! (cache &&
cache->should_load(HANDLER(file_).data_files) &&
cache->load(*journal.get()))) {
#endif // HAVE_BOOST_SERIALIZATION
if (price_db_path) { if (price_db_path) {
if (exists(*price_db_path)) { if (exists(*price_db_path)) {
parsing_context.push(*price_db_path); parsing_context.push(*price_db_path);
@ -191,12 +180,6 @@ std::size_t session_t::read_data(const string& master_account)
<< "] == journal->xacts.size() [" << journal->xacts.size() << "]"); << "] == journal->xacts.size() [" << journal->xacts.size() << "]");
assert(xact_count == journal->xacts.size()); assert(xact_count == journal->xacts.size());
#if HAVE_BOOST_SERIALIZATION
if (cache && cache->should_save(*journal.get()))
cache->save(*journal.get());
}
#endif // HAVE_BOOST_SERIALIZATION
if (populated_data_files) if (populated_data_files)
HANDLER(file_).data_files.clear(); HANDLER(file_).data_files.clear();
@ -333,8 +316,7 @@ option_t<session_t> * session_t::lookup_option(const char * p)
OPT_CH(price_exp_); OPT_CH(price_exp_);
break; break;
case 'c': case 'c':
OPT(cache_); OPT(check_payees);
else OPT(check_payees);
break; break;
case 'd': case 'd':
OPT(download); // -Q OPT(download); // -Q

View file

@ -97,7 +97,6 @@ public:
void report_options(std::ostream& out) void report_options(std::ostream& out)
{ {
HANDLER(cache_).report(out);
HANDLER(check_payees).report(out); HANDLER(check_payees).report(out);
HANDLER(day_break).report(out); HANDLER(day_break).report(out);
HANDLER(download).report(out); HANDLER(download).report(out);
@ -126,7 +125,6 @@ public:
* Option handlers * Option handlers
*/ */
OPTION(session_t, cache_);
OPTION(session_t, check_payees); OPTION(session_t, check_payees);
OPTION(session_t, day_break); OPTION(session_t, day_break);
OPTION(session_t, download); // -Q OPTION(session_t, download); // -Q

View file

@ -71,7 +71,6 @@
#define HAVE_BOOST_PYTHON @HAVE_BOOST_PYTHON@ #define HAVE_BOOST_PYTHON @HAVE_BOOST_PYTHON@
#define HAVE_BOOST_REGEX_UNICODE @HAVE_BOOST_REGEX_UNICODE@ #define HAVE_BOOST_REGEX_UNICODE @HAVE_BOOST_REGEX_UNICODE@
#define HAVE_BOOST_SERIALIZATION 0
#define DEBUG_MODE @DEBUG_MODE@ #define DEBUG_MODE @DEBUG_MODE@
#define NO_ASSERTS @NO_ASSERTS@ #define NO_ASSERTS @NO_ASSERTS@
@ -239,86 +238,8 @@ typedef std::ostream::pos_type ostream_pos_type;
#endif #endif
#define _f(str) boost::format(_(str)) #define _f(str) boost::format(_(str))
#if HAVE_BOOST_SERIALIZATION
#include <boost/archive/binary_iarchive.hpp>
#include <boost/archive/binary_oarchive.hpp>
#include <boost/serialization/base_object.hpp>
#include <boost/serialization/binary_object.hpp>
#include <boost/serialization/optional.hpp>
#include <boost/serialization/shared_ptr.hpp>
#include <boost/serialization/variant.hpp>
#include <boost/serialization/utility.hpp>
#include <boost/serialization/export.hpp>
#include <boost/serialization/level.hpp>
#include <boost/serialization/string.hpp>
#include <boost/serialization/vector.hpp>
#include <boost/serialization/deque.hpp>
#include <boost/serialization/list.hpp>
#include <boost/serialization/map.hpp>
#include <boost/date_time/posix_time/time_serialize.hpp>
#include <boost/date_time/gregorian/greg_serialize.hpp>
#include <boost/ptr_container/serialize_ptr_deque.hpp>
namespace boost {
namespace serialization {
template <class Archive>
void serialize(Archive& ar, boost::filesystem::path& p, const unsigned int)
{
std::string s;
if (Archive::is_saving::value)
s = p.string();
ar & s;
if (Archive::is_loading::value)
p = s;
}
template <class Archive, class T>
void serialize(Archive& ar, boost::intrusive_ptr<T>& ptr, const unsigned int)
{
if (Archive::is_saving::value) {
T * p = ptr.get();
ar & p;
}
else if (Archive::is_loading::value) {
T * p;
ar & p;
ptr.reset(p);
}
}
template <class Archive>
void serialize(Archive&, boost::any&, const unsigned int) {
// jww (2012-03-29): Should we really ignore any fields entirely?
// These occur inside value_t::storage_t::data's variant.
}
template <class Archive>
void serialize(Archive&, boost::blank&, const unsigned int) {}
template <class Archive, class T>
void serialize(Archive&, boost::function<T>&, const unsigned int) {}
template <class Archive>
void serialize(Archive& ar, istream_pos_type& pos, const unsigned int)
{
ar & make_binary_object(&pos, sizeof(istream_pos_type));
}
} // namespace serialization
} // namespace boost
#else // HAVE_BOOST_SERIALIZATION
#include <boost/ptr_container/ptr_deque.hpp> #include <boost/ptr_container/ptr_deque.hpp>
#endif // HAVE_BOOST_SERIALIZATION
#if HAVE_BOOST_PYTHON #if HAVE_BOOST_PYTHON
#include <boost/python.hpp> #include <boost/python.hpp>

View file

@ -153,20 +153,6 @@ struct date_traits_t
has_month == traits.has_month && has_month == traits.has_month &&
has_day == traits.has_day); has_day == traits.has_day);
} }
#if HAVE_BOOST_SERIALIZATION
private:
/** Serialization. */
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive& ar, const unsigned int /* version */) {
ar & has_year;
ar & has_month;
ar & has_day;
}
#endif // HAVE_BOOST_SERIALIZATION
}; };
struct date_duration_t struct date_duration_t
@ -247,19 +233,6 @@ struct date_duration_t
} }
static date_t find_nearest(const date_t& date, skip_quantum_t skip); static date_t find_nearest(const date_t& date, skip_quantum_t skip);
#if HAVE_BOOST_SERIALIZATION
private:
/** Serialization. */
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive& ar, const unsigned int /* version */) {
ar & quantum;
ar & length;
}
#endif // HAVE_BOOST_SERIALIZATION
}; };
class date_specifier_t class date_specifier_t
@ -343,21 +316,6 @@ public:
return out.str(); return out.str();
} }
#if HAVE_BOOST_SERIALIZATION
private:
/** Serialization. */
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive& ar, const unsigned int /* version */) {
ar & year;
ar & month;
ar & day;
ar & wday;
}
#endif // HAVE_BOOST_SERIALIZATION
}; };
class date_range_t class date_range_t
@ -420,20 +378,6 @@ public:
return out.str(); return out.str();
} }
#if HAVE_BOOST_SERIALIZATION
private:
/** Serialization. */
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive& ar, const unsigned int /* version */) {
ar & range_begin;
ar & range_end;
ar & end_inclusive;
}
#endif // HAVE_BOOST_SERIALIZATION
}; };
class date_specifier_or_range_t class date_specifier_or_range_t
@ -490,18 +434,6 @@ public:
return out.str(); return out.str();
} }
#if HAVE_BOOST_SERIALIZATION
private:
/** Serialization. */
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive& ar, const unsigned int /* version */) {
ar & specifier_or_range;
}
#endif // HAVE_BOOST_SERIALIZATION
}; };
class date_interval_t : public equality_comparable<date_interval_t> class date_interval_t : public equality_comparable<date_interval_t>
@ -594,24 +526,6 @@ public:
date_interval_t& operator++(); date_interval_t& operator++();
void dump(std::ostream& out); void dump(std::ostream& out);
#if HAVE_BOOST_SERIALIZATION
private:
/** Serialization. */
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive& ar, const unsigned int /* version */) {
ar & range;
ar & start;
ar & finish;
ar & aligned;
ar & next;
ar & duration;
ar & end_of_duration;
}
#endif // HAVE_BOOST_SERIALIZATION
}; };
void times_initialize(); void times_initialize();

View file

@ -227,20 +227,6 @@ public:
data = false; data = false;
type = VOID; type = VOID;
} }
#if HAVE_BOOST_SERIALIZATION
private:
/** Serialization. */
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive& ar, const unsigned int /* version */) {
ar & data;
ar & type;
ar & refc;
}
#endif // HAVE_BOOST_SERIALIZATION
}; };
private: private:
@ -965,20 +951,6 @@ public:
* Debugging methods. * Debugging methods.
*/ */
bool valid() const; bool valid() const;
#if HAVE_BOOST_SERIALIZATION
private:
/** Serialization. */
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive& ar, const unsigned int /* version */) {
ar & true_value;
ar & false_value;
ar & storage;
}
#endif // HAVE_BOOST_SERIALIZATION
}; };
#define NULL_VALUE (value_t()) #define NULL_VALUE (value_t())

View file

@ -87,20 +87,6 @@ public:
virtual bool valid() const { virtual bool valid() const {
return true; return true;
} }
#if HAVE_BOOST_SERIALIZATION
private:
/** Serialization. */
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive& ar, const unsigned int /* version */) {
ar & boost::serialization::base_object<item_t>(*this);
ar & journal;
ar & posts;
}
#endif // HAVE_BOOST_SERIALIZATION
}; };
class xact_t : public xact_base_t class xact_t : public xact_base_t
@ -142,20 +128,6 @@ public:
const string& name); const string& name);
virtual bool valid() const; virtual bool valid() const;
#if HAVE_BOOST_SERIALIZATION
private:
/** Serialization. */
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive& ar, const unsigned int /* version */) {
ar & boost::serialization::base_object<xact_base_t>(*this);
ar & code;
ar & payee;
}
#endif // HAVE_BOOST_SERIALIZATION
}; };
class auto_xact_t : public xact_base_t class auto_xact_t : public xact_base_t
@ -176,21 +148,6 @@ public:
bool _overwrite_existing) bool _overwrite_existing)
: tag_data(_tag_data), overwrite_existing(_overwrite_existing), : tag_data(_tag_data), overwrite_existing(_overwrite_existing),
apply_to_post(NULL) {} apply_to_post(NULL) {}
#if HAVE_BOOST_SERIALIZATION
private:
/** Serialization. */
deferred_tag_data_t() : apply_to_post(NULL) {}
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive& ar, const unsigned int /* version */) {
ar & tag_data;
ar & overwrite_existing;
ar & apply_to_post;
}
#endif // HAVE_BOOST_SERIALIZATION
}; };
typedef std::list<deferred_tag_data_t> deferred_notes_list; typedef std::list<deferred_tag_data_t> deferred_notes_list;
@ -236,21 +193,6 @@ private:
} }
virtual void extend_xact(xact_base_t& xact, parse_context_t& context); virtual void extend_xact(xact_base_t& xact, parse_context_t& context);
#if HAVE_BOOST_SERIALIZATION
private:
/** Serialization. */
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive& ar, const unsigned int /* version */) {
ar & boost::serialization::base_object<xact_base_t>(*this);
ar & predicate;
ar & check_exprs;
ar & deferred_notes;
}
#endif // HAVE_BOOST_SERIALIZATION
}; };
class period_xact_t : public xact_base_t class period_xact_t : public xact_base_t
@ -284,20 +226,6 @@ class period_xact_t : public xact_base_t
return string(_("generated periodic transaction")); return string(_("generated periodic transaction"));
} }
} }
#if HAVE_BOOST_SERIALIZATION
private:
/** Serialization. */
friend class boost::serialization::access;
template<class Archive>
void serialize(Archive& ar, const unsigned int /* version */) {
ar & boost::serialization::base_object<xact_base_t>(*this);
ar & period;
ar & period_string;
}
#endif // HAVE_BOOST_SERIALIZATION
}; };
typedef std::list<xact_t *> xacts_list; typedef std::list<xact_t *> xacts_list;

View file

@ -21,25 +21,18 @@ class CheckBaselineTests (CheckOptions):
self.untested_options = [ self.untested_options = [
'anon', 'anon',
'args-only', 'args-only',
'cache',
'debug', 'debug',
'download', 'download',
'file', 'file',
'force-color', 'force-color',
'force-pager', 'force-pager',
'full-help',
'help', 'help',
'help-calc',
'help-comm',
'help-disp',
'import', 'import',
'init-file',
'no-color', 'no-color',
'no-pager'
'options', 'options',
'price-db',
'price-exp', 'price-exp',
'revalued-total', 'revalued-total',
'script',
'seed', 'seed',
'trace', 'trace',
'verbose', 'verbose',

View file

@ -24,8 +24,12 @@ class DocTests:
self.testin_token = 'command' self.testin_token = 'command'
self.testout_token = 'output' self.testout_token = 'output'
self.testdat_token = 'input' self.testdat_token = 'input'
self.testfile_token = 'file'
self.validate_token = 'validate' self.validate_token = 'validate'
self.validate_cmd_token = 'validate-command'
self.validate_dat_token = 'validate-data'
self.testwithdat_token = 'with_input' self.testwithdat_token = 'with_input'
self.testwithfile_token = 'with_file'
def read_example(self): def read_example(self):
endexample = re.compile(r'^@end\s+smallexample\s*$') endexample = re.compile(r'^@end\s+smallexample\s*$')
@ -35,15 +39,15 @@ class DocTests:
self.current_line += 1 self.current_line += 1
if len(line) <= 0 or endexample.match(line): break if len(line) <= 0 or endexample.match(line): break
# Replace special texinfo character sequences with their ASCII counterpart # Replace special texinfo character sequences with their ASCII counterpart
example += line.replace("@@","@").replace("@{","{").replace("@}","}") example += re.sub(r'@([@{}])', r'\1', line)
return example return example
def test_id(self, example): def test_id(self, example):
return hashlib.sha1(example.rstrip()).hexdigest()[0:7].upper() return hashlib.sha1(example.rstrip()).hexdigest()[0:7].upper()
def find_examples(self): def find_examples(self):
startexample = re.compile(r'^@smallexample\s+@c\s+(%s|%s|%s)(?::([\dA-Fa-f]+|validate))?(?:,(.*))?' startexample = re.compile(r'^@smallexample\s+@c\s+(%s|%s|%s|%s)(?::([\dA-Fa-f]+|validate))?(?:,(.*))?'
% (self.testin_token, self.testout_token, self.testdat_token)) % (self.testin_token, self.testout_token, self.testdat_token, self.testfile_token))
while True: while True:
line = self.file.readline() line = self.file.readline()
self.current_line += 1 self.current_line += 1
@ -78,9 +82,9 @@ class DocTests:
if test_id == self.validate_token: if test_id == self.validate_token:
test_id = "Val-" + str(test_begin_line) test_id = "Val-" + str(test_begin_line)
if test_kind == self.testin_token: if test_kind == self.testin_token:
test_kind = "validate-command" test_kind = self.validate_cmd_token
elif test_kind == self.testdat_token: elif test_kind == self.testdat_token:
test_kind = "validate-data" test_kind = self.validate_dat_token
try: try:
self.examples[test_id] self.examples[test_id]
except KeyError: except KeyError:
@ -105,15 +109,15 @@ class DocTests:
try: try:
command = example[self.testin_token][self.testin_token] command = example[self.testin_token][self.testin_token]
except KeyError: except KeyError:
if 'validate-data' in example: if self.validate_dat_token in example:
command = '$ ledger bal' command = '$ ledger bal'
elif 'validate-command' in example: elif self.validate_cmd_token in example:
validate_command = True validate_command = True
command = example['validate-command']['validate-command'] command = example[self.validate_cmd_token][self.validate_cmd_token]
else: else:
return None return None
command = shlex.split(command) command = filter(lambda x: x != '\n', shlex.split(command))
if command[0] == '$': command.remove('$') if command[0] == '$': command.remove('$')
index = command.index('ledger') index = command.index('ledger')
command[index] = self.ledger command[index] = self.ledger
@ -145,7 +149,7 @@ class DocTests:
for test_id in tests: for test_id in tests:
validation = False validation = False
if "validate-data" in self.examples[test_id] or "validate-command" in self.examples[test_id]: if self.validate_dat_token in self.examples[test_id] or self.validate_cmd_token in self.examples[test_id]:
validation = True validation = True
example = self.examples[test_id] example = self.examples[test_id]
try: try:
@ -154,51 +158,52 @@ class DocTests:
failed.add(test_id) failed.add(test_id)
continue continue
try: output = example.get(self.testout_token, {}).get(self.testout_token)
output = example[self.testout_token][self.testout_token] input = example.get(self.testdat_token, {}).get(self.testdat_token)
except KeyError: if not input:
output = None with_input = example.get(self.testin_token, {}).get('opts', {}).get(self.testwithdat_token)
input = self.examples.get(with_input, {}).get(self.testdat_token, {}).get(self.testdat_token)
if not input:
input = example.get(self.validate_dat_token, {}).get(self.validate_dat_token)
try: if command and (output != None or validation):
input = example[self.testdat_token][self.testdat_token]
except KeyError:
try:
with_input = example[self.testin_token]['opts'][self.testwithdat_token]
input = self.examples[with_input][self.testdat_token][self.testdat_token]
except KeyError:
try:
input = example['validate-data']['validate-data']
except KeyError:
input = None
if command and (output or validation):
test_file_created = False test_file_created = False
if findex: if findex:
scriptpath = os.path.dirname(os.path.realpath(__file__)) scriptpath = os.path.dirname(os.path.realpath(__file__))
test_input_dir = scriptpath + '/../test/input/' test_input_dir = os.path.join(scriptpath, '..', 'test', 'input')
test_file = command[findex] test_file = command[findex]
if not os.path.exists(test_file): if not os.path.exists(test_file):
if input: if input:
test_file_created = True test_file_created = True
with open(test_file, 'w') as f: with open(test_file, 'w') as f:
f.write(input) f.write(input)
elif os.path.exists(test_input_dir + test_file): elif os.path.exists(os.path.join(test_input_dir, test_file)):
command[findex] = test_input_dir + test_file command[findex] = os.path.join(test_input_dir, test_file)
error = False try:
convert_idx = command.index('convert')
convert_file = command[convert_idx+1]
convert_data = example[self.testfile_token][self.testfile_token]
if not os.path.exists(convert_file):
with open(convert_file, 'w') as f:
f.write(convert_data)
except ValueError:
pass
error = None
try: try:
verify = subprocess.check_output(command, stderr=subprocess.STDOUT) verify = subprocess.check_output(command, stderr=subprocess.STDOUT)
except:
verify = str()
error = True
valid = (output == verify) or (not error and validation) valid = (output == verify) or (not error and validation)
except subprocess.CalledProcessError, e:
error = e.output
valid = False
failed.add(test_id)
if valid and test_file_created: if valid and test_file_created:
os.remove(test_file) os.remove(test_file)
if self.verbose > 0: if self.verbose > 0:
print test_id, ':', 'Passed' if valid else 'FAILED' print test_id, ':', 'Passed' if valid else 'FAILED: {}'.format(error) if error else 'FAILED'
else: else:
sys.stdout.write('.' if valid else 'E') sys.stdout.write('.' if valid else 'E')
if not valid: if not (valid or error):
failed.add(test_id) failed.add(test_id)
if self.verbose > 1: if self.verbose > 1:
print ' '.join(command) print ' '.join(command)
@ -206,6 +211,12 @@ class DocTests:
for line in unified_diff(output.split('\n'), verify.split('\n'), fromfile='generated', tofile='expected'): for line in unified_diff(output.split('\n'), verify.split('\n'), fromfile='generated', tofile='expected'):
print(line) print(line)
print print
else:
if self.verbose > 0:
print test_id, ':', 'Skipped'
else:
sys.stdout.write('X')
if not self.verbose: if not self.verbose:
print print
if len(failed) > 0: if len(failed) > 0:

View file

@ -14,17 +14,58 @@
Expenses:Food 20.00 EUR Expenses:Food 20.00 EUR
Liabilities:CC -20.00 EUR Liabilities:CC -20.00 EUR
test --input-date-format "%Y-%m-%d" --auto-match convert test/baseline/opt-auto-match.dat test --input-date-format "%Y-%m-%d" convert test/baseline/opt-auto-match.dat
2012/03/01 * Food 2012/03/01 * Food
Assets:Cash 10 Expenses:Unknown 10
Equity:Unknown Equity:Unknown
2012/03/02 * Phone 2012/03/02 * Phone
Assets:Cash 10 Expenses:Unknown 10
Equity:Unknown Equity:Unknown
2012/03/02 * Dining 2012/03/02 * Dining
Liabilities:CC 10 Expenses:Unknown 10
Equity:Unknown Equity:Unknown
end test end test
test --input-date-format "%Y-%m-%d" --auto-match convert test/baseline/opt-auto-match.dat
2012/03/01 * Food
Expenses:Food 10
Equity:Unknown
2012/03/02 * Phone
Expenses:Phone 10
Equity:Unknown
2012/03/02 * Dining
Expenses:Food 10
Equity:Unknown
end test
test --input-date-format "%Y-%m-%d" --account Assets:Bank convert test/baseline/opt-auto-match.dat
2012/03/01 * Food
Expenses:Unknown 10
Assets:Bank
2012/03/02 * Phone
Expenses:Unknown 10
Assets:Bank
2012/03/02 * Dining
Expenses:Unknown 10
Assets:Bank
end test
test --input-date-format "%Y-%m-%d" --auto-match --account Assets:Bank convert test/baseline/opt-auto-match.dat
2012/03/01 * Food
Expenses:Food 10
Assets:Bank
2012/03/02 * Phone
Expenses:Phone 10
Assets:Bank
2012/03/02 * Dining
Expenses:Food 10
Assets:Bank
end test

View file

@ -0,0 +1 @@
--decimal-comma

View file

@ -0,0 +1,10 @@
2012-03-17 Quick
Expenses:Food 12,50 €
Assets:Cash
test --init-file test/baseline/opt-init-file.dat bal
-12,50 € Assets:Cash
12,50 € Expenses:Food
--------------------
0
end test

View file

@ -0,0 +1,2 @@
P 2012-03-16 06:47:12 CAD $2.50
P 2012-03-17 06:47:12 CAD $3.50

View file

@ -0,0 +1,8 @@
2012-03-17 KFC
Expenses:Food 20 CAD
Assets:Cash
test pricedb --price-db test/baseline/opt-price-db.dat
P 2012/03/16 06:47:12 CAD $2.5
P 2012/03/17 06:47:12 CAD $3.5
end test

View file

@ -1,3 +1,13 @@
test -f /dev/null convert test/baseline/feat-convert-with-directives.dat --now '2014/08/01'
2012/01/01 * KFC
Expenses:Unknown $10
Equity:Unknown
2012/01/02 * REWE SAGT DANKE 123454321
Expenses:Unknown 10€
Equity:Unknown
end test
test -f /dev/null convert test/baseline/feat-convert-with-directives.dat --detail --now '2014/08/01' test -f /dev/null convert test/baseline/feat-convert-with-directives.dat --detail --now '2014/08/01'
2012/01/01 * KFC 2012/01/01 * KFC
; CSV: 2012/01/01,KFC,$10 ; CSV: 2012/01/01,KFC,$10

View file

@ -0,0 +1,3 @@
--no-pager --columns=80 bal
--no-pager --columns=80 reg
--no-pager --columns=80 print

View file

@ -0,0 +1,15 @@
2012-03-17 KFC
Expenses:Food 20 CAD
Assets:Cash
test --script test/baseline/opt-script.dat
-20 CAD Assets:Cash
20 CAD Expenses:Food
--------------------
0
12-Mar-17 KFC Expenses:Food 20 CAD 20 CAD
Assets:Cash -20 CAD 0
2012/03/17 KFC
Expenses:Food 20 CAD
Assets:Cash
end test

View file

@ -5,17 +5,17 @@
# Add [ci skip] to the commit message unless there are changes to files # Add [ci skip] to the commit message unless there are changes to files
# that are relevant for testing such as src/*, test/*, ledger3.texi, ... # that are relevant for testing such as src/*, test/*, ledger3.texi, ...
function add_ci_skip() add_ci_skip ()
{ {
pattern="$1"; shift pattern="$1"; shift
source="$1" source="$1"
# Don't add [ci skip] if it's already in the commit message source # Don't add [ci skip] if it's already in the commit message source
grep '\[ci skip\]' "$source" 2>&1 >/dev/null grep '\[ci skip\]' "$source" >/dev/null 2>&1
[ $? -eq 0 ] && return [ $? -eq 0 ] && return
if [ $(git diff --cached --name-only | grep --count "$pattern") -eq 0 ]; then if [ $(git diff --cached --name-only | grep --count "$pattern") -eq 0 ]; then
tempfile=$(mktemp $0.XXXXXX) tempfile=$(mktemp "${0}.XXXXXX")
cat - "$1" <<EOF > "$tempfile" cat - "$1" <<EOF > "$tempfile"
# It seems the changes to be committed are irrelevant for the continuous # It seems the changes to be committed are irrelevant for the continuous