Merge remote branch 'upstream/next' into next
This commit is contained in:
commit
b400d65be0
59 changed files with 675 additions and 463 deletions
38
acprep
38
acprep
|
|
@ -245,8 +245,8 @@ class CommandLineApp(object):
|
||||||
force_exit = True # If true, always ends run() with sys.exit()
|
force_exit = True # If true, always ends run() with sys.exit()
|
||||||
log_handler = None
|
log_handler = None
|
||||||
darwin_gcc = False
|
darwin_gcc = False
|
||||||
boost_version = "1_46_1"
|
boost_version = "1_47_0"
|
||||||
boost_major = "1_46_1"
|
boost_major = "1_47"
|
||||||
|
|
||||||
options = {
|
options = {
|
||||||
'debug': False,
|
'debug': False,
|
||||||
|
|
@ -338,7 +338,7 @@ class CommandLineApp(object):
|
||||||
self.log.setLevel(logging.DEBUG)
|
self.log.setLevel(logging.DEBUG)
|
||||||
elif self.options.verbose:
|
elif self.options.verbose:
|
||||||
self.log.setLevel(logging.INFO)
|
self.log.setLevel(logging.INFO)
|
||||||
|
|
||||||
exit_code = 0
|
exit_code = 0
|
||||||
try:
|
try:
|
||||||
# We could just call main() and catch a TypeError, but that would
|
# We could just call main() and catch a TypeError, but that would
|
||||||
|
|
@ -928,7 +928,7 @@ class PrepareBuild(CommandLineApp):
|
||||||
def setup_system_directories(self):
|
def setup_system_directories(self):
|
||||||
boost_include = self.boost_info.include_directory()
|
boost_include = self.boost_info.include_directory()
|
||||||
boost_library = self.boost_info.library_directory()
|
boost_library = self.boost_info.library_directory()
|
||||||
|
|
||||||
if re.match('/opt/local', self.boost_info.home_path):
|
if re.match('/opt/local', self.boost_info.home_path):
|
||||||
self.log.debug("Setting Python home to /opt/local based on Boost's location")
|
self.log.debug("Setting Python home to /opt/local based on Boost's location")
|
||||||
self.envvars['PYTHON_HOME'] = '/opt/local'
|
self.envvars['PYTHON_HOME'] = '/opt/local'
|
||||||
|
|
@ -1252,7 +1252,7 @@ class PrepareBuild(CommandLineApp):
|
||||||
home_path = '/usr/local/stow/boost_%s-%s' % \
|
home_path = '/usr/local/stow/boost_%s-%s' % \
|
||||||
(self.boost_version, self.boost_inc_ident),
|
(self.boost_version, self.boost_inc_ident),
|
||||||
suffix = '-%s-sd-%s' % \
|
suffix = '-%s-sd-%s' % \
|
||||||
(self.boost_lib_ident, self.boost_version),
|
(self.boost_lib_ident, self.boost_major),
|
||||||
file_suffix = '.dylib',
|
file_suffix = '.dylib',
|
||||||
include_path = 'include/boost-%s' % self.boost_major):
|
include_path = 'include/boost-%s' % self.boost_major):
|
||||||
pass
|
pass
|
||||||
|
|
@ -1260,7 +1260,7 @@ class PrepareBuild(CommandLineApp):
|
||||||
home_path = '/usr/local/stow/boost_%s-%s' % \
|
home_path = '/usr/local/stow/boost_%s-%s' % \
|
||||||
(self.boost_version, self.boost_inc_ident),
|
(self.boost_version, self.boost_inc_ident),
|
||||||
suffix = '-%s-d-%s' % \
|
suffix = '-%s-d-%s' % \
|
||||||
(self.boost_lib_ident, self.boost_version),
|
(self.boost_lib_ident, self.boost_major),
|
||||||
file_suffix = '.dylib',
|
file_suffix = '.dylib',
|
||||||
include_path = 'include/boost-%s' % self.boost_major):
|
include_path = 'include/boost-%s' % self.boost_major):
|
||||||
pass
|
pass
|
||||||
|
|
@ -1274,7 +1274,7 @@ class PrepareBuild(CommandLineApp):
|
||||||
home_path = '/usr/local/stow/boost_%s-%s' % \
|
home_path = '/usr/local/stow/boost_%s-%s' % \
|
||||||
(self.boost_version, self.boost_inc_ident),
|
(self.boost_version, self.boost_inc_ident),
|
||||||
suffix = '-%s-s-%s' % \
|
suffix = '-%s-s-%s' % \
|
||||||
(self.boost_lib_ident, self.boost_version),
|
(self.boost_lib_ident, self.boost_major),
|
||||||
file_suffix = '.dylib',
|
file_suffix = '.dylib',
|
||||||
include_path = 'include/boost-%s' % self.boost_major):
|
include_path = 'include/boost-%s' % self.boost_major):
|
||||||
pass
|
pass
|
||||||
|
|
@ -1282,7 +1282,7 @@ class PrepareBuild(CommandLineApp):
|
||||||
home_path = '/usr/local/stow/boost_%s-%s' % \
|
home_path = '/usr/local/stow/boost_%s-%s' % \
|
||||||
(self.boost_version, self.boost_inc_ident),
|
(self.boost_version, self.boost_inc_ident),
|
||||||
suffix = '-%s-%s' % \
|
suffix = '-%s-%s' % \
|
||||||
(self.boost_lib_ident, self.boost_version),
|
(self.boost_lib_ident, self.boost_major),
|
||||||
file_suffix = '.dylib',
|
file_suffix = '.dylib',
|
||||||
include_path = 'include/boost-%s' % self.boost_major):
|
include_path = 'include/boost-%s' % self.boost_major):
|
||||||
pass
|
pass
|
||||||
|
|
@ -1518,7 +1518,7 @@ class PrepareBuild(CommandLineApp):
|
||||||
match = re.search('/opt/local/lib/(.+?)\.dylib', line)
|
match = re.search('/opt/local/lib/(.+?)\.dylib', line)
|
||||||
if not match:
|
if not match:
|
||||||
continue
|
continue
|
||||||
|
|
||||||
lib = match.group(0)
|
lib = match.group(0)
|
||||||
base = basename(lib)
|
base = basename(lib)
|
||||||
|
|
||||||
|
|
@ -1587,7 +1587,7 @@ class PrepareBuild(CommandLineApp):
|
||||||
|
|
||||||
def phase_distcheck(self, *args):
|
def phase_distcheck(self, *args):
|
||||||
self.log.info('Executing phase: distcheck')
|
self.log.info('Executing phase: distcheck')
|
||||||
|
|
||||||
self.configure_flavor('default', False)
|
self.configure_flavor('default', False)
|
||||||
|
|
||||||
environ, conf_args = self.configure_environment()
|
environ, conf_args = self.configure_environment()
|
||||||
|
|
@ -1621,7 +1621,7 @@ class PrepareBuild(CommandLineApp):
|
||||||
'%s/' % self.source_dir, '%s/' % source_copy_dir)
|
'%s/' % self.source_dir, '%s/' % source_copy_dir)
|
||||||
|
|
||||||
self.source_dir = source_copy_dir
|
self.source_dir = source_copy_dir
|
||||||
|
|
||||||
def phase_proof(self, *args):
|
def phase_proof(self, *args):
|
||||||
self.log.info('Executing phase: proof')
|
self.log.info('Executing phase: proof')
|
||||||
|
|
||||||
|
|
@ -1633,15 +1633,15 @@ class PrepareBuild(CommandLineApp):
|
||||||
self.configure_flavor('opt', reset=False)
|
self.configure_flavor('opt', reset=False)
|
||||||
self.log.info('=== Testing opt ===')
|
self.log.info('=== Testing opt ===')
|
||||||
self.phase_make('fullcheck')
|
self.phase_make('fullcheck')
|
||||||
|
|
||||||
self.configure_flavor('gcov', reset=False)
|
self.configure_flavor('gcov', reset=False)
|
||||||
self.log.info('=== Testing gcov ===')
|
self.log.info('=== Testing gcov ===')
|
||||||
self.phase_make('check')
|
self.phase_make('check')
|
||||||
|
|
||||||
self.configure_flavor('debug', reset=False)
|
self.configure_flavor('debug', reset=False)
|
||||||
self.log.info('=== Testing debug ===')
|
self.log.info('=== Testing debug ===')
|
||||||
self.phase_make('fullcheck')
|
self.phase_make('fullcheck')
|
||||||
|
|
||||||
self.configure_flavor('default', reset=False)
|
self.configure_flavor('default', reset=False)
|
||||||
self.log.info('=== Testing default ===')
|
self.log.info('=== Testing default ===')
|
||||||
self.phase_make('fullcheck')
|
self.phase_make('fullcheck')
|
||||||
|
|
@ -1654,14 +1654,14 @@ class PrepareBuild(CommandLineApp):
|
||||||
self.log.info('Executing phase: makeall')
|
self.log.info('Executing phase: makeall')
|
||||||
|
|
||||||
self.configure_flavor('opt', reset)
|
self.configure_flavor('opt', reset)
|
||||||
|
|
||||||
system_hh_gch = join(self.source_dir, 'src', 'system.hh.gch')
|
system_hh_gch = join(self.source_dir, 'src', 'system.hh.gch')
|
||||||
if exists(system_hh_gch):
|
if exists(system_hh_gch):
|
||||||
os.remove(system_hh_gch)
|
os.remove(system_hh_gch)
|
||||||
|
|
||||||
self.log.info('=== Building opt ===')
|
self.log.info('=== Building opt ===')
|
||||||
self.phase_make(*args)
|
self.phase_make(*args)
|
||||||
|
|
||||||
self.configure_flavor('gcov', reset)
|
self.configure_flavor('gcov', reset)
|
||||||
|
|
||||||
system_hh_gch = join(self.source_dir, 'src', 'system.hh.gch')
|
system_hh_gch = join(self.source_dir, 'src', 'system.hh.gch')
|
||||||
|
|
@ -1670,7 +1670,7 @@ class PrepareBuild(CommandLineApp):
|
||||||
|
|
||||||
self.log.info('=== Building gcov ===')
|
self.log.info('=== Building gcov ===')
|
||||||
self.phase_make(*args)
|
self.phase_make(*args)
|
||||||
|
|
||||||
system_hh_gch = join(self.source_dir, 'src', 'system.hh.gch')
|
system_hh_gch = join(self.source_dir, 'src', 'system.hh.gch')
|
||||||
if exists(system_hh_gch):
|
if exists(system_hh_gch):
|
||||||
os.remove(system_hh_gch)
|
os.remove(system_hh_gch)
|
||||||
|
|
@ -1686,7 +1686,7 @@ class PrepareBuild(CommandLineApp):
|
||||||
|
|
||||||
self.log.info('=== Building debug ===')
|
self.log.info('=== Building debug ===')
|
||||||
self.phase_make(*args)
|
self.phase_make(*args)
|
||||||
|
|
||||||
self.configure_flavor('default', reset)
|
self.configure_flavor('default', reset)
|
||||||
|
|
||||||
#########################################################################
|
#########################################################################
|
||||||
|
|
@ -1696,7 +1696,7 @@ class PrepareBuild(CommandLineApp):
|
||||||
def phase_help(self, *args):
|
def phase_help(self, *args):
|
||||||
self.option_parser.print_help()
|
self.option_parser.print_help()
|
||||||
|
|
||||||
print """
|
print """
|
||||||
Of the optional ARGS, the first is an optional build FLAVOR, with the default
|
Of the optional ARGS, the first is an optional build FLAVOR, with the default
|
||||||
being 'debug':
|
being 'debug':
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -6,6 +6,22 @@ Then include the following line in your .vimrc or in ~/.vim/filetype.vim
|
||||||
You can also use a modeline like this in every ledger file
|
You can also use a modeline like this in every ledger file
|
||||||
vim:filetype=ledger
|
vim:filetype=ledger
|
||||||
|
|
||||||
|
Tips and useful commands
|
||||||
|
======================================================================
|
||||||
|
• Try account-completion (as explained below)
|
||||||
|
• :call LedgerSetDate(line('.'), 'effective')
|
||||||
|
will set today's date as the effective date of the current
|
||||||
|
transaction. You can use also 'actual' in place of 'effective'
|
||||||
|
or pass in a different date measured as seconds since 1st Jan 1970.
|
||||||
|
• :call LedgerSetTransactionState(line('.'), '*')
|
||||||
|
sets the state of the current transaction to '*'. You can
|
||||||
|
use this in custom mappings.
|
||||||
|
• :call LedgerToggleTransactionState(line('.'), ' *?!')
|
||||||
|
will toggle through the provided transaction states.
|
||||||
|
You can map this to double-clicking for example:
|
||||||
|
noremap <silent><buffer> <2-LeftMouse>
|
||||||
|
\ :call LedgerToggleTransactionState(line('.'), ' *?!')<CR>
|
||||||
|
|
||||||
Configuration
|
Configuration
|
||||||
======================================================================
|
======================================================================
|
||||||
Include the following let-statements somewhere in your .vimrc
|
Include the following let-statements somewhere in your .vimrc
|
||||||
|
|
@ -35,7 +51,7 @@ to modify the behaviour of the ledger filetype.
|
||||||
|
|
||||||
Completion
|
Completion
|
||||||
======================================================================
|
======================================================================
|
||||||
Omni completion is implemented for account names and tags.
|
Omni completion is currently implemented for account names only.
|
||||||
|
|
||||||
Accounts
|
Accounts
|
||||||
----------------------------------------------------------------------
|
----------------------------------------------------------------------
|
||||||
|
|
@ -52,38 +68,11 @@ When you want to complete on a virtual transaction,
|
||||||
it's currently best to keep the cursor in front of the closing bracket.
|
it's currently best to keep the cursor in front of the closing bracket.
|
||||||
Of course you can insert the closing bracket after calling the completion, too.
|
Of course you can insert the closing bracket after calling the completion, too.
|
||||||
|
|
||||||
Tags
|
|
||||||
----------------------------------------------------------------------
|
|
||||||
The support for completing tags is pretty basic right now
|
|
||||||
but it's useful to keep the spelling of your tags consistent.
|
|
||||||
You can call the completion after the ';' to get a list of all tags.
|
|
||||||
When you have a list of tags (:like: :this:) you can call
|
|
||||||
the completion too and everything up to the last ':' (excluding whitespace)
|
|
||||||
will be considered the beginning of the tag to search for.
|
|
||||||
|
|
||||||
Revision history (major changes)
|
|
||||||
======================================================================
|
|
||||||
2009-06-23 & 2009-06-25
|
|
||||||
J. Klähn: Omni-Completion for account names and tags
|
|
||||||
2009-06-17 J. Klähn: Highlight account text
|
|
||||||
Updated documentation and added fillstring option.
|
|
||||||
2009-06-15 J. Klähn: Split into multiple files
|
|
||||||
2009-06-12 J. Klähn: Use all available columns for foldtext
|
|
||||||
Also rewrote foldtext generation.
|
|
||||||
2009-03-25 J. Klähn: Allow Metadata
|
|
||||||
in transactions and postings (Ledger 3.0)
|
|
||||||
Also fixed alignment for multi-byte-characters
|
|
||||||
2009-01-28 S.Karrmann: minor fixes
|
|
||||||
2009-01-27 third version by S.Karrmann.
|
|
||||||
better extraction of the amount of the posting
|
|
||||||
decimal separator can be one of '.' and ','.
|
|
||||||
2005-02-05 first version (partly copied from ledger.vim 0.0.1)
|
|
||||||
|
|
||||||
License
|
License
|
||||||
======================================================================
|
======================================================================
|
||||||
Copyright 2009 by Johann Klähn
|
Copyright 2011-2009 by Johann Klähn
|
||||||
Copyright 2009 by Stefan Karrmann
|
Copyright 2009 by Stefan Karrmann
|
||||||
Copyright 2005 by Wolfgang Oertl
|
Copyright 2005 by Wolfgang Oertl
|
||||||
|
|
||||||
This program is free software: you can redistribute it and/or modify
|
This program is free software: you can redistribute it and/or modify
|
||||||
it under the terms of the GNU General Public License as published by
|
it under the terms of the GNU General Public License as published by
|
||||||
|
|
|
||||||
|
|
@ -1,6 +1,5 @@
|
||||||
" Vim filetype plugin file
|
" Vim filetype plugin file
|
||||||
" filetype: ledger
|
" filetype: ledger
|
||||||
" Version: 0.1.0
|
|
||||||
" by Johann Klähn; Use according to the terms of the GPL>=2.
|
" by Johann Klähn; Use according to the terms of the GPL>=2.
|
||||||
" vim:ts=2:sw=2:sts=2:foldmethod=marker
|
" vim:ts=2:sw=2:sts=2:foldmethod=marker
|
||||||
|
|
||||||
|
|
@ -137,22 +136,33 @@ function! LedgerComplete(findstart, base) "{{{1
|
||||||
if a:findstart
|
if a:findstart
|
||||||
let lnum = line('.')
|
let lnum = line('.')
|
||||||
let line = getline('.')
|
let line = getline('.')
|
||||||
let lastcol = col('.') - 2
|
|
||||||
let b:compl_context = ''
|
let b:compl_context = ''
|
||||||
if line =~ '^\s\+[^[:blank:];]' "{{{2 (account)
|
if line =~ '^\s\+[^[:blank:];]' "{{{2 (account)
|
||||||
let b:compl_context = 'account'
|
" only allow completion when in or at end of account name
|
||||||
if matchend(line, '^\s\+\%(\S \S\|\S\)\+') <= lastcol
|
if matchend(line, '^\s\+\%(\S \S\|\S\)\+') >= col('.') - 1
|
||||||
" only allow completion when in or at end of account name
|
" the start of the first non-blank character
|
||||||
return -1
|
" (excluding virtual-transaction-marks)
|
||||||
|
" is the beginning of the account name
|
||||||
|
let b:compl_context = 'account'
|
||||||
|
return matchend(line, '^\s\+[\[(]\?')
|
||||||
endif
|
endif
|
||||||
" the start of the first non-blank character
|
elseif line =~ '^\d' "{{{2 (description)
|
||||||
" (excluding virtual-transaction-marks)
|
let pre = matchend(line, '^\d\S\+\%(([^)]*)\|[*?!]\|\s\)\+')
|
||||||
" is the beginning of the account name
|
if pre < col('.') - 1
|
||||||
return matchend(line, '^\s\+[\[(]\?')
|
let b:compl_context = 'description'
|
||||||
else "}}}
|
return pre
|
||||||
return -1
|
endif
|
||||||
endif
|
elseif line =~ '^$' "{{{2 (new line)
|
||||||
|
let b:compl_context = 'new'
|
||||||
|
endif "}}}
|
||||||
|
return -1
|
||||||
else
|
else
|
||||||
|
if ! exists('b:compl_cache')
|
||||||
|
let b:compl_cache = s:collect_completion_data()
|
||||||
|
let b:compl_cache['#'] = changenr()
|
||||||
|
endif
|
||||||
|
|
||||||
|
let results = []
|
||||||
if b:compl_context == 'account' "{{{2 (account)
|
if b:compl_context == 'account' "{{{2 (account)
|
||||||
unlet! b:compl_context
|
unlet! b:compl_context
|
||||||
let hierarchy = split(a:base, ':')
|
let hierarchy = split(a:base, ':')
|
||||||
|
|
@ -160,7 +170,7 @@ function! LedgerComplete(findstart, base) "{{{1
|
||||||
call add(hierarchy, '')
|
call add(hierarchy, '')
|
||||||
endif
|
endif
|
||||||
|
|
||||||
let results = LedgerFindInTree(LedgerGetAccountHierarchy(), hierarchy)
|
let results = LedgerFindInTree(b:compl_cache.accounts, hierarchy)
|
||||||
" sort by alphabet and reverse because it will get reversed one more time
|
" sort by alphabet and reverse because it will get reversed one more time
|
||||||
if g:ledger_detailed_first
|
if g:ledger_detailed_first
|
||||||
let results = reverse(sort(results, 's:sort_accounts_by_depth'))
|
let results = reverse(sort(results, 's:sort_accounts_by_depth'))
|
||||||
|
|
@ -168,10 +178,19 @@ function! LedgerComplete(findstart, base) "{{{1
|
||||||
let results = sort(results)
|
let results = sort(results)
|
||||||
endif
|
endif
|
||||||
call insert(results, a:base)
|
call insert(results, a:base)
|
||||||
return results
|
elseif b:compl_context == 'description' "{{{2 (description)
|
||||||
else "}}}
|
let results = [a:base] + s:filter_items(b:compl_cache.descriptions, a:base)
|
||||||
|
elseif b:compl_context == 'new' "{{{2 (new line)
|
||||||
|
return [strftime('%Y/%m/%d')]
|
||||||
|
endif "}}}
|
||||||
|
|
||||||
|
" no completion (apart from a:base) found. update cache if file has changed
|
||||||
|
if len(results) <= 1 && b:compl_cache['#'] != changenr()
|
||||||
|
unlet b:compl_cache
|
||||||
|
return LedgerComplete(a:findstart, a:base)
|
||||||
|
else
|
||||||
unlet! b:compl_context
|
unlet! b:compl_context
|
||||||
return []
|
return results
|
||||||
endif
|
endif
|
||||||
endif
|
endif
|
||||||
endf "}}}
|
endf "}}}
|
||||||
|
|
@ -195,21 +214,6 @@ function! LedgerFindInTree(tree, levels) "{{{1
|
||||||
return results
|
return results
|
||||||
endf "}}}
|
endf "}}}
|
||||||
|
|
||||||
function! LedgerGetAccountHierarchy() "{{{1
|
|
||||||
let hierarchy = {}
|
|
||||||
let accounts = s:grep_buffer('^\s\+\zs[^[:blank:];]\%(\S \S\|\S\)\+\ze')
|
|
||||||
for name in accounts
|
|
||||||
" remove virtual-transaction-marks
|
|
||||||
let name = substitute(name, '\%(^\s*[\[(]\?\|[\])]\?\s*$\)', '', 'g')
|
|
||||||
let last = hierarchy
|
|
||||||
for part in split(name, ':')
|
|
||||||
let last[part] = get(last, part, {})
|
|
||||||
let last = last[part]
|
|
||||||
endfor
|
|
||||||
endfor
|
|
||||||
return hierarchy
|
|
||||||
endf "}}}
|
|
||||||
|
|
||||||
function! LedgerToggleTransactionState(lnum, ...)
|
function! LedgerToggleTransactionState(lnum, ...)
|
||||||
if a:0 == 1
|
if a:0 == 1
|
||||||
let chars = a:1
|
let chars = a:1
|
||||||
|
|
@ -278,6 +282,51 @@ function! LedgerSetDate(lnum, type, ...) "{{{1
|
||||||
call setline(trans['head'], trans.format_head())
|
call setline(trans['head'], trans.format_head())
|
||||||
endf "}}}
|
endf "}}}
|
||||||
|
|
||||||
|
function! s:collect_completion_data() "{{{1
|
||||||
|
let transactions = s:get_transactions()
|
||||||
|
let cache = {'descriptions': [], 'tags': {}, 'accounts': {}}
|
||||||
|
let accounts = []
|
||||||
|
for xact in transactions
|
||||||
|
" collect descriptions
|
||||||
|
if index(cache.descriptions, xact['description']) < 0
|
||||||
|
call add(cache.descriptions, xact['description'])
|
||||||
|
endif
|
||||||
|
let [t, postings] = xact.parse_body()
|
||||||
|
let tagdicts = [t]
|
||||||
|
|
||||||
|
" collect account names
|
||||||
|
for posting in postings
|
||||||
|
if has_key(posting, 'tags')
|
||||||
|
call add(tagdicts, posting.tags)
|
||||||
|
endif
|
||||||
|
" remove virtual-transaction-marks
|
||||||
|
let name = substitute(posting.account, '\%(^\s*[\[(]\?\|[\])]\?\s*$\)', '', 'g')
|
||||||
|
if index(accounts, name) < 0
|
||||||
|
call add(accounts, name)
|
||||||
|
endif
|
||||||
|
endfor
|
||||||
|
|
||||||
|
" collect tags
|
||||||
|
for tags in tagdicts | for [tag, val] in items(tags)
|
||||||
|
let values = get(cache.tags, tag, [])
|
||||||
|
if index(values, val) < 0
|
||||||
|
call add(values, val)
|
||||||
|
endif
|
||||||
|
let cache.tags[tag] = values
|
||||||
|
endfor | endfor
|
||||||
|
endfor
|
||||||
|
|
||||||
|
for account in accounts
|
||||||
|
let last = cache.accounts
|
||||||
|
for part in split(account, ':')
|
||||||
|
let last[part] = get(last, part, {})
|
||||||
|
let last = last[part]
|
||||||
|
endfor
|
||||||
|
endfor
|
||||||
|
|
||||||
|
return cache
|
||||||
|
endf "}}}
|
||||||
|
|
||||||
let s:transaction = {} "{{{1
|
let s:transaction = {} "{{{1
|
||||||
function! s:transaction.new() dict
|
function! s:transaction.new() dict
|
||||||
return copy(s:transaction)
|
return copy(s:transaction)
|
||||||
|
|
@ -293,7 +342,15 @@ function! s:transaction.from_lnum(lnum) dict "{{{2
|
||||||
let trans['head'] = head
|
let trans['head'] = head
|
||||||
let trans['tail'] = tail
|
let trans['tail'] = tail
|
||||||
|
|
||||||
let parts = split(getline(head), '\s\+')
|
" split off eventual comments at the end of line
|
||||||
|
let line = split(getline(head), '\ze\s*\%(\t\| \);', 1)
|
||||||
|
if len(line) > 1
|
||||||
|
let trans['appendix'] = join(line[1:], '')
|
||||||
|
endif
|
||||||
|
|
||||||
|
" parse rest of line
|
||||||
|
" FIXME (minor): will not preserve spacing (see 'join(parts)')
|
||||||
|
let parts = split(line[0], '\s\+')
|
||||||
if parts[0] ==# '~'
|
if parts[0] ==# '~'
|
||||||
let trans['expr'] = join(parts[1:])
|
let trans['expr'] = join(parts[1:])
|
||||||
return trans
|
return trans
|
||||||
|
|
@ -318,8 +375,6 @@ function! s:transaction.from_lnum(lnum) dict "{{{2
|
||||||
call remove(parts, 0)
|
call remove(parts, 0)
|
||||||
endfor
|
endfor
|
||||||
|
|
||||||
" FIXME: this will break comments at the end of this 'head' line
|
|
||||||
" they need 2 spaces in front of the semicolon
|
|
||||||
let trans['description'] = join(parts)
|
let trans['description'] = join(parts)
|
||||||
return trans
|
return trans
|
||||||
endf "}}}
|
endf "}}}
|
||||||
|
|
@ -402,7 +457,11 @@ function! s:transaction.format_head() dict "{{{2
|
||||||
if has_key(self, 'code') | call add(parts, '('.self['code'].')') | endif
|
if has_key(self, 'code') | call add(parts, '('.self['code'].')') | endif
|
||||||
if has_key(self, 'state') | call add(parts, self['state']) | endif
|
if has_key(self, 'state') | call add(parts, self['state']) | endif
|
||||||
if has_key(self, 'description') | call add(parts, self['description']) | endif
|
if has_key(self, 'description') | call add(parts, self['description']) | endif
|
||||||
return join(parts)
|
|
||||||
|
let line = join(parts)
|
||||||
|
if has_key(self, 'appendix') | let line .= self['appendix'] | endif
|
||||||
|
|
||||||
|
return line
|
||||||
endf "}}}
|
endf "}}}
|
||||||
"}}}
|
"}}}
|
||||||
|
|
||||||
|
|
@ -518,7 +577,7 @@ endf "}}}
|
||||||
|
|
||||||
" return only those items that start with a specified keyword
|
" return only those items that start with a specified keyword
|
||||||
function! s:filter_items(list, keyword) "{{{2
|
function! s:filter_items(list, keyword) "{{{2
|
||||||
return filter(a:list, 'v:val =~ ''^\V'.substitute(a:keyword, '\\', '\\\\', 'g').'''')
|
return filter(copy(a:list), 'v:val =~ ''^\V'.substitute(a:keyword, '\\', '\\\\', 'g').'''')
|
||||||
endf "}}}
|
endf "}}}
|
||||||
|
|
||||||
" return all lines matching an expression, returning only the matched part
|
" return all lines matching an expression, returning only the matched part
|
||||||
|
|
|
||||||
|
|
@ -1,19 +1,8 @@
|
||||||
" Vim syntax file
|
" Vim syntax file
|
||||||
" filetype: ledger
|
" filetype: ledger
|
||||||
" Version: 0.1.0
|
|
||||||
" by Johann Klähn; Use according to the terms of the GPL>=2.
|
" by Johann Klähn; Use according to the terms of the GPL>=2.
|
||||||
" by Stefan Karrmann; Use according to the terms of the GPL>=2.
|
" by Stefan Karrmann; Use according to the terms of the GPL>=2.
|
||||||
" by Wolfgang Oertl; Use according to the terms of the GPL>=2.
|
" by Wolfgang Oertl; Use according to the terms of the GPL>=2.
|
||||||
" Revision history
|
|
||||||
" 2009-06-12 J. Klähn: Use all available columns for foldtext
|
|
||||||
" 2009-03-25 J. Klähn: Allow Metadata
|
|
||||||
" in transactions and postings (Ledger 3.0)
|
|
||||||
" Also fixed alignment for multi-byte-characters
|
|
||||||
" 2009-01-28 S.Karrmann: minor fixes
|
|
||||||
" 2009-01-27 third version by S.Karrmann.
|
|
||||||
" better extraction of the amount of the posting
|
|
||||||
" decimal separator can be one of '.' and ','.
|
|
||||||
" 2005-02-05 first version (partly copied from ledger.vim 0.0.1)
|
|
||||||
" vim:ts=2:sw=2:sts=2:foldmethod=marker
|
" vim:ts=2:sw=2:sts=2:foldmethod=marker
|
||||||
|
|
||||||
if version < 600
|
if version < 600
|
||||||
|
|
|
||||||
|
|
@ -5,8 +5,8 @@
|
||||||
STOW_ROOT = /usr/local/stow
|
STOW_ROOT = /usr/local/stow
|
||||||
PRODUCTS = $(HOME)/Products
|
PRODUCTS = $(HOME)/Products
|
||||||
|
|
||||||
GCC_VERSION = 4.6
|
GCC_VERSION = 4.5
|
||||||
BOOST_VERSION = 1_46_1
|
BOOST_VERSION = 1_47_0
|
||||||
|
|
||||||
CC = gcc-mp-$(GCC_VERSION)
|
CC = gcc-mp-$(GCC_VERSION)
|
||||||
ifeq ($(CC),clang)
|
ifeq ($(CC),clang)
|
||||||
|
|
@ -51,7 +51,7 @@ all: boost-build #icu-build boost-icu-build
|
||||||
|
|
||||||
prepare-boost:
|
prepare-boost:
|
||||||
perl -i -pe 's/local command = \[ common\.get-invocation-command darwin : g\+\+ : .*/local command = [ common.get-invocation-command darwin : g++ : $(CXX) ] ;/;' $(BOOST_SOURCE)/tools/build/v2/tools/darwin.jam
|
perl -i -pe 's/local command = \[ common\.get-invocation-command darwin : g\+\+ : .*/local command = [ common.get-invocation-command darwin : g++ : $(CXX) ] ;/;' $(BOOST_SOURCE)/tools/build/v2/tools/darwin.jam
|
||||||
perl -i -pe 's/flags darwin\.compile OPTIONS : -no-cpp-precomp -gdwarf-2 ;/flags darwin\.compile OPTIONS : -gdwarf-2 ;/;' $(BOOST_SOURCE)/tools/build/v2/tools/darwin.jam
|
perl -i -pe 's/flags darwin\.compile OPTIONS : -no-cpp-precomp -gdwarf-2 (-fexceptions )?;/flags darwin\.compile OPTIONS : -gdwarf-2 \1;/;' $(BOOST_SOURCE)/tools/build/v2/tools/darwin.jam
|
||||||
|
|
||||||
boost-build: prepare-boost
|
boost-build: prepare-boost
|
||||||
(cd $(BOOST_SOURCE) && \
|
(cd $(BOOST_SOURCE) && \
|
||||||
|
|
|
||||||
|
|
@ -53,4 +53,30 @@
|
||||||
|
|
||||||
(provide 'ledger)
|
(provide 'ledger)
|
||||||
|
|
||||||
|
;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;
|
||||||
|
|
||||||
|
(defun ledger-create-test ()
|
||||||
|
(interactive)
|
||||||
|
(save-restriction
|
||||||
|
(org-narrow-to-subtree)
|
||||||
|
(save-excursion
|
||||||
|
(let (text beg)
|
||||||
|
(goto-char (point-min))
|
||||||
|
(forward-line 1)
|
||||||
|
(setq beg (point))
|
||||||
|
(search-forward ":PROPERTIES:")
|
||||||
|
(goto-char (line-beginning-position))
|
||||||
|
(setq text (buffer-substring-no-properties beg (point)))
|
||||||
|
(goto-char (point-min))
|
||||||
|
(re-search-forward ":ID:\\s-+\\([^-]+\\)")
|
||||||
|
(find-file-other-window
|
||||||
|
(format "~/src/ledger/test/regress/%s.test" (match-string 1)))
|
||||||
|
(sit-for 0)
|
||||||
|
(insert text)
|
||||||
|
(goto-char (point-min))
|
||||||
|
(while (not (eobp))
|
||||||
|
(goto-char (line-beginning-position))
|
||||||
|
(delete-char 3)
|
||||||
|
(forward-line 1))))))
|
||||||
|
|
||||||
;;; ledger.el ends here
|
;;; ledger.el ends here
|
||||||
|
|
|
||||||
|
|
@ -433,7 +433,9 @@ dropped."
|
||||||
|
|
||||||
;;;###autoload
|
;;;###autoload
|
||||||
(define-derived-mode ledger-mode text-mode "Ledger"
|
(define-derived-mode ledger-mode text-mode "Ledger"
|
||||||
"A mode for editing ledger data files."
|
"A mode for editing ledger data files.
|
||||||
|
|
||||||
|
\\{ledger-mode-map}"
|
||||||
(set (make-local-variable 'comment-start) " ; ")
|
(set (make-local-variable 'comment-start) " ; ")
|
||||||
(set (make-local-variable 'comment-end) "")
|
(set (make-local-variable 'comment-end) "")
|
||||||
(set (make-local-variable 'indent-tabs-mode) nil)
|
(set (make-local-variable 'indent-tabs-mode) nil)
|
||||||
|
|
@ -632,8 +634,7 @@ dropped."
|
||||||
|
|
||||||
(defvar ledger-reconcile-mode-abbrev-table)
|
(defvar ledger-reconcile-mode-abbrev-table)
|
||||||
|
|
||||||
(define-derived-mode ledger-reconcile-mode text-mode "Reconcile"
|
(defvar ledger-reconcile-mode-map
|
||||||
"A mode for reconciling ledger entries."
|
|
||||||
(let ((map (make-sparse-keymap)))
|
(let ((map (make-sparse-keymap)))
|
||||||
(define-key map [(control ?m)] 'ledger-reconcile-visit)
|
(define-key map [(control ?m)] 'ledger-reconcile-visit)
|
||||||
(define-key map [return] 'ledger-reconcile-visit)
|
(define-key map [return] 'ledger-reconcile-visit)
|
||||||
|
|
@ -647,7 +648,12 @@ dropped."
|
||||||
(define-key map [?p] 'previous-line)
|
(define-key map [?p] 'previous-line)
|
||||||
(define-key map [?s] 'ledger-reconcile-save)
|
(define-key map [?s] 'ledger-reconcile-save)
|
||||||
(define-key map [?q] 'ledger-reconcile-quit)
|
(define-key map [?q] 'ledger-reconcile-quit)
|
||||||
(use-local-map map)))
|
map))
|
||||||
|
|
||||||
|
(define-derived-mode ledger-reconcile-mode text-mode "Reconcile"
|
||||||
|
"A mode for reconciling ledger entries.
|
||||||
|
|
||||||
|
\\{ledger-reconcile-mode-map}")
|
||||||
|
|
||||||
;; Context sensitivity
|
;; Context sensitivity
|
||||||
|
|
||||||
|
|
@ -807,8 +813,7 @@ specified line, returns nil."
|
||||||
|
|
||||||
(defvar ledger-report-mode-abbrev-table)
|
(defvar ledger-report-mode-abbrev-table)
|
||||||
|
|
||||||
(define-derived-mode ledger-report-mode text-mode "Ledger-Report"
|
(defvar ledger-report-mode-map
|
||||||
"A mode for viewing ledger reports."
|
|
||||||
(let ((map (make-sparse-keymap)))
|
(let ((map (make-sparse-keymap)))
|
||||||
(define-key map [? ] 'scroll-up)
|
(define-key map [? ] 'scroll-up)
|
||||||
(define-key map [backspace] 'scroll-down)
|
(define-key map [backspace] 'scroll-down)
|
||||||
|
|
@ -825,7 +830,10 @@ specified line, returns nil."
|
||||||
'ledger-report-kill)
|
'ledger-report-kill)
|
||||||
(define-key map [(control ?c) (control ?l) (control ?e)]
|
(define-key map [(control ?c) (control ?l) (control ?e)]
|
||||||
'ledger-report-edit)
|
'ledger-report-edit)
|
||||||
(use-local-map map)))
|
map))
|
||||||
|
|
||||||
|
(define-derived-mode ledger-report-mode text-mode "Ledger-Report"
|
||||||
|
"A mode for viewing ledger reports.")
|
||||||
|
|
||||||
(defun ledger-report-read-name ()
|
(defun ledger-report-read-name ()
|
||||||
"Read the name of a ledger report to use, with completion.
|
"Read the name of a ledger report to use, with completion.
|
||||||
|
|
@ -1201,7 +1209,7 @@ the default."
|
||||||
;; A sample function for $ users
|
;; A sample function for $ users
|
||||||
|
|
||||||
(defun ledger-next-amount (&optional end)
|
(defun ledger-next-amount (&optional end)
|
||||||
(when (re-search-forward "\\( \\|\t\\| \t\\)[ \t]*-?\\([A-Z$]+ *\\)?\\(-?[0-9,]+?\\)\\(.[0-9]+\\)?\\( *[A-Z$]+\\)?\\([ \t]*@@?[^\n;]+?\\)?\\([ \t]+;.+?\\)?$" (marker-position end) t)
|
(when (re-search-forward "\\( \\|\t\\| \t\\)[ \t]*-?\\([A-Z$€£]+ *\\)?\\(-?[0-9,]+?\\)\\(.[0-9]+\\)?\\( *[A-Z$€£]+\\)?\\([ \t]*@@?[^\n;]+?\\)?\\([ \t]+;.+?\\)?$" (marker-position end) t)
|
||||||
(goto-char (match-beginning 0))
|
(goto-char (match-beginning 0))
|
||||||
(skip-syntax-forward " ")
|
(skip-syntax-forward " ")
|
||||||
(- (or (match-end 4)
|
(- (or (match-end 4)
|
||||||
|
|
|
||||||
|
|
@ -45,7 +45,7 @@ account_t::~account_t()
|
||||||
if (! pair.second->has_flags(ACCOUNT_TEMP) ||
|
if (! pair.second->has_flags(ACCOUNT_TEMP) ||
|
||||||
has_flags(ACCOUNT_TEMP)) {
|
has_flags(ACCOUNT_TEMP)) {
|
||||||
checked_delete(pair.second);
|
checked_delete(pair.second);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -152,7 +152,7 @@ namespace {
|
||||||
if (mpfr_asprintf(&buf, "%.*RNf", precision, tempfb) < 0)
|
if (mpfr_asprintf(&buf, "%.*RNf", precision, tempfb) < 0)
|
||||||
throw_(amount_error,
|
throw_(amount_error,
|
||||||
_("Cannot output amount to a floating-point representation"));
|
_("Cannot output amount to a floating-point representation"));
|
||||||
|
|
||||||
DEBUG("amount.convert", "mpfr_print = " << buf
|
DEBUG("amount.convert", "mpfr_print = " << buf
|
||||||
<< " (precision " << precision
|
<< " (precision " << precision
|
||||||
<< ", zeros_prec " << zeros_prec << ")");
|
<< ", zeros_prec " << zeros_prec << ")");
|
||||||
|
|
@ -1049,16 +1049,12 @@ bool amount_t::parse(std::istream& in, const parse_flags_t& flags)
|
||||||
// Create the commodity if has not already been seen, and update the
|
// Create the commodity if has not already been seen, and update the
|
||||||
// precision if something greater was used for the quantity.
|
// precision if something greater was used for the quantity.
|
||||||
|
|
||||||
bool newly_created = false;
|
|
||||||
|
|
||||||
if (symbol.empty()) {
|
if (symbol.empty()) {
|
||||||
commodity_ = NULL;
|
commodity_ = NULL;
|
||||||
} else {
|
} else {
|
||||||
commodity_ = commodity_pool_t::current_pool->find(symbol);
|
commodity_ = commodity_pool_t::current_pool->find(symbol);
|
||||||
if (! commodity_) {
|
if (! commodity_)
|
||||||
commodity_ = commodity_pool_t::current_pool->create(symbol);
|
commodity_ = commodity_pool_t::current_pool->create(symbol);
|
||||||
newly_created = true;
|
|
||||||
}
|
|
||||||
assert(commodity_);
|
assert(commodity_);
|
||||||
|
|
||||||
if (details)
|
if (details)
|
||||||
|
|
|
||||||
|
|
@ -349,7 +349,7 @@ public:
|
||||||
return temp;
|
return temp;
|
||||||
}
|
}
|
||||||
void in_place_truncate();
|
void in_place_truncate();
|
||||||
|
|
||||||
/** Yields an amount which has lost all of its extra precision, beyond what
|
/** Yields an amount which has lost all of its extra precision, beyond what
|
||||||
the display precision of the commodity would have printed. */
|
the display precision of the commodity would have printed. */
|
||||||
amount_t floored() const {
|
amount_t floored() const {
|
||||||
|
|
@ -358,7 +358,7 @@ public:
|
||||||
return temp;
|
return temp;
|
||||||
}
|
}
|
||||||
void in_place_floor();
|
void in_place_floor();
|
||||||
|
|
||||||
/** Yields an amount whose display precision is never truncated, even
|
/** Yields an amount whose display precision is never truncated, even
|
||||||
though its commodity normally displays only rounded values. */
|
though its commodity normally displays only rounded values. */
|
||||||
amount_t unrounded() const {
|
amount_t unrounded() const {
|
||||||
|
|
|
||||||
|
|
@ -138,9 +138,9 @@ post_handler_ptr chain_post_handlers(post_handler_ptr base_handler,
|
||||||
report.HANDLED(tail_) ?
|
report.HANDLED(tail_) ?
|
||||||
report.HANDLER(tail_).value.to_int() : 0));
|
report.HANDLER(tail_).value.to_int() : 0));
|
||||||
|
|
||||||
// changed_value_posts adds virtual posts to the list to account for changes
|
// display_filter_posts adds virtual posts to the list to account
|
||||||
// in market value of commodities, which otherwise would affect the running
|
// for changes in value of commodities, which otherwise would affect
|
||||||
// total unpredictably.
|
// the running total unpredictably.
|
||||||
display_filter = new display_filter_posts(handler, report,
|
display_filter = new display_filter_posts(handler, report,
|
||||||
report.HANDLED(revalued) &&
|
report.HANDLED(revalued) &&
|
||||||
! report.HANDLED(no_rounding));
|
! report.HANDLED(no_rounding));
|
||||||
|
|
|
||||||
|
|
@ -444,7 +444,7 @@ commodity_t::find_price(const optional<commodity_t&>& commodity,
|
||||||
return point;
|
return point;
|
||||||
}
|
}
|
||||||
return none;
|
return none;
|
||||||
}
|
}
|
||||||
|
|
||||||
optional<price_point_t>
|
optional<price_point_t>
|
||||||
commodity_t::check_for_updated_price(const optional<price_point_t>& point,
|
commodity_t::check_for_updated_price(const optional<price_point_t>& point,
|
||||||
|
|
@ -758,7 +758,7 @@ void to_xml(std::ostream& out, const commodity_t& comm,
|
||||||
out << '"';
|
out << '"';
|
||||||
|
|
||||||
x.close_attrs();
|
x.close_attrs();
|
||||||
|
|
||||||
{
|
{
|
||||||
push_xml y(out, "symbol");
|
push_xml y(out, "symbol");
|
||||||
out << y.guard(comm.symbol());
|
out << y.guard(comm.symbol());
|
||||||
|
|
|
||||||
|
|
@ -376,7 +376,7 @@ public:
|
||||||
#if defined(DEBUG_ON)
|
#if defined(DEBUG_ON)
|
||||||
, const int indent = 0
|
, const int indent = 0
|
||||||
#endif
|
#endif
|
||||||
) const;
|
) const;
|
||||||
|
|
||||||
optional<price_point_t>
|
optional<price_point_t>
|
||||||
check_for_updated_price(const optional<price_point_t>& point,
|
check_for_updated_price(const optional<price_point_t>& point,
|
||||||
|
|
|
||||||
|
|
@ -58,7 +58,7 @@ class compare_items
|
||||||
expr_t sort_order;
|
expr_t sort_order;
|
||||||
|
|
||||||
compare_items();
|
compare_items();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
compare_items(const compare_items& other) : sort_order(other.sort_order) {
|
compare_items(const compare_items& other) : sort_order(other.sort_order) {
|
||||||
TRACE_CTOR(compare_items, "copy");
|
TRACE_CTOR(compare_items, "copy");
|
||||||
|
|
|
||||||
|
|
@ -62,10 +62,10 @@ value_t convert_command(call_scope_t& args)
|
||||||
post_map_t post_map;
|
post_map_t post_map;
|
||||||
|
|
||||||
xacts_iterator journal_iter(journal);
|
xacts_iterator journal_iter(journal);
|
||||||
while (xact_t * xact = journal_iter()) {
|
while (xact_t * xact = *journal_iter++) {
|
||||||
post_t * post = NULL;
|
post_t * post = NULL;
|
||||||
xact_posts_iterator xact_iter(*xact);
|
xact_posts_iterator xact_iter(*xact);
|
||||||
while ((post = xact_iter()) != NULL) {
|
while ((post = *xact_iter++) != NULL) {
|
||||||
if (post->account == bucket)
|
if (post->account == bucket)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -95,7 +95,7 @@ value_t convert_command(call_scope_t& args)
|
||||||
foreach (post_t * post, xact->posts)
|
foreach (post_t * post, xact->posts)
|
||||||
post->amount.in_place_negate();
|
post->amount.in_place_negate();
|
||||||
}
|
}
|
||||||
|
|
||||||
bool matched = false;
|
bool matched = false;
|
||||||
if (! xact->posts.front()->amount.is_null()) {
|
if (! xact->posts.front()->amount.is_null()) {
|
||||||
post_map_t::iterator i = post_map.find(- xact->posts.front()->amount);
|
post_map_t::iterator i = post_map.find(- xact->posts.front()->amount);
|
||||||
|
|
@ -121,14 +121,10 @@ value_t convert_command(call_scope_t& args)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
if (xact->posts.front()->account == NULL) {
|
if (xact->posts.front()->account == NULL) {
|
||||||
xacts_iterator xi;
|
|
||||||
xi.xacts_i = current_xacts.begin();
|
|
||||||
xi.xacts_end = current_xacts.end();
|
|
||||||
xi.xacts_uninitialized = false;
|
|
||||||
|
|
||||||
// jww (2010-03-07): Bind this logic to an option: --auto-match
|
// jww (2010-03-07): Bind this logic to an option: --auto-match
|
||||||
if (account_t * acct =
|
if (account_t * acct =
|
||||||
lookup_probable_account(xact->payee, xi, bucket).second)
|
lookup_probable_account(xact->payee, current_xacts.rbegin(),
|
||||||
|
current_xacts.rend(), bucket).second)
|
||||||
xact->posts.front()->account = acct;
|
xact->posts.front()->account = acct;
|
||||||
else
|
else
|
||||||
xact->posts.front()->account = unknown;
|
xact->posts.front()->account = unknown;
|
||||||
|
|
@ -141,7 +137,7 @@ value_t convert_command(call_scope_t& args)
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
xact_posts_iterator xact_iter(*xact);
|
xact_posts_iterator xact_iter(*xact);
|
||||||
while (post_t * post = xact_iter())
|
while (post_t * post = *xact_iter++)
|
||||||
formatter(*post);
|
formatter(*post);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -289,7 +289,7 @@ xact_t * csv_reader::read_xact(journal_t& journal, account_t * bucket)
|
||||||
amt.set_commodity(*commodity_pool_t::current_pool->default_commodity);
|
amt.set_commodity(*commodity_pool_t::current_pool->default_commodity);
|
||||||
post->assigned_amount = amt;
|
post->assigned_amount = amt;
|
||||||
}
|
}
|
||||||
|
|
||||||
xact->add_post(post.release());
|
xact->add_post(post.release());
|
||||||
|
|
||||||
return xact.release();
|
return xact.release();
|
||||||
|
|
|
||||||
18
src/draft.cc
18
src/draft.cc
|
|
@ -66,16 +66,6 @@ void draft_t::xact_template_t::dump(std::ostream& out) const
|
||||||
<< _("<Posting copied from last related transaction>")
|
<< _("<Posting copied from last related transaction>")
|
||||||
<< std::endl;
|
<< std::endl;
|
||||||
} else {
|
} else {
|
||||||
bool has_only_from = true;
|
|
||||||
bool has_only_to = true;
|
|
||||||
|
|
||||||
foreach (const post_template_t& post, posts) {
|
|
||||||
if (post.from)
|
|
||||||
has_only_to = false;
|
|
||||||
else
|
|
||||||
has_only_from = false;
|
|
||||||
}
|
|
||||||
|
|
||||||
foreach (const post_template_t& post, posts) {
|
foreach (const post_template_t& post, posts) {
|
||||||
straccstream accum;
|
straccstream accum;
|
||||||
out << std::endl
|
out << std::endl
|
||||||
|
|
@ -245,12 +235,12 @@ xact_t * draft_t::insert(journal_t& journal)
|
||||||
if (tmpl->payee_mask.empty())
|
if (tmpl->payee_mask.empty())
|
||||||
throw std::runtime_error(_("'xact' command requires at least a payee"));
|
throw std::runtime_error(_("'xact' command requires at least a payee"));
|
||||||
|
|
||||||
xact_t * matching = NULL;
|
xact_t * matching = NULL;
|
||||||
|
|
||||||
std::auto_ptr<xact_t> added(new xact_t);
|
std::auto_ptr<xact_t> added(new xact_t);
|
||||||
|
|
||||||
xacts_iterator xi(journal);
|
if (xact_t * xact =
|
||||||
if (xact_t * xact = lookup_probable_account(tmpl->payee_mask.str(), xi).first) {
|
lookup_probable_account(tmpl->payee_mask.str(), journal.xacts.rbegin(),
|
||||||
|
journal.xacts.rend()).first) {
|
||||||
DEBUG("draft.xact", "Found payee by lookup: transaction on line "
|
DEBUG("draft.xact", "Found payee by lookup: transaction on line "
|
||||||
<< xact->pos->beg_line);
|
<< xact->pos->beg_line);
|
||||||
matching = xact;
|
matching = xact;
|
||||||
|
|
|
||||||
|
|
@ -93,10 +93,10 @@ string source_context(const path& file,
|
||||||
assert(len < 8192);
|
assert(len < 8192);
|
||||||
|
|
||||||
std::ostringstream out;
|
std::ostringstream out;
|
||||||
|
|
||||||
ifstream in(file);
|
ifstream in(file);
|
||||||
in.seekg(pos, std::ios::beg);
|
in.seekg(pos, std::ios::beg);
|
||||||
|
|
||||||
scoped_array<char> buf(new char[static_cast<std::size_t>(len) + 1]);
|
scoped_array<char> buf(new char[static_cast<std::size_t>(len) + 1]);
|
||||||
in.read(buf.get(), static_cast<std::streamsize>(len));
|
in.read(buf.get(), static_cast<std::streamsize>(len));
|
||||||
assert(in.gcount() == static_cast<std::streamsize>(len));
|
assert(in.gcount() == static_cast<std::streamsize>(len));
|
||||||
|
|
|
||||||
|
|
@ -130,7 +130,7 @@ public:
|
||||||
const optional<string>& original_string = none) {
|
const optional<string>& original_string = none) {
|
||||||
set_text(original_string ? *original_string : "<stream>");
|
set_text(original_string ? *original_string : "<stream>");
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void mark_uncompiled() {
|
virtual void mark_uncompiled() {
|
||||||
compiled = false;
|
compiled = false;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -53,7 +53,7 @@ void post_splitter::flush()
|
||||||
{
|
{
|
||||||
foreach (value_to_posts_map::value_type& pair, posts_map) {
|
foreach (value_to_posts_map::value_type& pair, posts_map) {
|
||||||
preflush_func(pair.first);
|
preflush_func(pair.first);
|
||||||
|
|
||||||
foreach (post_t * post, pair.second)
|
foreach (post_t * post, pair.second)
|
||||||
(*post_chain)(*post);
|
(*post_chain)(*post);
|
||||||
|
|
||||||
|
|
@ -83,25 +83,6 @@ void post_splitter::operator()(post_t& post)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
pass_down_posts::pass_down_posts(post_handler_ptr handler,
|
|
||||||
posts_iterator& iter)
|
|
||||||
: item_handler<post_t>(handler)
|
|
||||||
{
|
|
||||||
TRACE_CTOR(pass_down_posts, "post_handler_ptr, posts_iterator");
|
|
||||||
|
|
||||||
for (post_t * post = iter(); post; post = iter()) {
|
|
||||||
try {
|
|
||||||
item_handler<post_t>::operator()(*post);
|
|
||||||
}
|
|
||||||
catch (const std::exception&) {
|
|
||||||
add_error_context(item_context(*post, _("While handling posting")));
|
|
||||||
throw;
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
item_handler<post_t>::flush();
|
|
||||||
}
|
|
||||||
|
|
||||||
void truncate_xacts::flush()
|
void truncate_xacts::flush()
|
||||||
{
|
{
|
||||||
if (! posts.size())
|
if (! posts.size())
|
||||||
|
|
@ -434,7 +415,7 @@ void collapse_posts::report_subtotal()
|
||||||
bind_scope_t bound_scope(report, *post);
|
bind_scope_t bound_scope(report, *post);
|
||||||
if (only_predicate(bound_scope) && display_predicate(bound_scope))
|
if (only_predicate(bound_scope) && display_predicate(bound_scope))
|
||||||
displayed_count++;
|
displayed_count++;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (displayed_count == 1) {
|
if (displayed_count == 1) {
|
||||||
item_handler<post_t>::operator()(*last_post);
|
item_handler<post_t>::operator()(*last_post);
|
||||||
|
|
@ -460,6 +441,7 @@ void collapse_posts::report_subtotal()
|
||||||
xact.payee = last_xact->payee;
|
xact.payee = last_xact->payee;
|
||||||
xact._date = (is_valid(earliest_date) ?
|
xact._date = (is_valid(earliest_date) ?
|
||||||
earliest_date : last_xact->_date);
|
earliest_date : last_xact->_date);
|
||||||
|
|
||||||
DEBUG("filters.collapse", "Pseudo-xact date = " << *xact._date);
|
DEBUG("filters.collapse", "Pseudo-xact date = " << *xact._date);
|
||||||
DEBUG("filters.collapse", "earliest date = " << earliest_date);
|
DEBUG("filters.collapse", "earliest date = " << earliest_date);
|
||||||
DEBUG("filters.collapse", "latest date = " << latest_date);
|
DEBUG("filters.collapse", "latest date = " << latest_date);
|
||||||
|
|
@ -523,14 +505,11 @@ display_filter_posts::display_filter_posts(post_handler_ptr handler,
|
||||||
report_t& _report,
|
report_t& _report,
|
||||||
bool _show_rounding)
|
bool _show_rounding)
|
||||||
: item_handler<post_t>(handler), report(_report),
|
: item_handler<post_t>(handler), report(_report),
|
||||||
|
display_amount_expr(report.HANDLER(display_amount_).expr),
|
||||||
|
display_total_expr(report.HANDLER(display_total_).expr),
|
||||||
show_rounding(_show_rounding)
|
show_rounding(_show_rounding)
|
||||||
{
|
{
|
||||||
TRACE_CTOR(display_filter_posts,
|
TRACE_CTOR(display_filter_posts, "post_handler_ptr, report_t&, bool");
|
||||||
"post_handler_ptr, report_t&, account_t&, bool");
|
|
||||||
|
|
||||||
display_amount_expr = report.HANDLER(display_amount_).expr;
|
|
||||||
display_total_expr = report.HANDLER(display_total_).expr;
|
|
||||||
|
|
||||||
create_accounts();
|
create_accounts();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -606,17 +585,17 @@ changed_value_posts::changed_value_posts
|
||||||
bool _show_unrealized,
|
bool _show_unrealized,
|
||||||
display_filter_posts * _display_filter)
|
display_filter_posts * _display_filter)
|
||||||
: item_handler<post_t>(handler), report(_report),
|
: item_handler<post_t>(handler), report(_report),
|
||||||
|
total_expr(report.HANDLED(revalued_total_) ?
|
||||||
|
report.HANDLER(revalued_total_).expr :
|
||||||
|
report.HANDLER(display_total_).expr),
|
||||||
|
display_total_expr(report.HANDLER(display_total_).expr),
|
||||||
|
changed_values_only(report.HANDLED(revalued_only)),
|
||||||
for_accounts_report(_for_accounts_report),
|
for_accounts_report(_for_accounts_report),
|
||||||
show_unrealized(_show_unrealized), last_post(NULL),
|
show_unrealized(_show_unrealized), last_post(NULL),
|
||||||
display_filter(_display_filter)
|
display_filter(_display_filter)
|
||||||
{
|
{
|
||||||
TRACE_CTOR(changed_value_posts, "post_handler_ptr, report_t&, bool");
|
TRACE_CTOR(changed_value_posts,
|
||||||
|
"post_handler_ptr, report_t&, bool, bool, display_filter_posts *");
|
||||||
total_expr = (report.HANDLED(revalued_total_) ?
|
|
||||||
report.HANDLER(revalued_total_).expr :
|
|
||||||
report.HANDLER(display_total_).expr);
|
|
||||||
display_total_expr = report.HANDLER(display_total_).expr;
|
|
||||||
changed_values_only = report.HANDLED(revalued_only);
|
|
||||||
|
|
||||||
string gains_equity_account_name;
|
string gains_equity_account_name;
|
||||||
if (report.HANDLED(unrealized_gains_))
|
if (report.HANDLED(unrealized_gains_))
|
||||||
|
|
@ -755,7 +734,7 @@ void changed_value_posts::output_intermediate_prices(post_t& post,
|
||||||
case value_t::DATE:
|
case value_t::DATE:
|
||||||
default:
|
default:
|
||||||
assert(false);
|
assert(false);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
bind_scope_t inner_scope(report, temp);
|
bind_scope_t inner_scope(report, temp);
|
||||||
|
|
@ -937,8 +916,6 @@ void interval_posts::report_subtotal(const date_interval_t& interval)
|
||||||
|
|
||||||
void interval_posts::operator()(post_t& post)
|
void interval_posts::operator()(post_t& post)
|
||||||
{
|
{
|
||||||
date_t date = post.date();
|
|
||||||
|
|
||||||
if (! interval.find_period(post.date()))
|
if (! interval.find_period(post.date()))
|
||||||
return;
|
return;
|
||||||
|
|
||||||
|
|
@ -1373,7 +1350,7 @@ inject_posts::inject_posts(post_handler_ptr handler,
|
||||||
account_t * master)
|
account_t * master)
|
||||||
: item_handler<post_t>(handler)
|
: item_handler<post_t>(handler)
|
||||||
{
|
{
|
||||||
TRACE_CTOR(inject_posts, "post_handler_ptr, string");
|
TRACE_CTOR(inject_posts, "post_handler_ptr, string, account_t *");
|
||||||
|
|
||||||
scoped_array<char> buf(new char[tag_list.length() + 1]);
|
scoped_array<char> buf(new char[tag_list.length() + 1]);
|
||||||
std::strcpy(buf.get(), tag_list.c_str());
|
std::strcpy(buf.get(), tag_list.c_str());
|
||||||
|
|
@ -1381,9 +1358,9 @@ inject_posts::inject_posts(post_handler_ptr handler,
|
||||||
for (char * q = std::strtok(buf.get(), ",");
|
for (char * q = std::strtok(buf.get(), ",");
|
||||||
q;
|
q;
|
||||||
q = std::strtok(NULL, ",")) {
|
q = std::strtok(NULL, ",")) {
|
||||||
|
|
||||||
std::list<string> account_names;
|
std::list<string> account_names;
|
||||||
split_string(q, ':', account_names);
|
split_string(q, ':', account_names);
|
||||||
|
|
||||||
account_t * account =
|
account_t * account =
|
||||||
create_temp_account_from_path(account_names, temps, master);
|
create_temp_account_from_path(account_names, temps, master);
|
||||||
account->add_flags(ACCOUNT_GENERATED);
|
account->add_flags(ACCOUNT_GENERATED);
|
||||||
|
|
@ -1397,13 +1374,12 @@ void inject_posts::operator()(post_t& post)
|
||||||
{
|
{
|
||||||
foreach (tags_list_pair& pair, tags_list) {
|
foreach (tags_list_pair& pair, tags_list) {
|
||||||
optional<value_t> tag_value = post.get_tag(pair.first, false);
|
optional<value_t> tag_value = post.get_tag(pair.first, false);
|
||||||
|
// When checking if the transaction has the tag, only inject once
|
||||||
|
// per transaction.
|
||||||
if (! tag_value &&
|
if (! tag_value &&
|
||||||
pair.second.second.find(post.xact) == pair.second.second.end()) {
|
pair.second.second.find(post.xact) == pair.second.second.end() &&
|
||||||
// When checking if the transaction has the tag, only inject once
|
(tag_value = post.xact->get_tag(pair.first)))
|
||||||
// per transaction.
|
|
||||||
pair.second.second.insert(post.xact);
|
pair.second.second.insert(post.xact);
|
||||||
tag_value = post.xact->get_tag(pair.first);
|
|
||||||
}
|
|
||||||
|
|
||||||
if (tag_value) {
|
if (tag_value) {
|
||||||
xact_t& xact = temps.copy_xact(*post.xact);
|
xact_t& xact = temps.copy_xact(*post.xact);
|
||||||
|
|
@ -1422,25 +1398,4 @@ void inject_posts::operator()(post_t& post)
|
||||||
item_handler<post_t>::operator()(post);
|
item_handler<post_t>::operator()(post);
|
||||||
}
|
}
|
||||||
|
|
||||||
pass_down_accounts::pass_down_accounts(acct_handler_ptr handler,
|
|
||||||
accounts_iterator& iter,
|
|
||||||
const optional<predicate_t>& _pred,
|
|
||||||
const optional<scope_t&>& _context)
|
|
||||||
: item_handler<account_t>(handler), pred(_pred), context(_context)
|
|
||||||
{
|
|
||||||
TRACE_CTOR(pass_down_accounts, "acct_handler_ptr, accounts_iterator, ...");
|
|
||||||
|
|
||||||
for (account_t * account = iter(); account; account = iter()) {
|
|
||||||
if (! pred) {
|
|
||||||
item_handler<account_t>::operator()(*account);
|
|
||||||
} else {
|
|
||||||
bind_scope_t bound_scope(*context, *account);
|
|
||||||
if ((*pred)(bound_scope))
|
|
||||||
item_handler<account_t>::operator()(*account);
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
item_handler<account_t>::flush();
|
|
||||||
}
|
|
||||||
|
|
||||||
} // namespace ledger
|
} // namespace ledger
|
||||||
|
|
|
||||||
|
|
@ -73,10 +73,10 @@ public:
|
||||||
post_splitter(post_handler_ptr _post_chain,
|
post_splitter(post_handler_ptr _post_chain,
|
||||||
report_t& _report,
|
report_t& _report,
|
||||||
expr_t _group_by_expr)
|
expr_t _group_by_expr)
|
||||||
: post_chain(_post_chain), report(_report),
|
: post_chain(_post_chain), report(_report),
|
||||||
group_by_expr(_group_by_expr) {
|
group_by_expr(_group_by_expr) {
|
||||||
TRACE_CTOR(post_splitter, "scope_t&, post_handler_ptr, expr_t");
|
TRACE_CTOR(post_splitter, "scope_t&, post_handler_ptr, expr_t");
|
||||||
preflush_func = bind(&post_splitter::print_title, this, _1);
|
preflush_func = bind(&post_splitter::print_title, this, _1);
|
||||||
}
|
}
|
||||||
virtual ~post_splitter() {
|
virtual ~post_splitter() {
|
||||||
TRACE_DTOR(post_splitter);
|
TRACE_DTOR(post_splitter);
|
||||||
|
|
@ -97,6 +97,7 @@ public:
|
||||||
virtual void clear() {
|
virtual void clear() {
|
||||||
posts_map.clear();
|
posts_map.clear();
|
||||||
post_chain->clear();
|
post_chain->clear();
|
||||||
|
item_handler<post_t>::clear();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
@ -145,14 +146,28 @@ public:
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class posts_iterator;
|
template <typename Iterator>
|
||||||
|
|
||||||
class pass_down_posts : public item_handler<post_t>
|
class pass_down_posts : public item_handler<post_t>
|
||||||
{
|
{
|
||||||
pass_down_posts();
|
pass_down_posts();
|
||||||
|
|
||||||
public:
|
public:
|
||||||
pass_down_posts(post_handler_ptr handler, posts_iterator& iter);
|
pass_down_posts(post_handler_ptr handler, Iterator& iter)
|
||||||
|
: item_handler<post_t>(handler) {
|
||||||
|
TRACE_CTOR(pass_down_posts, "post_handler_ptr, posts_iterator");
|
||||||
|
|
||||||
|
while (post_t * post = *iter++) {
|
||||||
|
try {
|
||||||
|
item_handler<post_t>::operator()(*post);
|
||||||
|
}
|
||||||
|
catch (const std::exception&) {
|
||||||
|
add_error_context(item_context(*post, _("While handling posting")));
|
||||||
|
throw;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
item_handler<post_t>::flush();
|
||||||
|
}
|
||||||
|
|
||||||
virtual ~pass_down_posts() {
|
virtual ~pass_down_posts() {
|
||||||
TRACE_DTOR(pass_down_posts);
|
TRACE_DTOR(pass_down_posts);
|
||||||
|
|
@ -295,7 +310,7 @@ public:
|
||||||
virtual void clear() {
|
virtual void clear() {
|
||||||
sorter.clear();
|
sorter.clear();
|
||||||
last_xact = NULL;
|
last_xact = NULL;
|
||||||
|
|
||||||
item_handler<post_t>::clear();
|
item_handler<post_t>::clear();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -365,8 +380,9 @@ public:
|
||||||
|
|
||||||
virtual void clear() {
|
virtual void clear() {
|
||||||
temps.clear();
|
temps.clear();
|
||||||
|
comms.clear();
|
||||||
last_xact = NULL;
|
last_xact = NULL;
|
||||||
|
|
||||||
item_handler<post_t>::clear();
|
item_handler<post_t>::clear();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -442,7 +458,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual void flush() {
|
virtual void flush() {
|
||||||
report_subtotal();
|
report_subtotal();
|
||||||
item_handler<post_t>::flush();
|
item_handler<post_t>::flush();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -463,7 +479,7 @@ public:
|
||||||
temps.clear();
|
temps.clear();
|
||||||
create_accounts();
|
create_accounts();
|
||||||
component_posts.clear();
|
component_posts.clear();
|
||||||
|
|
||||||
item_handler<post_t>::clear();
|
item_handler<post_t>::clear();
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
@ -504,9 +520,9 @@ class display_filter_posts : public item_handler<post_t>
|
||||||
// This filter requires that calc_posts be used at some point
|
// This filter requires that calc_posts be used at some point
|
||||||
// later in the chain.
|
// later in the chain.
|
||||||
|
|
||||||
|
report_t& report;
|
||||||
expr_t display_amount_expr;
|
expr_t display_amount_expr;
|
||||||
expr_t display_total_expr;
|
expr_t display_total_expr;
|
||||||
report_t& report;
|
|
||||||
bool show_rounding;
|
bool show_rounding;
|
||||||
value_t last_display_total;
|
value_t last_display_total;
|
||||||
temporaries_t temps;
|
temporaries_t temps;
|
||||||
|
|
@ -552,9 +568,9 @@ class changed_value_posts : public item_handler<post_t>
|
||||||
// This filter requires that calc_posts be used at some point
|
// This filter requires that calc_posts be used at some point
|
||||||
// later in the chain.
|
// later in the chain.
|
||||||
|
|
||||||
|
report_t& report;
|
||||||
expr_t total_expr;
|
expr_t total_expr;
|
||||||
expr_t display_total_expr;
|
expr_t display_total_expr;
|
||||||
report_t& report;
|
|
||||||
bool changed_values_only;
|
bool changed_values_only;
|
||||||
bool for_accounts_report;
|
bool for_accounts_report;
|
||||||
bool show_unrealized;
|
bool show_unrealized;
|
||||||
|
|
@ -984,8 +1000,7 @@ class inject_posts : public item_handler<post_t>
|
||||||
// Account filters
|
// Account filters
|
||||||
//
|
//
|
||||||
|
|
||||||
class accounts_iterator;
|
template <typename Iterator>
|
||||||
|
|
||||||
class pass_down_accounts : public item_handler<account_t>
|
class pass_down_accounts : public item_handler<account_t>
|
||||||
{
|
{
|
||||||
pass_down_accounts();
|
pass_down_accounts();
|
||||||
|
|
@ -995,9 +1010,24 @@ class pass_down_accounts : public item_handler<account_t>
|
||||||
|
|
||||||
public:
|
public:
|
||||||
pass_down_accounts(acct_handler_ptr handler,
|
pass_down_accounts(acct_handler_ptr handler,
|
||||||
accounts_iterator& iter,
|
Iterator& iter,
|
||||||
const optional<predicate_t>& _pred = none,
|
const optional<predicate_t>& _pred = none,
|
||||||
const optional<scope_t&>& _context = none);
|
const optional<scope_t&>& _context = none)
|
||||||
|
: item_handler<account_t>(handler), pred(_pred), context(_context) {
|
||||||
|
TRACE_CTOR(pass_down_accounts, "acct_handler_ptr, accounts_iterator, ...");
|
||||||
|
|
||||||
|
while (account_t * account = *iter++) {
|
||||||
|
if (! pred) {
|
||||||
|
item_handler<account_t>::operator()(*account);
|
||||||
|
} else {
|
||||||
|
bind_scope_t bound_scope(*context, *account);
|
||||||
|
if ((*pred)(bound_scope))
|
||||||
|
item_handler<account_t>::operator()(*account);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
item_handler<account_t>::flush();
|
||||||
|
}
|
||||||
|
|
||||||
virtual ~pass_down_accounts() {
|
virtual ~pass_down_accounts() {
|
||||||
TRACE_DTOR(pass_down_accounts);
|
TRACE_DTOR(pass_down_accounts);
|
||||||
|
|
|
||||||
|
|
@ -271,14 +271,14 @@ void generate_posts_iterator::generate_date(std::ostream& out)
|
||||||
out.width(4);
|
out.width(4);
|
||||||
out.fill('0');
|
out.fill('0');
|
||||||
out << year_gen();
|
out << year_gen();
|
||||||
|
|
||||||
out.width(1);
|
out.width(1);
|
||||||
out << '/';
|
out << '/';
|
||||||
|
|
||||||
out.width(2);
|
out.width(2);
|
||||||
out.fill('0');
|
out.fill('0');
|
||||||
out << mon_gen();
|
out << mon_gen();
|
||||||
|
|
||||||
out.width(1);
|
out.width(1);
|
||||||
out << '/';
|
out << '/';
|
||||||
|
|
||||||
|
|
@ -350,9 +350,10 @@ void generate_posts_iterator::generate_xact(std::ostream& out)
|
||||||
out << '\n';
|
out << '\n';
|
||||||
}
|
}
|
||||||
|
|
||||||
post_t * generate_posts_iterator::operator()()
|
void generate_posts_iterator::increment()
|
||||||
{
|
{
|
||||||
post_t * post = posts();
|
post_t * post = *posts++;
|
||||||
|
|
||||||
if (post == NULL && quantity > 0) {
|
if (post == NULL && quantity > 0) {
|
||||||
std::ostringstream buf;
|
std::ostringstream buf;
|
||||||
generate_xact(buf);
|
generate_xact(buf);
|
||||||
|
|
@ -364,7 +365,7 @@ post_t * generate_posts_iterator::operator()()
|
||||||
if (session.journal->parse(in, session) != 0) {
|
if (session.journal->parse(in, session) != 0) {
|
||||||
VERIFY(session.journal->xacts.back()->valid());
|
VERIFY(session.journal->xacts.back()->valid());
|
||||||
posts.reset(*session.journal->xacts.back());
|
posts.reset(*session.journal->xacts.back());
|
||||||
post = posts();
|
post = *posts++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
catch (std::exception&) {
|
catch (std::exception&) {
|
||||||
|
|
@ -382,7 +383,8 @@ post_t * generate_posts_iterator::operator()()
|
||||||
|
|
||||||
quantity--;
|
quantity--;
|
||||||
}
|
}
|
||||||
return post;
|
|
||||||
|
m_node = post;
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace ledger
|
} // namespace ledger
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,9 @@ namespace ledger {
|
||||||
|
|
||||||
class session_t;
|
class session_t;
|
||||||
|
|
||||||
class generate_posts_iterator : public posts_iterator
|
class generate_posts_iterator
|
||||||
|
: public iterator_facade_base<generate_posts_iterator, post_t *,
|
||||||
|
boost::forward_traversal_tag>
|
||||||
{
|
{
|
||||||
session_t& session;
|
session_t& session;
|
||||||
unsigned int seed;
|
unsigned int seed;
|
||||||
|
|
@ -104,8 +106,8 @@ public:
|
||||||
virtual ~generate_posts_iterator() throw() {
|
virtual ~generate_posts_iterator() throw() {
|
||||||
TRACE_DTOR(generate_posts_iterator);
|
TRACE_DTOR(generate_posts_iterator);
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual post_t * operator()();
|
virtual void increment();
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
void generate_string(std::ostream& out, int len, bool only_alpha = false);
|
void generate_string(std::ostream& out, int len, bool only_alpha = false);
|
||||||
|
|
|
||||||
|
|
@ -535,7 +535,7 @@ string item_context(const item_t& item, const string& desc)
|
||||||
assert(len < 8192);
|
assert(len < 8192);
|
||||||
|
|
||||||
std::ostringstream out;
|
std::ostringstream out;
|
||||||
|
|
||||||
if (item.pos->pathname == path("/dev/stdin")) {
|
if (item.pos->pathname == path("/dev/stdin")) {
|
||||||
out << desc << _(" from standard input:");
|
out << desc << _(" from standard input:");
|
||||||
return out.str();
|
return out.str();
|
||||||
|
|
|
||||||
111
src/iterators.cc
111
src/iterators.cc
|
|
@ -41,37 +41,38 @@ void xacts_iterator::reset(journal_t& journal)
|
||||||
{
|
{
|
||||||
xacts_i = journal.xacts.begin();
|
xacts_i = journal.xacts.begin();
|
||||||
xacts_end = journal.xacts.end();
|
xacts_end = journal.xacts.end();
|
||||||
|
|
||||||
xacts_uninitialized = false;
|
xacts_uninitialized = false;
|
||||||
|
|
||||||
|
increment();
|
||||||
}
|
}
|
||||||
|
|
||||||
xact_t * xacts_iterator::operator()()
|
void xacts_iterator::increment()
|
||||||
{
|
{
|
||||||
if (xacts_i != xacts_end)
|
if (xacts_i != xacts_end)
|
||||||
return *xacts_i++;
|
m_node = *xacts_i++;
|
||||||
else
|
else
|
||||||
return NULL;
|
m_node = NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
void journal_posts_iterator::reset(journal_t& journal)
|
void journal_posts_iterator::reset(journal_t& journal)
|
||||||
{
|
{
|
||||||
xacts.reset(journal);
|
xacts.reset(journal);
|
||||||
|
increment();
|
||||||
xact_t * xact = xacts();
|
|
||||||
if (xact != NULL)
|
|
||||||
posts.reset(*xact);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
post_t * journal_posts_iterator::operator()()
|
void journal_posts_iterator::increment()
|
||||||
{
|
{
|
||||||
post_t * post = posts();
|
if (post_t * post = *posts++) {
|
||||||
if (post == NULL) {
|
m_node = post;
|
||||||
xact_t * xact = xacts();
|
}
|
||||||
if (xact != NULL) {
|
else if (xact_t * xact = *xacts++) {
|
||||||
posts.reset(*xact);
|
posts.reset(*xact);
|
||||||
post = posts();
|
m_node = *posts++;
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
m_node = NULL;
|
||||||
}
|
}
|
||||||
return post;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void posts_commodities_iterator::reset(journal_t& journal)
|
void posts_commodities_iterator::reset(journal_t& journal)
|
||||||
|
|
@ -80,7 +81,7 @@ void posts_commodities_iterator::reset(journal_t& journal)
|
||||||
|
|
||||||
std::set<commodity_t *> commodities;
|
std::set<commodity_t *> commodities;
|
||||||
|
|
||||||
for (post_t * post = journal_posts(); post; post = journal_posts()) {
|
while (const post_t * post = *journal_posts++) {
|
||||||
commodity_t& comm(post->amount.commodity());
|
commodity_t& comm(post->amount.commodity());
|
||||||
if (comm.flags() & COMMODITY_NOMARKET)
|
if (comm.flags() & COMMODITY_NOMARKET)
|
||||||
continue;
|
continue;
|
||||||
|
|
@ -136,47 +137,44 @@ void posts_commodities_iterator::reset(journal_t& journal)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
xacts.xacts_i = xact_temps.begin();
|
xacts.reset(xact_temps.begin(), xact_temps.end());
|
||||||
xacts.xacts_end = xact_temps.end();
|
|
||||||
|
|
||||||
xacts.xacts_uninitialized = false;
|
increment();
|
||||||
|
|
||||||
xact_t * xact = xacts();
|
|
||||||
if (xact != NULL)
|
|
||||||
posts.reset(*xact);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
post_t * posts_commodities_iterator::operator()()
|
void posts_commodities_iterator::increment()
|
||||||
{
|
{
|
||||||
post_t * post = posts();
|
if (post_t * post = *posts++) {
|
||||||
if (post == NULL) {
|
m_node = post;
|
||||||
xact_t * xact = xacts();
|
}
|
||||||
if (xact != NULL) {
|
else if (xact_t * xact = *xacts++) {
|
||||||
posts.reset(*xact);
|
posts.reset(*xact);
|
||||||
post = posts();
|
m_node = *posts++;
|
||||||
}
|
}
|
||||||
|
else {
|
||||||
|
m_node = NULL;
|
||||||
}
|
}
|
||||||
return post;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
account_t * basic_accounts_iterator::operator()()
|
void basic_accounts_iterator::increment()
|
||||||
{
|
{
|
||||||
while (! accounts_i.empty() &&
|
while (! accounts_i.empty() && accounts_i.back() == accounts_end.back()) {
|
||||||
accounts_i.back() == accounts_end.back()) {
|
|
||||||
accounts_i.pop_back();
|
accounts_i.pop_back();
|
||||||
accounts_end.pop_back();
|
accounts_end.pop_back();
|
||||||
}
|
}
|
||||||
if (accounts_i.empty())
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
account_t * account = (*(accounts_i.back()++)).second;
|
if (accounts_i.empty()) {
|
||||||
assert(account);
|
m_node = NULL;
|
||||||
|
} else {
|
||||||
|
account_t * account = (*(accounts_i.back()++)).second;
|
||||||
|
assert(account);
|
||||||
|
|
||||||
// If this account has children, queue them up to be iterated next.
|
// If this account has children, queue them up to be iterated next.
|
||||||
if (! account->accounts.empty())
|
if (! account->accounts.empty())
|
||||||
push_back(*account);
|
push_back(*account);
|
||||||
|
|
||||||
return account;
|
m_node = account;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
void sorted_accounts_iterator::push_back(account_t& account)
|
void sorted_accounts_iterator::push_back(account_t& account)
|
||||||
|
|
@ -231,7 +229,7 @@ void sorted_accounts_iterator::sort_accounts(account_t& account,
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
|
|
||||||
account_t * sorted_accounts_iterator::operator()()
|
void sorted_accounts_iterator::increment()
|
||||||
{
|
{
|
||||||
while (! sorted_accounts_i.empty() &&
|
while (! sorted_accounts_i.empty() &&
|
||||||
sorted_accounts_i.back() == sorted_accounts_end.back()) {
|
sorted_accounts_i.back() == sorted_accounts_end.back()) {
|
||||||
|
|
@ -240,19 +238,22 @@ account_t * sorted_accounts_iterator::operator()()
|
||||||
assert(! accounts_list.empty());
|
assert(! accounts_list.empty());
|
||||||
accounts_list.pop_back();
|
accounts_list.pop_back();
|
||||||
}
|
}
|
||||||
if (sorted_accounts_i.empty())
|
|
||||||
return NULL;
|
|
||||||
|
|
||||||
account_t * account = *sorted_accounts_i.back()++;
|
if (sorted_accounts_i.empty()) {
|
||||||
assert(account);
|
m_node = NULL;
|
||||||
|
} else {
|
||||||
|
account_t * account = *sorted_accounts_i.back()++;
|
||||||
|
assert(account);
|
||||||
|
|
||||||
// If this account has children, queue them up to be iterated next.
|
// If this account has children, queue them up to be iterated next.
|
||||||
if (! flatten_all && ! account->accounts.empty())
|
if (! flatten_all && ! account->accounts.empty())
|
||||||
push_back(*account);
|
push_back(*account);
|
||||||
|
|
||||||
// Make sure the sorting value gets recalculated for this account
|
// Make sure the sorting value gets recalculated for this account
|
||||||
account->xdata().drop_flags(ACCOUNT_EXT_SORT_CALC);
|
account->xdata().drop_flags(ACCOUNT_EXT_SORT_CALC);
|
||||||
return account;
|
|
||||||
|
m_node = account;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
} // namespace ledger
|
} // namespace ledger
|
||||||
|
|
|
||||||
145
src/iterators.h
145
src/iterators.h
|
|
@ -51,14 +51,35 @@ namespace ledger {
|
||||||
|
|
||||||
class journal_t;
|
class journal_t;
|
||||||
|
|
||||||
class posts_iterator : public noncopyable
|
template <typename Derived, typename Value, typename CategoryOrTraversal>
|
||||||
|
class iterator_facade_base
|
||||||
|
: public boost::iterator_facade<Derived, Value, CategoryOrTraversal>
|
||||||
{
|
{
|
||||||
|
typedef Value node_base;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
virtual ~posts_iterator() throw() {}
|
iterator_facade_base() : m_node(NULL) {}
|
||||||
virtual post_t * operator()() = 0;
|
|
||||||
|
explicit iterator_facade_base(node_base p) : m_node(p) {}
|
||||||
|
|
||||||
|
void increment();
|
||||||
|
|
||||||
|
private:
|
||||||
|
friend class boost::iterator_core_access;
|
||||||
|
|
||||||
|
bool equal(iterator_facade_base const& other) const {
|
||||||
|
return this->m_node == other.m_node;
|
||||||
|
}
|
||||||
|
|
||||||
|
node_base& dereference() const { return const_cast<node_base&>(m_node); }
|
||||||
|
|
||||||
|
protected:
|
||||||
|
node_base m_node;
|
||||||
};
|
};
|
||||||
|
|
||||||
class xact_posts_iterator : public posts_iterator
|
class xact_posts_iterator
|
||||||
|
: public iterator_facade_base<xact_posts_iterator, post_t *,
|
||||||
|
boost::forward_traversal_tag>
|
||||||
{
|
{
|
||||||
posts_list::iterator posts_i;
|
posts_list::iterator posts_i;
|
||||||
posts_list::iterator posts_end;
|
posts_list::iterator posts_end;
|
||||||
|
|
@ -66,33 +87,33 @@ class xact_posts_iterator : public posts_iterator
|
||||||
bool posts_uninitialized;
|
bool posts_uninitialized;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
xact_posts_iterator() : posts_uninitialized(true) {
|
xact_posts_iterator() : posts_uninitialized(true) {}
|
||||||
TRACE_CTOR(xact_posts_iterator, "");
|
|
||||||
}
|
|
||||||
xact_posts_iterator(xact_t& xact)
|
xact_posts_iterator(xact_t& xact)
|
||||||
: posts_uninitialized(true) {
|
: posts_uninitialized(true) {
|
||||||
TRACE_CTOR(xact_posts_iterator, "xact_t&");
|
|
||||||
reset(xact);
|
reset(xact);
|
||||||
}
|
}
|
||||||
virtual ~xact_posts_iterator() throw() {
|
~xact_posts_iterator() throw() {}
|
||||||
TRACE_DTOR(xact_posts_iterator);
|
|
||||||
}
|
|
||||||
|
|
||||||
void reset(xact_t& xact) {
|
void reset(xact_t& xact) {
|
||||||
posts_i = xact.posts.begin();
|
posts_i = xact.posts.begin();
|
||||||
posts_end = xact.posts.end();
|
posts_end = xact.posts.end();
|
||||||
|
|
||||||
posts_uninitialized = false;
|
posts_uninitialized = false;
|
||||||
|
|
||||||
|
increment();
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual post_t * operator()() {
|
void increment() {
|
||||||
if (posts_uninitialized || posts_i == posts_end)
|
if (posts_uninitialized || posts_i == posts_end)
|
||||||
return NULL;
|
m_node = NULL;
|
||||||
return *posts_i++;
|
else
|
||||||
|
m_node = *posts_i++;
|
||||||
}
|
}
|
||||||
};
|
};
|
||||||
|
|
||||||
class xacts_iterator : public noncopyable
|
class xacts_iterator
|
||||||
|
: public iterator_facade_base<xacts_iterator, xact_t *,
|
||||||
|
boost::forward_traversal_tag>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
xacts_list::iterator xacts_i;
|
xacts_list::iterator xacts_i;
|
||||||
|
|
@ -100,45 +121,49 @@ public:
|
||||||
|
|
||||||
bool xacts_uninitialized;
|
bool xacts_uninitialized;
|
||||||
|
|
||||||
xacts_iterator() : xacts_uninitialized(true) {
|
xacts_iterator() : xacts_uninitialized(true) {}
|
||||||
TRACE_CTOR(xacts_iterator, "");
|
xacts_iterator(journal_t& journal) : xacts_uninitialized(false) {
|
||||||
}
|
|
||||||
xacts_iterator(journal_t& journal) : xacts_uninitialized(true) {
|
|
||||||
TRACE_CTOR(xacts_iterator, "journal_t&");
|
|
||||||
reset(journal);
|
reset(journal);
|
||||||
}
|
}
|
||||||
virtual ~xacts_iterator() throw() {
|
xacts_iterator(xacts_list::iterator beg,
|
||||||
TRACE_DTOR(xacts_iterator);
|
xacts_list::iterator end) : xacts_uninitialized(false) {
|
||||||
|
reset(beg, end);
|
||||||
}
|
}
|
||||||
|
~xacts_iterator() throw() {}
|
||||||
|
|
||||||
void reset(journal_t& journal);
|
void reset(journal_t& journal);
|
||||||
|
|
||||||
xact_t * operator()();
|
void reset(xacts_list::iterator beg, xacts_list::iterator end) {
|
||||||
|
xacts_i = beg;
|
||||||
|
xacts_end = end;
|
||||||
|
increment();
|
||||||
|
}
|
||||||
|
|
||||||
|
void increment();
|
||||||
};
|
};
|
||||||
|
|
||||||
class journal_posts_iterator : public posts_iterator
|
class journal_posts_iterator
|
||||||
|
: public iterator_facade_base<journal_posts_iterator, post_t *,
|
||||||
|
boost::forward_traversal_tag>
|
||||||
{
|
{
|
||||||
xacts_iterator xacts;
|
xacts_iterator xacts;
|
||||||
xact_posts_iterator posts;
|
xact_posts_iterator posts;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
journal_posts_iterator() {
|
journal_posts_iterator() {}
|
||||||
TRACE_CTOR(journal_posts_iterator, "");
|
|
||||||
}
|
|
||||||
journal_posts_iterator(journal_t& journal) {
|
journal_posts_iterator(journal_t& journal) {
|
||||||
TRACE_CTOR(journal_posts_iterator, "journal_t&");
|
|
||||||
reset(journal);
|
reset(journal);
|
||||||
}
|
}
|
||||||
virtual ~journal_posts_iterator() throw() {
|
~journal_posts_iterator() throw() {}
|
||||||
TRACE_DTOR(journal_posts_iterator);
|
|
||||||
}
|
|
||||||
|
|
||||||
void reset(journal_t& journal);
|
void reset(journal_t& journal);
|
||||||
|
|
||||||
virtual post_t * operator()();
|
void increment();
|
||||||
};
|
};
|
||||||
|
|
||||||
class posts_commodities_iterator : public posts_iterator
|
class posts_commodities_iterator
|
||||||
|
: public iterator_facade_base<posts_commodities_iterator, post_t *,
|
||||||
|
boost::forward_traversal_tag>
|
||||||
{
|
{
|
||||||
protected:
|
protected:
|
||||||
journal_posts_iterator journal_posts;
|
journal_posts_iterator journal_posts;
|
||||||
|
|
@ -148,55 +173,44 @@ protected:
|
||||||
xacts_list xact_temps;
|
xacts_list xact_temps;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
posts_commodities_iterator() {
|
posts_commodities_iterator() {}
|
||||||
TRACE_CTOR(posts_commodities_iterator, "");
|
|
||||||
}
|
|
||||||
posts_commodities_iterator(journal_t& journal) {
|
posts_commodities_iterator(journal_t& journal) {
|
||||||
TRACE_CTOR(posts_commodities_iterator, "journal_t&");
|
|
||||||
reset(journal);
|
reset(journal);
|
||||||
}
|
}
|
||||||
virtual ~posts_commodities_iterator() throw() {
|
~posts_commodities_iterator() throw() {}
|
||||||
TRACE_DTOR(posts_commodities_iterator);
|
|
||||||
}
|
|
||||||
|
|
||||||
void reset(journal_t& journal);
|
void reset(journal_t& journal);
|
||||||
|
|
||||||
virtual post_t * operator()();
|
void increment();
|
||||||
};
|
};
|
||||||
|
|
||||||
class accounts_iterator : public noncopyable
|
class basic_accounts_iterator
|
||||||
{
|
: public iterator_facade_base<basic_accounts_iterator, account_t *,
|
||||||
public:
|
boost::forward_traversal_tag>
|
||||||
virtual ~accounts_iterator() throw() {}
|
|
||||||
virtual account_t * operator()() = 0;
|
|
||||||
};
|
|
||||||
|
|
||||||
class basic_accounts_iterator : public accounts_iterator
|
|
||||||
{
|
{
|
||||||
std::list<accounts_map::const_iterator> accounts_i;
|
std::list<accounts_map::const_iterator> accounts_i;
|
||||||
std::list<accounts_map::const_iterator> accounts_end;
|
std::list<accounts_map::const_iterator> accounts_end;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
basic_accounts_iterator() {
|
basic_accounts_iterator() {}
|
||||||
TRACE_CTOR(basic_accounts_iterator, "");
|
|
||||||
}
|
|
||||||
basic_accounts_iterator(account_t& account) {
|
basic_accounts_iterator(account_t& account) {
|
||||||
TRACE_CTOR(basic_accounts_iterator, "account_t&");
|
|
||||||
push_back(account);
|
push_back(account);
|
||||||
|
increment();
|
||||||
}
|
}
|
||||||
virtual ~basic_accounts_iterator() throw() {
|
~basic_accounts_iterator() throw() {}
|
||||||
TRACE_DTOR(basic_accounts_iterator);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
void increment();
|
||||||
|
|
||||||
|
private:
|
||||||
void push_back(account_t& account) {
|
void push_back(account_t& account) {
|
||||||
accounts_i.push_back(account.accounts.begin());
|
accounts_i.push_back(account.accounts.begin());
|
||||||
accounts_end.push_back(account.accounts.end());
|
accounts_end.push_back(account.accounts.end());
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual account_t * operator()();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
class sorted_accounts_iterator : public accounts_iterator
|
class sorted_accounts_iterator
|
||||||
|
: public iterator_facade_base<sorted_accounts_iterator, account_t *,
|
||||||
|
boost::forward_traversal_tag>
|
||||||
{
|
{
|
||||||
expr_t sort_cmp;
|
expr_t sort_cmp;
|
||||||
bool flatten_all;
|
bool flatten_all;
|
||||||
|
|
@ -211,18 +225,17 @@ public:
|
||||||
sorted_accounts_iterator(account_t& account,
|
sorted_accounts_iterator(account_t& account,
|
||||||
const expr_t& _sort_cmp, bool _flatten_all)
|
const expr_t& _sort_cmp, bool _flatten_all)
|
||||||
: sort_cmp(_sort_cmp), flatten_all(_flatten_all) {
|
: sort_cmp(_sort_cmp), flatten_all(_flatten_all) {
|
||||||
TRACE_CTOR(sorted_accounts_iterator, "const expr_t&, bool, account_t&");
|
|
||||||
push_back(account);
|
push_back(account);
|
||||||
|
increment();
|
||||||
}
|
}
|
||||||
virtual ~sorted_accounts_iterator() throw() {
|
~sorted_accounts_iterator() throw() {}
|
||||||
TRACE_DTOR(sorted_accounts_iterator);
|
|
||||||
}
|
|
||||||
|
|
||||||
|
void increment();
|
||||||
|
|
||||||
|
private:
|
||||||
void push_back(account_t& account);
|
void push_back(account_t& account);
|
||||||
void push_all(account_t& account, accounts_deque_t& deque);
|
void push_all(account_t& account, accounts_deque_t& deque);
|
||||||
void sort_accounts(account_t& account, accounts_deque_t& deque);
|
void sort_accounts(account_t& account, accounts_deque_t& deque);
|
||||||
|
|
||||||
virtual account_t * operator()();
|
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ledger
|
} // namespace ledger
|
||||||
|
|
|
||||||
|
|
@ -74,7 +74,7 @@ journal_t::~journal_t()
|
||||||
|
|
||||||
foreach (period_xact_t * xact, period_xacts)
|
foreach (period_xact_t * xact, period_xacts)
|
||||||
checked_delete(xact);
|
checked_delete(xact);
|
||||||
|
|
||||||
checked_delete(master);
|
checked_delete(master);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -60,9 +60,10 @@ namespace {
|
||||||
}
|
}
|
||||||
|
|
||||||
std::pair<xact_t *, account_t *>
|
std::pair<xact_t *, account_t *>
|
||||||
lookup_probable_account(const string& ident,
|
lookup_probable_account(const string& ident,
|
||||||
xacts_iterator& iter_func,
|
xacts_list::reverse_iterator iter,
|
||||||
account_t * ref_account)
|
xacts_list::reverse_iterator end,
|
||||||
|
account_t * ref_account)
|
||||||
{
|
{
|
||||||
scorecard_t scores;
|
scorecard_t scores;
|
||||||
|
|
||||||
|
|
@ -83,14 +84,15 @@ lookup_probable_account(const string& ident,
|
||||||
" with reference account: " << ref_account->fullname());
|
" with reference account: " << ref_account->fullname());
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
while (xact_t * xact = iter_func()) {
|
xact_t * xact;
|
||||||
|
while (iter != end && (xact = *iter++) != NULL) {
|
||||||
#if 0
|
#if 0
|
||||||
// Only consider transactions from the last two years (jww (2010-03-07):
|
// Only consider transactions from the last two years (jww (2010-03-07):
|
||||||
// make this an option)
|
// make this an option)
|
||||||
if ((CURRENT_DATE() - xact->date()).days() > 700)
|
if ((CURRENT_DATE() - xact->date()).days() > 700)
|
||||||
continue;
|
continue;
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
// An exact match is worth a score of 100 and terminates the search
|
// An exact match is worth a score of 100 and terminates the search
|
||||||
if (ident == xact->payee) {
|
if (ident == xact->payee) {
|
||||||
DEBUG("lookup", " we have an exact match, score = 100");
|
DEBUG("lookup", " we have an exact match, score = 100");
|
||||||
|
|
|
||||||
|
|
@ -47,9 +47,10 @@
|
||||||
namespace ledger {
|
namespace ledger {
|
||||||
|
|
||||||
std::pair<xact_t *, account_t *>
|
std::pair<xact_t *, account_t *>
|
||||||
lookup_probable_account(const string& ident,
|
lookup_probable_account(const string& ident,
|
||||||
xacts_iterator& iter_func,
|
xacts_list::reverse_iterator iter,
|
||||||
account_t * ref_account = NULL);
|
xacts_list::reverse_iterator end,
|
||||||
|
account_t * ref_account = NULL);
|
||||||
|
|
||||||
} // namespace ledger
|
} // namespace ledger
|
||||||
|
|
||||||
|
|
|
||||||
11
src/op.cc
11
src/op.cc
|
|
@ -164,6 +164,11 @@ value_t expr_t::op_t::calc(scope_t& scope, ptr_op_t * locus, const int depth)
|
||||||
result = as_value();
|
result = as_value();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
|
case O_DEFINE:
|
||||||
|
//result = left()->calc(scope, locus, depth + 1);
|
||||||
|
result = NULL_VALUE;
|
||||||
|
break;
|
||||||
|
|
||||||
case IDENT: {
|
case IDENT: {
|
||||||
ptr_op_t definition = left();
|
ptr_op_t definition = left();
|
||||||
if (! definition) {
|
if (! definition) {
|
||||||
|
|
@ -416,10 +421,8 @@ value_t expr_t::op_t::calc(scope_t& scope, ptr_op_t * locus, const int depth)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case LAST:
|
|
||||||
default:
|
default:
|
||||||
assert(false);
|
throw_(calc_error, _("Unexpected expr node '%1'") << op_context(this));
|
||||||
break;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
#if defined(DEBUG_ON)
|
#if defined(DEBUG_ON)
|
||||||
|
|
@ -435,7 +438,7 @@ value_t expr_t::op_t::calc(scope_t& scope, ptr_op_t * locus, const int depth)
|
||||||
return result;
|
return result;
|
||||||
|
|
||||||
}
|
}
|
||||||
catch (const std::exception&) {
|
catch (const std::exception&) {
|
||||||
if (locus && ! *locus)
|
if (locus && ! *locus)
|
||||||
*locus = this;
|
*locus = this;
|
||||||
throw;
|
throw;
|
||||||
|
|
|
||||||
|
|
@ -89,7 +89,7 @@ namespace {
|
||||||
catch (const std::exception&) {
|
catch (const std::exception&) {
|
||||||
if (name[0] == '-')
|
if (name[0] == '-')
|
||||||
add_error_context(_("While parsing option '%1'") << name);
|
add_error_context(_("While parsing option '%1'") << name);
|
||||||
|
|
||||||
else
|
else
|
||||||
add_error_context(_("While parsing environent variable '%1'") << name);
|
add_error_context(_("While parsing environent variable '%1'") << name);
|
||||||
throw;
|
throw;
|
||||||
|
|
@ -156,7 +156,7 @@ namespace {
|
||||||
op_bool_char_tuple(expr_t::ptr_op_t _op, bool _truth, char _ch)
|
op_bool_char_tuple(expr_t::ptr_op_t _op, bool _truth, char _ch)
|
||||||
: op(_op), truth(_truth), ch(_ch) {}
|
: op(_op), truth(_truth), ch(_ch) {}
|
||||||
};
|
};
|
||||||
}
|
}
|
||||||
|
|
||||||
strings_list process_arguments(strings_list args, scope_t& scope)
|
strings_list process_arguments(strings_list args, scope_t& scope)
|
||||||
{
|
{
|
||||||
|
|
|
||||||
|
|
@ -209,10 +209,12 @@ public:
|
||||||
|
|
||||||
#define CTOR(type, name) \
|
#define CTOR(type, name) \
|
||||||
name ## option_t() : option_t<type>(#name)
|
name ## option_t() : option_t<type>(#name)
|
||||||
|
#define CTOR_(type, name, base) \
|
||||||
|
name ## option_t() : option_t<type>(#name), base
|
||||||
#define DECL1(type, name, vartype, var, value) \
|
#define DECL1(type, name, vartype, var, value) \
|
||||||
vartype var ; \
|
vartype var ; \
|
||||||
name ## option_t() : option_t<type>(#name), var(value)
|
name ## option_t() : option_t<type>(#name), var(value)
|
||||||
|
|
||||||
#define DO() virtual void handler_thunk(call_scope_t&)
|
#define DO() virtual void handler_thunk(call_scope_t&)
|
||||||
#define DO_(var) virtual void handler_thunk(call_scope_t& var)
|
#define DO_(var) virtual void handler_thunk(call_scope_t& var)
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -298,7 +298,7 @@ commodity_pool_t::exchange(const amount_t& amount,
|
||||||
annotation.add_flags(ANNOTATION_DATE_CALCULATED);
|
annotation.add_flags(ANNOTATION_DATE_CALCULATED);
|
||||||
if (tag)
|
if (tag)
|
||||||
annotation.add_flags(ANNOTATION_TAG_CALCULATED);
|
annotation.add_flags(ANNOTATION_TAG_CALCULATED);
|
||||||
|
|
||||||
breakdown.amount = amount_t(amount, annotation);
|
breakdown.amount = amount_t(amount, annotation);
|
||||||
|
|
||||||
DEBUG("commodity.prices.add",
|
DEBUG("commodity.prices.add",
|
||||||
|
|
|
||||||
|
|
@ -115,7 +115,7 @@ date_t post_t::actual_date() const
|
||||||
return xact->date();
|
return xact->date();
|
||||||
}
|
}
|
||||||
return *_date;
|
return *_date;
|
||||||
}
|
}
|
||||||
|
|
||||||
optional<date_t> post_t::effective_date() const
|
optional<date_t> post_t::effective_date() const
|
||||||
{
|
{
|
||||||
|
|
@ -341,7 +341,7 @@ namespace {
|
||||||
value_t get_value_date(post_t& post) {
|
value_t get_value_date(post_t& post) {
|
||||||
if (post.has_xdata()) {
|
if (post.has_xdata()) {
|
||||||
post_t::xdata_t& xdata(post.xdata());
|
post_t::xdata_t& xdata(post.xdata());
|
||||||
if (! xdata.value_date.is_not_a_date())
|
if (! xdata.value_date.is_not_a_date())
|
||||||
return xdata.value_date;
|
return xdata.value_date;
|
||||||
}
|
}
|
||||||
return post.date();
|
return post.date();
|
||||||
|
|
|
||||||
|
|
@ -99,7 +99,7 @@ class ptristream : public std::istream
|
||||||
protected:
|
protected:
|
||||||
ptrinbuf buf;
|
ptrinbuf buf;
|
||||||
|
|
||||||
public:
|
public:
|
||||||
ptristream(char * ptr, std::size_t len = 0)
|
ptristream(char * ptr, std::size_t len = 0)
|
||||||
: std::istream(0), buf(ptr, len) {
|
: std::istream(0), buf(ptr, len) {
|
||||||
rdbuf(&buf);
|
rdbuf(&buf);
|
||||||
|
|
|
||||||
|
|
@ -56,7 +56,7 @@ namespace {
|
||||||
datetime_t& moment) {
|
datetime_t& moment) {
|
||||||
return balance.value(moment, in_terms_of);
|
return balance.value(moment, in_terms_of);
|
||||||
}
|
}
|
||||||
|
|
||||||
boost::optional<amount_t>
|
boost::optional<amount_t>
|
||||||
py_commodity_amount_0(const balance_t& balance) {
|
py_commodity_amount_0(const balance_t& balance) {
|
||||||
return balance.commodity_amount();
|
return balance.commodity_amount();
|
||||||
|
|
|
||||||
|
|
@ -181,7 +181,7 @@ namespace {
|
||||||
const datetime_t& date, const amount_t& price) {
|
const datetime_t& date, const amount_t& price) {
|
||||||
commodity.add_price(date, price);
|
commodity.add_price(date, price);
|
||||||
}
|
}
|
||||||
|
|
||||||
void py_add_price_3(commodity_t& commodity, const datetime_t& date,
|
void py_add_price_3(commodity_t& commodity, const datetime_t& date,
|
||||||
const amount_t& price, const bool reflexive) {
|
const amount_t& price, const bool reflexive) {
|
||||||
commodity.add_price(date, price, reflexive);
|
commodity.add_price(date, price, reflexive);
|
||||||
|
|
|
||||||
|
|
@ -191,7 +191,7 @@ namespace {
|
||||||
coll->chain =
|
coll->chain =
|
||||||
chain_post_handlers(post_handler_ptr(coll->posts_collector),
|
chain_post_handlers(post_handler_ptr(coll->posts_collector),
|
||||||
coll->report);
|
coll->report);
|
||||||
pass_down_posts(coll->chain, walker);
|
pass_down_posts<journal_posts_iterator>(coll->chain, walker);
|
||||||
}
|
}
|
||||||
catch (...) {
|
catch (...) {
|
||||||
current_report.session.journal.release();
|
current_report.session.journal.release();
|
||||||
|
|
|
||||||
|
|
@ -173,7 +173,7 @@ void export_post()
|
||||||
.def("xdata", py_xdata,
|
.def("xdata", py_xdata,
|
||||||
return_internal_reference<>())
|
return_internal_reference<>())
|
||||||
|
|
||||||
.def("add_to_value", &post_t::add_to_value)
|
//.def("add_to_value", &post_t::add_to_value)
|
||||||
.def("set_reported_account", &post_t::set_reported_account)
|
.def("set_reported_account", &post_t::set_reported_account)
|
||||||
|
|
||||||
.def("reported_account", py_reported_account,
|
.def("reported_account", py_reported_account,
|
||||||
|
|
|
||||||
|
|
@ -140,7 +140,7 @@ void export_xact()
|
||||||
|
|
||||||
class_< period_xact_t, bases<xact_base_t> > ("PeriodicTransaction")
|
class_< period_xact_t, bases<xact_base_t> > ("PeriodicTransaction")
|
||||||
.def(init<string>())
|
.def(init<string>())
|
||||||
|
|
||||||
.add_property("period",
|
.add_property("period",
|
||||||
make_getter(&period_xact_t::period),
|
make_getter(&period_xact_t::period),
|
||||||
make_setter(&period_xact_t::period))
|
make_setter(&period_xact_t::period))
|
||||||
|
|
|
||||||
|
|
@ -126,7 +126,7 @@ void python_interpreter_t::initialize()
|
||||||
void python_interpreter_t::hack_system_paths()
|
void python_interpreter_t::hack_system_paths()
|
||||||
{
|
{
|
||||||
// Hack ledger.__path__ so it points to a real location
|
// Hack ledger.__path__ so it points to a real location
|
||||||
python::object sys_module = python::import("sys");
|
python::object sys_module = python::import("sys");
|
||||||
python::object sys_dict = sys_module.attr("__dict__");
|
python::object sys_dict = sys_module.attr("__dict__");
|
||||||
|
|
||||||
python::list paths(sys_dict["path"]);
|
python::list paths(sys_dict["path"]);
|
||||||
|
|
@ -177,7 +177,7 @@ object python_interpreter_t::import_into_main(const string& str)
|
||||||
if (! mod)
|
if (! mod)
|
||||||
throw_(std::runtime_error,
|
throw_(std::runtime_error,
|
||||||
_("Failed to import Python module %1") << str);
|
_("Failed to import Python module %1") << str);
|
||||||
|
|
||||||
// Import all top-level entries directly into the main namespace
|
// Import all top-level entries directly into the main namespace
|
||||||
main_nspace.update(mod.attr("__dict__"));
|
main_nspace.update(mod.attr("__dict__"));
|
||||||
|
|
||||||
|
|
@ -193,7 +193,7 @@ object python_interpreter_t::import_option(const string& str)
|
||||||
{
|
{
|
||||||
path file(str);
|
path file(str);
|
||||||
|
|
||||||
python::object sys_module = python::import("sys");
|
python::object sys_module = python::import("sys");
|
||||||
python::object sys_dict = sys_module.attr("__dict__");
|
python::object sys_dict = sys_module.attr("__dict__");
|
||||||
|
|
||||||
python::list paths(sys_dict["path"]);
|
python::list paths(sys_dict["path"]);
|
||||||
|
|
@ -312,7 +312,7 @@ value_t python_interpreter_t::python_command(call_scope_t& args)
|
||||||
delete[] argv;
|
delete[] argv;
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
|
||||||
for (std::size_t i = 0; i < args.size() + 1; i++)
|
for (std::size_t i = 0; i < args.size() + 1; i++)
|
||||||
delete[] argv[i];
|
delete[] argv[i];
|
||||||
delete[] argv;
|
delete[] argv;
|
||||||
|
|
@ -445,7 +445,7 @@ namespace {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
value_t python_interpreter_t::functor_t::operator()(call_scope_t& args)
|
value_t python_interpreter_t::functor_t::operator()(call_scope_t& args)
|
||||||
{
|
{
|
||||||
try {
|
try {
|
||||||
|
|
|
||||||
|
|
@ -48,7 +48,7 @@ public:
|
||||||
: session_t(), main_nspace(), is_initialized(false) {
|
: session_t(), main_nspace(), is_initialized(false) {
|
||||||
TRACE_CTOR(python_interpreter_t, "");
|
TRACE_CTOR(python_interpreter_t, "");
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~python_interpreter_t() {
|
virtual ~python_interpreter_t() {
|
||||||
TRACE_DTOR(python_interpreter_t);
|
TRACE_DTOR(python_interpreter_t);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -173,7 +173,7 @@ namespace boost { namespace python {
|
||||||
arg_to_python(T const& x) \
|
arg_to_python(T const& x) \
|
||||||
: python::handle<>(expr) {} \
|
: python::handle<>(expr) {} \
|
||||||
}; \
|
}; \
|
||||||
}
|
}
|
||||||
|
|
||||||
// Specialize argument and return value converters for T using expr
|
// Specialize argument and return value converters for T using expr
|
||||||
# define BOOST_PYTHON_TO_PYTHON_BY_VALUE(T, expr, pytype) \
|
# define BOOST_PYTHON_TO_PYTHON_BY_VALUE(T, expr, pytype) \
|
||||||
|
|
|
||||||
|
|
@ -127,7 +127,6 @@ query_t::lexer_t::token_t query_t::lexer_t::next_token()
|
||||||
// fall through...
|
// fall through...
|
||||||
default: {
|
default: {
|
||||||
string ident;
|
string ident;
|
||||||
string::const_iterator beg = arg_i;
|
|
||||||
for (; arg_i != arg_end; ++arg_i) {
|
for (; arg_i != arg_end; ++arg_i) {
|
||||||
switch (*arg_i) {
|
switch (*arg_i) {
|
||||||
case '\0':
|
case '\0':
|
||||||
|
|
@ -296,7 +295,7 @@ query_t::parser_t::parse_query_term(query_t::lexer_t::token_t::kind_t tok_contex
|
||||||
if (tok.kind != lexer_t::token_t::TERM)
|
if (tok.kind != lexer_t::token_t::TERM)
|
||||||
throw_(parse_error,
|
throw_(parse_error,
|
||||||
_("Metadata equality operator not followed by term"));
|
_("Metadata equality operator not followed by term"));
|
||||||
|
|
||||||
expr_t::ptr_op_t arg2 = new expr_t::op_t(expr_t::op_t::VALUE);
|
expr_t::ptr_op_t arg2 = new expr_t::op_t(expr_t::op_t::VALUE);
|
||||||
assert(tok.value);
|
assert(tok.value);
|
||||||
arg2->set_value(mask_t(*tok.value));
|
arg2->set_value(mask_t(*tok.value));
|
||||||
|
|
@ -310,7 +309,7 @@ query_t::parser_t::parse_query_term(query_t::lexer_t::token_t::kind_t tok_contex
|
||||||
}
|
}
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
default: {
|
default: {
|
||||||
node = new expr_t::op_t(expr_t::op_t::O_MATCH);
|
node = new expr_t::op_t(expr_t::op_t::O_MATCH);
|
||||||
|
|
||||||
|
|
@ -536,11 +535,13 @@ query_t::parser_t::parse_query_expr(lexer_t::token_t::kind_t tok_context,
|
||||||
}
|
}
|
||||||
|
|
||||||
default:
|
default:
|
||||||
break;
|
goto done;
|
||||||
}
|
}
|
||||||
|
|
||||||
tok = lexer.peek_token();
|
tok = lexer.peek_token();
|
||||||
}
|
}
|
||||||
|
done:
|
||||||
|
;
|
||||||
}
|
}
|
||||||
|
|
||||||
return limiter;
|
return limiter;
|
||||||
|
|
|
||||||
|
|
@ -289,7 +289,7 @@ void report_t::parse_query_args(const value_t& args, const string& whence)
|
||||||
|
|
||||||
normalize_period(); // it needs normalization
|
normalize_period(); // it needs normalization
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
namespace {
|
namespace {
|
||||||
struct posts_flusher
|
struct posts_flusher
|
||||||
|
|
@ -318,7 +318,7 @@ void report_t::posts_report(post_handler_ptr handler)
|
||||||
handler = chain_pre_post_handlers(handler, *this);
|
handler = chain_pre_post_handlers(handler, *this);
|
||||||
|
|
||||||
journal_posts_iterator walker(*session.journal.get());
|
journal_posts_iterator walker(*session.journal.get());
|
||||||
pass_down_posts(handler, walker);
|
pass_down_posts<journal_posts_iterator>(handler, walker);
|
||||||
|
|
||||||
if (! HANDLED(group_by_))
|
if (! HANDLED(group_by_))
|
||||||
posts_flusher(handler, *this)(value_t());
|
posts_flusher(handler, *this)(value_t());
|
||||||
|
|
@ -334,7 +334,7 @@ void report_t::generate_report(post_handler_ptr handler)
|
||||||
HANDLED(head_) ?
|
HANDLED(head_) ?
|
||||||
static_cast<unsigned int>(HANDLER(head_).value.to_long()) : 50);
|
static_cast<unsigned int>(HANDLER(head_).value.to_long()) : 50);
|
||||||
|
|
||||||
pass_down_posts(handler, walker);
|
pass_down_posts<generate_posts_iterator>(handler, walker);
|
||||||
}
|
}
|
||||||
|
|
||||||
void report_t::xact_report(post_handler_ptr handler, xact_t& xact)
|
void report_t::xact_report(post_handler_ptr handler, xact_t& xact)
|
||||||
|
|
@ -342,7 +342,7 @@ void report_t::xact_report(post_handler_ptr handler, xact_t& xact)
|
||||||
handler = chain_handlers(handler, *this);
|
handler = chain_handlers(handler, *this);
|
||||||
|
|
||||||
xact_posts_iterator walker(xact);
|
xact_posts_iterator walker(xact);
|
||||||
pass_down_posts(handler, walker);
|
pass_down_posts<xact_posts_iterator>(handler, walker);
|
||||||
|
|
||||||
xact.clear_xdata();
|
xact.clear_xdata();
|
||||||
}
|
}
|
||||||
|
|
@ -382,25 +382,34 @@ namespace {
|
||||||
report.HANDLER(display_total_).expr.mark_uncompiled();
|
report.HANDLER(display_total_).expr.mark_uncompiled();
|
||||||
report.HANDLER(revalued_total_).expr.mark_uncompiled();
|
report.HANDLER(revalued_total_).expr.mark_uncompiled();
|
||||||
|
|
||||||
scoped_ptr<accounts_iterator> iter;
|
|
||||||
if (! report.HANDLED(sort_)) {
|
|
||||||
iter.reset(new basic_accounts_iterator(*report.session.journal->master));
|
|
||||||
} else {
|
|
||||||
expr_t sort_expr(report.HANDLER(sort_).str());
|
|
||||||
sort_expr.set_context(&report);
|
|
||||||
iter.reset(new sorted_accounts_iterator(*report.session.journal->master,
|
|
||||||
sort_expr, report.HANDLED(flat)));
|
|
||||||
}
|
|
||||||
|
|
||||||
if (report.HANDLED(display_)) {
|
if (report.HANDLED(display_)) {
|
||||||
DEBUG("report.predicate",
|
DEBUG("report.predicate",
|
||||||
"Display predicate = " << report.HANDLER(display_).str());
|
"Display predicate = " << report.HANDLER(display_).str());
|
||||||
pass_down_accounts(handler, *iter.get(),
|
if (! report.HANDLED(sort_)) {
|
||||||
predicate_t(report.HANDLER(display_).str(),
|
basic_accounts_iterator iter(*report.session.journal->master);
|
||||||
report.what_to_keep()),
|
pass_down_accounts<basic_accounts_iterator>
|
||||||
report);
|
(handler, iter, predicate_t(report.HANDLER(display_).str(),
|
||||||
|
report.what_to_keep()), report);
|
||||||
|
} else {
|
||||||
|
expr_t sort_expr(report.HANDLER(sort_).str());
|
||||||
|
sort_expr.set_context(&report);
|
||||||
|
sorted_accounts_iterator iter(*report.session.journal->master,
|
||||||
|
sort_expr, report.HANDLED(flat));
|
||||||
|
pass_down_accounts<sorted_accounts_iterator>
|
||||||
|
(handler, iter, predicate_t(report.HANDLER(display_).str(),
|
||||||
|
report.what_to_keep()), report);
|
||||||
|
}
|
||||||
} else {
|
} else {
|
||||||
pass_down_accounts(handler, *iter.get());
|
if (! report.HANDLED(sort_)) {
|
||||||
|
basic_accounts_iterator iter(*report.session.journal->master);
|
||||||
|
pass_down_accounts<basic_accounts_iterator>(handler, iter);
|
||||||
|
} else {
|
||||||
|
expr_t sort_expr(report.HANDLER(sort_).str());
|
||||||
|
sort_expr.set_context(&report);
|
||||||
|
sorted_accounts_iterator iter(*report.session.journal->master,
|
||||||
|
sort_expr, report.HANDLED(flat));
|
||||||
|
pass_down_accounts<sorted_accounts_iterator>(handler, iter);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
report.session.journal->clear_xdata();
|
report.session.journal->clear_xdata();
|
||||||
|
|
@ -428,7 +437,7 @@ void report_t::accounts_report(acct_handler_ptr handler)
|
||||||
// objects created within it during the call to pass_down_posts, which will
|
// objects created within it during the call to pass_down_posts, which will
|
||||||
// be needed later by the pass_down_accounts.
|
// be needed later by the pass_down_accounts.
|
||||||
journal_posts_iterator walker(*session.journal.get());
|
journal_posts_iterator walker(*session.journal.get());
|
||||||
pass_down_posts(chain, walker);
|
pass_down_posts<journal_posts_iterator>(chain, walker);
|
||||||
|
|
||||||
if (! HANDLED(group_by_))
|
if (! HANDLED(group_by_))
|
||||||
accounts_flusher(handler, *this)(value_t());
|
accounts_flusher(handler, *this)(value_t());
|
||||||
|
|
@ -439,7 +448,7 @@ void report_t::commodities_report(post_handler_ptr handler)
|
||||||
handler = chain_handlers(handler, *this);
|
handler = chain_handlers(handler, *this);
|
||||||
|
|
||||||
posts_commodities_iterator walker(*session.journal.get());
|
posts_commodities_iterator walker(*session.journal.get());
|
||||||
pass_down_posts(handler, walker);
|
pass_down_posts<posts_commodities_iterator>(handler, walker);
|
||||||
|
|
||||||
session.journal->clear_xdata();
|
session.journal->clear_xdata();
|
||||||
}
|
}
|
||||||
|
|
@ -648,7 +657,8 @@ value_t report_t::fn_quoted(call_scope_t& args)
|
||||||
std::ostringstream out;
|
std::ostringstream out;
|
||||||
|
|
||||||
out << '"';
|
out << '"';
|
||||||
foreach (const char ch, args.get<string>(0)) {
|
string arg(args.get<string>(0));
|
||||||
|
foreach (const char ch, arg) {
|
||||||
if (ch == '"')
|
if (ch == '"')
|
||||||
out << "\\\"";
|
out << "\\\"";
|
||||||
else
|
else
|
||||||
|
|
@ -663,7 +673,8 @@ value_t report_t::fn_join(call_scope_t& args)
|
||||||
{
|
{
|
||||||
std::ostringstream out;
|
std::ostringstream out;
|
||||||
|
|
||||||
foreach (const char ch, args.get<string>(0)) {
|
string arg(args.get<string>(0));
|
||||||
|
foreach (const char ch, arg) {
|
||||||
if (ch != '\n')
|
if (ch != '\n')
|
||||||
out << ch;
|
out << ch;
|
||||||
else
|
else
|
||||||
|
|
|
||||||
|
|
@ -68,7 +68,7 @@ class xact_t;
|
||||||
// --- The details of #1 and #2 together represent the ItemHandler.
|
// --- The details of #1 and #2 together represent the ItemHandler.
|
||||||
//
|
//
|
||||||
// 3. Mode of the report. Currently there are four modes:
|
// 3. Mode of the report. Currently there are four modes:
|
||||||
//
|
//
|
||||||
// a. Posting or commodity iteration. In this mode, all the journal's
|
// a. Posting or commodity iteration. In this mode, all the journal's
|
||||||
// xacts, the postings of a specific xact, or all the journal's
|
// xacts, the postings of a specific xact, or all the journal's
|
||||||
// commodities are walked. In the first two cases, it's the underlying
|
// commodities are walked. In the first two cases, it's the underlying
|
||||||
|
|
@ -86,7 +86,7 @@ class xact_t;
|
||||||
// c. Write journal. In this mode, a single function is called that output
|
// c. Write journal. In this mode, a single function is called that output
|
||||||
// the journal object as a textual file. #2 is used to print out each
|
// the journal object as a textual file. #2 is used to print out each
|
||||||
// posting in the journal.
|
// posting in the journal.
|
||||||
//
|
//
|
||||||
// d. Dump binary file. This is just like 'c', except that it dumps out a
|
// d. Dump binary file. This is just like 'c', except that it dumps out a
|
||||||
// binary file and #2 is completely ignored.
|
// binary file and #2 is completely ignored.
|
||||||
//
|
//
|
||||||
|
|
|
||||||
|
|
@ -646,7 +646,7 @@ class value_scope_t : public child_scope_t
|
||||||
public:
|
public:
|
||||||
value_scope_t(scope_t& _parent, const value_t& _value)
|
value_scope_t(scope_t& _parent, const value_t& _value)
|
||||||
: child_scope_t(_parent), value(_value) {}
|
: child_scope_t(_parent), value(_value) {}
|
||||||
|
|
||||||
virtual string description() {
|
virtual string description() {
|
||||||
return parent->description();
|
return parent->description();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
135
src/series.h
Normal file
135
src/series.h
Normal file
|
|
@ -0,0 +1,135 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2003-2010, John Wiegley. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
*
|
||||||
|
* - Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* - Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* - Neither the name of New Artisans LLC nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived from
|
||||||
|
* this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @addtogroup expr
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file series.h
|
||||||
|
* @author John Wiegley
|
||||||
|
*
|
||||||
|
* @ingroup expr
|
||||||
|
*/
|
||||||
|
#ifndef _SERIES_H
|
||||||
|
#define _SERIES_H
|
||||||
|
|
||||||
|
#include "scope.h"
|
||||||
|
|
||||||
|
namespace ledger {
|
||||||
|
|
||||||
|
class expr_series_t
|
||||||
|
{
|
||||||
|
protected:
|
||||||
|
scope_t * context;
|
||||||
|
|
||||||
|
public:
|
||||||
|
optional<std::list<expr_t> > exprs;
|
||||||
|
expr_t default_expr;
|
||||||
|
std::string variable;
|
||||||
|
|
||||||
|
expr_series_t(const std::string& _variable)
|
||||||
|
: context(NULL), default_expr(_variable), variable(_variable) {
|
||||||
|
TRACE_CTOR(expr_series_t, "std::string");
|
||||||
|
}
|
||||||
|
expr_series_t(const expr_t& expr, const std::string& _variable)
|
||||||
|
: context(const_cast<expr_t&>(expr).get_context()),
|
||||||
|
default_expr(expr), variable(_variable) {
|
||||||
|
TRACE_CTOR(expr_series_t, "expr_t, std::string");
|
||||||
|
}
|
||||||
|
expr_series_t(const expr_series_t& other)
|
||||||
|
: context(other.context), exprs(other.exprs),
|
||||||
|
default_expr(other.default_expr), variable(other.variable) {
|
||||||
|
TRACE_CTOR(expr_series_t, "copy");
|
||||||
|
}
|
||||||
|
virtual ~expr_series_t() {
|
||||||
|
TRACE_DTOR(expr_series_t);
|
||||||
|
}
|
||||||
|
|
||||||
|
scope_t * get_context() {
|
||||||
|
return context;
|
||||||
|
}
|
||||||
|
void set_context(scope_t * scope) {
|
||||||
|
context = scope;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool empty() const {
|
||||||
|
return ! exprs || exprs->empty();
|
||||||
|
}
|
||||||
|
|
||||||
|
void push_back(const expr_t& expr) {
|
||||||
|
if (! exprs)
|
||||||
|
exprs = std::list<expr_t>();
|
||||||
|
exprs->push_back(expr);
|
||||||
|
}
|
||||||
|
void pop_back() {
|
||||||
|
assert(exprs);
|
||||||
|
exprs->pop_back();
|
||||||
|
}
|
||||||
|
|
||||||
|
void mark_uncompiled() {
|
||||||
|
if (exprs)
|
||||||
|
foreach (expr_t& expr, *exprs)
|
||||||
|
expr.mark_uncompiled();
|
||||||
|
else
|
||||||
|
default_expr.mark_uncompiled();
|
||||||
|
}
|
||||||
|
|
||||||
|
void compile(scope_t& scope) {
|
||||||
|
if (exprs)
|
||||||
|
foreach (expr_t& expr, *exprs)
|
||||||
|
expr.compile(scope);
|
||||||
|
else
|
||||||
|
default_expr.compile(scope);
|
||||||
|
}
|
||||||
|
|
||||||
|
value_t calc(scope_t& scope) {
|
||||||
|
if (exprs) {
|
||||||
|
value_t result;
|
||||||
|
symbol_scope_t sym_scope(scope);
|
||||||
|
std::size_t len(exprs->size());
|
||||||
|
|
||||||
|
foreach (expr_t& expr, *exprs) {
|
||||||
|
result = expr.calc(sym_scope);
|
||||||
|
if (--len > 0)
|
||||||
|
sym_scope.define(symbol_t::FUNCTION, variable,
|
||||||
|
expr_t::op_t::wrap_value(result));
|
||||||
|
}
|
||||||
|
return result;
|
||||||
|
} else {
|
||||||
|
return default_expr.calc(scope);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace ledger
|
||||||
|
|
||||||
|
#endif // _SERIES_H
|
||||||
|
|
@ -178,7 +178,7 @@ void session_t::close_journal_files()
|
||||||
{
|
{
|
||||||
journal.reset();
|
journal.reset();
|
||||||
amount_t::shutdown();
|
amount_t::shutdown();
|
||||||
|
|
||||||
journal.reset(new journal_t);
|
journal.reset(new journal_t);
|
||||||
amount_t::initialize();
|
amount_t::initialize();
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -158,6 +158,7 @@ typedef std::ostream::pos_type ostream_pos_type;
|
||||||
#include <boost/iostreams/write.hpp>
|
#include <boost/iostreams/write.hpp>
|
||||||
#define BOOST_IOSTREAMS_USE_DEPRECATED 1
|
#define BOOST_IOSTREAMS_USE_DEPRECATED 1
|
||||||
#include <boost/iostreams/device/file_descriptor.hpp>
|
#include <boost/iostreams/device/file_descriptor.hpp>
|
||||||
|
#include <boost/iterator/iterator_facade.hpp>
|
||||||
#include <boost/iterator/transform_iterator.hpp>
|
#include <boost/iterator/transform_iterator.hpp>
|
||||||
#include <boost/lexical_cast.hpp>
|
#include <boost/lexical_cast.hpp>
|
||||||
#include <boost/operators.hpp>
|
#include <boost/operators.hpp>
|
||||||
|
|
@ -204,7 +205,7 @@ namespace serialization {
|
||||||
template <class Archive>
|
template <class Archive>
|
||||||
void serialize(Archive& ar, boost::filesystem::path& p, const unsigned int)
|
void serialize(Archive& ar, boost::filesystem::path& p, const unsigned int)
|
||||||
{
|
{
|
||||||
std::string s;
|
std::string s;
|
||||||
if (Archive::is_saving::value)
|
if (Archive::is_saving::value)
|
||||||
s = p.string();
|
s = p.string();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -129,7 +129,7 @@ namespace {
|
||||||
(in.peek() == ' ' || in.peek() == '\t'));
|
(in.peek() == ' ' || in.peek() == '\t'));
|
||||||
}
|
}
|
||||||
|
|
||||||
void read_next_directive();
|
void read_next_directive();
|
||||||
|
|
||||||
#if defined(TIMELOG_SUPPORT)
|
#if defined(TIMELOG_SUPPORT)
|
||||||
void clock_in_directive(char * line, bool capitalized);
|
void clock_in_directive(char * line, bool capitalized);
|
||||||
|
|
@ -270,7 +270,7 @@ void instance_t::parse()
|
||||||
string err_context = error_context();
|
string err_context = error_context();
|
||||||
if (! err_context.empty())
|
if (! err_context.empty())
|
||||||
std::cerr << err_context << std::endl;
|
std::cerr << err_context << std::endl;
|
||||||
|
|
||||||
if (! current_context.empty())
|
if (! current_context.empty())
|
||||||
std::cerr << current_context << std::endl;
|
std::cerr << current_context << std::endl;
|
||||||
|
|
||||||
|
|
@ -442,7 +442,7 @@ void instance_t::clock_in_directive(char * line, bool /*capitalized*/)
|
||||||
}
|
}
|
||||||
|
|
||||||
void instance_t::clock_out_directive(char * line, bool /*capitalized*/)
|
void instance_t::clock_out_directive(char * line, bool /*capitalized*/)
|
||||||
{
|
{
|
||||||
string datetime(line, 2, 19);
|
string datetime(line, 2, 19);
|
||||||
|
|
||||||
char * p = skip_ws(line + 22);
|
char * p = skip_ws(line + 22);
|
||||||
|
|
@ -546,7 +546,7 @@ void instance_t::automated_xact_directive(char * line)
|
||||||
try {
|
try {
|
||||||
query_t query;
|
query_t query;
|
||||||
keep_details_t keeper(true, true, true);
|
keep_details_t keeper(true, true, true);
|
||||||
expr_t::ptr_op_t expr =
|
expr_t::ptr_op_t expr =
|
||||||
query.parse_args(string_value(skip_ws(line + 1)).to_sequence(),
|
query.parse_args(string_value(skip_ws(line + 1)).to_sequence(),
|
||||||
keeper, false, true);
|
keeper, false, true);
|
||||||
|
|
||||||
|
|
@ -831,7 +831,7 @@ void instance_t::alias_directive(char * line)
|
||||||
|
|
||||||
void instance_t::fixed_directive(char * line)
|
void instance_t::fixed_directive(char * line)
|
||||||
{
|
{
|
||||||
if (optional<std::pair<commodity_t *, price_point_t> > price_point =
|
if (optional<std::pair<commodity_t *, price_point_t> > price_point =
|
||||||
commodity_pool_t::current_pool->parse_price_directive(trim_ws(line),
|
commodity_pool_t::current_pool->parse_price_directive(trim_ws(line),
|
||||||
true)) {
|
true)) {
|
||||||
context.state_stack.push_front(fixed_rate_t(price_point->first,
|
context.state_stack.push_front(fixed_rate_t(price_point->first,
|
||||||
|
|
@ -1165,11 +1165,7 @@ post_t * instance_t::parse_post(char * line,
|
||||||
|
|
||||||
// Parse the optional amount
|
// Parse the optional amount
|
||||||
|
|
||||||
bool saw_amount = false;
|
|
||||||
|
|
||||||
if (next && *next && (*next != ';' && *next != '=')) {
|
if (next && *next && (*next != ';' && *next != '=')) {
|
||||||
saw_amount = true;
|
|
||||||
|
|
||||||
beg = next - line;
|
beg = next - line;
|
||||||
ptristream stream(next, len - beg);
|
ptristream stream(next, len - beg);
|
||||||
|
|
||||||
|
|
@ -1320,7 +1316,7 @@ post_t * instance_t::parse_post(char * line,
|
||||||
|
|
||||||
amount_t& amt(*post->assigned_amount);
|
amount_t& amt(*post->assigned_amount);
|
||||||
value_t account_total
|
value_t account_total
|
||||||
(post->account->amount(false).strip_annotations(keep_details_t()));
|
(post->account->amount().strip_annotations(keep_details_t()));
|
||||||
|
|
||||||
DEBUG("post.assign",
|
DEBUG("post.assign",
|
||||||
"line " << linenum << ": " "account balance = " << account_total);
|
"line " << linenum << ": " "account balance = " << account_total);
|
||||||
|
|
@ -1569,6 +1565,7 @@ xact_t * instance_t::parse_xact(char * line,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if 0
|
||||||
if (xact->_state == item_t::UNCLEARED) {
|
if (xact->_state == item_t::UNCLEARED) {
|
||||||
item_t::state_t result = item_t::CLEARED;
|
item_t::state_t result = item_t::CLEARED;
|
||||||
|
|
||||||
|
|
@ -1582,6 +1579,7 @@ xact_t * instance_t::parse_xact(char * line,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
xact->pos->end_pos = curr_pos;
|
xact->pos->end_pos = curr_pos;
|
||||||
xact->pos->end_line = linenum;
|
xact->pos->end_line = linenum;
|
||||||
|
|
|
||||||
|
|
@ -280,7 +280,7 @@ optional<date_time::weekdays> string_to_day_of_week(const std::string& str)
|
||||||
else
|
else
|
||||||
return none;
|
return none;
|
||||||
}
|
}
|
||||||
|
|
||||||
optional<date_time::months_of_year>
|
optional<date_time::months_of_year>
|
||||||
string_to_month_of_year(const std::string& str)
|
string_to_month_of_year(const std::string& str)
|
||||||
{
|
{
|
||||||
|
|
@ -709,12 +709,9 @@ void date_parser_t::determine_when(date_parser_t::lexer_t::token_t& tok,
|
||||||
when += gregorian::years(amount * adjust);
|
when += gregorian::years(amount * adjust);
|
||||||
break;
|
break;
|
||||||
case lexer_t::token_t::TOK_QUARTER:
|
case lexer_t::token_t::TOK_QUARTER:
|
||||||
case lexer_t::token_t::TOK_QUARTERS: {
|
case lexer_t::token_t::TOK_QUARTERS:
|
||||||
date_t temp =
|
|
||||||
date_duration_t::find_nearest(today, date_duration_t::QUARTERS);
|
|
||||||
when += gregorian::months(amount * 3 * adjust);
|
when += gregorian::months(amount * 3 * adjust);
|
||||||
break;
|
break;
|
||||||
}
|
|
||||||
case lexer_t::token_t::TOK_MONTH:
|
case lexer_t::token_t::TOK_MONTH:
|
||||||
case lexer_t::token_t::TOK_MONTHS:
|
case lexer_t::token_t::TOK_MONTHS:
|
||||||
when += gregorian::months(amount * adjust);
|
when += gregorian::months(amount * adjust);
|
||||||
|
|
|
||||||
|
|
@ -203,7 +203,7 @@ struct date_duration_t
|
||||||
}
|
}
|
||||||
~date_duration_t() throw() {
|
~date_duration_t() throw() {
|
||||||
TRACE_DTOR(date_duration_t);
|
TRACE_DTOR(date_duration_t);
|
||||||
}
|
}
|
||||||
|
|
||||||
date_t add(const date_t& date) const {
|
date_t add(const date_t& date) const {
|
||||||
switch (quantum) {
|
switch (quantum) {
|
||||||
|
|
@ -431,7 +431,7 @@ public:
|
||||||
out << "from" << range_begin->to_string();
|
out << "from" << range_begin->to_string();
|
||||||
if (range_end)
|
if (range_end)
|
||||||
out << " to" << range_end->to_string();
|
out << " to" << range_end->to_string();
|
||||||
|
|
||||||
return out.str();
|
return out.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
26
src/value.cc
26
src/value.cc
|
|
@ -333,7 +333,7 @@ value_t& value_t::operator+=(const value_t& val)
|
||||||
for (; i != end(); i++, j++)
|
for (; i != end(); i++, j++)
|
||||||
*i += *j;
|
*i += *j;
|
||||||
} else {
|
} else {
|
||||||
add_error_context(_("While adding %1 to %2:") << *this << val);
|
add_error_context(_("While adding %1 to %2:") << val << *this);
|
||||||
throw_(value_error, _("Cannot add sequences of different lengths"));
|
throw_(value_error, _("Cannot add sequences of different lengths"));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -446,7 +446,7 @@ value_t& value_t::operator+=(const value_t& val)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
add_error_context(_("While adding %1 to %2:") << *this << val);
|
add_error_context(_("While adding %1 to %2:") << val << *this);
|
||||||
throw_(value_error, _("Cannot add %1 to %2") << val.label() << label());
|
throw_(value_error, _("Cannot add %1 to %2") << val.label() << label());
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
|
|
@ -465,7 +465,7 @@ value_t& value_t::operator-=(const value_t& val)
|
||||||
for (; i != end(); i++, j++)
|
for (; i != end(); i++, j++)
|
||||||
*i -= *j;
|
*i -= *j;
|
||||||
} else {
|
} else {
|
||||||
add_error_context(_("While subtracting %1 to %2:") << *this << val);
|
add_error_context(_("While subtracting %1 from %2:") << val << *this);
|
||||||
throw_(value_error, _("Cannot subtract sequences of different lengths"));
|
throw_(value_error, _("Cannot subtract sequences of different lengths"));
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -588,7 +588,7 @@ value_t& value_t::operator-=(const value_t& val)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
add_error_context(_("While subtracting %1 from %2:") << *this << val);
|
add_error_context(_("While subtracting %1 from %2:") << val << *this);
|
||||||
throw_(value_error, _("Cannot subtract %1 from %2") << val.label() << label());
|
throw_(value_error, _("Cannot subtract %1 from %2") << val.label() << label());
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
|
|
@ -670,7 +670,7 @@ value_t& value_t::operator*=(const value_t& val)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
add_error_context(_("While multiplying %1 with %2:") << *this << val);
|
add_error_context(_("While multiplying %1 with %2:") << val << *this);
|
||||||
throw_(value_error, _("Cannot multiply %1 with %2") << label() << val.label());
|
throw_(value_error, _("Cannot multiply %1 with %2") << label() << val.label());
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
|
|
@ -748,7 +748,7 @@ value_t& value_t::operator/=(const value_t& val)
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
add_error_context(_("While dividing %1 by %2:") << *this << val);
|
add_error_context(_("While dividing %1 by %2:") << val << *this);
|
||||||
throw_(value_error, _("Cannot divide %1 by %2") << label() << val.label());
|
throw_(value_error, _("Cannot divide %1 by %2") << label() << val.label());
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
|
|
@ -760,7 +760,7 @@ bool value_t::is_equal_to(const value_t& val) const
|
||||||
switch (type()) {
|
switch (type()) {
|
||||||
case VOID:
|
case VOID:
|
||||||
return val.type() == VOID;
|
return val.type() == VOID;
|
||||||
|
|
||||||
case BOOLEAN:
|
case BOOLEAN:
|
||||||
if (val.is_boolean())
|
if (val.is_boolean())
|
||||||
return as_boolean() == val.as_boolean();
|
return as_boolean() == val.as_boolean();
|
||||||
|
|
@ -834,7 +834,7 @@ bool value_t::is_equal_to(const value_t& val) const
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
add_error_context(_("While comparing equality of %1 to %2:") << *this << val);
|
add_error_context(_("While comparing equality of %1 and %2:") << *this << val);
|
||||||
throw_(value_error, _("Cannot compare %1 to %2") << label() << val.label());
|
throw_(value_error, _("Cannot compare %1 to %2") << label() << val.label());
|
||||||
|
|
||||||
return *this;
|
return *this;
|
||||||
|
|
@ -1263,8 +1263,8 @@ void value_t::in_place_cast(type_t cast_type)
|
||||||
}
|
}
|
||||||
|
|
||||||
add_error_context(_("While converting %1:") << *this);
|
add_error_context(_("While converting %1:") << *this);
|
||||||
throw_(value_error,
|
throw_(value_error, _("Cannot convert %1 to %2")
|
||||||
_("Cannot convert %1 to %2") << label() << label(cast_type));
|
<< label() << label(cast_type));
|
||||||
}
|
}
|
||||||
|
|
||||||
void value_t::in_place_negate()
|
void value_t::in_place_negate()
|
||||||
|
|
@ -1721,11 +1721,13 @@ string value_t::label(optional<type_t> the_type) const
|
||||||
return _("<invalid>");
|
return _("<invalid>");
|
||||||
}
|
}
|
||||||
|
|
||||||
void value_t::print(std::ostream& out,
|
void value_t::print(std::ostream& _out,
|
||||||
const int first_width,
|
const int first_width,
|
||||||
const int latter_width,
|
const int latter_width,
|
||||||
const uint_least8_t flags) const
|
const uint_least8_t flags) const
|
||||||
{
|
{
|
||||||
|
std::ostringstream out;
|
||||||
|
|
||||||
if (first_width > 0 &&
|
if (first_width > 0 &&
|
||||||
(! is_amount() || as_amount().is_zero()) &&
|
(! is_amount() || as_amount().is_zero()) &&
|
||||||
! is_balance() && ! is_string()) {
|
! is_balance() && ! is_string()) {
|
||||||
|
|
@ -1821,6 +1823,8 @@ void value_t::print(std::ostream& out,
|
||||||
add_error_context(_("While printing %1:") << *this);
|
add_error_context(_("While printing %1:") << *this);
|
||||||
throw_(value_error, _("Cannot print %1") << label());
|
throw_(value_error, _("Cannot print %1") << label());
|
||||||
}
|
}
|
||||||
|
|
||||||
|
_out << out.str();
|
||||||
}
|
}
|
||||||
|
|
||||||
void value_t::dump(std::ostream& out, const bool relaxed) const
|
void value_t::dump(std::ostream& out, const bool relaxed) const
|
||||||
|
|
|
||||||
|
|
@ -139,7 +139,7 @@ private:
|
||||||
scope_t *, // SCOPE
|
scope_t *, // SCOPE
|
||||||
boost::any // ANY
|
boost::any // ANY
|
||||||
> data;
|
> data;
|
||||||
|
|
||||||
type_t type;
|
type_t type;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
|
|
@ -192,7 +192,7 @@ bool xact_base_t::finalize()
|
||||||
DEBUG("xact.finalize", "there were no costs, and a valid top_post");
|
DEBUG("xact.finalize", "there were no costs, and a valid top_post");
|
||||||
|
|
||||||
balance_t::amounts_map::const_iterator a = bal.amounts.begin();
|
balance_t::amounts_map::const_iterator a = bal.amounts.begin();
|
||||||
|
|
||||||
const amount_t * x = &(*a++).second;
|
const amount_t * x = &(*a++).second;
|
||||||
const amount_t * y = &(*a++).second;
|
const amount_t * y = &(*a++).second;
|
||||||
|
|
||||||
|
|
@ -418,7 +418,7 @@ bool xact_base_t::verify()
|
||||||
|
|
||||||
amount_t& p(post->cost ? *post->cost : post->amount);
|
amount_t& p(post->cost ? *post->cost : post->amount);
|
||||||
assert(! p.is_null());
|
assert(! p.is_null());
|
||||||
|
|
||||||
// If the amount was a cost, it very likely has the "keep_precision" flag
|
// If the amount was a cost, it very likely has the "keep_precision" flag
|
||||||
// set, meaning commodity display precision is ignored when displaying the
|
// set, meaning commodity display precision is ignored when displaying the
|
||||||
// amount. We never want this set for the balance, so we must clear the
|
// amount. We never want this set for the balance, so we must clear the
|
||||||
|
|
@ -609,7 +609,7 @@ namespace {
|
||||||
.match(post.reported_account()->fullname());
|
.match(post.reported_account()->fullname());
|
||||||
else
|
else
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case expr_t::op_t::O_NOT:
|
case expr_t::op_t::O_NOT:
|
||||||
return ! post_pred(op->left(), post);
|
return ! post_pred(op->left(), post);
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -61,7 +61,7 @@ public:
|
||||||
xact_base_t() : item_t(), journal(NULL) {
|
xact_base_t() : item_t(), journal(NULL) {
|
||||||
TRACE_CTOR(xact_base_t, "");
|
TRACE_CTOR(xact_base_t, "");
|
||||||
}
|
}
|
||||||
xact_base_t(const xact_base_t& e);
|
xact_base_t(const xact_base_t& e);
|
||||||
|
|
||||||
virtual ~xact_base_t();
|
virtual ~xact_base_t();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -119,6 +119,7 @@ pkginclude_HEADERS = \
|
||||||
src/query.h \
|
src/query.h \
|
||||||
src/format.h \
|
src/format.h \
|
||||||
src/option.h \
|
src/option.h \
|
||||||
|
src/series.h \
|
||||||
\
|
\
|
||||||
src/item.h \
|
src/item.h \
|
||||||
src/post.h \
|
src/post.h \
|
||||||
|
|
|
||||||
|
|
@ -66,7 +66,7 @@ AC_ARG_ENABLE(doxygen,
|
||||||
AM_CONDITIONAL(USE_DOXYGEN, test x$doxygen = xtrue)
|
AM_CONDITIONAL(USE_DOXYGEN, test x$doxygen = xtrue)
|
||||||
|
|
||||||
AC_ARG_ENABLE(cache,
|
AC_ARG_ENABLE(cache,
|
||||||
[ --enable-cache Enable use of the --cache option],
|
[ --enable-cache Enable use of the --cache option],
|
||||||
[case "${enableval}" in
|
[case "${enableval}" in
|
||||||
yes) cache=true ;;
|
yes) cache=true ;;
|
||||||
no) cache=false ;;
|
no) cache=false ;;
|
||||||
|
|
@ -76,7 +76,7 @@ AC_ARG_ENABLE(cache,
|
||||||
AM_CONDITIONAL(USE_CACHE_OPTION, test x$cache = xtrue)
|
AM_CONDITIONAL(USE_CACHE_OPTION, test x$cache = xtrue)
|
||||||
|
|
||||||
AC_ARG_ENABLE(python,
|
AC_ARG_ENABLE(python,
|
||||||
[ --enable-python Turn on Python support (experimental)],
|
[ --enable-python Turn on Python support (experimental)],
|
||||||
[case "${enableval}" in
|
[case "${enableval}" in
|
||||||
yes) python=true ;;
|
yes) python=true ;;
|
||||||
no) python=false ;;
|
no) python=false ;;
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue