Merge branch 'next'
This commit is contained in:
commit
a2cb549b1d
53 changed files with 4092 additions and 439 deletions
|
|
@ -59,6 +59,7 @@ libledger_data_la_SOURCES = \
|
||||||
src/timelog.cc \
|
src/timelog.cc \
|
||||||
src/textual.cc \
|
src/textual.cc \
|
||||||
src/journal.cc \
|
src/journal.cc \
|
||||||
|
src/archive.cc \
|
||||||
src/account.cc \
|
src/account.cc \
|
||||||
src/xact.cc \
|
src/xact.cc \
|
||||||
src/post.cc \
|
src/post.cc \
|
||||||
|
|
@ -118,6 +119,7 @@ pkginclude_HEADERS = \
|
||||||
src/xact.h \
|
src/xact.h \
|
||||||
src/account.h \
|
src/account.h \
|
||||||
src/journal.h \
|
src/journal.h \
|
||||||
|
src/archive.h \
|
||||||
src/timelog.h \
|
src/timelog.h \
|
||||||
src/iterators.h \
|
src/iterators.h \
|
||||||
src/compare.h \
|
src/compare.h \
|
||||||
|
|
|
||||||
61
README-1ST
Normal file
61
README-1ST
Normal file
|
|
@ -0,0 +1,61 @@
|
||||||
|
|
||||||
|
README FIRST!!!
|
||||||
|
|
||||||
|
===============================================================================
|
||||||
|
|
||||||
|
To build this code after doing a Git clone, run:
|
||||||
|
|
||||||
|
$ ./acprep update
|
||||||
|
|
||||||
|
If you try to configure/build on your own, you are almost certainly going to
|
||||||
|
run into problems. In future, you can run this command again and it will keep
|
||||||
|
you updated with the very latest version.
|
||||||
|
|
||||||
|
===============================================================================
|
||||||
|
|
||||||
|
F.A.Q.
|
||||||
|
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
|
- Q: The build fails saying it can't find utf8.h
|
||||||
|
|
||||||
|
A: You didn't run ./acprep update.
|
||||||
|
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
|
- Q: Configure fails saying it can't find boost_regex
|
||||||
|
|
||||||
|
A: Look in config.log and search for "boost_regex", then scroll down a bit
|
||||||
|
until you see the exact compile error. Usually it's failing because
|
||||||
|
your include directory is different from anything acprep is expecting to
|
||||||
|
see. It could also be failing because your Boost libraries have a
|
||||||
|
custom "suffix" on them.
|
||||||
|
|
||||||
|
Let's say your Boost was installed in ~/boost, and every library has the
|
||||||
|
suffix '-xgcc42'. This is what you would run:
|
||||||
|
|
||||||
|
CPPFLAGS=-I$HOME/boost acprep --boost=xgcc42 update
|
||||||
|
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
|
- Q: Configure fails saying it can't find MPFR
|
||||||
|
|
||||||
|
A: You need MPFR version 2.4.0 or higher. This version does not come with
|
||||||
|
most Debian distributions, so you will need to build it.
|
||||||
|
|
||||||
|
----------------------------------------------------------------------
|
||||||
|
|
||||||
|
- Q: Something else fails, or Ledger crashes on startup
|
||||||
|
|
||||||
|
A: This, I am most interested in hearing about. Please e-mail me a copy of
|
||||||
|
config.log and your build log to <johnw@newartisans.com>. Also, if
|
||||||
|
Ledger is crashing, try running it under gdb like so:
|
||||||
|
|
||||||
|
$ gdb ledger
|
||||||
|
(gdb) run <ARGS TO LEDGER>
|
||||||
|
... runs till crash ...
|
||||||
|
(gdb) bt
|
||||||
|
|
||||||
|
Send me that backtrace output, and the output from "ledger --version".
|
||||||
|
|
||||||
|
----------------------------------------------------------------------
|
||||||
216
acprep
216
acprep
|
|
@ -293,7 +293,7 @@ class PrepareBuild(CommandLineApp):
|
||||||
else:
|
else:
|
||||||
cmd = 'config'
|
cmd = 'config'
|
||||||
|
|
||||||
self.log.debug('Invoking primary phase: ' + cmd)
|
self.log.info('Invoking primary phase: ' + cmd)
|
||||||
PrepareBuild.__dict__['phase_' + cmd](self, *args)
|
PrepareBuild.__dict__['phase_' + cmd](self, *args)
|
||||||
|
|
||||||
#########################################################################
|
#########################################################################
|
||||||
|
|
@ -364,7 +364,7 @@ class PrepareBuild(CommandLineApp):
|
||||||
|
|
||||||
def ensure(self, dirname):
|
def ensure(self, dirname):
|
||||||
if not exists(dirname):
|
if not exists(dirname):
|
||||||
self.log.debug('Making directory: ' + dirname)
|
self.log.info('Making directory: ' + dirname)
|
||||||
os.makedirs(dirname)
|
os.makedirs(dirname)
|
||||||
elif not isdir(dirname):
|
elif not isdir(dirname):
|
||||||
self.log.error('Directory is not a directory: ' + dirname)
|
self.log.error('Directory is not a directory: ' + dirname)
|
||||||
|
|
@ -396,11 +396,11 @@ class PrepareBuild(CommandLineApp):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def phase_products(self, *args):
|
def phase_products(self, *args):
|
||||||
self.log.debug('Executing phase: products')
|
self.log.info('Executing phase: products')
|
||||||
print self.products_directory()
|
print self.products_directory()
|
||||||
|
|
||||||
def phase_info(self, *args):
|
def phase_info(self, *args):
|
||||||
self.log.debug('Executing phase: info')
|
self.log.info('Executing phase: info')
|
||||||
|
|
||||||
environ, conf_args = self.configure_environment()
|
environ, conf_args = self.configure_environment()
|
||||||
|
|
||||||
|
|
@ -433,7 +433,7 @@ class PrepareBuild(CommandLineApp):
|
||||||
self.log.debug(' %s' % arg)
|
self.log.debug(' %s' % arg)
|
||||||
|
|
||||||
def phase_sloc(self, *args):
|
def phase_sloc(self, *args):
|
||||||
self.log.debug('Executing phase: sloc')
|
self.log.info('Executing phase: sloc')
|
||||||
self.execute('sloccount', 'src', 'python', 'lisp', 'test')
|
self.execute('sloccount', 'src', 'python', 'lisp', 'test')
|
||||||
|
|
||||||
#########################################################################
|
#########################################################################
|
||||||
|
|
@ -441,13 +441,13 @@ class PrepareBuild(CommandLineApp):
|
||||||
#########################################################################
|
#########################################################################
|
||||||
|
|
||||||
def phase_gettext(self, *args):
|
def phase_gettext(self, *args):
|
||||||
self.log.debug('Executing phase: gettext')
|
self.log.info('Executing phase: gettext')
|
||||||
|
|
||||||
# configure the template files
|
# configure the template files
|
||||||
assert exists('po') and isdir('po')
|
assert exists('po') and isdir('po')
|
||||||
if not exists(join('po', 'Makevars')):
|
if not exists(join('po', 'Makevars')):
|
||||||
assert exists(join('po', 'Makevars.template'))
|
assert exists(join('po', 'Makevars.template'))
|
||||||
self.log.debug('Moving po/Makevars.template -> po/Makevars')
|
self.log.info('Moving po/Makevars.template -> po/Makevars')
|
||||||
os.rename(join('po', 'Makevars.template'),
|
os.rename(join('po', 'Makevars.template'),
|
||||||
join('po', 'Makevars'))
|
join('po', 'Makevars'))
|
||||||
|
|
||||||
|
|
@ -460,22 +460,36 @@ class PrepareBuild(CommandLineApp):
|
||||||
POTFILES_in.close()
|
POTFILES_in.close()
|
||||||
|
|
||||||
def phase_version(self, *args):
|
def phase_version(self, *args):
|
||||||
self.log.debug('Executing phase: version')
|
self.log.info('Executing phase: version')
|
||||||
version_m4 = open('version.m4', 'w')
|
version_m4 = open('version.m4', 'w')
|
||||||
version_m4.write("m4_define([VERSION_NUMBER], [%s])" %
|
version_m4.write("m4_define([VERSION_NUMBER], [%s])" %
|
||||||
self.current_version())
|
self.current_version())
|
||||||
version_m4.close()
|
version_m4.close()
|
||||||
|
|
||||||
def phase_autogen(self, *args):
|
def phase_autogen(self, *args):
|
||||||
self.log.debug('Executing phase: autogen')
|
self.log.info('Executing phase: autogen')
|
||||||
self.execute('sh', 'autogen.sh')
|
|
||||||
|
if not exists('autogen.sh') or \
|
||||||
|
self.isnewer('tools/autogen.sh', 'autogen.sh'):
|
||||||
|
shutil.copyfile('tools/autogen.sh', 'autogen.sh')
|
||||||
|
|
||||||
|
self.execute('sh', 'tools/autogen.sh')
|
||||||
|
|
||||||
def phase_aclocal(self, *args):
|
def phase_aclocal(self, *args):
|
||||||
self.log.debug('Executing phase: aclocal')
|
self.log.info('Executing phase: aclocal')
|
||||||
self.execute('aclocal', '-I', 'm4')
|
self.execute('aclocal', '-I', 'm4')
|
||||||
|
|
||||||
def phase_autoconf(self, *args):
|
def phase_autoconf(self, *args):
|
||||||
self.log.debug('Executing phase: autoconf')
|
self.log.info('Executing phase: autoconf')
|
||||||
|
|
||||||
|
if not exists('configure.ac') or \
|
||||||
|
self.isnewer('tools/configure.ac', 'configure.ac'):
|
||||||
|
shutil.copyfile('tools/configure.ac', 'configure.ac')
|
||||||
|
|
||||||
|
if not exists('Makefile.am') or \
|
||||||
|
self.isnewer('tools/Makefile.am', 'Makefile.am'):
|
||||||
|
shutil.copyfile('tools/Makefile.am', 'Makefile.am')
|
||||||
|
|
||||||
reason = self.need_to_prepare_autotools()
|
reason = self.need_to_prepare_autotools()
|
||||||
if reason:
|
if reason:
|
||||||
self.log.info('autogen.sh must be run ' + reason)
|
self.log.info('autogen.sh must be run ' + reason)
|
||||||
|
|
@ -491,13 +505,13 @@ class PrepareBuild(CommandLineApp):
|
||||||
#########################################################################
|
#########################################################################
|
||||||
|
|
||||||
def phase_submodule(self, *args):
|
def phase_submodule(self, *args):
|
||||||
self.log.debug('Executing phase: submodule')
|
self.log.info('Executing phase: submodule')
|
||||||
if exists('.git') and isdir('.git'):
|
if exists('.git') and isdir('.git'):
|
||||||
self.execute('git', 'submodule', 'init')
|
self.execute('git', 'submodule', 'init')
|
||||||
self.execute('git', 'submodule', 'update')
|
self.execute('git', 'submodule', 'update')
|
||||||
|
|
||||||
def phase_pull(self, *args):
|
def phase_pull(self, *args):
|
||||||
self.log.debug('Executing phase: pull')
|
self.log.info('Executing phase: pull')
|
||||||
if not exists('.git') and not isdir('.git'):
|
if not exists('.git') and not isdir('.git'):
|
||||||
self.log.error("This is not a Git clone.")
|
self.log.error("This is not a Git clone.")
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
@ -509,7 +523,7 @@ class PrepareBuild(CommandLineApp):
|
||||||
#########################################################################
|
#########################################################################
|
||||||
|
|
||||||
def phase_dependencies(self, *args):
|
def phase_dependencies(self, *args):
|
||||||
self.log.debug('Executing phase: dependencies')
|
self.log.info('Executing phase: dependencies')
|
||||||
|
|
||||||
self.log.info("Installing Ledger's build dependencies ...")
|
self.log.info("Installing Ledger's build dependencies ...")
|
||||||
|
|
||||||
|
|
@ -581,7 +595,7 @@ class PrepareBuild(CommandLineApp):
|
||||||
self.execute(*packages)
|
self.execute(*packages)
|
||||||
|
|
||||||
def phase_buildlibs(self, *args):
|
def phase_buildlibs(self, *args):
|
||||||
self.log.debug('Executing phase: buildlibs')
|
self.log.info('Executing phase: buildlibs')
|
||||||
|
|
||||||
try:
|
try:
|
||||||
os.chdir('lib')
|
os.chdir('lib')
|
||||||
|
|
@ -645,12 +659,12 @@ class PrepareBuild(CommandLineApp):
|
||||||
entries.sort()
|
entries.sort()
|
||||||
for entry in entries:
|
for entry in entries:
|
||||||
if re.search('boost_regex', entry):
|
if re.search('boost_regex', entry):
|
||||||
self.log.debug('Found a Boost library: ' + entry)
|
self.log.info('Found a Boost library: ' + entry)
|
||||||
|
|
||||||
match = re.match('libboost_regex([^.]*)\.(a|so|dylib)', entry)
|
match = re.match('libboost_regex([^.]*)\.(a|so|dylib)', entry)
|
||||||
if match:
|
if match:
|
||||||
suffix = match.group(1)
|
suffix = match.group(1)
|
||||||
self.log.debug('Found Boost suffix => ' + suffix)
|
self.log.info('Found Boost suffix => ' + suffix)
|
||||||
self.envvars['BOOST_HOME'] = dirname(path)
|
self.envvars['BOOST_HOME'] = dirname(path)
|
||||||
return suffix
|
return suffix
|
||||||
else:
|
else:
|
||||||
|
|
@ -660,20 +674,20 @@ class PrepareBuild(CommandLineApp):
|
||||||
|
|
||||||
def locate_boost(self):
|
def locate_boost(self):
|
||||||
if self.envvars['BOOST_SUFFIX']:
|
if self.envvars['BOOST_SUFFIX']:
|
||||||
self.log.debug(("Not looking for Boost, since " +
|
self.log.info(("Not looking for Boost, since " +
|
||||||
"a suffix of '%s' was given") %
|
"a suffix of '%s' was given") %
|
||||||
self.envvars['BOOST_SUFFIX'])
|
self.envvars['BOOST_SUFFIX'])
|
||||||
else:
|
else:
|
||||||
suffix = None
|
suffix = None
|
||||||
for path in ['/usr/local/lib', '/opt/local/lib',
|
for path in ['/usr/local/lib', '/opt/local/lib',
|
||||||
'/sw/lib', '/usr/lib']:
|
'/sw/lib', '/usr/lib']:
|
||||||
self.log.debug('Looking for Boost in %s...' % path)
|
self.log.info('Looking for Boost in %s...' % path)
|
||||||
suffix = self.locate_boost_in_dir(path)
|
suffix = self.locate_boost_in_dir(path)
|
||||||
if suffix is not None:
|
if suffix is not None:
|
||||||
self.log.debug('Boost is located here:')
|
self.log.info('Boost is located here:')
|
||||||
self.log.debug('BOOST_HOME => ' +
|
self.log.info('BOOST_HOME => ' +
|
||||||
self.envvars['BOOST_HOME'])
|
self.envvars['BOOST_HOME'])
|
||||||
self.log.debug('BOOST_SUFFIX => ' + suffix)
|
self.log.info('BOOST_SUFFIX => ' + suffix)
|
||||||
break
|
break
|
||||||
if suffix is None:
|
if suffix is None:
|
||||||
self.log.error("Boost could not be found.")
|
self.log.error("Boost could not be found.")
|
||||||
|
|
@ -695,7 +709,7 @@ class PrepareBuild(CommandLineApp):
|
||||||
'/sw/include']:
|
'/sw/include']:
|
||||||
if exists(path) and isdir(path) and \
|
if exists(path) and isdir(path) and \
|
||||||
path != '/usr/include':
|
path != '/usr/include':
|
||||||
self.log.debug('Noticing include directory => ' + path)
|
self.log.info('Noticing include directory => ' + path)
|
||||||
self.sys_include_dirs.append(path)
|
self.sys_include_dirs.append(path)
|
||||||
|
|
||||||
# Each of these becomes '-L<name>'
|
# Each of these becomes '-L<name>'
|
||||||
|
|
@ -707,17 +721,19 @@ class PrepareBuild(CommandLineApp):
|
||||||
'/opt/local/lib',
|
'/opt/local/lib',
|
||||||
'/sw/lib']:
|
'/sw/lib']:
|
||||||
if exists(path) and isdir(path):
|
if exists(path) and isdir(path):
|
||||||
self.log.debug('Noticing library directory => ' + path)
|
self.log.info('Noticing library directory => ' + path)
|
||||||
self.sys_library_dirs.append(path)
|
self.sys_library_dirs.append(path)
|
||||||
|
|
||||||
def setup_for_johnw(self):
|
def setup_for_johnw(self):
|
||||||
# jww (2009-03-09): Some peculiarities specific to my system
|
# jww (2009-03-09): Some peculiarities specific to my system
|
||||||
if exists('/usr/local/stow/cppunit/include'):
|
if exists('/Users/johnw/Dropbox/Accounts/ledger.dat'):
|
||||||
self.sys_include_dirs.insert(0, '/usr/local/stow/cppunit/include')
|
if exists('/usr/local/stow/cppunit/include'):
|
||||||
self.sys_library_dirs.insert(0, '/usr/local/stow/cppunit/lib')
|
self.sys_include_dirs.insert(0, '/usr/local/stow/cppunit/include')
|
||||||
|
self.sys_library_dirs.insert(0, '/usr/local/stow/cppunit/lib')
|
||||||
|
|
||||||
self.CXXFLAGS.append('-march=nocona')
|
self.CXXFLAGS.append('-march=nocona')
|
||||||
self.CXXFLAGS.append('-msse3')
|
self.CXXFLAGS.append('-msse3')
|
||||||
|
self.CPPFLAGS.append('-D_GLIBCXX_FULLY_DYNAMIC_STRING=1')
|
||||||
|
|
||||||
self.options.use_glibcxx_debug = True
|
self.options.use_glibcxx_debug = True
|
||||||
|
|
||||||
|
|
@ -726,7 +742,7 @@ class PrepareBuild(CommandLineApp):
|
||||||
|
|
||||||
system = self.get_stdout('uname', '-s')
|
system = self.get_stdout('uname', '-s')
|
||||||
|
|
||||||
self.log.debug('System type is => ' + system)
|
self.log.info('System type is => ' + system)
|
||||||
|
|
||||||
# These options are global defaults at the moment
|
# These options are global defaults at the moment
|
||||||
#self.option_warn()
|
#self.option_warn()
|
||||||
|
|
@ -796,7 +812,7 @@ class PrepareBuild(CommandLineApp):
|
||||||
self.log.error('Unknown build flavor "%s"' % self.current_flavor)
|
self.log.error('Unknown build flavor "%s"' % self.current_flavor)
|
||||||
sys.exit(1)
|
sys.exit(1)
|
||||||
|
|
||||||
self.log.debug('Setting up build flavor => ' + self.current_flavor)
|
self.log.info('Setting up build flavor => ' + self.current_flavor)
|
||||||
PrepareBuild.__dict__['setup_flavor_' + self.current_flavor](self)
|
PrepareBuild.__dict__['setup_flavor_' + self.current_flavor](self)
|
||||||
|
|
||||||
self.setup_flags()
|
self.setup_flags()
|
||||||
|
|
@ -927,23 +943,23 @@ class PrepareBuild(CommandLineApp):
|
||||||
#########################################################################
|
#########################################################################
|
||||||
|
|
||||||
def setup_flavor_default(self):
|
def setup_flavor_default(self):
|
||||||
if exists('/usr/local/lib/libboost_regex-xgcc44-s-1_40.a'):
|
if exists('/opt/local/lib/libboost_regex.a'):
|
||||||
self.envvars['BOOST_HOME'] = '/usr/local'
|
|
||||||
self.envvars['BOOST_SUFFIX'] = '-xgcc44-s-1_40'
|
|
||||||
self.log.debug('Setting BOOST_SUFFIX => %s' %
|
|
||||||
self.envvars['BOOST_SUFFIX'])
|
|
||||||
|
|
||||||
self.sys_include_dirs.append('/usr/local/include/boost-1_40')
|
|
||||||
|
|
||||||
elif exists('/opt/local/lib/libboost_regex.a'):
|
|
||||||
self.envvars['BOOST_HOME'] = '/opt/local'
|
self.envvars['BOOST_HOME'] = '/opt/local'
|
||||||
self.envvars['BOOST_SUFFIX'] = ''
|
self.envvars['BOOST_SUFFIX'] = ''
|
||||||
|
|
||||||
self.log.debug('Setting BOOST_SUFFIX => %s' %
|
self.log.info('Setting BOOST_SUFFIX => %s' %
|
||||||
self.envvars['BOOST_SUFFIX'])
|
self.envvars['BOOST_SUFFIX'])
|
||||||
|
|
||||||
self.sys_include_dirs.append('/opt/local/include/boost')
|
self.sys_include_dirs.append('/opt/local/include/boost')
|
||||||
|
|
||||||
|
elif exists('/usr/local/lib/libboost_regex-xgcc44-s-1_40.a'):
|
||||||
|
self.envvars['BOOST_HOME'] = '/usr/local'
|
||||||
|
self.envvars['BOOST_SUFFIX'] = '-xgcc44-s-1_40'
|
||||||
|
self.log.info('Setting BOOST_SUFFIX => %s' %
|
||||||
|
self.envvars['BOOST_SUFFIX'])
|
||||||
|
|
||||||
|
self.sys_include_dirs.append('/usr/local/include/boost-1_40')
|
||||||
|
|
||||||
def setup_flavor_debug(self):
|
def setup_flavor_debug(self):
|
||||||
self.configure_args.append('--enable-debug')
|
self.configure_args.append('--enable-debug')
|
||||||
|
|
||||||
|
|
@ -960,64 +976,65 @@ class PrepareBuild(CommandLineApp):
|
||||||
self.sys_include_dirs.remove('/usr/local/stow/cppunit/include')
|
self.sys_include_dirs.remove('/usr/local/stow/cppunit/include')
|
||||||
self.sys_library_dirs.remove('/usr/local/stow/cppunit/lib')
|
self.sys_library_dirs.remove('/usr/local/stow/cppunit/lib')
|
||||||
|
|
||||||
self.sys_include_dirs.insert(0, '/usr/local/stow/cppunit-debug/include')
|
if exists('/usr/local/stow/cppunit-debug/include'):
|
||||||
self.sys_library_dirs.insert(0, '/usr/local/stow/cppunit-debug/lib')
|
self.sys_include_dirs.insert(0, '/usr/local/stow/cppunit-debug/include')
|
||||||
|
self.sys_library_dirs.insert(0, '/usr/local/stow/cppunit-debug/lib')
|
||||||
|
|
||||||
if exists('/usr/local/lib/libboost_regex-xgcc44-sd-1_40.a'):
|
if exists('/opt/local/lib/libboost_regex-d.a'):
|
||||||
self.envvars['BOOST_HOME'] = '/usr/local'
|
|
||||||
self.envvars['BOOST_SUFFIX'] = '-xgcc44-sd-1_40'
|
|
||||||
self.log.debug('Setting BOOST_SUFFIX => %s' %
|
|
||||||
self.envvars['BOOST_SUFFIX'])
|
|
||||||
|
|
||||||
self.sys_include_dirs.append('/usr/local/include/boost-1_40')
|
|
||||||
|
|
||||||
elif exists('/opt/local/lib/libboost_regex-d.a'):
|
|
||||||
self.envvars['BOOST_HOME'] = '/opt/local'
|
self.envvars['BOOST_HOME'] = '/opt/local'
|
||||||
self.envvars['BOOST_SUFFIX'] = '-d'
|
self.envvars['BOOST_SUFFIX'] = '-d'
|
||||||
|
|
||||||
self.log.debug('Setting BOOST_SUFFIX => %s' %
|
self.log.info('Setting BOOST_SUFFIX => %s' %
|
||||||
self.envvars['BOOST_SUFFIX'])
|
self.envvars['BOOST_SUFFIX'])
|
||||||
|
|
||||||
self.sys_include_dirs.append('/opt/local/include/boost')
|
self.sys_include_dirs.append('/opt/local/include/boost')
|
||||||
else:
|
|
||||||
if exists('/usr/local/lib/libboost_regex-xgcc44-s-1_40.a'):
|
elif exists('/usr/local/lib/libboost_regex-xgcc44-sd-1_40.a'):
|
||||||
self.envvars['BOOST_HOME'] = '/usr/local'
|
self.envvars['BOOST_HOME'] = '/usr/local'
|
||||||
self.envvars['BOOST_SUFFIX'] = '-xgcc44-s-1_40'
|
self.envvars['BOOST_SUFFIX'] = '-xgcc44-sd-1_40'
|
||||||
self.log.debug('Setting BOOST_SUFFIX => %s' %
|
self.log.info('Setting BOOST_SUFFIX => %s' %
|
||||||
self.envvars['BOOST_SUFFIX'])
|
self.envvars['BOOST_SUFFIX'])
|
||||||
|
|
||||||
self.sys_include_dirs.append('/usr/local/include/boost-1_40')
|
self.sys_include_dirs.append('/usr/local/include/boost-1_40')
|
||||||
|
else:
|
||||||
elif exists('/opt/local/lib/libboost_regex.a'):
|
if exists('/opt/local/lib/libboost_regex.a'):
|
||||||
self.envvars['BOOST_HOME'] = '/opt/local'
|
self.envvars['BOOST_HOME'] = '/opt/local'
|
||||||
self.envvars['BOOST_SUFFIX'] = ''
|
self.envvars['BOOST_SUFFIX'] = ''
|
||||||
|
|
||||||
self.log.debug('Setting BOOST_SUFFIX => %s' %
|
self.log.info('Setting BOOST_SUFFIX => %s' %
|
||||||
self.envvars['BOOST_SUFFIX'])
|
self.envvars['BOOST_SUFFIX'])
|
||||||
|
|
||||||
self.sys_include_dirs.append('/opt/local/include/boost')
|
self.sys_include_dirs.append('/opt/local/include/boost')
|
||||||
|
|
||||||
|
elif exists('/usr/local/lib/libboost_regex-xgcc44-s-1_40.a'):
|
||||||
|
self.envvars['BOOST_HOME'] = '/usr/local'
|
||||||
|
self.envvars['BOOST_SUFFIX'] = '-xgcc44-s-1_40'
|
||||||
|
self.log.info('Setting BOOST_SUFFIX => %s' %
|
||||||
|
self.envvars['BOOST_SUFFIX'])
|
||||||
|
|
||||||
|
self.sys_include_dirs.append('/usr/local/include/boost-1_40')
|
||||||
|
|
||||||
def setup_flavor_opt(self):
|
def setup_flavor_opt(self):
|
||||||
self.CXXFLAGS.append('-O3')
|
self.CXXFLAGS.append('-O3')
|
||||||
self.CXXFLAGS.append('-fomit-frame-pointer')
|
self.CXXFLAGS.append('-fomit-frame-pointer')
|
||||||
|
|
||||||
if exists('/usr/local/lib/libboost_regex-xgcc44-s-1_40.a'):
|
if exists('/opt/local/lib/libboost_regex.a'):
|
||||||
self.envvars['BOOST_HOME'] = '/usr/local'
|
|
||||||
self.envvars['BOOST_SUFFIX'] = '-xgcc44-s-1_40'
|
|
||||||
self.log.debug('Setting BOOST_SUFFIX => %s' %
|
|
||||||
self.envvars['BOOST_SUFFIX'])
|
|
||||||
|
|
||||||
self.sys_include_dirs.append('/usr/local/include/boost-1_40')
|
|
||||||
|
|
||||||
elif exists('/opt/local/lib/libboost_regex.a'):
|
|
||||||
self.envvars['BOOST_HOME'] = '/opt/local'
|
self.envvars['BOOST_HOME'] = '/opt/local'
|
||||||
self.envvars['BOOST_SUFFIX'] = ''
|
self.envvars['BOOST_SUFFIX'] = ''
|
||||||
|
|
||||||
self.log.debug('Setting BOOST_SUFFIX => %s' %
|
self.log.info('Setting BOOST_SUFFIX => %s' %
|
||||||
self.envvars['BOOST_SUFFIX'])
|
self.envvars['BOOST_SUFFIX'])
|
||||||
|
|
||||||
self.sys_include_dirs.append('/opt/local/include/boost')
|
self.sys_include_dirs.append('/opt/local/include/boost')
|
||||||
|
|
||||||
|
elif exists('/usr/local/lib/libboost_regex-xgcc44-s-1_40.a'):
|
||||||
|
self.envvars['BOOST_HOME'] = '/usr/local'
|
||||||
|
self.envvars['BOOST_SUFFIX'] = '-xgcc44-s-1_40'
|
||||||
|
self.log.info('Setting BOOST_SUFFIX => %s' %
|
||||||
|
self.envvars['BOOST_SUFFIX'])
|
||||||
|
|
||||||
|
self.sys_include_dirs.append('/usr/local/include/boost-1_40')
|
||||||
|
|
||||||
def setup_flavor_gcov(self):
|
def setup_flavor_gcov(self):
|
||||||
self.CXXFLAGS.append('-g')
|
self.CXXFLAGS.append('-g')
|
||||||
self.CXXFLAGS.append('-fprofile-arcs')
|
self.CXXFLAGS.append('-fprofile-arcs')
|
||||||
|
|
@ -1038,7 +1055,7 @@ class PrepareBuild(CommandLineApp):
|
||||||
"""Alter the Makefile so that it's not nearly so verbose.
|
"""Alter the Makefile so that it's not nearly so verbose.
|
||||||
|
|
||||||
This makes errors and warnings much easier to spot."""
|
This makes errors and warnings much easier to spot."""
|
||||||
self.log.debug('Executing phase: patch')
|
self.log.info('Executing phase: patch')
|
||||||
|
|
||||||
if exists('Makefile'):
|
if exists('Makefile'):
|
||||||
self.log.debug('Patching generated Makefile')
|
self.log.debug('Patching generated Makefile')
|
||||||
|
|
@ -1108,7 +1125,7 @@ class PrepareBuild(CommandLineApp):
|
||||||
return False
|
return False
|
||||||
|
|
||||||
def phase_configure(self, *args):
|
def phase_configure(self, *args):
|
||||||
self.log.debug('Executing phase: configure')
|
self.log.info('Executing phase: configure')
|
||||||
|
|
||||||
self.configured = True
|
self.configured = True
|
||||||
|
|
||||||
|
|
@ -1130,7 +1147,10 @@ class PrepareBuild(CommandLineApp):
|
||||||
self.log.debug('configure args => ' + str(conf_args))
|
self.log.debug('configure args => ' + str(conf_args))
|
||||||
|
|
||||||
configure = Popen(conf_args, shell=False, env=environ)
|
configure = Popen(conf_args, shell=False, env=environ)
|
||||||
configure.wait()
|
retcode = configure.wait()
|
||||||
|
if retcode < 0:
|
||||||
|
self.log.error("Child was terminated by signal", -retcode)
|
||||||
|
sys.exit(1)
|
||||||
|
|
||||||
if not self.options.no_patch:
|
if not self.options.no_patch:
|
||||||
self.phase_patch()
|
self.phase_patch()
|
||||||
|
|
@ -1145,7 +1165,7 @@ class PrepareBuild(CommandLineApp):
|
||||||
os.chdir(self.source_dir)
|
os.chdir(self.source_dir)
|
||||||
|
|
||||||
def phase_config(self, *args):
|
def phase_config(self, *args):
|
||||||
self.log.debug('Executing phase: config')
|
self.log.info('Executing phase: config')
|
||||||
self.phase_submodule()
|
self.phase_submodule()
|
||||||
self.phase_autoconf()
|
self.phase_autoconf()
|
||||||
self.phase_configure(*args)
|
self.phase_configure(*args)
|
||||||
|
|
@ -1157,7 +1177,7 @@ class PrepareBuild(CommandLineApp):
|
||||||
#########################################################################
|
#########################################################################
|
||||||
|
|
||||||
def phase_make(self, *args):
|
def phase_make(self, *args):
|
||||||
self.log.debug('Executing phase: make')
|
self.log.info('Executing phase: make')
|
||||||
|
|
||||||
config_args = []
|
config_args = []
|
||||||
make_args = []
|
make_args = []
|
||||||
|
|
@ -1182,15 +1202,12 @@ class PrepareBuild(CommandLineApp):
|
||||||
self.log.debug('Changing directory to ' + build_dir)
|
self.log.debug('Changing directory to ' + build_dir)
|
||||||
os.chdir(build_dir)
|
os.chdir(build_dir)
|
||||||
|
|
||||||
self.log.debug('make args => ' + str(make_args))
|
self.execute(*(['make'] + make_args))
|
||||||
|
|
||||||
configure = Popen(['make'] + make_args, shell=False)
|
|
||||||
configure.wait()
|
|
||||||
finally:
|
finally:
|
||||||
os.chdir(self.source_dir)
|
os.chdir(self.source_dir)
|
||||||
|
|
||||||
def phase_update(self, *args):
|
def phase_update(self, *args):
|
||||||
self.log.debug('Executing phase: update')
|
self.log.info('Executing phase: update')
|
||||||
self.phase_pull()
|
self.phase_pull()
|
||||||
self.phase_make(*args)
|
self.phase_make(*args)
|
||||||
|
|
||||||
|
|
@ -1199,15 +1216,15 @@ class PrepareBuild(CommandLineApp):
|
||||||
#########################################################################
|
#########################################################################
|
||||||
|
|
||||||
def phase_clean(self, *args):
|
def phase_clean(self, *args):
|
||||||
self.log.debug('Executing phase: clean')
|
self.log.info('Executing phase: clean')
|
||||||
self.phase_make('clean')
|
self.phase_make('clean')
|
||||||
|
|
||||||
def phase_distclean(self, *args):
|
def phase_distclean(self, *args):
|
||||||
self.log.debug('Executing phase: distclean')
|
self.log.info('Executing phase: distclean')
|
||||||
self.phase_make('distclean')
|
self.phase_make('distclean')
|
||||||
|
|
||||||
def phase_gitclean(self, *args):
|
def phase_gitclean(self, *args):
|
||||||
self.log.debug('Executing phase: gitclean')
|
self.log.info('Executing phase: gitclean')
|
||||||
self.execute('git', 'clean', '-dfx')
|
self.execute('git', 'clean', '-dfx')
|
||||||
|
|
||||||
#########################################################################
|
#########################################################################
|
||||||
|
|
@ -1238,7 +1255,7 @@ class PrepareBuild(CommandLineApp):
|
||||||
'@loader_path/' + base, dest_file)
|
'@loader_path/' + base, dest_file)
|
||||||
|
|
||||||
def phase_bindmg(self, *args):
|
def phase_bindmg(self, *args):
|
||||||
self.log.debug('Executing phase: bindmg')
|
self.log.info('Executing phase: bindmg')
|
||||||
|
|
||||||
self.phase_make()
|
self.phase_make()
|
||||||
|
|
||||||
|
|
@ -1263,7 +1280,7 @@ class PrepareBuild(CommandLineApp):
|
||||||
shutil.rmtree(tempdir)
|
shutil.rmtree(tempdir)
|
||||||
|
|
||||||
def phase_upload(self, *args):
|
def phase_upload(self, *args):
|
||||||
self.log.debug('Executing phase: upload')
|
self.log.info('Executing phase: upload')
|
||||||
|
|
||||||
self.phase_bindmg()
|
self.phase_bindmg()
|
||||||
|
|
||||||
|
|
@ -1295,7 +1312,7 @@ class PrepareBuild(CommandLineApp):
|
||||||
shutil.rmtree(self.build_directory())
|
shutil.rmtree(self.build_directory())
|
||||||
|
|
||||||
def phase_distcheck(self, *args):
|
def phase_distcheck(self, *args):
|
||||||
self.log.debug('Executing phase: distcheck')
|
self.log.info('Executing phase: distcheck')
|
||||||
|
|
||||||
self.configure_flavor('default', False)
|
self.configure_flavor('default', False)
|
||||||
|
|
||||||
|
|
@ -1320,7 +1337,7 @@ class PrepareBuild(CommandLineApp):
|
||||||
self.phase_make(*make_args)
|
self.phase_make(*make_args)
|
||||||
|
|
||||||
def phase_rsync(self, *args):
|
def phase_rsync(self, *args):
|
||||||
self.log.debug('Executing phase: rsync')
|
self.log.info('Executing phase: rsync')
|
||||||
|
|
||||||
source_copy_dir = join(self.ensure(self.products_directory()),
|
source_copy_dir = join(self.ensure(self.products_directory()),
|
||||||
'ledger-proof')
|
'ledger-proof')
|
||||||
|
|
@ -1332,32 +1349,28 @@ class PrepareBuild(CommandLineApp):
|
||||||
self.source_dir = source_copy_dir
|
self.source_dir = source_copy_dir
|
||||||
|
|
||||||
def phase_proof(self, *args):
|
def phase_proof(self, *args):
|
||||||
self.log.debug('Executing phase: proof')
|
self.log.info('Executing phase: proof')
|
||||||
|
|
||||||
|
self.phase_makeall(*args)
|
||||||
|
|
||||||
self.log.info('=== Copying source tree ===')
|
self.log.info('=== Copying source tree ===')
|
||||||
self.phase_rsync()
|
self.phase_rsync()
|
||||||
|
|
||||||
|
self.phase_makeall(*args)
|
||||||
|
|
||||||
self.configure_flavor('opt')
|
self.configure_flavor('opt')
|
||||||
self.log.info('=== Building opt ===')
|
|
||||||
self.phase_make(*args)
|
|
||||||
self.log.info('=== Testing opt ===')
|
self.log.info('=== Testing opt ===')
|
||||||
self.phase_make('fullcheck')
|
self.phase_make('fullcheck')
|
||||||
|
|
||||||
self.configure_flavor('gcov')
|
self.configure_flavor('gcov')
|
||||||
self.log.info('=== Building gcov ===')
|
|
||||||
self.phase_make(*args)
|
|
||||||
self.log.info('=== Testing gcov ===')
|
self.log.info('=== Testing gcov ===')
|
||||||
self.phase_make('check')
|
self.phase_make('check')
|
||||||
|
|
||||||
self.configure_flavor('debug')
|
self.configure_flavor('debug')
|
||||||
self.log.info('=== Building debug ===')
|
|
||||||
self.phase_make(*args)
|
|
||||||
self.log.info('=== Testing debug ===')
|
self.log.info('=== Testing debug ===')
|
||||||
self.phase_make('fullcheck')
|
self.phase_make('fullcheck')
|
||||||
|
|
||||||
self.configure_flavor('default')
|
self.configure_flavor('default')
|
||||||
self.log.info('=== Building default ===')
|
|
||||||
self.phase_make(*args)
|
|
||||||
self.log.info('=== Testing default ===')
|
self.log.info('=== Testing default ===')
|
||||||
self.phase_make('fullcheck')
|
self.phase_make('fullcheck')
|
||||||
|
|
||||||
|
|
@ -1365,7 +1378,7 @@ class PrepareBuild(CommandLineApp):
|
||||||
self.phase_distcheck()
|
self.phase_distcheck()
|
||||||
|
|
||||||
def phase_makeall(self, *args):
|
def phase_makeall(self, *args):
|
||||||
self.log.debug('Executing phase: makeall')
|
self.log.info('Executing phase: makeall')
|
||||||
|
|
||||||
self.configure_flavor('opt', False)
|
self.configure_flavor('opt', False)
|
||||||
|
|
||||||
|
|
@ -1403,11 +1416,6 @@ class PrepareBuild(CommandLineApp):
|
||||||
|
|
||||||
self.configure_flavor('default', False)
|
self.configure_flavor('default', False)
|
||||||
|
|
||||||
def phase_do_all(self, *args):
|
|
||||||
self.log.debug('Executing phase: do_all')
|
|
||||||
self.phase_makeall(*args)
|
|
||||||
self.phase_proof(*args)
|
|
||||||
|
|
||||||
#########################################################################
|
#########################################################################
|
||||||
# Help #
|
# Help #
|
||||||
#########################################################################
|
#########################################################################
|
||||||
|
|
|
||||||
0
autogen.sh
Executable file → Normal file
0
autogen.sh
Executable file → Normal file
32
configure.ac
32
configure.ac
|
|
@ -280,6 +280,38 @@ else
|
||||||
AC_MSG_FAILURE("Could not find boost_iostreams library (set CPPFLAGS and LDFLAGS?)")
|
AC_MSG_FAILURE("Could not find boost_iostreams library (set CPPFLAGS and LDFLAGS?)")
|
||||||
fi
|
fi
|
||||||
|
|
||||||
|
# check for boost_serialization
|
||||||
|
AC_CACHE_CHECK(
|
||||||
|
[if boost_serialization is available],
|
||||||
|
[boost_serialization_cpplib_avail_cv_],
|
||||||
|
[boost_serialization_save_libs=$LIBS
|
||||||
|
LIBS="-lboost_serialization$BOOST_SUFFIX -lboost_system$BOOST_SUFFIX $LIBS"
|
||||||
|
AC_LANG_PUSH(C++)
|
||||||
|
AC_LINK_IFELSE(
|
||||||
|
[AC_LANG_PROGRAM(
|
||||||
|
[[#include <boost/archive/binary_oarchive.hpp>
|
||||||
|
#include <iostream>
|
||||||
|
struct foo {
|
||||||
|
int a;
|
||||||
|
template<class Archive>
|
||||||
|
void serialize(Archive & ar, const unsigned int) {
|
||||||
|
ar & a;
|
||||||
|
}
|
||||||
|
};]],
|
||||||
|
[[boost::archive::binary_oarchive oa(std::cout);
|
||||||
|
foo x;
|
||||||
|
oa << x;]])],
|
||||||
|
[boost_serialization_cpplib_avail_cv_=true],
|
||||||
|
[boost_serialization_cpplib_avail_cv_=false])
|
||||||
|
AC_LANG_POP
|
||||||
|
LIBS=$boost_serialization_save_libs])
|
||||||
|
|
||||||
|
if [test x$boost_serialization_cpplib_avail_cv_ = xtrue ]; then
|
||||||
|
AC_DEFINE([HAVE_BOOST_SERIALIZATION], [1], [Whether Boost.Serialization is available])
|
||||||
|
LIBS="-lboost_serialization$BOOST_SUFFIX $LIBS"
|
||||||
|
fi
|
||||||
|
AM_CONDITIONAL(HAVE_BOOST_SERIALIZATION, test x$boost_serialization_cpplib_avail_cv_ = xtrue)
|
||||||
|
|
||||||
# check for Python
|
# check for Python
|
||||||
AM_PATH_PYTHON(2.4,, :)
|
AM_PATH_PYTHON(2.4,, :)
|
||||||
if [test "$PYTHON" != :]; then
|
if [test "$PYTHON" != :]; then
|
||||||
|
|
|
||||||
|
|
@ -4,7 +4,7 @@
|
||||||
|
|
||||||
;; Emacs Lisp Archive Entry
|
;; Emacs Lisp Archive Entry
|
||||||
;; Filename: ledger.el
|
;; Filename: ledger.el
|
||||||
;; Version: 2.7
|
;; Version: 3.0
|
||||||
;; Date: Fri 18-Jul-2008
|
;; Date: Fri 18-Jul-2008
|
||||||
;; Keywords: data
|
;; Keywords: data
|
||||||
;; Author: John Wiegley (johnw AT gnu DOT org)
|
;; Author: John Wiegley (johnw AT gnu DOT org)
|
||||||
|
|
|
||||||
|
|
@ -458,7 +458,7 @@ void account_t::xdata_t::details_t::update(post_t& post,
|
||||||
posts_virtuals_count++;
|
posts_virtuals_count++;
|
||||||
|
|
||||||
if (gather_all)
|
if (gather_all)
|
||||||
filenames.insert(post.pathname);
|
filenames.insert(post.pos->pathname);
|
||||||
|
|
||||||
date_t date = post.date();
|
date_t date = post.date();
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -232,6 +232,26 @@ public:
|
||||||
return xdata_ && xdata_->has_flags(flags);
|
return xdata_ && xdata_->has_flags(flags);
|
||||||
}
|
}
|
||||||
std::size_t children_with_flags(xdata_t::flags_t flags) const;
|
std::size_t children_with_flags(xdata_t::flags_t flags) const;
|
||||||
|
|
||||||
|
#if defined(HAVE_BOOST_SERIALIZATION)
|
||||||
|
private:
|
||||||
|
/** Serialization. */
|
||||||
|
|
||||||
|
friend class boost::serialization::access;
|
||||||
|
|
||||||
|
template<class Archive>
|
||||||
|
void serialize(Archive & ar, const unsigned int /* version */) {
|
||||||
|
ar & boost::serialization::base_object<supports_flags<> >(*this);
|
||||||
|
ar & boost::serialization::base_object<scope_t>(*this);
|
||||||
|
ar & parent;
|
||||||
|
ar & name;
|
||||||
|
ar & note;
|
||||||
|
ar & depth;
|
||||||
|
ar & accounts;
|
||||||
|
ar & posts;
|
||||||
|
ar & _fullname;
|
||||||
|
}
|
||||||
|
#endif // HAVE_BOOST_SERIALIZATION
|
||||||
};
|
};
|
||||||
|
|
||||||
std::ostream& operator<<(std::ostream& out, const account_t& account);
|
std::ostream& operator<<(std::ostream& out, const account_t& account);
|
||||||
|
|
|
||||||
101
src/amount.cc
101
src/amount.cc
|
|
@ -56,25 +56,25 @@ struct amount_t::bigint_t : public supports_flags<>
|
||||||
|
|
||||||
mpq_t val;
|
mpq_t val;
|
||||||
precision_t prec;
|
precision_t prec;
|
||||||
uint_least16_t ref;
|
uint_least16_t refc;
|
||||||
|
|
||||||
#define MP(bigint) ((bigint)->val)
|
#define MP(bigint) ((bigint)->val)
|
||||||
|
|
||||||
bigint_t() : prec(0), ref(1) {
|
bigint_t() : prec(0), refc(1) {
|
||||||
TRACE_CTOR(bigint_t, "");
|
TRACE_CTOR(bigint_t, "");
|
||||||
mpq_init(val);
|
mpq_init(val);
|
||||||
}
|
}
|
||||||
bigint_t(const bigint_t& other)
|
bigint_t(const bigint_t& other)
|
||||||
: supports_flags<>(static_cast<uint_least8_t>
|
: supports_flags<>(static_cast<uint_least8_t>
|
||||||
(other.flags() & ~BIGINT_BULK_ALLOC)),
|
(other.flags() & ~BIGINT_BULK_ALLOC)),
|
||||||
prec(other.prec), ref(1) {
|
prec(other.prec), refc(1) {
|
||||||
TRACE_CTOR(bigint_t, "copy");
|
TRACE_CTOR(bigint_t, "copy");
|
||||||
mpq_init(val);
|
mpq_init(val);
|
||||||
mpq_set(val, other.val);
|
mpq_set(val, other.val);
|
||||||
}
|
}
|
||||||
~bigint_t() {
|
~bigint_t() {
|
||||||
TRACE_DTOR(bigint_t);
|
TRACE_DTOR(bigint_t);
|
||||||
assert(ref == 0);
|
assert(refc == 0);
|
||||||
mpq_clear(val);
|
mpq_clear(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -83,8 +83,8 @@ struct amount_t::bigint_t : public supports_flags<>
|
||||||
DEBUG("ledger.validate", "amount_t::bigint_t: prec > 128");
|
DEBUG("ledger.validate", "amount_t::bigint_t: prec > 128");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (ref > 16535) {
|
if (refc > 16535) {
|
||||||
DEBUG("ledger.validate", "amount_t::bigint_t: ref > 16535");
|
DEBUG("ledger.validate", "amount_t::bigint_t: refc > 16535");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
if (flags() & ~(BIGINT_BULK_ALLOC | BIGINT_KEEP_PREC)) {
|
if (flags() & ~(BIGINT_BULK_ALLOC | BIGINT_KEEP_PREC)) {
|
||||||
|
|
@ -94,6 +94,20 @@ struct amount_t::bigint_t : public supports_flags<>
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(HAVE_BOOST_SERIALIZATION)
|
||||||
|
private:
|
||||||
|
friend class boost::serialization::access;
|
||||||
|
|
||||||
|
template<class Archive>
|
||||||
|
void serialize(Archive& ar, const unsigned int /* version */)
|
||||||
|
{
|
||||||
|
ar & boost::serialization::base_object<supports_flags<> >(*this);
|
||||||
|
ar & val;
|
||||||
|
ar & prec;
|
||||||
|
ar & refc;
|
||||||
|
}
|
||||||
|
#endif // HAVE_BOOST_SERIALIZATION
|
||||||
};
|
};
|
||||||
|
|
||||||
shared_ptr<commodity_pool_t> amount_t::current_pool;
|
shared_ptr<commodity_pool_t> amount_t::current_pool;
|
||||||
|
|
@ -147,8 +161,8 @@ void amount_t::_copy(const amount_t& amt)
|
||||||
} else {
|
} else {
|
||||||
quantity = amt.quantity;
|
quantity = amt.quantity;
|
||||||
DEBUG("amounts.refs",
|
DEBUG("amounts.refs",
|
||||||
quantity << " ref++, now " << (quantity->ref + 1));
|
quantity << " refc++, now " << (quantity->refc + 1));
|
||||||
quantity->ref++;
|
quantity->refc++;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
commodity_ = amt.commodity_;
|
commodity_ = amt.commodity_;
|
||||||
|
|
@ -160,7 +174,7 @@ void amount_t::_dup()
|
||||||
{
|
{
|
||||||
VERIFY(valid());
|
VERIFY(valid());
|
||||||
|
|
||||||
if (quantity->ref > 1) {
|
if (quantity->refc > 1) {
|
||||||
bigint_t * q = new bigint_t(*quantity);
|
bigint_t * q = new bigint_t(*quantity);
|
||||||
_release();
|
_release();
|
||||||
quantity = q;
|
quantity = q;
|
||||||
|
|
@ -184,9 +198,9 @@ void amount_t::_release()
|
||||||
{
|
{
|
||||||
VERIFY(valid());
|
VERIFY(valid());
|
||||||
|
|
||||||
DEBUG("amounts.refs", quantity << " ref--, now " << (quantity->ref - 1));
|
DEBUG("amounts.refs", quantity << " refc--, now " << (quantity->refc - 1));
|
||||||
|
|
||||||
if (--quantity->ref == 0) {
|
if (--quantity->refc == 0) {
|
||||||
if (quantity->has_flags(BIGINT_BULK_ALLOC))
|
if (quantity->has_flags(BIGINT_BULK_ALLOC))
|
||||||
quantity->~bigint_t();
|
quantity->~bigint_t();
|
||||||
else
|
else
|
||||||
|
|
@ -920,7 +934,7 @@ bool amount_t::parse(std::istream& in, const parse_flags_t& flags)
|
||||||
quantity = new bigint_t;
|
quantity = new bigint_t;
|
||||||
safe_holder.reset(quantity);
|
safe_holder.reset(quantity);
|
||||||
}
|
}
|
||||||
else if (quantity->ref > 1) {
|
else if (quantity->refc > 1) {
|
||||||
_release();
|
_release();
|
||||||
quantity = new bigint_t;
|
quantity = new bigint_t;
|
||||||
safe_holder.reset(quantity);
|
safe_holder.reset(quantity);
|
||||||
|
|
@ -1095,8 +1109,8 @@ bool amount_t::valid() const
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
||||||
if (quantity->ref == 0) {
|
if (quantity->refc == 0) {
|
||||||
DEBUG("ledger.validate", "amount_t: quantity->ref == 0");
|
DEBUG("ledger.validate", "amount_t: quantity->refc == 0");
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -1107,4 +1121,63 @@ bool amount_t::valid() const
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(HAVE_BOOST_SERIALIZATION)
|
||||||
|
|
||||||
|
template<class Archive>
|
||||||
|
void amount_t::serialize(Archive& ar, const unsigned int /* version */)
|
||||||
|
{
|
||||||
|
ar & current_pool;
|
||||||
|
ar & is_initialized;
|
||||||
|
ar & quantity;
|
||||||
|
ar & commodity_;
|
||||||
|
}
|
||||||
|
|
||||||
|
#endif // HAVE_BOOST_SERIALIZATION
|
||||||
|
|
||||||
} // namespace ledger
|
} // namespace ledger
|
||||||
|
|
||||||
|
#if defined(HAVE_BOOST_SERIALIZATION)
|
||||||
|
namespace boost {
|
||||||
|
namespace serialization {
|
||||||
|
|
||||||
|
template <class Archive>
|
||||||
|
void serialize(Archive& ar, MP_INT& mpz, const unsigned int /* version */)
|
||||||
|
{
|
||||||
|
ar & mpz._mp_alloc;
|
||||||
|
ar & mpz._mp_size;
|
||||||
|
ar & mpz._mp_d;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class Archive>
|
||||||
|
void serialize(Archive& ar, MP_RAT& mpq, const unsigned int /* version */)
|
||||||
|
{
|
||||||
|
ar & mpq._mp_num;
|
||||||
|
ar & mpq._mp_den;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class Archive>
|
||||||
|
void serialize(Archive& ar, long unsigned int& integer,
|
||||||
|
const unsigned int /* version */)
|
||||||
|
{
|
||||||
|
ar & make_binary_object(&integer, sizeof(long unsigned int));
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace serialization
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
BOOST_CLASS_EXPORT(ledger::annotated_commodity_t)
|
||||||
|
|
||||||
|
template void boost::serialization::serialize(boost::archive::binary_oarchive&,
|
||||||
|
MP_INT&, const unsigned int);
|
||||||
|
template void boost::serialization::serialize(boost::archive::binary_iarchive&,
|
||||||
|
MP_RAT&, const unsigned int);
|
||||||
|
template void boost::serialization::serialize(boost::archive::binary_iarchive&,
|
||||||
|
long unsigned int&,
|
||||||
|
const unsigned int);
|
||||||
|
|
||||||
|
template void ledger::amount_t::serialize(boost::archive::binary_oarchive&,
|
||||||
|
const unsigned int);
|
||||||
|
template void ledger::amount_t::serialize(boost::archive::binary_iarchive&,
|
||||||
|
const unsigned int);
|
||||||
|
|
||||||
|
#endif // HAVE_BOOST_SERIALIZATION
|
||||||
|
|
|
||||||
10
src/amount.h
10
src/amount.h
|
|
@ -691,6 +691,16 @@ public:
|
||||||
|
|
||||||
bool valid() const;
|
bool valid() const;
|
||||||
|
|
||||||
|
#if defined(HAVE_BOOST_SERIALIZATION)
|
||||||
|
private:
|
||||||
|
/** Serialization. */
|
||||||
|
|
||||||
|
friend class boost::serialization::access;
|
||||||
|
|
||||||
|
template<class Archive>
|
||||||
|
void serialize(Archive & ar, const unsigned int /* version */);
|
||||||
|
#endif // HAVE_BOOST_SERIALIZATION
|
||||||
|
|
||||||
/*@}*/
|
/*@}*/
|
||||||
};
|
};
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -98,6 +98,21 @@ struct annotation_t : public supports_flags<>,
|
||||||
assert(*this);
|
assert(*this);
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(HAVE_BOOST_SERIALIZATION)
|
||||||
|
private:
|
||||||
|
/** Serialization. */
|
||||||
|
|
||||||
|
friend class boost::serialization::access;
|
||||||
|
|
||||||
|
template<class Archive>
|
||||||
|
void serialize(Archive & ar, const unsigned int /* version */) {
|
||||||
|
ar & boost::serialization::base_object<supports_flags<> >(*this);
|
||||||
|
ar & price;
|
||||||
|
ar & date;
|
||||||
|
ar & tag;
|
||||||
|
}
|
||||||
|
#endif // HAVE_BOOST_SERIALIZATION
|
||||||
};
|
};
|
||||||
|
|
||||||
struct keep_details_t
|
struct keep_details_t
|
||||||
|
|
@ -136,6 +151,21 @@ struct keep_details_t
|
||||||
return keep_price || keep_date || keep_tag;
|
return keep_price || keep_date || keep_tag;
|
||||||
}
|
}
|
||||||
bool keep_any(const commodity_t& comm) const;
|
bool keep_any(const commodity_t& comm) const;
|
||||||
|
|
||||||
|
#if defined(HAVE_BOOST_SERIALIZATION)
|
||||||
|
private:
|
||||||
|
/** Serialization. */
|
||||||
|
|
||||||
|
friend class boost::serialization::access;
|
||||||
|
|
||||||
|
template<class Archive>
|
||||||
|
void serialize(Archive & ar, const unsigned int /* version */) {
|
||||||
|
ar & keep_price;
|
||||||
|
ar & keep_date;
|
||||||
|
ar & keep_tag;
|
||||||
|
ar & only_actuals;
|
||||||
|
}
|
||||||
|
#endif // HAVE_BOOST_SERIALIZATION
|
||||||
};
|
};
|
||||||
|
|
||||||
inline std::ostream& operator<<(std::ostream& out,
|
inline std::ostream& operator<<(std::ostream& out,
|
||||||
|
|
@ -183,6 +213,22 @@ public:
|
||||||
|
|
||||||
virtual commodity_t& strip_annotations(const keep_details_t& what_to_keep);
|
virtual commodity_t& strip_annotations(const keep_details_t& what_to_keep);
|
||||||
virtual void write_annotations(std::ostream& out) const;
|
virtual void write_annotations(std::ostream& out) const;
|
||||||
|
|
||||||
|
#if defined(HAVE_BOOST_SERIALIZATION)
|
||||||
|
private:
|
||||||
|
explicit annotated_commodity_t() : ptr(NULL) {}
|
||||||
|
|
||||||
|
/** Serialization. */
|
||||||
|
|
||||||
|
friend class boost::serialization::access;
|
||||||
|
|
||||||
|
template<class Archive>
|
||||||
|
void serialize(Archive & ar, const unsigned int /* version */) {
|
||||||
|
ar & boost::serialization::base_object<commodity_t>(*this);
|
||||||
|
ar & ptr;
|
||||||
|
ar & details;
|
||||||
|
}
|
||||||
|
#endif // HAVE_BOOST_SERIALIZATION
|
||||||
};
|
};
|
||||||
|
|
||||||
inline annotated_commodity_t&
|
inline annotated_commodity_t&
|
||||||
|
|
|
||||||
247
src/archive.cc
Normal file
247
src/archive.cc
Normal file
|
|
@ -0,0 +1,247 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2003-2009, John Wiegley. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
*
|
||||||
|
* - Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* - Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* - Neither the name of New Artisans LLC nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived from
|
||||||
|
* this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#include <system.hh>
|
||||||
|
|
||||||
|
#if defined(HAVE_BOOST_SERIALIZATION)
|
||||||
|
|
||||||
|
#include "archive.h"
|
||||||
|
#include "amount.h"
|
||||||
|
#include "commodity.h"
|
||||||
|
#include "pool.h"
|
||||||
|
#include "scope.h"
|
||||||
|
#include "account.h"
|
||||||
|
#include "post.h"
|
||||||
|
#include "xact.h"
|
||||||
|
|
||||||
|
#define ARCHIVE_VERSION 0x03000001
|
||||||
|
|
||||||
|
//BOOST_IS_ABSTRACT(ledger::scope_t)
|
||||||
|
BOOST_CLASS_EXPORT(ledger::scope_t)
|
||||||
|
BOOST_CLASS_EXPORT(ledger::child_scope_t)
|
||||||
|
BOOST_CLASS_EXPORT(ledger::symbol_scope_t)
|
||||||
|
BOOST_CLASS_EXPORT(ledger::call_scope_t)
|
||||||
|
BOOST_CLASS_EXPORT(ledger::account_t)
|
||||||
|
BOOST_CLASS_EXPORT(ledger::item_t)
|
||||||
|
BOOST_CLASS_EXPORT(ledger::post_t)
|
||||||
|
BOOST_CLASS_EXPORT(ledger::xact_base_t)
|
||||||
|
BOOST_CLASS_EXPORT(ledger::xact_t)
|
||||||
|
BOOST_CLASS_EXPORT(ledger::auto_xact_t)
|
||||||
|
BOOST_CLASS_EXPORT(ledger::period_xact_t)
|
||||||
|
|
||||||
|
template void ledger::journal_t::serialize(boost::archive::binary_oarchive&,
|
||||||
|
const unsigned int);
|
||||||
|
template void ledger::journal_t::serialize(boost::archive::binary_iarchive&,
|
||||||
|
const unsigned int);
|
||||||
|
namespace ledger {
|
||||||
|
|
||||||
|
void archive_t::read_header()
|
||||||
|
{
|
||||||
|
if (exists(file)) {
|
||||||
|
// Open the stream, read the version number and the list of sources
|
||||||
|
ifstream stream(file, std::ios::binary);
|
||||||
|
boost::archive::binary_iarchive iarchive(stream);
|
||||||
|
|
||||||
|
DEBUG("archive.journal", "Reading header from archive");
|
||||||
|
iarchive >> *this;
|
||||||
|
|
||||||
|
DEBUG("archive.journal",
|
||||||
|
"Version number: " << std::hex << version << std::dec);
|
||||||
|
DEBUG("archive.journal", "Number of sources: " << sources.size());
|
||||||
|
|
||||||
|
foreach (const journal_t::fileinfo_t& i, sources)
|
||||||
|
DEBUG("archive.journal", "Loaded source: " << *i.filename);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
bool archive_t::should_load(const std::list<path>& data_files)
|
||||||
|
{
|
||||||
|
std::size_t found = 0;
|
||||||
|
|
||||||
|
DEBUG("archive.journal", "Should the archive be loaded?");
|
||||||
|
|
||||||
|
if (! exists(file)) {
|
||||||
|
DEBUG("archive.journal", "No, it does not exist");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (version != ARCHIVE_VERSION) {
|
||||||
|
DEBUG("archive.journal", "No, it fails the version check");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data_files.empty()) {
|
||||||
|
DEBUG("archive.journal", "No, there were no data files!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (sources.empty()) {
|
||||||
|
DEBUG("archive.journal", "No, there were no sources!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (data_files.size() != sources.size()) {
|
||||||
|
DEBUG("archive.journal", "No, number of sources doesn't match: "
|
||||||
|
<< data_files.size() << " != " << sources.size());
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (const path& p, data_files) {
|
||||||
|
DEBUG("archive.journal", "Scanning for data file: " << p);
|
||||||
|
|
||||||
|
if (! exists(p)) {
|
||||||
|
DEBUG("archive.journal", "No, an input source no longer exists: " << p);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (const journal_t::fileinfo_t& i, sources) {
|
||||||
|
assert(! i.from_stream);
|
||||||
|
assert(i.filename);
|
||||||
|
|
||||||
|
DEBUG("archive.journal", "Comparing against source file: " << *i.filename);
|
||||||
|
|
||||||
|
if (*i.filename == p) {
|
||||||
|
if (! exists(*i.filename)) {
|
||||||
|
DEBUG("archive.journal",
|
||||||
|
"No, a referent source no longer exists: " << *i.filename);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i.modtime != posix_time::from_time_t(last_write_time(p))) {
|
||||||
|
DEBUG("archive.journal", "No, a source's modtime has changed: " << p);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (i.size != file_size(p)) {
|
||||||
|
DEBUG("archive.journal", "No, a source's size has changed: " << p);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
found++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (found != data_files.size()) {
|
||||||
|
DEBUG("archive.journal", "No, not every source's name matched");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEBUG("archive.journal", "Yes, it should be loaded!");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
bool archive_t::should_save(shared_ptr<journal_t> journal)
|
||||||
|
{
|
||||||
|
std::list<path> data_files;
|
||||||
|
|
||||||
|
DEBUG("archive.journal", "Should the archive be saved?");
|
||||||
|
|
||||||
|
if (journal->was_loaded) {
|
||||||
|
DEBUG("archive.journal", "No, it's one we loaded before");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (journal->sources.empty()) {
|
||||||
|
DEBUG("archive.journal", "No, there were no sources!");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
foreach (const journal_t::fileinfo_t& i, journal->sources) {
|
||||||
|
if (i.from_stream) {
|
||||||
|
DEBUG("archive.journal", "No, one source was from a stream");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! exists(*i.filename)) {
|
||||||
|
DEBUG("archive.journal",
|
||||||
|
"No, a source no longer exists: " << *i.filename);
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
data_files.push_back(*i.filename);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (should_load(data_files)) {
|
||||||
|
DEBUG("archive.journal", "No, because it's still loadable");
|
||||||
|
return false;
|
||||||
|
}
|
||||||
|
|
||||||
|
DEBUG("archive.journal", "Yes, it should be saved!");
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
void archive_t::save(shared_ptr<journal_t> journal)
|
||||||
|
{
|
||||||
|
INFO_START(archive, "Saved journal file cache");
|
||||||
|
|
||||||
|
ofstream archive(file, std::ios::binary);
|
||||||
|
boost::archive::binary_oarchive oa(archive);
|
||||||
|
|
||||||
|
version = ARCHIVE_VERSION;
|
||||||
|
sources = journal->sources;
|
||||||
|
|
||||||
|
foreach (const journal_t::fileinfo_t& i, sources)
|
||||||
|
DEBUG("archive.journal", "Saving source: " << *i.filename);
|
||||||
|
|
||||||
|
DEBUG("archive.journal",
|
||||||
|
"Creating archive with version " << std::hex << version << std::dec);
|
||||||
|
oa << *this;
|
||||||
|
|
||||||
|
DEBUG("archive.journal",
|
||||||
|
"Archiving journal with " << sources.size() << " sources");
|
||||||
|
oa << *journal;
|
||||||
|
|
||||||
|
INFO_FINISH(archive);
|
||||||
|
}
|
||||||
|
|
||||||
|
bool archive_t::load(shared_ptr<journal_t> journal)
|
||||||
|
{
|
||||||
|
INFO_START(archive, "Read cached journal file");
|
||||||
|
|
||||||
|
ifstream stream(file, std::ios::binary);
|
||||||
|
boost::archive::binary_iarchive iarchive(stream);
|
||||||
|
|
||||||
|
// Skip past the archive header, it was already read in before
|
||||||
|
archive_t temp;
|
||||||
|
iarchive >> temp;
|
||||||
|
|
||||||
|
iarchive >> *journal.get();
|
||||||
|
journal->was_loaded = true;
|
||||||
|
|
||||||
|
INFO_FINISH(archive);
|
||||||
|
|
||||||
|
return true;
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace ledger
|
||||||
|
|
||||||
|
#endif // HAVE_BOOST_SERIALIZATION
|
||||||
105
src/archive.h
Normal file
105
src/archive.h
Normal file
|
|
@ -0,0 +1,105 @@
|
||||||
|
/*
|
||||||
|
* Copyright (c) 2003-2009, John Wiegley. All rights reserved.
|
||||||
|
*
|
||||||
|
* Redistribution and use in source and binary forms, with or without
|
||||||
|
* modification, are permitted provided that the following conditions are
|
||||||
|
* met:
|
||||||
|
*
|
||||||
|
* - Redistributions of source code must retain the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer.
|
||||||
|
*
|
||||||
|
* - Redistributions in binary form must reproduce the above copyright
|
||||||
|
* notice, this list of conditions and the following disclaimer in the
|
||||||
|
* documentation and/or other materials provided with the distribution.
|
||||||
|
*
|
||||||
|
* - Neither the name of New Artisans LLC nor the names of its
|
||||||
|
* contributors may be used to endorse or promote products derived from
|
||||||
|
* this software without specific prior written permission.
|
||||||
|
*
|
||||||
|
* THIS SOFTWARE IS PROVIDED BY THE COPYRIGHT HOLDERS AND CONTRIBUTORS
|
||||||
|
* "AS IS" AND ANY EXPRESS OR IMPLIED WARRANTIES, INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, THE IMPLIED WARRANTIES OF MERCHANTABILITY AND FITNESS FOR
|
||||||
|
* A PARTICULAR PURPOSE ARE DISCLAIMED. IN NO EVENT SHALL THE COPYRIGHT
|
||||||
|
* OWNER OR CONTRIBUTORS BE LIABLE FOR ANY DIRECT, INDIRECT, INCIDENTAL,
|
||||||
|
* SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT NOT
|
||||||
|
* LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
|
||||||
|
* DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
|
||||||
|
* THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
|
||||||
|
* (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE
|
||||||
|
* OF THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @defgroup report Reporting
|
||||||
|
*/
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @file archive.h
|
||||||
|
* @author John Wiegley
|
||||||
|
*
|
||||||
|
* @ingroup report
|
||||||
|
*
|
||||||
|
* @brief Brief
|
||||||
|
*
|
||||||
|
* Long.
|
||||||
|
*/
|
||||||
|
#ifndef _ARCHIVE_H
|
||||||
|
#define _ARCHIVE_H
|
||||||
|
|
||||||
|
#include "journal.h"
|
||||||
|
|
||||||
|
namespace ledger {
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Brief
|
||||||
|
*
|
||||||
|
* Long.
|
||||||
|
*/
|
||||||
|
class archive_t
|
||||||
|
{
|
||||||
|
path file;
|
||||||
|
uint32_t version;
|
||||||
|
|
||||||
|
std::list<journal_t::fileinfo_t> sources;
|
||||||
|
|
||||||
|
public:
|
||||||
|
archive_t() {
|
||||||
|
TRACE_CTOR(archive_t, "");
|
||||||
|
}
|
||||||
|
archive_t(const path& _file)
|
||||||
|
: file(_file), version(0) {
|
||||||
|
TRACE_CTOR(archive_t, "const path&");
|
||||||
|
}
|
||||||
|
archive_t(const archive_t& ar)
|
||||||
|
: file(ar.file), version(0) {
|
||||||
|
TRACE_CTOR(archive_t, "copy");
|
||||||
|
}
|
||||||
|
~archive_t() {
|
||||||
|
TRACE_DTOR(archive_t);
|
||||||
|
}
|
||||||
|
|
||||||
|
void read_header();
|
||||||
|
|
||||||
|
bool should_load(const std::list<path>& data_files);
|
||||||
|
bool should_save(shared_ptr<journal_t> journal);
|
||||||
|
|
||||||
|
void save(shared_ptr<journal_t> journal);
|
||||||
|
bool load(shared_ptr<journal_t> journal);
|
||||||
|
|
||||||
|
#if defined(HAVE_BOOST_SERIALIZATION)
|
||||||
|
private:
|
||||||
|
/** Serialization. */
|
||||||
|
|
||||||
|
friend class boost::serialization::access;
|
||||||
|
|
||||||
|
template<class Archive>
|
||||||
|
void serialize(Archive & ar, const unsigned int /* version */) {
|
||||||
|
ar & version;
|
||||||
|
ar & sources;
|
||||||
|
}
|
||||||
|
#endif // HAVE_BOOST_SERIALIZATION
|
||||||
|
};
|
||||||
|
|
||||||
|
} // namespace ledger
|
||||||
|
|
||||||
|
#endif // _ARCHIVE_H
|
||||||
|
|
@ -228,12 +228,14 @@ balance_t::commodity_amount(const optional<const commodity_t&>& commodity) const
|
||||||
return temp.commodity_amount(commodity);
|
return temp.commodity_amount(commodity);
|
||||||
|
|
||||||
throw_(amount_error,
|
throw_(amount_error,
|
||||||
_("Requested amount of a balance with multiple commodities: %1") << temp);
|
_("Requested amount of a balance with multiple commodities: %1")
|
||||||
|
<< temp);
|
||||||
}
|
}
|
||||||
#endif
|
#endif
|
||||||
}
|
}
|
||||||
else if (amounts.size() > 0) {
|
else if (amounts.size() > 0) {
|
||||||
amounts_map::const_iterator i = amounts.find(&*commodity);
|
amounts_map::const_iterator i =
|
||||||
|
amounts.find(const_cast<commodity_t *>(&*commodity));
|
||||||
if (i != amounts.end())
|
if (i != amounts.end())
|
||||||
return i->second;
|
return i->second;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -80,7 +80,7 @@ class balance_t
|
||||||
multiplicative<balance_t, long> > > > > > > > > > > > > >
|
multiplicative<balance_t, long> > > > > > > > > > > > > >
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef std::map<const commodity_t *, amount_t> amounts_map;
|
typedef std::map<commodity_t *, amount_t> amounts_map;
|
||||||
|
|
||||||
amounts_map amounts;
|
amounts_map amounts;
|
||||||
|
|
||||||
|
|
@ -523,6 +523,18 @@ public:
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(HAVE_BOOST_SERIALIZATION)
|
||||||
|
private:
|
||||||
|
/** Serialization. */
|
||||||
|
|
||||||
|
friend class boost::serialization::access;
|
||||||
|
|
||||||
|
template<class Archive>
|
||||||
|
void serialize(Archive & ar, const unsigned int /* version */) {
|
||||||
|
ar & amounts;
|
||||||
|
}
|
||||||
|
#endif // HAVE_BOOST_SERIALIZATION
|
||||||
};
|
};
|
||||||
|
|
||||||
inline std::ostream& operator<<(std::ostream& out, const balance_t& bal) {
|
inline std::ostream& operator<<(std::ostream& out, const balance_t& bal) {
|
||||||
|
|
|
||||||
14
src/chain.cc
14
src/chain.cc
|
|
@ -223,33 +223,33 @@ post_handler_ptr chain_post_handlers(report_t& report,
|
||||||
|
|
||||||
if (report.HANDLED(set_account_))
|
if (report.HANDLED(set_account_))
|
||||||
handler.reset(new transfer_details(handler, transfer_details::SET_ACCOUNT,
|
handler.reset(new transfer_details(handler, transfer_details::SET_ACCOUNT,
|
||||||
report.session.master.get(),
|
report.session.journal->master,
|
||||||
report.HANDLER(set_account_).str(),
|
report.HANDLER(set_account_).str(),
|
||||||
report));
|
report));
|
||||||
else if (report.HANDLED(set_payee_))
|
else if (report.HANDLED(set_payee_))
|
||||||
handler.reset(new transfer_details(handler, transfer_details::SET_PAYEE,
|
handler.reset(new transfer_details(handler, transfer_details::SET_PAYEE,
|
||||||
report.session.master.get(),
|
report.session.journal->master,
|
||||||
report.HANDLER(set_payee_).str(),
|
report.HANDLER(set_payee_).str(),
|
||||||
report));
|
report));
|
||||||
else if (report.HANDLED(comm_as_payee))
|
else if (report.HANDLED(comm_as_payee))
|
||||||
handler.reset(new transfer_details(handler, transfer_details::SET_PAYEE,
|
handler.reset(new transfer_details(handler, transfer_details::SET_PAYEE,
|
||||||
report.session.master.get(),
|
report.session.journal->master,
|
||||||
expr_t("commodity"), report));
|
expr_t("commodity"), report));
|
||||||
else if (report.HANDLED(code_as_payee))
|
else if (report.HANDLED(code_as_payee))
|
||||||
handler.reset(new transfer_details(handler, transfer_details::SET_PAYEE,
|
handler.reset(new transfer_details(handler, transfer_details::SET_PAYEE,
|
||||||
report.session.master.get(),
|
report.session.journal->master,
|
||||||
expr_t("code"), report));
|
expr_t("code"), report));
|
||||||
else if (report.HANDLED(payee_as_account))
|
else if (report.HANDLED(payee_as_account))
|
||||||
handler.reset(new transfer_details(handler, transfer_details::SET_ACCOUNT,
|
handler.reset(new transfer_details(handler, transfer_details::SET_ACCOUNT,
|
||||||
report.session.master.get(),
|
report.session.journal->master,
|
||||||
expr_t("payee"), report));
|
expr_t("payee"), report));
|
||||||
else if (report.HANDLED(comm_as_account))
|
else if (report.HANDLED(comm_as_account))
|
||||||
handler.reset(new transfer_details(handler, transfer_details::SET_ACCOUNT,
|
handler.reset(new transfer_details(handler, transfer_details::SET_ACCOUNT,
|
||||||
report.session.master.get(),
|
report.session.journal->master,
|
||||||
expr_t("commodity"), report));
|
expr_t("commodity"), report));
|
||||||
else if (report.HANDLED(code_as_account))
|
else if (report.HANDLED(code_as_account))
|
||||||
handler.reset(new transfer_details(handler, transfer_details::SET_ACCOUNT,
|
handler.reset(new transfer_details(handler, transfer_details::SET_ACCOUNT,
|
||||||
report.session.master.get(),
|
report.session.journal->master,
|
||||||
expr_t("code"), report));
|
expr_t("code"), report));
|
||||||
|
|
||||||
return handler;
|
return handler;
|
||||||
|
|
|
||||||
|
|
@ -62,6 +62,19 @@ struct price_point_t
|
||||||
{
|
{
|
||||||
datetime_t when;
|
datetime_t when;
|
||||||
amount_t price;
|
amount_t price;
|
||||||
|
|
||||||
|
#if defined(HAVE_BOOST_SERIALIZATION)
|
||||||
|
private:
|
||||||
|
/** Serialization. */
|
||||||
|
|
||||||
|
friend class boost::serialization::access;
|
||||||
|
|
||||||
|
template<class Archive>
|
||||||
|
void serialize(Archive & ar, const unsigned int /* version */) {
|
||||||
|
ar & when;
|
||||||
|
ar & price;
|
||||||
|
}
|
||||||
|
#endif // HAVE_BOOST_SERIALIZATION
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -78,7 +91,7 @@ class commodity_t
|
||||||
public:
|
public:
|
||||||
class base_t : public noncopyable, public supports_flags<uint_least16_t>
|
class base_t : public noncopyable, public supports_flags<uint_least16_t>
|
||||||
{
|
{
|
||||||
base_t();
|
base_t() {}
|
||||||
|
|
||||||
public:
|
public:
|
||||||
typedef std::map<const datetime_t, amount_t> history_map;
|
typedef std::map<const datetime_t, amount_t> history_map;
|
||||||
|
|
@ -100,6 +113,18 @@ public:
|
||||||
, const int indent = 0
|
, const int indent = 0
|
||||||
#endif
|
#endif
|
||||||
) const;
|
) const;
|
||||||
|
|
||||||
|
#if defined(HAVE_BOOST_SERIALIZATION)
|
||||||
|
private:
|
||||||
|
/** Serialization. */
|
||||||
|
|
||||||
|
friend class boost::serialization::access;
|
||||||
|
|
||||||
|
template<class Archive>
|
||||||
|
void serialize(Archive & ar, const unsigned int /* version */) {
|
||||||
|
ar & prices;
|
||||||
|
}
|
||||||
|
#endif // HAVE_BOOST_SERIALIZATION
|
||||||
};
|
};
|
||||||
|
|
||||||
typedef std::map<commodity_t *, history_t> history_by_commodity_map;
|
typedef std::map<commodity_t *, history_t> history_by_commodity_map;
|
||||||
|
|
@ -126,6 +151,18 @@ public:
|
||||||
|
|
||||||
optional<history_t&>
|
optional<history_t&>
|
||||||
history(const optional<commodity_t&>& commodity = none);
|
history(const optional<commodity_t&>& commodity = none);
|
||||||
|
|
||||||
|
#if defined(HAVE_BOOST_SERIALIZATION)
|
||||||
|
private:
|
||||||
|
/** Serialization. */
|
||||||
|
|
||||||
|
friend class boost::serialization::access;
|
||||||
|
|
||||||
|
template<class Archive>
|
||||||
|
void serialize(Archive & ar, const unsigned int /* version */) {
|
||||||
|
ar & histories;
|
||||||
|
}
|
||||||
|
#endif // HAVE_BOOST_SERIALIZATION
|
||||||
};
|
};
|
||||||
|
|
||||||
#define COMMODITY_STYLE_DEFAULTS 0x000
|
#define COMMODITY_STYLE_DEFAULTS 0x000
|
||||||
|
|
@ -158,6 +195,25 @@ public:
|
||||||
~base_t() {
|
~base_t() {
|
||||||
TRACE_DTOR(base_t);
|
TRACE_DTOR(base_t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(HAVE_BOOST_SERIALIZATION)
|
||||||
|
private:
|
||||||
|
/** Serialization. */
|
||||||
|
|
||||||
|
friend class boost::serialization::access;
|
||||||
|
|
||||||
|
template<class Archive>
|
||||||
|
void serialize(Archive & ar, const unsigned int /* version */) {
|
||||||
|
ar & boost::serialization::base_object<supports_flags<uint_least16_t> >(*this);
|
||||||
|
ar & symbol;
|
||||||
|
ar & precision;
|
||||||
|
ar & name;
|
||||||
|
ar & note;
|
||||||
|
ar & varied_history;
|
||||||
|
ar & smaller;
|
||||||
|
ar & larger;
|
||||||
|
}
|
||||||
|
#endif // HAVE_BOOST_SERIALIZATION
|
||||||
};
|
};
|
||||||
|
|
||||||
public:
|
public:
|
||||||
|
|
@ -330,6 +386,31 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
bool valid() const;
|
bool valid() const;
|
||||||
|
|
||||||
|
#if defined(HAVE_BOOST_SERIALIZATION)
|
||||||
|
private:
|
||||||
|
supports_flags<uint_least16_t> temp_flags;
|
||||||
|
|
||||||
|
protected:
|
||||||
|
explicit commodity_t()
|
||||||
|
: delegates_flags<uint_least16_t>(temp_flags), parent_(NULL),
|
||||||
|
annotated(false) {}
|
||||||
|
|
||||||
|
private:
|
||||||
|
/** Serialization. */
|
||||||
|
|
||||||
|
friend class boost::serialization::access;
|
||||||
|
|
||||||
|
template<class Archive>
|
||||||
|
void serialize(Archive & ar, const unsigned int /* version */) {
|
||||||
|
ar & boost::serialization::base_object<delegates_flags<uint_least16_t> >(*this);
|
||||||
|
ar & base;
|
||||||
|
ar & parent_;
|
||||||
|
ar & qualified_symbol;
|
||||||
|
ar & mapping_key_;
|
||||||
|
ar & annotated;
|
||||||
|
}
|
||||||
|
#endif // HAVE_BOOST_SERIALIZATION
|
||||||
};
|
};
|
||||||
|
|
||||||
inline std::ostream& operator<<(std::ostream& out, const commodity_t& comm) {
|
inline std::ostream& operator<<(std::ostream& out, const commodity_t& comm) {
|
||||||
|
|
|
||||||
|
|
@ -252,7 +252,7 @@ namespace {
|
||||||
if (tmpl.payee_mask.match((*j)->payee)) {
|
if (tmpl.payee_mask.match((*j)->payee)) {
|
||||||
matching = *j;
|
matching = *j;
|
||||||
DEBUG("derive.xact",
|
DEBUG("derive.xact",
|
||||||
"Found payee match: transaction on line " << (*j)->beg_line);
|
"Found payee match: transaction on line " << (*j)->pos->beg_line);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -332,7 +332,7 @@ namespace {
|
||||||
if (post.account_mask->match(x->account->fullname())) {
|
if (post.account_mask->match(x->account->fullname())) {
|
||||||
new_post.reset(new post_t(*x));
|
new_post.reset(new post_t(*x));
|
||||||
DEBUG("derive.xact",
|
DEBUG("derive.xact",
|
||||||
"Founding posting from line " << x->beg_line);
|
"Founding posting from line " << x->pos->beg_line);
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
|
|
@ -40,8 +40,8 @@ namespace ledger {
|
||||||
|
|
||||||
void format_emacs_posts::write_xact(xact_t& xact)
|
void format_emacs_posts::write_xact(xact_t& xact)
|
||||||
{
|
{
|
||||||
out << "\"" << xact.pathname << "\" "
|
out << "\"" << xact.pos->pathname << "\" "
|
||||||
<< (xact.beg_line + 1) << " ";
|
<< (xact.pos->beg_line + 1) << " ";
|
||||||
|
|
||||||
tm when = gregorian::to_tm(xact.date());
|
tm when = gregorian::to_tm(xact.date());
|
||||||
std::time_t date = std::mktime(&when); // jww (2008-04-20): Is this GMT or local?
|
std::time_t date = std::mktime(&when); // jww (2008-04-20): Is this GMT or local?
|
||||||
|
|
@ -77,7 +77,7 @@ void format_emacs_posts::operator()(post_t& post)
|
||||||
out << "\n";
|
out << "\n";
|
||||||
}
|
}
|
||||||
|
|
||||||
out << " (" << (post.beg_line + 1) << " ";
|
out << " (" << (post.pos->beg_line + 1) << " ";
|
||||||
out << "\"" << post.reported_account()->fullname() << "\" \""
|
out << "\"" << post.reported_account()->fullname() << "\" \""
|
||||||
<< post.amount << "\"";
|
<< post.amount << "\"";
|
||||||
|
|
||||||
|
|
|
||||||
|
|
@ -96,10 +96,10 @@ string source_context(const path& file,
|
||||||
ifstream in(file);
|
ifstream in(file);
|
||||||
in.seekg(pos, std::ios::beg);
|
in.seekg(pos, std::ios::beg);
|
||||||
|
|
||||||
scoped_array<char> buf(new char[len + 1]);
|
scoped_array<char> buf(new char[static_cast<std::size_t>(len) + 1]);
|
||||||
in.read(buf.get(), len);
|
in.read(buf.get(), static_cast<std::streamsize>(len));
|
||||||
assert(in.gcount() == len);
|
assert(in.gcount() == static_cast<std::streamsize>(len));
|
||||||
buf[len] = '\0';
|
buf[static_cast<std::size_t>(len)] = '\0';
|
||||||
|
|
||||||
bool first = true;
|
bool first = true;
|
||||||
for (char * p = std::strtok(buf.get(), "\n");
|
for (char * p = std::strtok(buf.get(), "\n");
|
||||||
|
|
|
||||||
18
src/expr.h
18
src/expr.h
|
|
@ -103,7 +103,7 @@ public:
|
||||||
expr_t(const string& _str, const uint_least8_t flags = 0);
|
expr_t(const string& _str, const uint_least8_t flags = 0);
|
||||||
expr_t(std::istream& in, const uint_least8_t flags = 0);
|
expr_t(std::istream& in, const uint_least8_t flags = 0);
|
||||||
|
|
||||||
virtual ~expr_t() throw();
|
~expr_t() throw();
|
||||||
|
|
||||||
expr_t& operator=(const expr_t& _expr);
|
expr_t& operator=(const expr_t& _expr);
|
||||||
expr_t& operator=(const string& _expr) {
|
expr_t& operator=(const string& _expr) {
|
||||||
|
|
@ -163,6 +163,22 @@ public:
|
||||||
void dump(std::ostream& out) const;
|
void dump(std::ostream& out) const;
|
||||||
|
|
||||||
static value_t eval(const string& _expr, scope_t& scope);
|
static value_t eval(const string& _expr, scope_t& scope);
|
||||||
|
|
||||||
|
#if defined(HAVE_BOOST_SERIALIZATION)
|
||||||
|
private:
|
||||||
|
/** Serialization. */
|
||||||
|
|
||||||
|
friend class boost::serialization::access;
|
||||||
|
|
||||||
|
template<class Archive>
|
||||||
|
void serialize(Archive & ar, const unsigned int /* version */) {
|
||||||
|
ar & ptr;
|
||||||
|
ar & context;
|
||||||
|
ar & str;
|
||||||
|
if (Archive::is_loading::value)
|
||||||
|
compiled = false;
|
||||||
|
}
|
||||||
|
#endif // HAVE_BOOST_SERIALIZATION
|
||||||
};
|
};
|
||||||
|
|
||||||
std::ostream& operator<<(std::ostream& out, const expr_t& expr);
|
std::ostream& operator<<(std::ostream& out, const expr_t& expr);
|
||||||
|
|
|
||||||
22
src/flags.h
22
src/flags.h
|
|
@ -99,6 +99,17 @@ public:
|
||||||
void drop_flags(const flags_t arg) {
|
void drop_flags(const flags_t arg) {
|
||||||
_flags = static_cast<T>(static_cast<U>(_flags) & static_cast<U>(~arg));
|
_flags = static_cast<T>(static_cast<U>(_flags) & static_cast<U>(~arg));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(HAVE_BOOST_SERIALIZATION)
|
||||||
|
private:
|
||||||
|
friend class boost::serialization::access;
|
||||||
|
|
||||||
|
template<class Archive>
|
||||||
|
void serialize(Archive & ar, const unsigned int /* version */)
|
||||||
|
{
|
||||||
|
ar & _flags;
|
||||||
|
}
|
||||||
|
#endif // HAVE_BOOST_SERIALIZATION
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -201,6 +212,17 @@ public:
|
||||||
void drop_flags(const flags_t arg) {
|
void drop_flags(const flags_t arg) {
|
||||||
_flags.drop_flags(arg);
|
_flags.drop_flags(arg);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(HAVE_BOOST_SERIALIZATION)
|
||||||
|
private:
|
||||||
|
friend class boost::serialization::access;
|
||||||
|
|
||||||
|
template<class Archive>
|
||||||
|
void serialize(Archive & ar, const unsigned int /* version */)
|
||||||
|
{
|
||||||
|
ar & _flags;
|
||||||
|
}
|
||||||
|
#endif // HAVE_BOOST_SERIALIZATION
|
||||||
};
|
};
|
||||||
|
|
||||||
#endif // _FLAGS_H
|
#endif // _FLAGS_H
|
||||||
|
|
|
||||||
|
|
@ -435,17 +435,18 @@ void global_scope_t::normalize_report_options(const string& verb)
|
||||||
item_t::use_effective_date = (rep.HANDLED(effective) &&
|
item_t::use_effective_date = (rep.HANDLED(effective) &&
|
||||||
! rep.HANDLED(actual_dates));
|
! rep.HANDLED(actual_dates));
|
||||||
|
|
||||||
rep.session.commodity_pool->keep_base = rep.HANDLED(base);
|
rep.session.journal->commodity_pool->keep_base = rep.HANDLED(base);
|
||||||
rep.session.commodity_pool->get_quotes = rep.session.HANDLED(download);
|
rep.session.journal->commodity_pool->get_quotes = rep.session.HANDLED(download);
|
||||||
|
|
||||||
if (rep.session.HANDLED(price_exp_))
|
if (rep.session.HANDLED(price_exp_))
|
||||||
rep.session.commodity_pool->quote_leeway =
|
rep.session.journal->commodity_pool->quote_leeway =
|
||||||
rep.session.HANDLER(price_exp_).value.as_long();
|
rep.session.HANDLER(price_exp_).value.as_long();
|
||||||
|
|
||||||
if (rep.session.HANDLED(price_db_))
|
if (rep.session.HANDLED(price_db_))
|
||||||
rep.session.commodity_pool->price_db = rep.session.HANDLER(price_db_).str();
|
rep.session.journal->commodity_pool->price_db =
|
||||||
|
rep.session.HANDLER(price_db_).str();
|
||||||
else
|
else
|
||||||
rep.session.commodity_pool->price_db = none;
|
rep.session.journal->commodity_pool->price_db = none;
|
||||||
|
|
||||||
if (rep.HANDLED(date_format_))
|
if (rep.HANDLED(date_format_))
|
||||||
set_date_format(rep.HANDLER(date_format_).str().c_str());
|
set_date_format(rep.HANDLER(date_format_).str().c_str());
|
||||||
|
|
@ -542,7 +543,8 @@ void global_scope_t::normalize_report_options(const string& verb)
|
||||||
|
|
||||||
if (! rep.HANDLER(date_width_).specified)
|
if (! rep.HANDLER(date_width_).specified)
|
||||||
rep.HANDLER(date_width_)
|
rep.HANDLER(date_width_)
|
||||||
.on_with(none, format_date(CURRENT_DATE(), FMT_PRINTED).length());
|
.on_with(none, static_cast<long>(format_date(CURRENT_DATE(),
|
||||||
|
FMT_PRINTED).length()));
|
||||||
|
|
||||||
long date_width = rep.HANDLER(date_width_).value.to_long();
|
long date_width = rep.HANDLER(date_width_).value.to_long();
|
||||||
long payee_width = (rep.HANDLER(payee_width_).specified ?
|
long payee_width = (rep.HANDLER(payee_width_).specified ?
|
||||||
|
|
|
||||||
|
|
@ -118,9 +118,9 @@ void interactive_t::verify_arguments() const
|
||||||
label = _("any value");
|
label = _("any value");
|
||||||
wrong_arg = false;
|
wrong_arg = false;
|
||||||
break;
|
break;
|
||||||
case 'P':
|
case '^':
|
||||||
label = _("a pointer");
|
label = _("a scope");
|
||||||
wrong_arg = ! next_arg->is_pointer();
|
wrong_arg = ! next_arg->is_scope();
|
||||||
break;
|
break;
|
||||||
case 'S':
|
case 'S':
|
||||||
label = _("a sequence");
|
label = _("a sequence");
|
||||||
|
|
|
||||||
32
src/item.cc
32
src/item.cc
|
|
@ -187,7 +187,7 @@ namespace {
|
||||||
}
|
}
|
||||||
|
|
||||||
value_t get_actual(item_t& item) {
|
value_t get_actual(item_t& item) {
|
||||||
return ! item.has_flags(ITEM_GENERATED);
|
return ! item.has_flags(ITEM_GENERATED | ITEM_TEMP);
|
||||||
}
|
}
|
||||||
|
|
||||||
value_t get_date(item_t& item) {
|
value_t get_date(item_t& item) {
|
||||||
|
|
@ -224,23 +224,26 @@ namespace {
|
||||||
}
|
}
|
||||||
|
|
||||||
value_t get_pathname(item_t& item) {
|
value_t get_pathname(item_t& item) {
|
||||||
return string_value(item.pathname.string());
|
if (item.pos)
|
||||||
|
return string_value(item.pos->pathname.string());
|
||||||
|
else
|
||||||
|
return string_value(empty_string);
|
||||||
}
|
}
|
||||||
|
|
||||||
value_t get_beg_pos(item_t& item) {
|
value_t get_beg_pos(item_t& item) {
|
||||||
return long(item.beg_pos);
|
return item.pos ? long(item.pos->beg_pos) : 0L;
|
||||||
}
|
}
|
||||||
|
|
||||||
value_t get_beg_line(item_t& item) {
|
value_t get_beg_line(item_t& item) {
|
||||||
return long(item.beg_line);
|
return item.pos ? long(item.pos->beg_line) : 0L;
|
||||||
}
|
}
|
||||||
|
|
||||||
value_t get_end_pos(item_t& item) {
|
value_t get_end_pos(item_t& item) {
|
||||||
return long(item.end_pos);
|
return item.pos ? long(item.pos->end_pos) : 0L;
|
||||||
}
|
}
|
||||||
|
|
||||||
value_t get_end_line(item_t& item) {
|
value_t get_end_line(item_t& item) {
|
||||||
return long(item.end_line);
|
return item.pos ? long(item.pos->end_line) : 0L;
|
||||||
}
|
}
|
||||||
|
|
||||||
value_t get_depth(item_t&) {
|
value_t get_depth(item_t&) {
|
||||||
|
|
@ -397,12 +400,13 @@ bool item_t::valid() const
|
||||||
|
|
||||||
void print_item(std::ostream& out, const item_t& item, const string& prefix)
|
void print_item(std::ostream& out, const item_t& item, const string& prefix)
|
||||||
{
|
{
|
||||||
out << source_context(item.pathname, item.beg_pos, item.end_pos, prefix);
|
out << source_context(item.pos->pathname, item.pos->beg_pos,
|
||||||
|
item.pos->end_pos, prefix);
|
||||||
}
|
}
|
||||||
|
|
||||||
string item_context(const item_t& item, const string& desc)
|
string item_context(const item_t& item, const string& desc)
|
||||||
{
|
{
|
||||||
std::streamoff len = item.end_pos - item.beg_pos;
|
std::streamoff len = item.pos->end_pos - item.pos->beg_pos;
|
||||||
if (! len)
|
if (! len)
|
||||||
return _("<no item context>");
|
return _("<no item context>");
|
||||||
|
|
||||||
|
|
@ -411,18 +415,18 @@ string item_context(const item_t& item, const string& desc)
|
||||||
|
|
||||||
std::ostringstream out;
|
std::ostringstream out;
|
||||||
|
|
||||||
if (item.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();
|
||||||
}
|
}
|
||||||
|
|
||||||
out << desc << _(" from \"") << item.pathname.string() << "\"";
|
out << desc << _(" from \"") << item.pos->pathname.string() << "\"";
|
||||||
|
|
||||||
if (item.beg_line != item.end_line)
|
if (item.pos->beg_line != item.pos->end_line)
|
||||||
out << _(", lines ") << item.beg_line << "-"
|
out << _(", lines ") << item.pos->beg_line << "-"
|
||||||
<< item.end_line << ":\n";
|
<< item.pos->end_line << ":\n";
|
||||||
else
|
else
|
||||||
out << _(", line ") << item.beg_line << ":\n";
|
out << _(", line ") << item.pos->beg_line << ":\n";
|
||||||
|
|
||||||
print_item(out, item, "> ");
|
print_item(out, item, "> ");
|
||||||
|
|
||||||
|
|
|
||||||
97
src/item.h
97
src/item.h
|
|
@ -50,6 +50,53 @@
|
||||||
|
|
||||||
namespace ledger {
|
namespace ledger {
|
||||||
|
|
||||||
|
struct position_t
|
||||||
|
{
|
||||||
|
path pathname;
|
||||||
|
istream_pos_type beg_pos;
|
||||||
|
std::size_t beg_line;
|
||||||
|
istream_pos_type end_pos;
|
||||||
|
std::size_t end_line;
|
||||||
|
|
||||||
|
position_t() : beg_pos(0), beg_line(0), end_pos(0), end_line(0) {
|
||||||
|
TRACE_CTOR(position_t, "");
|
||||||
|
}
|
||||||
|
position_t(const position_t& pos) {
|
||||||
|
TRACE_CTOR(position_t, "copy");
|
||||||
|
*this = pos;
|
||||||
|
}
|
||||||
|
~position_t() throw() {
|
||||||
|
TRACE_DTOR(position_t);
|
||||||
|
}
|
||||||
|
|
||||||
|
position_t& operator=(const position_t& pos) {
|
||||||
|
if (this != &pos) {
|
||||||
|
pathname = pos.pathname;
|
||||||
|
beg_pos = pos.beg_pos;
|
||||||
|
beg_line = pos.beg_line;
|
||||||
|
end_pos = pos.end_pos;
|
||||||
|
end_line = pos.end_line;
|
||||||
|
}
|
||||||
|
return *this;
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(HAVE_BOOST_SERIALIZATION)
|
||||||
|
private:
|
||||||
|
/** Serialization. */
|
||||||
|
|
||||||
|
friend class boost::serialization::access;
|
||||||
|
|
||||||
|
template<class Archive>
|
||||||
|
void serialize(Archive & ar, const unsigned int /* version */) {
|
||||||
|
ar & pathname;
|
||||||
|
ar & beg_pos;
|
||||||
|
ar & beg_line;
|
||||||
|
ar & end_pos;
|
||||||
|
ar & end_line;
|
||||||
|
}
|
||||||
|
#endif // HAVE_BOOST_SERIALIZATION
|
||||||
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @brief Brief
|
* @brief Brief
|
||||||
*
|
*
|
||||||
|
|
@ -61,28 +108,21 @@ public:
|
||||||
#define ITEM_NORMAL 0x00 // no flags at all, a basic posting
|
#define ITEM_NORMAL 0x00 // no flags at all, a basic posting
|
||||||
// jww (2009-10-27): I'm not consistent on the difference between these two.
|
// jww (2009-10-27): I'm not consistent on the difference between these two.
|
||||||
#define ITEM_GENERATED 0x01 // posting was not found in a journal
|
#define ITEM_GENERATED 0x01 // posting was not found in a journal
|
||||||
#define ITEM_TEMP 0x02 // posting is a temporary object
|
#define ITEM_TEMP 0x02 // posting is a managed temporary
|
||||||
|
|
||||||
enum state_t { UNCLEARED = 0, CLEARED, PENDING };
|
enum state_t { UNCLEARED = 0, CLEARED, PENDING };
|
||||||
|
|
||||||
state_t _state;
|
|
||||||
|
|
||||||
optional<date_t> _date;
|
|
||||||
optional<date_t> _date_eff;
|
|
||||||
optional<string> note;
|
|
||||||
|
|
||||||
typedef std::map<string, optional<string> > string_map;
|
typedef std::map<string, optional<string> > string_map;
|
||||||
|
|
||||||
|
state_t _state;
|
||||||
|
optional<date_t> _date;
|
||||||
|
optional<date_t> _date_eff;
|
||||||
|
optional<string> note;
|
||||||
|
optional<position_t> pos;
|
||||||
optional<string_map> metadata;
|
optional<string_map> metadata;
|
||||||
|
|
||||||
path pathname;
|
|
||||||
istream_pos_type beg_pos;
|
|
||||||
std::size_t beg_line;
|
|
||||||
istream_pos_type end_pos;
|
|
||||||
std::size_t end_line;
|
|
||||||
|
|
||||||
item_t(flags_t _flags = ITEM_NORMAL, const optional<string>& _note = none)
|
item_t(flags_t _flags = ITEM_NORMAL, const optional<string>& _note = none)
|
||||||
: supports_flags<>(_flags), _state(UNCLEARED), note(_note),
|
: supports_flags<>(_flags), _state(UNCLEARED), note(_note)
|
||||||
beg_pos(0), beg_line(0), end_pos(0), end_line(0)
|
|
||||||
{
|
{
|
||||||
TRACE_CTOR(item_t, "flags_t, const string&");
|
TRACE_CTOR(item_t, "flags_t, const string&");
|
||||||
}
|
}
|
||||||
|
|
@ -102,14 +142,8 @@ public:
|
||||||
|
|
||||||
_date = item._date;
|
_date = item._date;
|
||||||
_date_eff = item._date_eff;
|
_date_eff = item._date_eff;
|
||||||
|
|
||||||
note = item.note;
|
note = item.note;
|
||||||
|
pos = item.pos;
|
||||||
pathname = item.pathname;
|
|
||||||
beg_pos = item.beg_pos;
|
|
||||||
beg_line = item.beg_line;
|
|
||||||
end_pos = item.end_pos;
|
|
||||||
end_line = item.end_line;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool operator==(const item_t& xact) {
|
virtual bool operator==(const item_t& xact) {
|
||||||
|
|
@ -158,6 +192,25 @@ public:
|
||||||
virtual expr_t::ptr_op_t lookup(const string& name);
|
virtual expr_t::ptr_op_t lookup(const string& name);
|
||||||
|
|
||||||
bool valid() const;
|
bool valid() const;
|
||||||
|
|
||||||
|
#if defined(HAVE_BOOST_SERIALIZATION)
|
||||||
|
private:
|
||||||
|
/** Serialization. */
|
||||||
|
|
||||||
|
friend class boost::serialization::access;
|
||||||
|
|
||||||
|
template<class Archive>
|
||||||
|
void serialize(Archive & ar, const unsigned int /* version */) {
|
||||||
|
ar & boost::serialization::base_object<supports_flags<> >(*this);
|
||||||
|
ar & boost::serialization::base_object<scope_t>(*this);
|
||||||
|
ar & _state;
|
||||||
|
ar & _date;
|
||||||
|
ar & _date_eff;
|
||||||
|
ar & note;
|
||||||
|
ar & metadata;
|
||||||
|
ar & pos;
|
||||||
|
}
|
||||||
|
#endif // HAVE_BOOST_SERIALIZATION
|
||||||
};
|
};
|
||||||
|
|
||||||
value_t get_comment(item_t& item);
|
value_t get_comment(item_t& item);
|
||||||
|
|
|
||||||
|
|
@ -32,11 +32,34 @@
|
||||||
#include <system.hh>
|
#include <system.hh>
|
||||||
|
|
||||||
#include "journal.h"
|
#include "journal.h"
|
||||||
|
#include "amount.h"
|
||||||
|
#include "commodity.h"
|
||||||
|
#include "pool.h"
|
||||||
#include "xact.h"
|
#include "xact.h"
|
||||||
#include "account.h"
|
#include "account.h"
|
||||||
|
|
||||||
namespace ledger {
|
namespace ledger {
|
||||||
|
|
||||||
|
journal_t::journal_t()
|
||||||
|
: master(new account_t), was_loaded(false),
|
||||||
|
commodity_pool(new commodity_pool_t)
|
||||||
|
{
|
||||||
|
TRACE_CTOR(journal_t, "");
|
||||||
|
|
||||||
|
// Add time commodity conversions, so that timelog's may be parsed
|
||||||
|
// in terms of seconds, but reported as minutes or hours.
|
||||||
|
if (commodity_t * commodity = commodity_pool->create("s"))
|
||||||
|
commodity->add_flags(COMMODITY_BUILTIN | COMMODITY_NOMARKET);
|
||||||
|
else
|
||||||
|
assert(false);
|
||||||
|
|
||||||
|
// Add a "percentile" commodity
|
||||||
|
if (commodity_t * commodity = commodity_pool->create("%"))
|
||||||
|
commodity->add_flags(COMMODITY_BUILTIN | COMMODITY_NOMARKET);
|
||||||
|
else
|
||||||
|
assert(false);
|
||||||
|
}
|
||||||
|
|
||||||
journal_t::~journal_t()
|
journal_t::~journal_t()
|
||||||
{
|
{
|
||||||
TRACE_DTOR(journal_t);
|
TRACE_DTOR(journal_t);
|
||||||
|
|
@ -52,6 +75,9 @@ 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);
|
||||||
|
commodity_pool.reset();
|
||||||
}
|
}
|
||||||
|
|
||||||
void journal_t::add_account(account_t * acct)
|
void journal_t::add_account(account_t * acct)
|
||||||
|
|
|
||||||
|
|
@ -48,11 +48,11 @@
|
||||||
|
|
||||||
#include "utils.h"
|
#include "utils.h"
|
||||||
#include "hooks.h"
|
#include "hooks.h"
|
||||||
|
#include "times.h"
|
||||||
|
|
||||||
namespace ledger {
|
namespace ledger {
|
||||||
|
|
||||||
typedef std::list<path> paths_list;
|
class commodity_pool_t;
|
||||||
|
|
||||||
class xact_t;
|
class xact_t;
|
||||||
class auto_xact_t;
|
class auto_xact_t;
|
||||||
class xact_finalizer_t;
|
class xact_finalizer_t;
|
||||||
|
|
@ -72,18 +72,60 @@ typedef std::list<period_xact_t *> period_xacts_list;
|
||||||
class journal_t : public noncopyable
|
class journal_t : public noncopyable
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
account_t * master;
|
struct fileinfo_t
|
||||||
account_t * basket;
|
{
|
||||||
xacts_list xacts;
|
optional<path> filename;
|
||||||
|
uintmax_t size;
|
||||||
|
datetime_t modtime;
|
||||||
|
bool from_stream;
|
||||||
|
|
||||||
auto_xacts_list auto_xacts;
|
fileinfo_t() : size(0), from_stream(true) {
|
||||||
period_xacts_list period_xacts;
|
TRACE_CTOR(journal_t::fileinfo_t, "");
|
||||||
|
}
|
||||||
|
fileinfo_t(const path& _filename)
|
||||||
|
: filename(_filename), from_stream(false) {
|
||||||
|
TRACE_CTOR(journal_t::fileinfo_t, "const path&");
|
||||||
|
size = file_size(*filename);
|
||||||
|
modtime = posix_time::from_time_t(last_write_time(*filename));
|
||||||
|
}
|
||||||
|
fileinfo_t(const fileinfo_t& info)
|
||||||
|
: filename(info.filename), size(info.size),
|
||||||
|
modtime(info.modtime), from_stream(info.from_stream)
|
||||||
|
{
|
||||||
|
TRACE_CTOR(journal_t::fileinfo_t, "copy");
|
||||||
|
}
|
||||||
|
~fileinfo_t() throw() {
|
||||||
|
TRACE_DTOR(journal_t::fileinfo_t);
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(HAVE_BOOST_SERIALIZATION)
|
||||||
|
private:
|
||||||
|
/** Serialization. */
|
||||||
|
|
||||||
|
friend class boost::serialization::access;
|
||||||
|
|
||||||
|
template<class Archive>
|
||||||
|
void serialize(Archive & ar, const unsigned int /* version */) {
|
||||||
|
ar & filename;
|
||||||
|
ar & size;
|
||||||
|
ar & modtime;
|
||||||
|
ar & from_stream;
|
||||||
|
}
|
||||||
|
#endif // HAVE_BOOST_SERIALIZATION
|
||||||
|
};
|
||||||
|
|
||||||
|
account_t * master;
|
||||||
|
account_t * basket;
|
||||||
|
xacts_list xacts;
|
||||||
|
auto_xacts_list auto_xacts;
|
||||||
|
period_xacts_list period_xacts;
|
||||||
|
std::list<fileinfo_t> sources;
|
||||||
|
bool was_loaded;
|
||||||
|
|
||||||
|
shared_ptr<commodity_pool_t> commodity_pool;
|
||||||
hooks_t<xact_finalizer_t, xact_t> xact_finalize_hooks;
|
hooks_t<xact_finalizer_t, xact_t> xact_finalize_hooks;
|
||||||
|
|
||||||
journal_t(account_t * _master = NULL) : master(_master) {
|
journal_t();
|
||||||
TRACE_CTOR(journal_t, "");
|
|
||||||
}
|
|
||||||
~journal_t();
|
~journal_t();
|
||||||
|
|
||||||
// These four methods are delegated to the current session, since all
|
// These four methods are delegated to the current session, since all
|
||||||
|
|
@ -110,6 +152,23 @@ public:
|
||||||
bool strict = false);
|
bool strict = false);
|
||||||
|
|
||||||
bool valid() const;
|
bool valid() const;
|
||||||
|
|
||||||
|
#if defined(HAVE_BOOST_SERIALIZATION)
|
||||||
|
private:
|
||||||
|
/** Serialization. */
|
||||||
|
|
||||||
|
friend class boost::serialization::access;
|
||||||
|
|
||||||
|
template<class Archive>
|
||||||
|
void serialize(Archive & ar, const unsigned int /* version */) {
|
||||||
|
ar & master;
|
||||||
|
ar & basket;
|
||||||
|
ar & xacts;
|
||||||
|
ar & auto_xacts;
|
||||||
|
ar & period_xacts;
|
||||||
|
ar & sources;
|
||||||
|
}
|
||||||
|
#endif // HAVE_BOOST_SERIALIZATION
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ledger
|
} // namespace ledger
|
||||||
|
|
|
||||||
19
src/mask.h
19
src/mask.h
|
|
@ -94,6 +94,25 @@ public:
|
||||||
}
|
}
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(HAVE_BOOST_SERIALIZATION)
|
||||||
|
private:
|
||||||
|
/** Serialization. */
|
||||||
|
|
||||||
|
friend class boost::serialization::access;
|
||||||
|
|
||||||
|
template<class Archive>
|
||||||
|
void serialize(Archive & ar, const unsigned int /* version */) {
|
||||||
|
string temp;
|
||||||
|
if (Archive::is_loading::value) {
|
||||||
|
ar & temp;
|
||||||
|
*this = temp;
|
||||||
|
} else {
|
||||||
|
temp = expr.str();
|
||||||
|
ar & temp;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif // HAVE_BOOST_SERIALIZATION
|
||||||
};
|
};
|
||||||
|
|
||||||
inline std::ostream& operator<<(std::ostream& out, const mask_t& mask) {
|
inline std::ostream& operator<<(std::ostream& out, const mask_t& mask) {
|
||||||
|
|
|
||||||
|
|
@ -172,12 +172,12 @@ value_t expr_t::op_t::calc(scope_t& scope, ptr_op_t * locus, const int depth)
|
||||||
left()->left() && left()->left()->is_function()) {
|
left()->left() && left()->left()->is_function()) {
|
||||||
call_scope_t call_args(scope);
|
call_scope_t call_args(scope);
|
||||||
if (value_t obj = left()->left()->as_function()(call_args)) {
|
if (value_t obj = left()->left()->as_function()(call_args)) {
|
||||||
if (obj.is_pointer()) {
|
if (obj.is_scope()) {
|
||||||
if (obj.as_pointer_lval<scope_t>() == NULL) {
|
if (obj.as_scope() == NULL) {
|
||||||
throw_(calc_error,
|
throw_(calc_error,
|
||||||
_("Left operand of . operator is NULL"));
|
_("Left operand of . operator is NULL"));
|
||||||
} else {
|
} else {
|
||||||
scope_t& objscope(obj.as_ref_lval<scope_t>());
|
scope_t& objscope(*obj.as_scope());
|
||||||
if (ptr_op_t member = objscope.lookup(right()->as_ident())) {
|
if (ptr_op_t member = objscope.lookup(right()->as_ident())) {
|
||||||
result = member->calc(objscope, NULL, depth + 1);
|
result = member->calc(objscope, NULL, depth + 1);
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
28
src/op.h
28
src/op.h
|
|
@ -192,6 +192,7 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
ptr_op_t& left() {
|
ptr_op_t& left() {
|
||||||
|
assert(kind > TERMINALS || kind == IDENT);
|
||||||
return left_;
|
return left_;
|
||||||
}
|
}
|
||||||
const ptr_op_t& left() const {
|
const ptr_op_t& left() const {
|
||||||
|
|
@ -289,6 +290,33 @@ public:
|
||||||
|
|
||||||
static ptr_op_t wrap_value(const value_t& val);
|
static ptr_op_t wrap_value(const value_t& val);
|
||||||
static ptr_op_t wrap_functor(const function_t& fobj);
|
static ptr_op_t wrap_functor(const function_t& fobj);
|
||||||
|
|
||||||
|
#if defined(HAVE_BOOST_SERIALIZATION)
|
||||||
|
private:
|
||||||
|
/** Serialization. */
|
||||||
|
|
||||||
|
friend class boost::serialization::access;
|
||||||
|
|
||||||
|
template<class Archive>
|
||||||
|
void serialize(Archive & ar, const unsigned int /* version */) {
|
||||||
|
ar & refc;
|
||||||
|
ar & kind;
|
||||||
|
if (Archive::is_loading::value || ! left_ || left_->kind != FUNCTION) {
|
||||||
|
ar & left_;
|
||||||
|
} else {
|
||||||
|
ptr_op_t temp_op;
|
||||||
|
ar & temp_op;
|
||||||
|
}
|
||||||
|
if (Archive::is_loading::value || kind == VALUE || kind == IDENT ||
|
||||||
|
(kind > UNARY_OPERATORS &&
|
||||||
|
(! has_right() || ! right()->is_function()))) {
|
||||||
|
ar & data;
|
||||||
|
} else {
|
||||||
|
variant<ptr_op_t, value_t, string, function_t> temp_data;
|
||||||
|
ar & temp_data;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
#endif // HAVE_BOOST_SERIALIZATION
|
||||||
};
|
};
|
||||||
|
|
||||||
inline expr_t::ptr_op_t
|
inline expr_t::ptr_op_t
|
||||||
|
|
|
||||||
|
|
@ -203,7 +203,7 @@ void format_accounts::flush()
|
||||||
disp_pred.predicate.parse(report.HANDLER(display_).str());
|
disp_pred.predicate.parse(report.HANDLER(display_).str());
|
||||||
}
|
}
|
||||||
|
|
||||||
mark_accounts(*report.session.master, report.HANDLED(flat));
|
mark_accounts(*report.session.journal->master, report.HANDLED(flat));
|
||||||
|
|
||||||
std::size_t displayed = 0;
|
std::size_t displayed = 0;
|
||||||
|
|
||||||
|
|
@ -212,7 +212,7 @@ void format_accounts::flush()
|
||||||
|
|
||||||
if (displayed > 1 &&
|
if (displayed > 1 &&
|
||||||
! report.HANDLED(no_total) && ! report.HANDLED(percent)) {
|
! report.HANDLED(no_total) && ! report.HANDLED(percent)) {
|
||||||
bind_scope_t bound_scope(report, *report.session.master);
|
bind_scope_t bound_scope(report, *report.session.journal->master);
|
||||||
separator_format.format(out, bound_scope);
|
separator_format.format(out, bound_scope);
|
||||||
total_line_format.format(out, bound_scope);
|
total_line_format.format(out, bound_scope);
|
||||||
}
|
}
|
||||||
|
|
|
||||||
18
src/pool.h
18
src/pool.h
|
|
@ -134,6 +134,24 @@ public:
|
||||||
parse_price_expression(const std::string& str,
|
parse_price_expression(const std::string& str,
|
||||||
const bool add_prices = true,
|
const bool add_prices = true,
|
||||||
const optional<datetime_t>& moment = none);
|
const optional<datetime_t>& moment = none);
|
||||||
|
|
||||||
|
#if defined(HAVE_BOOST_SERIALIZATION)
|
||||||
|
private:
|
||||||
|
/** Serialization. */
|
||||||
|
|
||||||
|
friend class boost::serialization::access;
|
||||||
|
|
||||||
|
template<class Archive>
|
||||||
|
void serialize(Archive & ar, const unsigned int /* version */) {
|
||||||
|
ar & commodities;
|
||||||
|
ar & null_commodity;
|
||||||
|
ar & default_commodity;
|
||||||
|
ar & keep_base;
|
||||||
|
ar & price_db;
|
||||||
|
ar & quote_leeway;
|
||||||
|
ar & get_quotes;
|
||||||
|
}
|
||||||
|
#endif // HAVE_BOOST_SERIALIZATION
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ledger
|
} // namespace ledger
|
||||||
|
|
|
||||||
17
src/post.h
17
src/post.h
|
|
@ -205,6 +205,23 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
friend class xact_t;
|
friend class xact_t;
|
||||||
|
|
||||||
|
#if defined(HAVE_BOOST_SERIALIZATION)
|
||||||
|
private:
|
||||||
|
/** Serialization. */
|
||||||
|
|
||||||
|
friend class boost::serialization::access;
|
||||||
|
|
||||||
|
template<class Archive>
|
||||||
|
void serialize(Archive & ar, const unsigned int /* version */) {
|
||||||
|
ar & boost::serialization::base_object<item_t>(*this);
|
||||||
|
ar & xact;
|
||||||
|
ar & account;
|
||||||
|
ar & amount;
|
||||||
|
ar & cost;
|
||||||
|
ar & assigned_amount;
|
||||||
|
}
|
||||||
|
#endif // HAVE_BOOST_SERIALIZATION
|
||||||
};
|
};
|
||||||
|
|
||||||
} // namespace ledger
|
} // namespace ledger
|
||||||
|
|
|
||||||
|
|
@ -94,6 +94,19 @@ public:
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(HAVE_BOOST_SERIALIZATION)
|
||||||
|
private:
|
||||||
|
/** Serialization. */
|
||||||
|
|
||||||
|
friend class boost::serialization::access;
|
||||||
|
|
||||||
|
template<class Archive>
|
||||||
|
void serialize(Archive & ar, const unsigned int /* version */) {
|
||||||
|
ar & predicate;
|
||||||
|
ar & what_to_keep;
|
||||||
|
}
|
||||||
|
#endif // HAVE_BOOST_SERIALIZATION
|
||||||
};
|
};
|
||||||
|
|
||||||
class query_lexer_t
|
class query_lexer_t
|
||||||
|
|
|
||||||
|
|
@ -45,8 +45,8 @@ BOOST_PYTHON_MEMBER_FUNCTION_OVERLOADS(value_overloads, value, 0, 2)
|
||||||
namespace {
|
namespace {
|
||||||
expr_t py_value_getattr(const value_t& value, const string& name)
|
expr_t py_value_getattr(const value_t& value, const string& name)
|
||||||
{
|
{
|
||||||
if (value.is_pointer()) {
|
if (value.is_scope()) {
|
||||||
if (scope_t * scope = value.as_pointer<scope_t>())
|
if (scope_t * scope = value.as_scope())
|
||||||
return expr_t(scope->lookup(name), scope);
|
return expr_t(scope->lookup(name), scope);
|
||||||
}
|
}
|
||||||
throw_(value_error, _("Cannot lookup attributes in %1") << value.label());
|
throw_(value_error, _("Cannot lookup attributes in %1") << value.label());
|
||||||
|
|
@ -283,7 +283,7 @@ void export_value()
|
||||||
.value("BALANCE", value_t::BALANCE)
|
.value("BALANCE", value_t::BALANCE)
|
||||||
.value("STRING", value_t::STRING)
|
.value("STRING", value_t::STRING)
|
||||||
.value("SEQUENCE", value_t::SEQUENCE)
|
.value("SEQUENCE", value_t::SEQUENCE)
|
||||||
.value("POINTER", value_t::POINTER)
|
.value("SCOPE", value_t::SCOPE)
|
||||||
;
|
;
|
||||||
|
|
||||||
scope().attr("NULL_VALUE") = NULL_VALUE;
|
scope().attr("NULL_VALUE") = NULL_VALUE;
|
||||||
|
|
|
||||||
|
|
@ -87,11 +87,11 @@ void report_t::accounts_report(acct_handler_ptr handler)
|
||||||
|
|
||||||
scoped_ptr<accounts_iterator> iter;
|
scoped_ptr<accounts_iterator> iter;
|
||||||
if (! HANDLED(sort_)) {
|
if (! HANDLED(sort_)) {
|
||||||
iter.reset(new basic_accounts_iterator(*session.master));
|
iter.reset(new basic_accounts_iterator(*session.journal->master));
|
||||||
} else {
|
} else {
|
||||||
expr_t sort_expr(HANDLER(sort_).str());
|
expr_t sort_expr(HANDLER(sort_).str());
|
||||||
sort_expr.set_context(this);
|
sort_expr.set_context(this);
|
||||||
iter.reset(new sorted_accounts_iterator(*session.master.get(),
|
iter.reset(new sorted_accounts_iterator(*session.journal->master,
|
||||||
sort_expr, HANDLED(flat)));
|
sort_expr, HANDLED(flat)));
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
|
||||||
66
src/scope.h
66
src/scope.h
|
|
@ -67,6 +67,16 @@ public:
|
||||||
|
|
||||||
virtual void define(const string&, expr_t::ptr_op_t) {}
|
virtual void define(const string&, expr_t::ptr_op_t) {}
|
||||||
virtual expr_t::ptr_op_t lookup(const string& name) = 0;
|
virtual expr_t::ptr_op_t lookup(const string& name) = 0;
|
||||||
|
|
||||||
|
#if defined(HAVE_BOOST_SERIALIZATION)
|
||||||
|
private:
|
||||||
|
/** Serialization. */
|
||||||
|
|
||||||
|
friend class boost::serialization::access;
|
||||||
|
|
||||||
|
template<class Archive>
|
||||||
|
void serialize(Archive &, const unsigned int /* version */) {}
|
||||||
|
#endif // HAVE_BOOST_SERIALIZATION
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -100,6 +110,19 @@ public:
|
||||||
return parent->lookup(name);
|
return parent->lookup(name);
|
||||||
return NULL;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(HAVE_BOOST_SERIALIZATION)
|
||||||
|
private:
|
||||||
|
/** Serialization. */
|
||||||
|
|
||||||
|
friend class boost::serialization::access;
|
||||||
|
|
||||||
|
template<class Archive>
|
||||||
|
void serialize(Archive & ar, const unsigned int /* version */) {
|
||||||
|
ar & boost::serialization::base_object<scope_t>(*this);
|
||||||
|
ar & parent;
|
||||||
|
}
|
||||||
|
#endif // HAVE_BOOST_SERIALIZATION
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -127,6 +150,19 @@ public:
|
||||||
virtual void define(const string& name, expr_t::ptr_op_t def);
|
virtual void define(const string& name, expr_t::ptr_op_t def);
|
||||||
|
|
||||||
virtual expr_t::ptr_op_t lookup(const string& name);
|
virtual expr_t::ptr_op_t lookup(const string& name);
|
||||||
|
|
||||||
|
#if defined(HAVE_BOOST_SERIALIZATION)
|
||||||
|
private:
|
||||||
|
/** Serialization. */
|
||||||
|
|
||||||
|
friend class boost::serialization::access;
|
||||||
|
|
||||||
|
template<class Archive>
|
||||||
|
void serialize(Archive & ar, const unsigned int /* version */) {
|
||||||
|
ar & boost::serialization::base_object<child_scope_t>(*this);
|
||||||
|
ar & symbols;
|
||||||
|
}
|
||||||
|
#endif // HAVE_BOOST_SERIALIZATION
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -138,8 +174,6 @@ class call_scope_t : public child_scope_t
|
||||||
{
|
{
|
||||||
value_t args;
|
value_t args;
|
||||||
|
|
||||||
call_scope_t();
|
|
||||||
|
|
||||||
public:
|
public:
|
||||||
explicit call_scope_t(scope_t& _parent) : child_scope_t(_parent) {
|
explicit call_scope_t(scope_t& _parent) : child_scope_t(_parent) {
|
||||||
TRACE_CTOR(call_scope_t, "scope_t&");
|
TRACE_CTOR(call_scope_t, "scope_t&");
|
||||||
|
|
@ -182,6 +216,21 @@ public:
|
||||||
bool empty() const {
|
bool empty() const {
|
||||||
return args.size() == 0;
|
return args.size() == 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(HAVE_BOOST_SERIALIZATION)
|
||||||
|
private:
|
||||||
|
explicit call_scope_t() {}
|
||||||
|
|
||||||
|
/** Serialization. */
|
||||||
|
|
||||||
|
friend class boost::serialization::access;
|
||||||
|
|
||||||
|
template<class Archive>
|
||||||
|
void serialize(Archive & ar, const unsigned int /* version */) {
|
||||||
|
ar & boost::serialization::base_object<child_scope_t>(*this);
|
||||||
|
ar & args;
|
||||||
|
}
|
||||||
|
#endif // HAVE_BOOST_SERIALIZATION
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -215,6 +264,19 @@ public:
|
||||||
return def;
|
return def;
|
||||||
return child_scope_t::lookup(name);
|
return child_scope_t::lookup(name);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(HAVE_BOOST_SERIALIZATION)
|
||||||
|
private:
|
||||||
|
/** Serialization. */
|
||||||
|
|
||||||
|
friend class boost::serialization::access;
|
||||||
|
|
||||||
|
template<class Archive>
|
||||||
|
void serialize(Archive & ar, const unsigned int /* version */) {
|
||||||
|
ar & boost::serialization::base_object<child_scope_t>(*this);
|
||||||
|
ar & grandchild;
|
||||||
|
}
|
||||||
|
#endif // HAVE_BOOST_SERIALIZATION
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
130
src/session.cc
130
src/session.cc
|
|
@ -32,13 +32,12 @@
|
||||||
#include <system.hh>
|
#include <system.hh>
|
||||||
|
|
||||||
#include "session.h"
|
#include "session.h"
|
||||||
#include "commodity.h"
|
|
||||||
#include "pool.h"
|
|
||||||
#include "xact.h"
|
#include "xact.h"
|
||||||
#include "account.h"
|
#include "account.h"
|
||||||
#include "journal.h"
|
#include "journal.h"
|
||||||
#include "iterators.h"
|
#include "iterators.h"
|
||||||
#include "filters.h"
|
#include "filters.h"
|
||||||
|
#include "archive.h"
|
||||||
|
|
||||||
namespace ledger {
|
namespace ledger {
|
||||||
|
|
||||||
|
|
@ -46,7 +45,7 @@ void set_session_context(session_t * session)
|
||||||
{
|
{
|
||||||
if (session) {
|
if (session) {
|
||||||
times_initialize();
|
times_initialize();
|
||||||
amount_t::initialize(session->commodity_pool);
|
amount_t::initialize(session->journal->commodity_pool);
|
||||||
|
|
||||||
// jww (2009-02-04): Is amount_t the right place for parse_conversion to
|
// jww (2009-02-04): Is amount_t the right place for parse_conversion to
|
||||||
// happen?
|
// happen?
|
||||||
|
|
@ -64,12 +63,8 @@ void set_session_context(session_t * session)
|
||||||
|
|
||||||
session_t::session_t()
|
session_t::session_t()
|
||||||
: flush_on_next_data_file(false),
|
: flush_on_next_data_file(false),
|
||||||
|
|
||||||
current_year(CURRENT_DATE().year()),
|
current_year(CURRENT_DATE().year()),
|
||||||
|
journal(new journal_t)
|
||||||
commodity_pool(new commodity_pool_t),
|
|
||||||
master(new account_t),
|
|
||||||
journal(new journal_t(master.get()))
|
|
||||||
{
|
{
|
||||||
TRACE_CTOR(session_t, "");
|
TRACE_CTOR(session_t, "");
|
||||||
|
|
||||||
|
|
@ -77,19 +72,6 @@ session_t::session_t()
|
||||||
HANDLER(price_db_).on(none, (path(home_var) / ".pricedb").string());
|
HANDLER(price_db_).on(none, (path(home_var) / ".pricedb").string());
|
||||||
else
|
else
|
||||||
HANDLER(price_db_).on(none, path("./.pricedb").string());
|
HANDLER(price_db_).on(none, path("./.pricedb").string());
|
||||||
|
|
||||||
// Add time commodity conversions, so that timelog's may be parsed
|
|
||||||
// in terms of seconds, but reported as minutes or hours.
|
|
||||||
if (commodity_t * commodity = commodity_pool->create("s"))
|
|
||||||
commodity->add_flags(COMMODITY_BUILTIN | COMMODITY_NOMARKET);
|
|
||||||
else
|
|
||||||
assert(false);
|
|
||||||
|
|
||||||
// Add a "percentile" commodity
|
|
||||||
if (commodity_t * commodity = commodity_pool->create("%"))
|
|
||||||
commodity->add_flags(COMMODITY_BUILTIN | COMMODITY_NOMARKET);
|
|
||||||
else
|
|
||||||
assert(false);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
std::size_t session_t::read_journal(std::istream& in,
|
std::size_t session_t::read_journal(std::istream& in,
|
||||||
|
|
@ -123,6 +105,9 @@ std::size_t session_t::read_journal(const path& pathname,
|
||||||
|
|
||||||
std::size_t session_t::read_data(const string& master_account)
|
std::size_t session_t::read_data(const string& master_account)
|
||||||
{
|
{
|
||||||
|
bool populated_data_files = false;
|
||||||
|
bool populated_price_db = false;
|
||||||
|
|
||||||
if (HANDLER(file_).data_files.empty()) {
|
if (HANDLER(file_).data_files.empty()) {
|
||||||
path file;
|
path file;
|
||||||
if (const char * home_var = std::getenv("HOME"))
|
if (const char * home_var = std::getenv("HOME"))
|
||||||
|
|
@ -132,6 +117,8 @@ std::size_t session_t::read_data(const string& master_account)
|
||||||
HANDLER(file_).data_files.push_back(file);
|
HANDLER(file_).data_files.push_back(file);
|
||||||
else
|
else
|
||||||
throw_(parse_error, "No journal file was specified (please use -f)");
|
throw_(parse_error, "No journal file was specified (please use -f)");
|
||||||
|
|
||||||
|
populated_data_files = true;
|
||||||
}
|
}
|
||||||
|
|
||||||
std::size_t xact_count = 0;
|
std::size_t xact_count = 0;
|
||||||
|
|
@ -140,43 +127,75 @@ std::size_t session_t::read_data(const string& master_account)
|
||||||
if (! master_account.empty())
|
if (! master_account.empty())
|
||||||
acct = journal->find_account(master_account);
|
acct = journal->find_account(master_account);
|
||||||
|
|
||||||
if (HANDLED(price_db_)) {
|
optional<path> price_db_path;
|
||||||
path price_db_path = resolve_path(HANDLER(price_db_).str());
|
if (HANDLED(price_db_))
|
||||||
if (exists(price_db_path) && read_journal(price_db_path) > 0)
|
price_db_path = resolve_path(HANDLER(price_db_).str());
|
||||||
|
|
||||||
|
optional<archive_t> cache;
|
||||||
|
if (HANDLED(cache_) && master_account.empty()) {
|
||||||
|
cache = archive_t(HANDLED(cache_).str());
|
||||||
|
cache->read_header();
|
||||||
|
|
||||||
|
if (price_db_path) {
|
||||||
|
HANDLER(file_).data_files.push_back(*price_db_path);
|
||||||
|
populated_price_db = true;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
if (! (cache &&
|
||||||
|
cache->should_load(HANDLER(file_).data_files) &&
|
||||||
|
cache->load(journal))) {
|
||||||
|
if (price_db_path) {
|
||||||
|
if (exists(*price_db_path) && read_journal(*price_db_path) > 0)
|
||||||
throw_(parse_error, _("Transactions not allowed in price history file"));
|
throw_(parse_error, _("Transactions not allowed in price history file"));
|
||||||
}
|
journal->sources.push_back(journal_t::fileinfo_t(*price_db_path));
|
||||||
|
HANDLER(file_).data_files.remove(*price_db_path);
|
||||||
|
}
|
||||||
|
|
||||||
foreach (const path& pathname, HANDLER(file_).data_files) {
|
foreach (const path& pathname, HANDLER(file_).data_files) {
|
||||||
path filename = resolve_path(pathname);
|
path filename = resolve_path(pathname);
|
||||||
if (filename == "-") {
|
if (filename == "-") {
|
||||||
// To avoid problems with stdin and pipes, etc., we read the entire
|
// To avoid problems with stdin and pipes, etc., we read the entire
|
||||||
// file in beforehand into a memory buffer, and then parcel it out
|
// file in beforehand into a memory buffer, and then parcel it out
|
||||||
// from there.
|
// from there.
|
||||||
std::ostringstream buffer;
|
std::ostringstream buffer;
|
||||||
|
|
||||||
while (std::cin.good() && ! std::cin.eof()) {
|
while (std::cin.good() && ! std::cin.eof()) {
|
||||||
char line[8192];
|
char line[8192];
|
||||||
std::cin.read(line, 8192);
|
std::cin.read(line, 8192);
|
||||||
std::streamsize count = std::cin.gcount();
|
std::streamsize count = std::cin.gcount();
|
||||||
buffer.write(line, count);
|
buffer.write(line, count);
|
||||||
|
}
|
||||||
|
buffer.flush();
|
||||||
|
|
||||||
|
std::istringstream buf_in(buffer.str());
|
||||||
|
|
||||||
|
xact_count += read_journal(buf_in, "/dev/stdin", acct);
|
||||||
|
journal->sources.push_back(journal_t::fileinfo_t());
|
||||||
}
|
}
|
||||||
buffer.flush();
|
else if (exists(filename)) {
|
||||||
|
xact_count += read_journal(filename, acct);
|
||||||
|
journal->sources.push_back(journal_t::fileinfo_t(filename));
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
throw_(parse_error, _("Could not read journal file '%1'") << filename);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
std::istringstream buf_in(buffer.str());
|
assert(xact_count == journal->xacts.size());
|
||||||
|
|
||||||
xact_count += read_journal(buf_in, "/dev/stdin", acct);
|
if (cache && cache->should_save(journal))
|
||||||
}
|
cache->save(journal);
|
||||||
else if (exists(filename)) {
|
|
||||||
xact_count += read_journal(filename, acct);
|
|
||||||
}
|
|
||||||
else {
|
|
||||||
throw_(parse_error, _("Could not read journal file '%1'") << filename);
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (populated_data_files)
|
||||||
|
HANDLER(file_).data_files.clear();
|
||||||
|
else if (populated_price_db)
|
||||||
|
HANDLER(file_).data_files.remove(*price_db_path);
|
||||||
|
|
||||||
VERIFY(journal->valid());
|
VERIFY(journal->valid());
|
||||||
|
|
||||||
return xact_count;
|
return journal->xacts.size();
|
||||||
}
|
}
|
||||||
|
|
||||||
void session_t::read_journal_files()
|
void session_t::read_journal_files()
|
||||||
|
|
@ -200,14 +219,10 @@ void session_t::read_journal_files()
|
||||||
void session_t::close_journal_files()
|
void session_t::close_journal_files()
|
||||||
{
|
{
|
||||||
journal.reset();
|
journal.reset();
|
||||||
master.reset();
|
|
||||||
commodity_pool.reset();
|
|
||||||
amount_t::shutdown();
|
amount_t::shutdown();
|
||||||
|
|
||||||
commodity_pool.reset(new commodity_pool_t);
|
journal.reset(new journal_t);
|
||||||
amount_t::initialize(commodity_pool);
|
amount_t::initialize(journal->commodity_pool);
|
||||||
master.reset(new account_t);
|
|
||||||
journal.reset(new journal_t(master.get()));
|
|
||||||
}
|
}
|
||||||
|
|
||||||
void session_t::clean_posts()
|
void session_t::clean_posts()
|
||||||
|
|
@ -224,9 +239,9 @@ void session_t::clean_posts(xact_t& xact)
|
||||||
|
|
||||||
void session_t::clean_accounts()
|
void session_t::clean_accounts()
|
||||||
{
|
{
|
||||||
basic_accounts_iterator acct_walker(*master);
|
basic_accounts_iterator acct_walker(*journal->master);
|
||||||
pass_down_accounts(acct_handler_ptr(new clear_account_xdata), acct_walker);
|
pass_down_accounts(acct_handler_ptr(new clear_account_xdata), acct_walker);
|
||||||
master->clear_xdata();
|
journal->master->clear_xdata();
|
||||||
}
|
}
|
||||||
|
|
||||||
option_t<session_t> * session_t::lookup_option(const char * p)
|
option_t<session_t> * session_t::lookup_option(const char * p)
|
||||||
|
|
@ -241,6 +256,9 @@ option_t<session_t> * session_t::lookup_option(const char * p)
|
||||||
case 'a':
|
case 'a':
|
||||||
OPT_(account_); // -a
|
OPT_(account_); // -a
|
||||||
break;
|
break;
|
||||||
|
case 'c':
|
||||||
|
OPT(cache_);
|
||||||
|
break;
|
||||||
case 'd':
|
case 'd':
|
||||||
OPT(download); // -Q
|
OPT(download); // -Q
|
||||||
break;
|
break;
|
||||||
|
|
|
||||||
|
|
@ -66,12 +66,9 @@ class session_t : public symbol_scope_t
|
||||||
friend void set_session_context(session_t * session);
|
friend void set_session_context(session_t * session);
|
||||||
|
|
||||||
public:
|
public:
|
||||||
bool flush_on_next_data_file;
|
bool flush_on_next_data_file;
|
||||||
date_t::year_type current_year;
|
date_t::year_type current_year;
|
||||||
|
shared_ptr<journal_t> journal;
|
||||||
shared_ptr<commodity_pool_t> commodity_pool;
|
|
||||||
scoped_ptr<account_t> master;
|
|
||||||
scoped_ptr<journal_t> journal;
|
|
||||||
|
|
||||||
explicit session_t();
|
explicit session_t();
|
||||||
virtual ~session_t() {
|
virtual ~session_t() {
|
||||||
|
|
@ -106,6 +103,7 @@ public:
|
||||||
void report_options(std::ostream& out)
|
void report_options(std::ostream& out)
|
||||||
{
|
{
|
||||||
HANDLER(account_).report(out);
|
HANDLER(account_).report(out);
|
||||||
|
HANDLER(cache_).report(out);
|
||||||
HANDLER(download).report(out);
|
HANDLER(download).report(out);
|
||||||
HANDLER(file_).report(out);
|
HANDLER(file_).report(out);
|
||||||
HANDLER(input_date_format_).report(out);
|
HANDLER(input_date_format_).report(out);
|
||||||
|
|
@ -123,6 +121,7 @@ public:
|
||||||
*/
|
*/
|
||||||
|
|
||||||
OPTION(session_t, account_); // -a
|
OPTION(session_t, account_); // -a
|
||||||
|
OPTION(session_t, cache_);
|
||||||
OPTION(session_t, download); // -Q
|
OPTION(session_t, download); // -Q
|
||||||
|
|
||||||
OPTION__
|
OPTION__
|
||||||
|
|
|
||||||
|
|
@ -46,7 +46,7 @@ value_t report_statistics(call_scope_t& args)
|
||||||
std::ostream& out(report.output_stream);
|
std::ostream& out(report.output_stream);
|
||||||
|
|
||||||
const account_t::xdata_t::details_t&
|
const account_t::xdata_t::details_t&
|
||||||
statistics(report.session.master->family_details(true));
|
statistics(report.session.journal->master->family_details(true));
|
||||||
|
|
||||||
if (! is_valid(statistics.earliest_post) &&
|
if (! is_valid(statistics.earliest_post) &&
|
||||||
! is_valid(statistics.latest_post))
|
! is_valid(statistics.latest_post))
|
||||||
|
|
|
||||||
|
|
@ -138,7 +138,6 @@ typedef std::ostream::pos_type ostream_pos_type;
|
||||||
|
|
||||||
#include <boost/algorithm/string/classification.hpp>
|
#include <boost/algorithm/string/classification.hpp>
|
||||||
#include <boost/algorithm/string/predicate.hpp>
|
#include <boost/algorithm/string/predicate.hpp>
|
||||||
#include <boost/any.hpp>
|
|
||||||
#include <boost/bind.hpp>
|
#include <boost/bind.hpp>
|
||||||
#include <boost/cast.hpp>
|
#include <boost/cast.hpp>
|
||||||
#include <boost/current_function.hpp>
|
#include <boost/current_function.hpp>
|
||||||
|
|
@ -168,6 +167,74 @@ typedef std::ostream::pos_type ostream_pos_type;
|
||||||
#include <boost/variant.hpp>
|
#include <boost/variant.hpp>
|
||||||
#include <boost/version.hpp>
|
#include <boost/version.hpp>
|
||||||
|
|
||||||
|
#if defined(HAVE_BOOST_SERIALIZATION)
|
||||||
|
|
||||||
|
#include <boost/archive/binary_iarchive.hpp>
|
||||||
|
#include <boost/archive/binary_oarchive.hpp>
|
||||||
|
|
||||||
|
#include <boost/serialization/base_object.hpp>
|
||||||
|
#include <boost/serialization/binary_object.hpp>
|
||||||
|
#include <boost/serialization/optional.hpp>
|
||||||
|
#include <boost/serialization/shared_ptr.hpp>
|
||||||
|
#include <boost/serialization/variant.hpp>
|
||||||
|
#include <boost/serialization/utility.hpp>
|
||||||
|
#include <boost/serialization/export.hpp>
|
||||||
|
#include <boost/serialization/level.hpp>
|
||||||
|
#include <boost/serialization/string.hpp>
|
||||||
|
#include <boost/serialization/vector.hpp>
|
||||||
|
#include <boost/serialization/deque.hpp>
|
||||||
|
#include <boost/serialization/list.hpp>
|
||||||
|
#include <boost/serialization/map.hpp>
|
||||||
|
|
||||||
|
#include <boost/date_time/posix_time/time_serialize.hpp>
|
||||||
|
#include <boost/date_time/gregorian/greg_serialize.hpp>
|
||||||
|
|
||||||
|
namespace boost {
|
||||||
|
namespace serialization {
|
||||||
|
|
||||||
|
template <class Archive>
|
||||||
|
void serialize(Archive& ar, boost::filesystem::path& p, const unsigned int)
|
||||||
|
{
|
||||||
|
std::string s;
|
||||||
|
if (Archive::is_saving::value)
|
||||||
|
s = p.string();
|
||||||
|
|
||||||
|
ar & s;
|
||||||
|
|
||||||
|
if (Archive::is_loading::value)
|
||||||
|
p = s;
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class Archive, class T>
|
||||||
|
void serialize(Archive& ar, boost::intrusive_ptr<T>& ptr, const unsigned int)
|
||||||
|
{
|
||||||
|
if (Archive::is_saving::value) {
|
||||||
|
T * p = ptr.get();
|
||||||
|
ar & p;
|
||||||
|
}
|
||||||
|
else if (Archive::is_loading::value) {
|
||||||
|
T * p;
|
||||||
|
ar & p;
|
||||||
|
ptr.reset(p);
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class Archive, class T>
|
||||||
|
void serialize(Archive&, boost::function<T>&, const unsigned int)
|
||||||
|
{
|
||||||
|
}
|
||||||
|
|
||||||
|
template <class Archive>
|
||||||
|
void serialize(Archive& ar, istream_pos_type& pos, const unsigned int)
|
||||||
|
{
|
||||||
|
ar & make_binary_object(&pos, sizeof(istream_pos_type));
|
||||||
|
}
|
||||||
|
|
||||||
|
} // namespace serialization
|
||||||
|
} // namespace boost
|
||||||
|
|
||||||
|
#endif // HAVE_BOOST_SERIALIZATION
|
||||||
|
|
||||||
#if defined(HAVE_BOOST_PYTHON)
|
#if defined(HAVE_BOOST_PYTHON)
|
||||||
|
|
||||||
#include <boost/python.hpp>
|
#include <boost/python.hpp>
|
||||||
|
|
|
||||||
|
|
@ -525,11 +525,12 @@ void instance_t::automated_xact_directive(char * line)
|
||||||
|
|
||||||
journal.auto_xacts.push_back(ae.get());
|
journal.auto_xacts.push_back(ae.get());
|
||||||
|
|
||||||
ae->pathname = pathname;
|
ae->pos = position_t();
|
||||||
ae->beg_pos = pos;
|
ae->pos->pathname = pathname;
|
||||||
ae->beg_line = lnum;
|
ae->pos->beg_pos = pos;
|
||||||
ae->end_pos = curr_pos;
|
ae->pos->beg_line = lnum;
|
||||||
ae->end_line = linenum;
|
ae->pos->end_pos = curr_pos;
|
||||||
|
ae->pos->end_line = linenum;
|
||||||
|
|
||||||
ae.release();
|
ae.release();
|
||||||
}
|
}
|
||||||
|
|
@ -565,11 +566,12 @@ void instance_t::period_xact_directive(char * line)
|
||||||
|
|
||||||
journal.period_xacts.push_back(pe.get());
|
journal.period_xacts.push_back(pe.get());
|
||||||
|
|
||||||
pe->pathname = pathname;
|
pe->pos = position_t();
|
||||||
pe->beg_pos = pos;
|
pe->pos->pathname = pathname;
|
||||||
pe->beg_line = lnum;
|
pe->pos->beg_pos = pos;
|
||||||
pe->end_pos = curr_pos;
|
pe->pos->beg_line = lnum;
|
||||||
pe->end_line = linenum;
|
pe->pos->end_pos = curr_pos;
|
||||||
|
pe->pos->end_line = linenum;
|
||||||
|
|
||||||
pe.release();
|
pe.release();
|
||||||
} else {
|
} else {
|
||||||
|
|
@ -778,10 +780,11 @@ post_t * instance_t::parse_post(char * line,
|
||||||
|
|
||||||
std::auto_ptr<post_t> post(new post_t);
|
std::auto_ptr<post_t> post(new post_t);
|
||||||
|
|
||||||
post->xact = xact; // this could be NULL
|
post->xact = xact; // this could be NULL
|
||||||
post->pathname = pathname;
|
post->pos = position_t();
|
||||||
post->beg_pos = line_beg_pos;
|
post->pos->pathname = pathname;
|
||||||
post->beg_line = linenum;
|
post->pos->beg_pos = line_beg_pos;
|
||||||
|
post->pos->beg_line = linenum;
|
||||||
|
|
||||||
char buf[MAX_LINE + 1];
|
char buf[MAX_LINE + 1];
|
||||||
std::strcpy(buf, line);
|
std::strcpy(buf, line);
|
||||||
|
|
@ -1056,8 +1059,8 @@ post_t * instance_t::parse_post(char * line,
|
||||||
_("Unexpected char '%1' (Note: inline math requires parentheses)")
|
_("Unexpected char '%1' (Note: inline math requires parentheses)")
|
||||||
<< *next);
|
<< *next);
|
||||||
|
|
||||||
post->end_pos = curr_pos;
|
post->pos->end_pos = curr_pos;
|
||||||
post->end_line = linenum;
|
post->pos->end_line = linenum;
|
||||||
|
|
||||||
if (! tag_stack.empty()) {
|
if (! tag_stack.empty()) {
|
||||||
foreach (const string& tag, tag_stack)
|
foreach (const string& tag, tag_stack)
|
||||||
|
|
@ -1107,9 +1110,10 @@ xact_t * instance_t::parse_xact(char * line,
|
||||||
|
|
||||||
std::auto_ptr<xact_t> xact(new xact_t);
|
std::auto_ptr<xact_t> xact(new xact_t);
|
||||||
|
|
||||||
xact->pathname = pathname;
|
xact->pos = position_t();
|
||||||
xact->beg_pos = line_beg_pos;
|
xact->pos->pathname = pathname;
|
||||||
xact->beg_line = linenum;
|
xact->pos->beg_pos = line_beg_pos;
|
||||||
|
xact->pos->beg_line = linenum;
|
||||||
|
|
||||||
bool reveal_context = true;
|
bool reveal_context = true;
|
||||||
|
|
||||||
|
|
@ -1189,8 +1193,8 @@ xact_t * instance_t::parse_xact(char * line,
|
||||||
|
|
||||||
// This is a trailing note, and possibly a metadata info tag
|
// This is a trailing note, and possibly a metadata info tag
|
||||||
item->append_note(p + 1, current_year);
|
item->append_note(p + 1, current_year);
|
||||||
item->end_pos = curr_pos;
|
item->pos->end_pos = curr_pos;
|
||||||
item->end_line++;
|
item->pos->end_line++;
|
||||||
} else {
|
} else {
|
||||||
reveal_context = false;
|
reveal_context = false;
|
||||||
|
|
||||||
|
|
@ -1216,8 +1220,8 @@ xact_t * instance_t::parse_xact(char * line,
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
xact->end_pos = curr_pos;
|
xact->pos->end_pos = curr_pos;
|
||||||
xact->end_line = linenum;
|
xact->pos->end_line = linenum;
|
||||||
|
|
||||||
if (! tag_stack.empty()) {
|
if (! tag_stack.empty()) {
|
||||||
foreach (const string& tag, tag_stack)
|
foreach (const string& tag, tag_stack)
|
||||||
|
|
@ -1232,8 +1236,8 @@ xact_t * instance_t::parse_xact(char * line,
|
||||||
catch (const std::exception& err) {
|
catch (const std::exception& err) {
|
||||||
if (reveal_context) {
|
if (reveal_context) {
|
||||||
add_error_context(_("While parsing transaction:"));
|
add_error_context(_("While parsing transaction:"));
|
||||||
add_error_context(source_context(xact->pathname,
|
add_error_context(source_context(xact->pos->pathname,
|
||||||
xact->beg_pos, curr_pos, "> "));
|
xact->pos->beg_pos, curr_pos, "> "));
|
||||||
}
|
}
|
||||||
throw;
|
throw;
|
||||||
}
|
}
|
||||||
|
|
|
||||||
122
src/times.cc
122
src/times.cc
|
|
@ -314,50 +314,18 @@ date_t parse_date(const char * str, optional<date_t::year_type> current_year)
|
||||||
return parse_date_mask(str, current_year, saw_year);
|
return parse_date_mask(str, current_year, saw_year);
|
||||||
}
|
}
|
||||||
|
|
||||||
date_t date_interval_t::add_duration(const date_t& date,
|
|
||||||
const duration_t& duration)
|
|
||||||
{
|
|
||||||
if (duration.type() == typeid(gregorian::days))
|
|
||||||
return date + boost::get<gregorian::days>(duration);
|
|
||||||
else if (duration.type() == typeid(gregorian::weeks))
|
|
||||||
return date + boost::get<gregorian::weeks>(duration);
|
|
||||||
else if (duration.type() == typeid(gregorian::months))
|
|
||||||
return date + boost::get<gregorian::months>(duration);
|
|
||||||
else
|
|
||||||
assert(duration.type() == typeid(gregorian::years));
|
|
||||||
return date + boost::get<gregorian::years>(duration);
|
|
||||||
}
|
|
||||||
|
|
||||||
date_t date_interval_t::subtract_duration(const date_t& date,
|
|
||||||
const duration_t& duration)
|
|
||||||
{
|
|
||||||
if (duration.type() == typeid(gregorian::days))
|
|
||||||
return date - boost::get<gregorian::days>(duration);
|
|
||||||
else if (duration.type() == typeid(gregorian::weeks))
|
|
||||||
return date - boost::get<gregorian::weeks>(duration);
|
|
||||||
else if (duration.type() == typeid(gregorian::months))
|
|
||||||
return date - boost::get<gregorian::months>(duration);
|
|
||||||
else
|
|
||||||
assert(duration.type() == typeid(gregorian::years));
|
|
||||||
return date - boost::get<gregorian::years>(duration);
|
|
||||||
}
|
|
||||||
|
|
||||||
std::ostream& operator<<(std::ostream& out,
|
std::ostream& operator<<(std::ostream& out,
|
||||||
const date_interval_t::duration_t& duration)
|
const date_interval_t::duration_t& duration)
|
||||||
{
|
{
|
||||||
if (duration.type() == typeid(gregorian::days))
|
if (duration.quantum == date_interval_t::duration_t::DAYS)
|
||||||
out << boost::get<gregorian::days>(duration).days()
|
out << duration.length << " day(s)";
|
||||||
<< " day(s)";
|
else if (duration.quantum == date_interval_t::duration_t::WEEKS)
|
||||||
else if (duration.type() == typeid(gregorian::weeks))
|
out << duration.length << " week(s)";
|
||||||
out << (boost::get<gregorian::weeks>(duration).days() / 7)
|
else if (duration.quantum == date_interval_t::duration_t::MONTHS)
|
||||||
<< " week(s)";
|
out << duration.length << " month(s)";
|
||||||
else if (duration.type() == typeid(gregorian::months))
|
|
||||||
out << boost::get<gregorian::months>(duration).number_of_months()
|
|
||||||
<< " month(s)";
|
|
||||||
else {
|
else {
|
||||||
assert(duration.type() == typeid(gregorian::years));
|
assert(duration.quantum == date_interval_t::duration_t::YEARS);
|
||||||
out << boost::get<gregorian::years>(duration).number_of_years()
|
out << duration.length << " year(s)";
|
||||||
<< " year(s)";
|
|
||||||
}
|
}
|
||||||
return out;
|
return out;
|
||||||
}
|
}
|
||||||
|
|
@ -365,7 +333,7 @@ std::ostream& operator<<(std::ostream& out,
|
||||||
void date_interval_t::resolve_end()
|
void date_interval_t::resolve_end()
|
||||||
{
|
{
|
||||||
if (start && ! end_of_duration) {
|
if (start && ! end_of_duration) {
|
||||||
end_of_duration = add_duration(*start, *duration);
|
end_of_duration = duration->add(*start);
|
||||||
DEBUG("times.interval",
|
DEBUG("times.interval",
|
||||||
"stabilize: end_of_duration = " << *end_of_duration);
|
"stabilize: end_of_duration = " << *end_of_duration);
|
||||||
}
|
}
|
||||||
|
|
@ -383,7 +351,7 @@ void date_interval_t::resolve_end()
|
||||||
}
|
}
|
||||||
|
|
||||||
if (start && ! next) {
|
if (start && ! next) {
|
||||||
next = add_duration(*start, *skip_duration);
|
next = skip_duration->add(*start);
|
||||||
DEBUG("times.interval",
|
DEBUG("times.interval",
|
||||||
"stabilize: next set to: " << *next);
|
"stabilize: next set to: " << *next);
|
||||||
}
|
}
|
||||||
|
|
@ -423,8 +391,8 @@ void date_interval_t::stabilize(const optional<date_t>& date)
|
||||||
|
|
||||||
date_t when = start ? *start : *date;
|
date_t when = start ? *start : *date;
|
||||||
|
|
||||||
if (duration->type() == typeid(gregorian::months) ||
|
if (duration->quantum == duration_t::MONTHS ||
|
||||||
duration->type() == typeid(gregorian::years)) {
|
duration->quantum == duration_t::YEARS) {
|
||||||
DEBUG("times.interval", "stabilize: monthly or yearly duration");
|
DEBUG("times.interval", "stabilize: monthly or yearly duration");
|
||||||
|
|
||||||
start = date_t(when.year(), gregorian::Jan, 1);
|
start = date_t(when.year(), gregorian::Jan, 1);
|
||||||
|
|
@ -433,7 +401,7 @@ void date_interval_t::stabilize(const optional<date_t>& date)
|
||||||
|
|
||||||
start = date_t(when - gregorian::days(400));
|
start = date_t(when - gregorian::days(400));
|
||||||
|
|
||||||
if (duration->type() == typeid(gregorian::weeks)) {
|
if (duration->quantum == duration_t::WEEKS) {
|
||||||
// Move it to a Sunday
|
// Move it to a Sunday
|
||||||
while (start->day_of_week() != start_of_week)
|
while (start->day_of_week() != start_of_week)
|
||||||
*start += gregorian::days(1);
|
*start += gregorian::days(1);
|
||||||
|
|
@ -540,8 +508,8 @@ bool date_interval_t::find_period(const date_t& date)
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
scan = add_duration(scan, *skip_duration);
|
scan = skip_duration->add(scan);
|
||||||
end_of_scan = add_duration(scan, *duration);
|
end_of_scan = duration->add(scan);
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
|
|
@ -565,7 +533,7 @@ date_interval_t& date_interval_t::operator++()
|
||||||
} else {
|
} else {
|
||||||
start = *next;
|
start = *next;
|
||||||
|
|
||||||
end_of_duration = add_duration(*start, *duration);
|
end_of_duration = duration->add(*start);
|
||||||
}
|
}
|
||||||
|
|
||||||
next = none;
|
next = none;
|
||||||
|
|
@ -634,15 +602,15 @@ namespace {
|
||||||
assert(look_for_start || look_for_end);
|
assert(look_for_start || look_for_end);
|
||||||
|
|
||||||
if (word == _("year")) {
|
if (word == _("year")) {
|
||||||
duration = gregorian::years(1);
|
duration = date_interval_t::duration_t(date_interval_t::duration_t::YEARS, 1);
|
||||||
start = gregorian::date(start.year(), 1, 1);
|
start = gregorian::date(start.year(), 1, 1);
|
||||||
}
|
}
|
||||||
else if (word == _("month")) {
|
else if (word == _("month")) {
|
||||||
duration = gregorian::months(1);
|
duration = date_interval_t::duration_t(date_interval_t::duration_t::MONTHS, 1);
|
||||||
start = gregorian::date(start.year(), start.month(), 1);
|
start = gregorian::date(start.year(), start.month(), 1);
|
||||||
}
|
}
|
||||||
else if (word == _("today") || word == _("day")) {
|
else if (word == _("today") || word == _("day")) {
|
||||||
duration = gregorian::days(1);
|
duration = date_interval_t::duration_t(date_interval_t::duration_t::DAYS, 1);
|
||||||
}
|
}
|
||||||
else {
|
else {
|
||||||
parse_specifier = true;
|
parse_specifier = true;
|
||||||
|
|
@ -651,15 +619,15 @@ namespace {
|
||||||
if (parse_specifier)
|
if (parse_specifier)
|
||||||
parse_inclusion_specifier(word, &start, &end);
|
parse_inclusion_specifier(word, &start, &end);
|
||||||
else
|
else
|
||||||
end = date_interval_t::add_duration(start, *duration);
|
end = duration->add(start);
|
||||||
|
|
||||||
if (type == _("last") && duration) {
|
if (type == _("last") && duration) {
|
||||||
start = date_interval_t::subtract_duration(start, *duration);
|
start = duration->subtract(start);
|
||||||
end = date_interval_t::subtract_duration(end, *duration);
|
end = duration->subtract(end);
|
||||||
}
|
}
|
||||||
else if (type == _("next") && duration) {
|
else if (type == _("next") && duration) {
|
||||||
start = date_interval_t::add_duration(start, *duration);
|
start = duration->add(start);
|
||||||
end = date_interval_t::add_duration(end, *duration);
|
end = duration->add(end);
|
||||||
}
|
}
|
||||||
|
|
||||||
if (look_for_start && is_valid(start)) interval.start = start;
|
if (look_for_start && is_valid(start)) interval.start = start;
|
||||||
|
|
@ -683,41 +651,41 @@ void date_interval_t::parse(std::istream& in)
|
||||||
int quantity = lexical_cast<int>(word);
|
int quantity = lexical_cast<int>(word);
|
||||||
read_lower_word(in, word);
|
read_lower_word(in, word);
|
||||||
if (word == _("days"))
|
if (word == _("days"))
|
||||||
duration = gregorian::days(quantity);
|
duration = duration_t(duration_t::DAYS, quantity);
|
||||||
else if (word == _("weeks"))
|
else if (word == _("weeks"))
|
||||||
duration = gregorian::weeks(quantity);
|
duration = duration_t(duration_t::WEEKS, quantity);
|
||||||
else if (word == _("months"))
|
else if (word == _("months"))
|
||||||
duration = gregorian::months(quantity);
|
duration = duration_t(duration_t::MONTHS, quantity);
|
||||||
else if (word == _("quarters"))
|
else if (word == _("quarters"))
|
||||||
duration = gregorian::months(3 * quantity);
|
duration = duration_t(duration_t::MONTHS, 3 * quantity);
|
||||||
else if (word == _("years"))
|
else if (word == _("years"))
|
||||||
duration = gregorian::years(quantity);
|
duration = duration_t(duration_t::YEARS, quantity);
|
||||||
}
|
}
|
||||||
else if (word == _("day"))
|
else if (word == _("day"))
|
||||||
duration = gregorian::days(1);
|
duration = duration_t(duration_t::DAYS, 1);
|
||||||
else if (word == _("week"))
|
else if (word == _("week"))
|
||||||
duration = gregorian::weeks(1);
|
duration = duration_t(duration_t::WEEKS, 1);
|
||||||
else if (word == _("month"))
|
else if (word == _("month"))
|
||||||
duration = gregorian::months(1);
|
duration = duration_t(duration_t::MONTHS, 1);
|
||||||
else if (word == _("quarter"))
|
else if (word == _("quarter"))
|
||||||
duration = gregorian::months(3);
|
duration = duration_t(duration_t::MONTHS, 3);
|
||||||
else if (word == _("year"))
|
else if (word == _("year"))
|
||||||
duration = gregorian::years(1);
|
duration = duration_t(duration_t::YEARS, 1);
|
||||||
}
|
}
|
||||||
else if (word == _("daily"))
|
else if (word == _("daily"))
|
||||||
duration = gregorian::days(1);
|
duration = duration_t(duration_t::DAYS, 1);
|
||||||
else if (word == _("weekly"))
|
else if (word == _("weekly"))
|
||||||
duration = gregorian::weeks(1);
|
duration = duration_t(duration_t::WEEKS, 1);
|
||||||
else if (word == _("biweekly"))
|
else if (word == _("biweekly"))
|
||||||
duration = gregorian::weeks(2);
|
duration = duration_t(duration_t::WEEKS, 2);
|
||||||
else if (word == _("monthly"))
|
else if (word == _("monthly"))
|
||||||
duration = gregorian::months(1);
|
duration = duration_t(duration_t::MONTHS, 1);
|
||||||
else if (word == _("bimonthly"))
|
else if (word == _("bimonthly"))
|
||||||
duration = gregorian::months(2);
|
duration = duration_t(duration_t::MONTHS, 2);
|
||||||
else if (word == _("quarterly"))
|
else if (word == _("quarterly"))
|
||||||
duration = gregorian::months(3);
|
duration = duration_t(duration_t::MONTHS, 3);
|
||||||
else if (word == _("yearly"))
|
else if (word == _("yearly"))
|
||||||
duration = gregorian::years(1);
|
duration = duration_t(duration_t::YEARS, 1);
|
||||||
else if (word == _("this") || word == _("last") || word == _("next") ||
|
else if (word == _("this") || word == _("last") || word == _("next") ||
|
||||||
word == _("today")) {
|
word == _("today")) {
|
||||||
parse_date_words(in, word, *this);
|
parse_date_words(in, word, *this);
|
||||||
|
|
@ -760,17 +728,17 @@ void date_interval_t::parse(std::istream& in)
|
||||||
|
|
||||||
if (wday) {
|
if (wday) {
|
||||||
while (start->day_of_week() != *wday)
|
while (start->day_of_week() != *wday)
|
||||||
*start -= gregorian::days(1);
|
*start = duration_t(duration_t::DAYS, 1).subtract(*start);
|
||||||
|
|
||||||
if (! end)
|
if (! end)
|
||||||
end = *start + gregorian::days(1);
|
end = duration_t(duration_t::DAYS, 1).add(*start);
|
||||||
} else {
|
} else {
|
||||||
bool overwrite_end = false;
|
bool overwrite_end = false;
|
||||||
|
|
||||||
if (year) {
|
if (year) {
|
||||||
start = date_t(*year, 1, 1);
|
start = date_t(*year, 1, 1);
|
||||||
if (! end) {
|
if (! end) {
|
||||||
end = *start + gregorian::years(1);
|
end = duration_t(duration_t::YEARS, 1).add(*start);
|
||||||
overwrite_end = true;
|
overwrite_end = true;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
@ -778,7 +746,7 @@ void date_interval_t::parse(std::istream& in)
|
||||||
if (mon) {
|
if (mon) {
|
||||||
start = date_t(start->year(), *mon, 1);
|
start = date_t(start->year(), *mon, 1);
|
||||||
if (! end || overwrite_end)
|
if (! end || overwrite_end)
|
||||||
end = *start + gregorian::months(1);
|
end = duration_t(duration_t::MONTHS, 1).add(*start);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
||||||
88
src/times.h
88
src/times.h
|
|
@ -119,10 +119,71 @@ void set_input_date_format(const char * format);
|
||||||
class date_interval_t : public equality_comparable<date_interval_t>
|
class date_interval_t : public equality_comparable<date_interval_t>
|
||||||
{
|
{
|
||||||
public:
|
public:
|
||||||
typedef variant<gregorian::days,
|
struct duration_t
|
||||||
gregorian::weeks,
|
{
|
||||||
gregorian::months,
|
enum skip_quantum_t {
|
||||||
gregorian::years> duration_t;
|
DAYS, WEEKS, MONTHS, YEARS
|
||||||
|
} quantum;
|
||||||
|
int length;
|
||||||
|
|
||||||
|
duration_t() : quantum(DAYS), length(0) {
|
||||||
|
TRACE_CTOR(date_interval_t::duration_t, "");
|
||||||
|
}
|
||||||
|
duration_t(skip_quantum_t _quantum, int _length)
|
||||||
|
: quantum(_quantum), length(_length) {
|
||||||
|
TRACE_CTOR(date_interval_t::duration_t, "skip_quantum_t, int");
|
||||||
|
}
|
||||||
|
duration_t(const duration_t& dur)
|
||||||
|
: quantum(dur.quantum), length(dur.length) {
|
||||||
|
TRACE_CTOR(date_interval_t::duration_t, "copy");
|
||||||
|
}
|
||||||
|
~duration_t() throw() {
|
||||||
|
TRACE_DTOR(date_interval_t::duration_t);
|
||||||
|
}
|
||||||
|
|
||||||
|
date_t add(const date_t& date) const {
|
||||||
|
switch (quantum) {
|
||||||
|
case DAYS:
|
||||||
|
return date + gregorian::days(length);
|
||||||
|
case WEEKS:
|
||||||
|
return date + gregorian::weeks(length);
|
||||||
|
case MONTHS:
|
||||||
|
return date + gregorian::months(length);
|
||||||
|
case YEARS:
|
||||||
|
return date + gregorian::years(length);
|
||||||
|
default:
|
||||||
|
assert(0); return date_t();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
date_t subtract(const date_t& date) const {
|
||||||
|
switch (quantum) {
|
||||||
|
case DAYS:
|
||||||
|
return date - gregorian::days(length);
|
||||||
|
case WEEKS:
|
||||||
|
return date - gregorian::weeks(length);
|
||||||
|
case MONTHS:
|
||||||
|
return date - gregorian::months(length);
|
||||||
|
case YEARS:
|
||||||
|
return date - gregorian::years(length);
|
||||||
|
default:
|
||||||
|
assert(0); return date_t();
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
#if defined(HAVE_BOOST_SERIALIZATION)
|
||||||
|
private:
|
||||||
|
/** Serialization. */
|
||||||
|
|
||||||
|
friend class boost::serialization::access;
|
||||||
|
|
||||||
|
template<class Archive>
|
||||||
|
void serialize(Archive & ar, const unsigned int /* version */) {
|
||||||
|
ar & quantum;
|
||||||
|
ar & length;
|
||||||
|
}
|
||||||
|
#endif // HAVE_BOOST_SERIALIZATION
|
||||||
|
};
|
||||||
|
|
||||||
static date_t add_duration(const date_t& date,
|
static date_t add_duration(const date_t& date,
|
||||||
const duration_t& duration);
|
const duration_t& duration);
|
||||||
|
|
@ -196,6 +257,25 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
date_interval_t& operator++();
|
date_interval_t& operator++();
|
||||||
|
|
||||||
|
#if defined(HAVE_BOOST_SERIALIZATION)
|
||||||
|
private:
|
||||||
|
/** Serialization. */
|
||||||
|
|
||||||
|
friend class boost::serialization::access;
|
||||||
|
|
||||||
|
template<class Archive>
|
||||||
|
void serialize(Archive & ar, const unsigned int /* version */) {
|
||||||
|
ar & start;
|
||||||
|
ar & aligned;
|
||||||
|
ar & skip_duration;
|
||||||
|
ar & factor;
|
||||||
|
ar & next;
|
||||||
|
ar & duration;
|
||||||
|
ar & end_of_duration;
|
||||||
|
ar & end;
|
||||||
|
}
|
||||||
|
#endif // HAVE_BOOST_SERIALIZATION
|
||||||
};
|
};
|
||||||
|
|
||||||
void times_initialize();
|
void times_initialize();
|
||||||
|
|
|
||||||
12
src/utils.h
12
src/utils.h
|
|
@ -178,6 +178,18 @@ public:
|
||||||
string(const char * str, size_type x);
|
string(const char * str, size_type x);
|
||||||
string(const char * str, size_type x, size_type y);
|
string(const char * str, size_type x, size_type y);
|
||||||
~string() throw();
|
~string() throw();
|
||||||
|
|
||||||
|
#if defined(HAVE_BOOST_SERIALIZATION)
|
||||||
|
private:
|
||||||
|
/** Serialization. */
|
||||||
|
|
||||||
|
friend class boost::serialization::access;
|
||||||
|
|
||||||
|
template<class Archive>
|
||||||
|
void serialize(Archive & ar, const unsigned int /* version */) {
|
||||||
|
ar & boost::serialization::base_object<std::string>(*this);
|
||||||
|
}
|
||||||
|
#endif // HAVE_BOOST_SERIALIZATION
|
||||||
};
|
};
|
||||||
|
|
||||||
inline string operator+(const string& __lhs, const string& __rhs)
|
inline string operator+(const string& __lhs, const string& __rhs)
|
||||||
|
|
|
||||||
22
src/value.cc
22
src/value.cc
|
|
@ -113,8 +113,8 @@ value_t::operator bool() const
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
return false;
|
return false;
|
||||||
case POINTER:
|
case SCOPE:
|
||||||
return ! as_any_pointer().empty();
|
return as_scope() != NULL;
|
||||||
default:
|
default:
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
@ -1206,8 +1206,8 @@ bool value_t::is_realzero() const
|
||||||
case SEQUENCE:
|
case SEQUENCE:
|
||||||
return as_sequence().empty();
|
return as_sequence().empty();
|
||||||
|
|
||||||
case POINTER:
|
case SCOPE:
|
||||||
return as_any_pointer().empty();
|
return as_scope() == NULL;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw_(value_error, _("Cannot determine if %1 is really zero") << label());
|
throw_(value_error, _("Cannot determine if %1 is really zero") << label());
|
||||||
|
|
@ -1235,8 +1235,8 @@ bool value_t::is_zero() const
|
||||||
case SEQUENCE:
|
case SEQUENCE:
|
||||||
return as_sequence().empty();
|
return as_sequence().empty();
|
||||||
|
|
||||||
case POINTER:
|
case SCOPE:
|
||||||
return as_any_pointer().empty();
|
return as_scope() == NULL;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
throw_(value_error, _("Cannot determine if %1 is zero") << label());
|
throw_(value_error, _("Cannot determine if %1 is zero") << label());
|
||||||
|
|
@ -1474,7 +1474,7 @@ value_t value_t::strip_annotations(const keep_details_t& what_to_keep) const
|
||||||
case DATE:
|
case DATE:
|
||||||
case STRING:
|
case STRING:
|
||||||
case MASK:
|
case MASK:
|
||||||
case POINTER:
|
case SCOPE:
|
||||||
return *this;
|
return *this;
|
||||||
|
|
||||||
case SEQUENCE: {
|
case SEQUENCE: {
|
||||||
|
|
@ -1579,8 +1579,8 @@ void value_t::print(std::ostream& out,
|
||||||
break;
|
break;
|
||||||
}
|
}
|
||||||
|
|
||||||
case POINTER:
|
case SCOPE:
|
||||||
out << "<POINTER>";
|
out << "<SCOPE>";
|
||||||
break;
|
break;
|
||||||
|
|
||||||
default:
|
default:
|
||||||
|
|
@ -1647,8 +1647,8 @@ void value_t::dump(std::ostream& out, const bool relaxed) const
|
||||||
out << '/' << as_mask() << '/';
|
out << '/' << as_mask() << '/';
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case POINTER:
|
case SCOPE:
|
||||||
out << boost::unsafe_any_cast<const void *>(&as_any_pointer());
|
out << as_scope();
|
||||||
break;
|
break;
|
||||||
|
|
||||||
case SEQUENCE: {
|
case SEQUENCE: {
|
||||||
|
|
|
||||||
92
src/value.h
92
src/value.h
|
|
@ -56,6 +56,8 @@ namespace ledger {
|
||||||
|
|
||||||
DECLARE_EXCEPTION(value_error, std::runtime_error);
|
DECLARE_EXCEPTION(value_error, std::runtime_error);
|
||||||
|
|
||||||
|
class scope_t;
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* @class value_t
|
* @class value_t
|
||||||
*
|
*
|
||||||
|
|
@ -107,7 +109,7 @@ public:
|
||||||
STRING, // a string object
|
STRING, // a string object
|
||||||
MASK, // a regular expression mask
|
MASK, // a regular expression mask
|
||||||
SEQUENCE, // a vector of value_t objects
|
SEQUENCE, // a vector of value_t objects
|
||||||
POINTER // an opaque pointer of any type
|
SCOPE // a pointer to a scope
|
||||||
};
|
};
|
||||||
|
|
||||||
private:
|
private:
|
||||||
|
|
@ -134,7 +136,7 @@ private:
|
||||||
string, // STRING
|
string, // STRING
|
||||||
mask_t, // MASK
|
mask_t, // MASK
|
||||||
sequence_t *, // SEQUENCE
|
sequence_t *, // SEQUENCE
|
||||||
boost::any // POINTER
|
scope_t * // SCOPE
|
||||||
> data;
|
> data;
|
||||||
|
|
||||||
type_t type;
|
type_t type;
|
||||||
|
|
@ -225,6 +227,20 @@ private:
|
||||||
data = false;
|
data = false;
|
||||||
type = VOID;
|
type = VOID;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(HAVE_BOOST_SERIALIZATION)
|
||||||
|
private:
|
||||||
|
/** Serialization. */
|
||||||
|
|
||||||
|
friend class boost::serialization::access;
|
||||||
|
|
||||||
|
template<class Archive>
|
||||||
|
void serialize(Archive & ar, const unsigned int /* version */) {
|
||||||
|
ar & data;
|
||||||
|
ar & type;
|
||||||
|
ar & refc;
|
||||||
|
}
|
||||||
|
#endif // HAVE_BOOST_SERIALIZATION
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -332,10 +348,9 @@ public:
|
||||||
set_sequence(val);
|
set_sequence(val);
|
||||||
}
|
}
|
||||||
|
|
||||||
template <typename T>
|
explicit value_t(scope_t * item) {
|
||||||
explicit value_t(T * item) {
|
TRACE_CTOR(value_t, "scope_t *");
|
||||||
TRACE_CTOR(value_t, "T *");
|
set_scope(item);
|
||||||
set_pointer(item);
|
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -687,50 +702,19 @@ public:
|
||||||
}
|
}
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Dealing with pointers is bit involved because we actually deal
|
* Dealing with scope pointers.
|
||||||
* with typed pointers. For example, if you call as_pointer it
|
|
||||||
* returns a boost::any object, but if you use as_pointer<void>,
|
|
||||||
* then it returns a void *. The latter form only succeeds if the
|
|
||||||
* stored pointers was assigned to the value as a void*, otherwise
|
|
||||||
* it throws an exception.
|
|
||||||
*/
|
*/
|
||||||
bool is_pointer() const {
|
bool is_scope() const {
|
||||||
return is_type(POINTER);
|
return is_type(SCOPE);
|
||||||
}
|
}
|
||||||
boost::any& as_any_pointer_lval() {
|
scope_t * as_scope() const {
|
||||||
VERIFY(is_pointer());
|
VERIFY(is_scope());
|
||||||
_dup();
|
return boost::get<scope_t *>(storage->data);
|
||||||
return boost::get<boost::any>(storage->data);
|
|
||||||
}
|
}
|
||||||
template <typename T>
|
void set_scope(scope_t * val) {
|
||||||
T * as_pointer_lval() {
|
set_type(SCOPE);
|
||||||
return any_cast<T *>(as_any_pointer_lval());
|
|
||||||
}
|
|
||||||
template <typename T>
|
|
||||||
T& as_ref_lval() {
|
|
||||||
return *as_pointer_lval<T>();
|
|
||||||
}
|
|
||||||
const boost::any& as_any_pointer() const {
|
|
||||||
VERIFY(is_pointer());
|
|
||||||
return boost::get<boost::any>(storage->data);
|
|
||||||
}
|
|
||||||
template <typename T>
|
|
||||||
T * as_pointer() const {
|
|
||||||
return any_cast<T *>(as_any_pointer());
|
|
||||||
}
|
|
||||||
template <typename T>
|
|
||||||
T& as_ref() const {
|
|
||||||
return *as_pointer<T>();
|
|
||||||
}
|
|
||||||
void set_any_pointer(const boost::any& val) {
|
|
||||||
set_type(POINTER);
|
|
||||||
storage->data = val;
|
storage->data = val;
|
||||||
}
|
}
|
||||||
template <typename T>
|
|
||||||
void set_pointer(T * val) {
|
|
||||||
set_type(POINTER);
|
|
||||||
storage->data = boost::any(val);
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* Data conversion methods. These methods convert a value object to
|
* Data conversion methods. These methods convert a value object to
|
||||||
|
|
@ -902,8 +886,8 @@ public:
|
||||||
return _("a regexp");
|
return _("a regexp");
|
||||||
case SEQUENCE:
|
case SEQUENCE:
|
||||||
return _("a sequence");
|
return _("a sequence");
|
||||||
case POINTER:
|
case SCOPE:
|
||||||
return _("a pointer");
|
return _("a scope");
|
||||||
default:
|
default:
|
||||||
assert(false);
|
assert(false);
|
||||||
break;
|
break;
|
||||||
|
|
@ -926,6 +910,20 @@ public:
|
||||||
* Debugging methods.
|
* Debugging methods.
|
||||||
*/
|
*/
|
||||||
bool valid() const;
|
bool valid() const;
|
||||||
|
|
||||||
|
#if defined(HAVE_BOOST_SERIALIZATION)
|
||||||
|
private:
|
||||||
|
/** Serialization. */
|
||||||
|
|
||||||
|
friend class boost::serialization::access;
|
||||||
|
|
||||||
|
template<class Archive>
|
||||||
|
void serialize(Archive & ar, const unsigned int /* version */) {
|
||||||
|
ar & true_value;
|
||||||
|
ar & false_value;
|
||||||
|
ar & storage;
|
||||||
|
}
|
||||||
|
#endif // HAVE_BOOST_SERIALIZATION
|
||||||
};
|
};
|
||||||
|
|
||||||
#define NULL_VALUE (value_t())
|
#define NULL_VALUE (value_t())
|
||||||
|
|
|
||||||
|
|
@ -499,7 +499,7 @@ void auto_xact_t::extend_xact(xact_base_t& xact, bool post_handler)
|
||||||
|
|
||||||
IF_DEBUG("xact.extend") {
|
IF_DEBUG("xact.extend") {
|
||||||
DEBUG("xact.extend",
|
DEBUG("xact.extend",
|
||||||
"Initial post on line " << initial_post->beg_line << ": "
|
"Initial post on line " << initial_post->pos->beg_line << ": "
|
||||||
<< "amount " << initial_post->amount << " (precision "
|
<< "amount " << initial_post->amount << " (precision "
|
||||||
<< initial_post->amount.precision() << ")");
|
<< initial_post->amount.precision() << ")");
|
||||||
|
|
||||||
|
|
@ -509,7 +509,7 @@ void auto_xact_t::extend_xact(xact_base_t& xact, bool post_handler)
|
||||||
#endif
|
#endif
|
||||||
|
|
||||||
DEBUG("xact.extend",
|
DEBUG("xact.extend",
|
||||||
"Posting on line " << post->beg_line << ": "
|
"Posting on line " << post->pos->beg_line << ": "
|
||||||
<< "amount " << post->amount << ", amt " << amt
|
<< "amount " << post->amount << ", amt " << amt
|
||||||
<< " (precision " << post->amount.precision()
|
<< " (precision " << post->amount.precision()
|
||||||
<< " != " << amt.precision() << ")");
|
<< " != " << amt.precision() << ")");
|
||||||
|
|
|
||||||
69
src/xact.h
69
src/xact.h
|
|
@ -80,6 +80,20 @@ public:
|
||||||
|
|
||||||
virtual bool finalize();
|
virtual bool finalize();
|
||||||
virtual bool valid() const = 0;
|
virtual bool valid() const = 0;
|
||||||
|
|
||||||
|
#if defined(HAVE_BOOST_SERIALIZATION)
|
||||||
|
private:
|
||||||
|
/** Serialization. */
|
||||||
|
|
||||||
|
friend class boost::serialization::access;
|
||||||
|
|
||||||
|
template<class Archive>
|
||||||
|
void serialize(Archive & ar, const unsigned int /* version */) {
|
||||||
|
ar & boost::serialization::base_object<item_t>(*this);
|
||||||
|
ar & journal;
|
||||||
|
ar & posts;
|
||||||
|
}
|
||||||
|
#endif // HAVE_BOOST_SERIALIZATION
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -111,6 +125,20 @@ public:
|
||||||
virtual expr_t::ptr_op_t lookup(const string& name);
|
virtual expr_t::ptr_op_t lookup(const string& name);
|
||||||
|
|
||||||
virtual bool valid() const;
|
virtual bool valid() const;
|
||||||
|
|
||||||
|
#if defined(HAVE_BOOST_SERIALIZATION)
|
||||||
|
private:
|
||||||
|
/** Serialization. */
|
||||||
|
|
||||||
|
friend class boost::serialization::access;
|
||||||
|
|
||||||
|
template<class Archive>
|
||||||
|
void serialize(Archive & ar, const unsigned int /* version */) {
|
||||||
|
ar & boost::serialization::base_object<xact_base_t>(*this);
|
||||||
|
ar & code;
|
||||||
|
ar & payee;
|
||||||
|
}
|
||||||
|
#endif // HAVE_BOOST_SERIALIZATION
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -154,6 +182,19 @@ public:
|
||||||
virtual bool valid() const {
|
virtual bool valid() const {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(HAVE_BOOST_SERIALIZATION)
|
||||||
|
private:
|
||||||
|
/** Serialization. */
|
||||||
|
|
||||||
|
friend class boost::serialization::access;
|
||||||
|
|
||||||
|
template<class Archive>
|
||||||
|
void serialize(Archive & ar, const unsigned int /* version */) {
|
||||||
|
ar & boost::serialization::base_object<xact_base_t>(*this);
|
||||||
|
ar & predicate;
|
||||||
|
}
|
||||||
|
#endif // HAVE_BOOST_SERIALIZATION
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -180,6 +221,18 @@ struct auto_xact_finalizer_t : public xact_finalizer_t
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual bool operator()(xact_t& xact, bool post);
|
virtual bool operator()(xact_t& xact, bool post);
|
||||||
|
|
||||||
|
#if defined(HAVE_BOOST_SERIALIZATION)
|
||||||
|
private:
|
||||||
|
/** Serialization. */
|
||||||
|
|
||||||
|
friend class boost::serialization::access;
|
||||||
|
|
||||||
|
template<class Archive>
|
||||||
|
void serialize(Archive & ar, const unsigned int /* version */) {
|
||||||
|
ar & journal;
|
||||||
|
}
|
||||||
|
#endif // HAVE_BOOST_SERIALIZATION
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
@ -205,7 +258,7 @@ class period_xact_t : public xact_base_t
|
||||||
TRACE_CTOR(period_xact_t, "const string&");
|
TRACE_CTOR(period_xact_t, "const string&");
|
||||||
}
|
}
|
||||||
|
|
||||||
virtual ~period_xact_t() throw() {
|
virtual ~period_xact_t() {
|
||||||
TRACE_DTOR(period_xact_t);
|
TRACE_DTOR(period_xact_t);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|
@ -218,6 +271,20 @@ class period_xact_t : public xact_base_t
|
||||||
#endif
|
#endif
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
#if defined(HAVE_BOOST_SERIALIZATION)
|
||||||
|
private:
|
||||||
|
/** Serialization. */
|
||||||
|
|
||||||
|
friend class boost::serialization::access;
|
||||||
|
|
||||||
|
template<class Archive>
|
||||||
|
void serialize(Archive & ar, const unsigned int /* version */) {
|
||||||
|
ar & boost::serialization::base_object<xact_base_t>(*this);
|
||||||
|
ar & period;
|
||||||
|
ar & period_string;
|
||||||
|
}
|
||||||
|
#endif // HAVE_BOOST_SERIALIZATION
|
||||||
};
|
};
|
||||||
|
|
||||||
/**
|
/**
|
||||||
|
|
|
||||||
520
tools/Makefile.am
Normal file
520
tools/Makefile.am
Normal file
|
|
@ -0,0 +1,520 @@
|
||||||
|
VERSION = 3.0
|
||||||
|
ACLOCAL_AMFLAGS = -I m4
|
||||||
|
dist_man_MANS = doc/ledger.1
|
||||||
|
SUBDIRS = po intl
|
||||||
|
EXTRA_DIST = autogen.sh config.rpath contrib src/system.hh.in
|
||||||
|
DISTCLEANFILES = .timestamp
|
||||||
|
|
||||||
|
lib_LTLIBRARIES = \
|
||||||
|
libledger_report.la \
|
||||||
|
libledger_data.la \
|
||||||
|
libledger_expr.la \
|
||||||
|
libledger_math.la \
|
||||||
|
libledger_util.la
|
||||||
|
|
||||||
|
lib_cppflags = -I$(srcdir)/src -I$(srcdir)/lib \
|
||||||
|
-I$(srcdir)/lib/utfcpp/source
|
||||||
|
|
||||||
|
libledger_util_la_SOURCES = \
|
||||||
|
src/stream.cc \
|
||||||
|
src/mask.cc \
|
||||||
|
src/times.cc \
|
||||||
|
src/error.cc \
|
||||||
|
src/utils.cc \
|
||||||
|
src/accum.cc \
|
||||||
|
lib/sha1.cpp
|
||||||
|
|
||||||
|
libledger_util_la_CPPFLAGS = $(lib_cppflags)
|
||||||
|
libledger_util_la_LDFLAGS = -release $(VERSION).0
|
||||||
|
|
||||||
|
libledger_math_la_SOURCES = \
|
||||||
|
src/value.cc \
|
||||||
|
src/balance.cc \
|
||||||
|
src/quotes.cc \
|
||||||
|
src/pool.cc \
|
||||||
|
src/annotate.cc \
|
||||||
|
src/commodity.cc \
|
||||||
|
src/amount.cc
|
||||||
|
|
||||||
|
libledger_math_la_CPPFLAGS = $(lib_cppflags)
|
||||||
|
libledger_math_la_LDFLAGS = -release $(VERSION).0
|
||||||
|
|
||||||
|
libledger_expr_la_SOURCES = \
|
||||||
|
src/option.cc \
|
||||||
|
src/format.cc \
|
||||||
|
src/predicate.cc \
|
||||||
|
src/scope.cc \
|
||||||
|
src/interactive.cc \
|
||||||
|
src/expr.cc \
|
||||||
|
src/op.cc \
|
||||||
|
src/parser.cc \
|
||||||
|
src/token.cc
|
||||||
|
|
||||||
|
libledger_expr_la_CPPFLAGS = $(lib_cppflags)
|
||||||
|
libledger_expr_la_LDFLAGS = -release $(VERSION).0
|
||||||
|
|
||||||
|
libledger_data_la_SOURCES = \
|
||||||
|
src/compare.cc \
|
||||||
|
src/iterators.cc \
|
||||||
|
src/timelog.cc \
|
||||||
|
src/textual.cc \
|
||||||
|
src/journal.cc \
|
||||||
|
src/archive.cc \
|
||||||
|
src/account.cc \
|
||||||
|
src/xact.cc \
|
||||||
|
src/post.cc \
|
||||||
|
src/item.cc
|
||||||
|
|
||||||
|
libledger_data_la_CPPFLAGS = $(lib_cppflags)
|
||||||
|
libledger_data_la_LDFLAGS = -release $(VERSION).0
|
||||||
|
|
||||||
|
libledger_report_la_SOURCES = \
|
||||||
|
src/stats.cc \
|
||||||
|
src/generate.cc \
|
||||||
|
src/derive.cc \
|
||||||
|
src/emacs.cc \
|
||||||
|
src/output.cc \
|
||||||
|
src/precmd.cc \
|
||||||
|
src/chain.cc \
|
||||||
|
src/filters.cc \
|
||||||
|
src/temps.cc \
|
||||||
|
src/report.cc \
|
||||||
|
src/session.cc
|
||||||
|
|
||||||
|
libledger_report_la_CPPFLAGS = $(lib_cppflags)
|
||||||
|
libledger_report_la_LDFLAGS = -release $(VERSION).0
|
||||||
|
|
||||||
|
pkginclude_HEADERS = \
|
||||||
|
src/utils.h \
|
||||||
|
src/flags.h \
|
||||||
|
src/hooks.h \
|
||||||
|
src/error.h \
|
||||||
|
src/times.h \
|
||||||
|
src/mask.h \
|
||||||
|
src/stream.h \
|
||||||
|
src/pstream.h \
|
||||||
|
src/unistring.h \
|
||||||
|
src/accum.h \
|
||||||
|
\
|
||||||
|
src/amount.h \
|
||||||
|
src/commodity.h \
|
||||||
|
src/annotate.h \
|
||||||
|
src/pool.h \
|
||||||
|
src/quotes.h \
|
||||||
|
src/balance.h \
|
||||||
|
src/value.h \
|
||||||
|
\
|
||||||
|
src/token.h \
|
||||||
|
src/parser.h \
|
||||||
|
src/op.h \
|
||||||
|
src/expr.h \
|
||||||
|
src/scope.h \
|
||||||
|
src/interactive.h \
|
||||||
|
src/predicate.h \
|
||||||
|
src/format.h \
|
||||||
|
src/option.h \
|
||||||
|
\
|
||||||
|
src/item.h \
|
||||||
|
src/post.h \
|
||||||
|
src/xact.h \
|
||||||
|
src/account.h \
|
||||||
|
src/journal.h \
|
||||||
|
src/archive.h \
|
||||||
|
src/timelog.h \
|
||||||
|
src/iterators.h \
|
||||||
|
src/compare.h \
|
||||||
|
\
|
||||||
|
src/session.h \
|
||||||
|
src/report.h \
|
||||||
|
src/filters.h \
|
||||||
|
src/temps.h \
|
||||||
|
src/chain.h \
|
||||||
|
src/precmd.h \
|
||||||
|
src/derive.h \
|
||||||
|
src/generate.h \
|
||||||
|
src/stats.h \
|
||||||
|
src/output.h \
|
||||||
|
src/emacs.h \
|
||||||
|
\
|
||||||
|
src/global.h \
|
||||||
|
\
|
||||||
|
src/pyinterp.h \
|
||||||
|
\
|
||||||
|
lib/sha1.h \
|
||||||
|
lib/gettext.h \
|
||||||
|
\
|
||||||
|
lib/utfcpp/source/utf8.h \
|
||||||
|
lib/utfcpp/source/utf8/checked.h \
|
||||||
|
lib/utfcpp/source/utf8/core.h \
|
||||||
|
lib/utfcpp/source/utf8/unchecked.h
|
||||||
|
|
||||||
|
nodist_libledger_util_la_SOURCES = system.hh
|
||||||
|
|
||||||
|
BUILT_SOURCES = system.hh
|
||||||
|
CLEANFILES = system.hh
|
||||||
|
|
||||||
|
system.hh: src/system.hh.in
|
||||||
|
cp -p $< $@
|
||||||
|
|
||||||
|
if USE_PCH
|
||||||
|
nodist_libledger_util_la_SOURCES += system.hh.gch
|
||||||
|
|
||||||
|
BUILT_SOURCES += system.hh.gch
|
||||||
|
CLEANFILES += system.hh.gch
|
||||||
|
|
||||||
|
system.hh.gch: system.hh
|
||||||
|
$(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \
|
||||||
|
$(lib_cppflags) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) \
|
||||||
|
-o $@ $<
|
||||||
|
endif
|
||||||
|
|
||||||
|
######################################################################
|
||||||
|
|
||||||
|
bin_PROGRAMS = ledger
|
||||||
|
|
||||||
|
ledger_CPPFLAGS = $(lib_cppflags)
|
||||||
|
if HAVE_BOOST_PYTHON
|
||||||
|
ledger_CPPFLAGS += -I$(srcdir)/python
|
||||||
|
endif
|
||||||
|
ledger_SOURCES = src/main.cc src/global.cc
|
||||||
|
ledger_LDADD = $(LIBOBJS) $(lib_LTLIBRARIES) $(INTLLIBS)
|
||||||
|
ledger_LDFLAGS = -static
|
||||||
|
|
||||||
|
info_TEXINFOS = doc/ledger.texi
|
||||||
|
|
||||||
|
dist_lisp_LISP = lisp/ledger.el lisp/timeclock.el
|
||||||
|
ELCFILES =
|
||||||
|
DISTCLEANFILES += ledger.elc timeclock.elc
|
||||||
|
|
||||||
|
all_sources = $(libledger_util_la_SOURCES) \
|
||||||
|
$(libledger_math_la_SOURCES) \
|
||||||
|
$(libledger_expr_la_SOURCES) \
|
||||||
|
$(libledger_data_la_SOURCES) \
|
||||||
|
$(libledger_report_la_SOURCES) \
|
||||||
|
$(libledger_python_la_SOURCES) \
|
||||||
|
src/pyledger.cc
|
||||||
|
|
||||||
|
all_files = $(all_sources) $(pkginclude_HEADERS)
|
||||||
|
|
||||||
|
######################################################################
|
||||||
|
|
||||||
|
if HAVE_BOOST_PYTHON
|
||||||
|
|
||||||
|
lib_LTLIBRARIES += libledger_python.la
|
||||||
|
|
||||||
|
libledger_python_la_SOURCES = \
|
||||||
|
src/pyutils.h \
|
||||||
|
src/pyfstream.h \
|
||||||
|
src/py_amount.cc \
|
||||||
|
src/py_balance.cc \
|
||||||
|
src/py_chain.cc \
|
||||||
|
src/py_commodity.cc \
|
||||||
|
src/py_expr.cc \
|
||||||
|
src/py_flags.cc \
|
||||||
|
src/py_format.cc \
|
||||||
|
src/py_global.cc \
|
||||||
|
src/py_item.cc \
|
||||||
|
src/py_journal.cc \
|
||||||
|
src/py_post.cc \
|
||||||
|
src/py_report.cc \
|
||||||
|
src/py_scope.cc \
|
||||||
|
src/py_session.cc \
|
||||||
|
src/py_timelog.cc \
|
||||||
|
src/py_times.cc \
|
||||||
|
src/py_utils.cc \
|
||||||
|
src/py_value.cc \
|
||||||
|
src/py_xact.cc \
|
||||||
|
src/pyinterp.cc
|
||||||
|
|
||||||
|
libledger_python_la_CPPFLAGS = $(lib_cppflags) -I$(srcdir)/python
|
||||||
|
|
||||||
|
pyexec_LTLIBRARIES = ledger.la
|
||||||
|
|
||||||
|
ledger_la_CPPFLAGS = $(libledger_python_la_CPPFLAGS)
|
||||||
|
ledger_la_SOURCES = src/pyledger.cc
|
||||||
|
ledger_la_DEPENDENCIES = $(lib_LTLIBRARIES)
|
||||||
|
ledger_la_LDFLAGS = -avoid-version -module
|
||||||
|
ledger_la_LIBADD = $(LIBOBJS) $(lib_LTLIBRARIES) $(INTLLIBS)
|
||||||
|
|
||||||
|
pkgpython_PYTHON = python/__init__.py \
|
||||||
|
python/hello.py \
|
||||||
|
python/server.py
|
||||||
|
|
||||||
|
endif
|
||||||
|
|
||||||
|
######################################################################
|
||||||
|
|
||||||
|
TESTS =
|
||||||
|
|
||||||
|
if HAVE_PYTHON
|
||||||
|
TESTS += RegressTests BaselineTests ConfirmTests GenerateTests
|
||||||
|
endif
|
||||||
|
|
||||||
|
if HAVE_CPPUNIT
|
||||||
|
TESTS += \
|
||||||
|
UtilTests \
|
||||||
|
MathTests \
|
||||||
|
ExprTests \
|
||||||
|
DataTests \
|
||||||
|
ReportTests
|
||||||
|
endif
|
||||||
|
|
||||||
|
if HAVE_BOOST_PYTHON
|
||||||
|
TESTS += PyUnitTests
|
||||||
|
endif
|
||||||
|
|
||||||
|
check_PROGRAMS = $(TESTS)
|
||||||
|
|
||||||
|
UtilTests_SOURCES = \
|
||||||
|
test/UnitTests.cc \
|
||||||
|
test/UnitTests.h \
|
||||||
|
test/UtilTests.cc \
|
||||||
|
test/unit/t_utils.cc \
|
||||||
|
test/unit/t_utils.h \
|
||||||
|
test/unit/t_times.cc \
|
||||||
|
test/unit/t_times.h
|
||||||
|
|
||||||
|
UtilTests_CPPFLAGS = -I$(srcdir)/test $(lib_cppflags)
|
||||||
|
UtilTests_LDADD = libledger_util.la -lcppunit
|
||||||
|
|
||||||
|
MathTests_SOURCES = \
|
||||||
|
test/UnitTests.cc \
|
||||||
|
test/UnitTests.h \
|
||||||
|
test/MathTests.cc \
|
||||||
|
test/unit/t_commodity.cc \
|
||||||
|
test/unit/t_commodity.h \
|
||||||
|
test/unit/t_amount.cc \
|
||||||
|
test/unit/t_amount.h \
|
||||||
|
test/unit/t_balance.cc \
|
||||||
|
test/unit/t_balance.h
|
||||||
|
|
||||||
|
MathTests_CPPFLAGS = -I$(srcdir)/test $(lib_cppflags)
|
||||||
|
MathTests_LDADD = libledger_math.la $(UtilTests_LDADD)
|
||||||
|
|
||||||
|
ExprTests_SOURCES = \
|
||||||
|
test/UnitTests.cc \
|
||||||
|
test/UnitTests.h \
|
||||||
|
test/ExprTests.cc \
|
||||||
|
test/unit/t_expr.cc \
|
||||||
|
test/unit/t_expr.h
|
||||||
|
|
||||||
|
ExprTests_CPPFLAGS = -I$(srcdir)/test $(lib_cppflags)
|
||||||
|
ExprTests_LDADD = libledger_expr.la $(MathTests_LDADD)
|
||||||
|
|
||||||
|
DataTests_SOURCES = \
|
||||||
|
test/UnitTests.cc \
|
||||||
|
test/UnitTests.h \
|
||||||
|
test/DataTests.cc
|
||||||
|
|
||||||
|
DataTests_CPPFLAGS = -I$(srcdir)/test $(lib_cppflags)
|
||||||
|
DataTests_LDADD = libledger_data.la $(ExprTests_LDADD)
|
||||||
|
|
||||||
|
ReportTests_SOURCES = \
|
||||||
|
test/UnitTests.cc \
|
||||||
|
test/UnitTests.h \
|
||||||
|
test/ReportTests.cc
|
||||||
|
|
||||||
|
ReportTests_CPPFLAGS = -I$(srcdir)/test $(lib_cppflags)
|
||||||
|
ReportTests_LDADD = libledger_report.la $(DataTests_LDADD)
|
||||||
|
|
||||||
|
all_tests_sources = \
|
||||||
|
$(UtilTests_SOURCES) \
|
||||||
|
$(MathTests_SOURCES) \
|
||||||
|
$(ExprTests_SOURCES) \
|
||||||
|
$(DataTests_SOURCES) \
|
||||||
|
$(ReportTests_SOURCES)
|
||||||
|
|
||||||
|
PyUnitTests_SOURCES = test/PyUnitTests.py
|
||||||
|
|
||||||
|
all_py_tests_sources = \
|
||||||
|
$(patsubst test/unit/%.cc,$(top_builddir)/test/python/%.py, \
|
||||||
|
$(filter test/unit/t_%.cc,$(all_tests_sources)))
|
||||||
|
|
||||||
|
test/python/%.py: test/unit/%.cc test/convert.py
|
||||||
|
$(PYTHON) $(srcdir)/test/convert.py $< $@
|
||||||
|
|
||||||
|
test/python/UnitTests.py: $(all_py_tests_sources)
|
||||||
|
@echo "from unittest import TextTestRunner, TestSuite" > $@
|
||||||
|
@for file in $$(ls $(srcdir)/test/unit/*.cc); do \
|
||||||
|
base=$$(basename $$file); \
|
||||||
|
base=$$(echo $$base | sed 's/\.cc//'); \
|
||||||
|
echo "import $$base" >> $@; \
|
||||||
|
done
|
||||||
|
@echo "suites = [" >> $@
|
||||||
|
@for file in $$(ls $(srcdir)/test/unit/*.cc); do \
|
||||||
|
base=$$(basename $$file); \
|
||||||
|
base=$$(echo $$base | sed 's/\.cc//'); \
|
||||||
|
echo " $$base.suite()," >> $@; \
|
||||||
|
done
|
||||||
|
@echo "]" >> $@
|
||||||
|
@echo "TextTestRunner().run(TestSuite(suites))" >> $@
|
||||||
|
|
||||||
|
ledger_python = $(top_builddir)/ledger$(EXEEXT) python
|
||||||
|
|
||||||
|
ESC_python=`echo "$(ledger_python)" | sed 's/\//\\\\\//g'`
|
||||||
|
ESC_srcdir=`echo "$(srcdir)" | sed 's/\//\\\\\//g'`
|
||||||
|
ESC_builddir=`echo "$(top_builddir)" | sed 's/\//\\\\\//g'`
|
||||||
|
ESC_distdir=`echo "$(distdir)" | sed 's/\//\\\\\//g'`
|
||||||
|
|
||||||
|
# jww (2007-05-10): This rule will not be triggered on systems that
|
||||||
|
# define an EXEEXT.
|
||||||
|
PyUnitTests: test/PyUnitTests.py test/python/UnitTests.py
|
||||||
|
@cat $(srcdir)/test/PyUnitTests.py \
|
||||||
|
| sed "s/%python%/$(ESC_python)/" \
|
||||||
|
| sed "s/%srcdir%/$(ESC_srcdir)/g" \
|
||||||
|
| sed "s/%builddir%/$(ESC_builddir)/g" > $@
|
||||||
|
chmod 755 $@
|
||||||
|
|
||||||
|
RegressTests_SOURCES = test/RegressTests.py
|
||||||
|
|
||||||
|
EXTRA_DIST += test/regress test/convert.py test/LedgerHarness.py
|
||||||
|
|
||||||
|
RegressTests: $(srcdir)/test/RegressTests.py
|
||||||
|
echo "$(PYTHON) $(srcdir)/test/RegressTests.py $(top_builddir)/ledger$(EXEEXT) $(srcdir)/test/regress \"\$$@\"" > $@
|
||||||
|
chmod 755 $@
|
||||||
|
|
||||||
|
BaselineTests_SOURCES = test/RegressTests.py
|
||||||
|
|
||||||
|
EXTRA_DIST += test/baseline
|
||||||
|
|
||||||
|
BaselineTests: $(srcdir)/test/RegressTests.py
|
||||||
|
echo "$(PYTHON) $(srcdir)/test/RegressTests.py $(top_builddir)/ledger$(EXEEXT) $(srcdir)/test/baseline \"\$$@\"" > $@
|
||||||
|
chmod 755 $@
|
||||||
|
|
||||||
|
ConfirmTests_SOURCES = test/ConfirmTests.py
|
||||||
|
|
||||||
|
EXTRA_DIST += test/input
|
||||||
|
|
||||||
|
test/input/mondo.dat: test/input/standard.dat
|
||||||
|
@for i in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 ; do \
|
||||||
|
for j in 1 2 3 4 5 6 7 8 9 10 11 12 13 14 15 16 ; do \
|
||||||
|
cat $< >> $@; \
|
||||||
|
done; \
|
||||||
|
done
|
||||||
|
|
||||||
|
ConfirmTests: $(srcdir)/test/ConfirmTests.py
|
||||||
|
echo "$(PYTHON) $(srcdir)/test/ConfirmTests.py $(top_builddir)/ledger$(EXEEXT) $(srcdir)/test/input \"\$$@\"" > $@
|
||||||
|
chmod 755 $@
|
||||||
|
|
||||||
|
GenerateTests_SOURCES = test/GenerateTests.py
|
||||||
|
|
||||||
|
GenerateTests: $(srcdir)/test/GenerateTests.py
|
||||||
|
echo "$(PYTHON) $(srcdir)/test/GenerateTests.py $(top_builddir)/ledger$(EXEEXT) 1 20 \"\$$@\"" > $@
|
||||||
|
chmod 755 $@
|
||||||
|
|
||||||
|
FULLCHECK=$(srcdir)/test/fullcheck.sh
|
||||||
|
|
||||||
|
if HAVE_CPPUNIT
|
||||||
|
cppunittests: check
|
||||||
|
@sh $(FULLCHECK) $(top_builddir)/UtilTests$(EXEEXT) --verify \
|
||||||
|
2>&1 | grep -v '^GuardMalloc:'
|
||||||
|
@sh $(FULLCHECK) $(top_builddir)/MathTests$(EXEEXT) --verify \
|
||||||
|
2>&1 | grep -v '^GuardMalloc:'
|
||||||
|
@sh $(FULLCHECK) $(top_builddir)/ExprTests$(EXEEXT) --verify \
|
||||||
|
2>&1 | grep -v '^GuardMalloc:'
|
||||||
|
@sh $(FULLCHECK) $(top_builddir)/DataTests$(EXEEXT) --verify \
|
||||||
|
2>&1 | grep -v '^GuardMalloc:'
|
||||||
|
@sh $(FULLCHECK) $(top_builddir)/ReportTests$(EXEEXT) --verify \
|
||||||
|
2>&1 | grep -v '^GuardMalloc:'
|
||||||
|
else
|
||||||
|
cppunittests: check
|
||||||
|
@test 1 -eq 1
|
||||||
|
endif
|
||||||
|
|
||||||
|
fullcheck: cppunittests
|
||||||
|
@$(top_builddir)/RegressTests --verify
|
||||||
|
@$(top_builddir)/BaselineTests --verify
|
||||||
|
@$(top_builddir)/ConfirmTests --verify
|
||||||
|
@$(top_builddir)/GenerateTests --verify
|
||||||
|
@$(top_builddir)/RegressTests --gmalloc
|
||||||
|
@$(top_builddir)/BaselineTests --gmalloc
|
||||||
|
# @$(top_builddir)/ConfirmTests --gmalloc
|
||||||
|
# @$(top_builddir)/GenerateTests --gmalloc
|
||||||
|
|
||||||
|
######################################################################
|
||||||
|
|
||||||
|
EXTRA_DIST += doc/README doc/LICENSE doc/NEWS doc/ledger.pdf
|
||||||
|
if USE_DOXYGEN
|
||||||
|
EXTRA_DIST += doc/Doxyfile doc/refman.pdf
|
||||||
|
endif
|
||||||
|
|
||||||
|
DISTCLEANFILES += doc/ledger.info doc/ledger.pdf
|
||||||
|
if USE_DOXYGEN
|
||||||
|
DISTCLEANFILES += Doxyfile.gen doc/Doxyfile.bak doc/refman.pdf
|
||||||
|
endif
|
||||||
|
|
||||||
|
if USE_DOXYGEN
|
||||||
|
dist-hook-doxygen:
|
||||||
|
find $(distdir)/doc -name .dirstamp -delete
|
||||||
|
rm -fr $(distdir)/doc/latex \
|
||||||
|
$(distdir)/doc/Doxyfile.bak \
|
||||||
|
$(distdir)/doc/Doxyfile.gen
|
||||||
|
cp -pR doc/html $(distdir)/doc
|
||||||
|
else
|
||||||
|
dist-hook-doxygen:
|
||||||
|
@test 1 -eq 1
|
||||||
|
endif
|
||||||
|
|
||||||
|
dist-hook: dist-hook-doxygen
|
||||||
|
find $(distdir) -name .DS_Store -delete
|
||||||
|
find $(distdir) -name .localized -delete
|
||||||
|
rm -f $(distdir)/README.textile
|
||||||
|
cp -p $(srcdir)/doc/README $(distdir)/README
|
||||||
|
|
||||||
|
if USE_DOXYGEN
|
||||||
|
distclean-local-doxygen:
|
||||||
|
rm -fr doc/html doc/latex
|
||||||
|
rm -f doc/refman.pdf
|
||||||
|
else
|
||||||
|
distclean-local-doxygen:
|
||||||
|
@test 1 -eq 1
|
||||||
|
endif
|
||||||
|
|
||||||
|
distclean-local: distclean-local-doxygen
|
||||||
|
rm -fr test/python
|
||||||
|
|
||||||
|
if USE_DOXYGEN
|
||||||
|
ESC_top_builddir=`cd $(top_builddir); pwd | sed 's/\//\\\\\//g'`
|
||||||
|
|
||||||
|
Doxyfile.gen: doc/Doxyfile
|
||||||
|
cat $< | sed "s/%srcdir%/$(ESC_srcdir)/g" \
|
||||||
|
| sed "s/%builddir%/$(ESC_top_builddir)/g" > $@
|
||||||
|
|
||||||
|
doc/html/index.html: Doxyfile.gen $(all_files)
|
||||||
|
BUILD_DIR=`cd $(top_builddir); pwd`; \
|
||||||
|
(cd $(srcdir); doxygen $$BUILD_DIR/Doxyfile.gen)
|
||||||
|
|
||||||
|
# The intention with the following rules is that all of the Doxygen
|
||||||
|
# documentation (both HTML and PDF) is built locally before distcheck is
|
||||||
|
# run, since it's quite possible that the user will not have a complete
|
||||||
|
# TeX + Doxygen + dot environment on their own system.
|
||||||
|
|
||||||
|
doc/refman.pdf: doc/html/index.html
|
||||||
|
(cd doc/latex && make)
|
||||||
|
cp doc/latex/refman.pdf $@
|
||||||
|
|
||||||
|
docs: pdf doc/refman.pdf
|
||||||
|
else
|
||||||
|
docs: pdf
|
||||||
|
endif
|
||||||
|
|
||||||
|
libs:
|
||||||
|
@echo Building dependency libs and installing in /usr/local/stow ...
|
||||||
|
git submodule update --init
|
||||||
|
(cd lib; make)
|
||||||
|
|
||||||
|
report: all
|
||||||
|
-rm -fr build
|
||||||
|
lcov -d $(shell pwd) --zerocounters
|
||||||
|
-mkdir doc/report
|
||||||
|
lcov -c -i -d $(shell pwd) -o doc/report/ledger_base.info
|
||||||
|
make fullcheck
|
||||||
|
lcov -c -d $(shell pwd) --checksum -o doc/report/ledger_test.info
|
||||||
|
lcov -a doc/report/ledger_base.info \
|
||||||
|
-a doc/report/ledger_test.info -o doc/report/ledger_total.info
|
||||||
|
lcov --extract doc/report/ledger_total.info '*src/ledger/*' \
|
||||||
|
-o doc/report/ledger_cov.info
|
||||||
|
genhtml -o doc/report doc/report/ledger_cov.info
|
||||||
|
@echo Coverage reported generated\; now open doc/report/index.html
|
||||||
|
|
||||||
|
# Makefile.am ends here
|
||||||
1491
tools/autogen.sh
Executable file
1491
tools/autogen.sh
Executable file
File diff suppressed because it is too large
Load diff
391
tools/configure.ac
Normal file
391
tools/configure.ac
Normal file
|
|
@ -0,0 +1,391 @@
|
||||||
|
# -*- Autoconf -*-
|
||||||
|
# Process this file with autoconf to produce a configure script.
|
||||||
|
|
||||||
|
AC_PREREQ(2.61)
|
||||||
|
|
||||||
|
m4_include([version.m4])
|
||||||
|
|
||||||
|
AC_INIT([ledger],[VERSION_NUMBER],[johnw@newartisans.com])
|
||||||
|
|
||||||
|
AC_CONFIG_AUX_DIR([.])
|
||||||
|
AM_INIT_AUTOMAKE([dist-bzip2 foreign])
|
||||||
|
AC_CONFIG_MACRO_DIR([m4])
|
||||||
|
|
||||||
|
AC_CONFIG_SRCDIR([src/main.cc])
|
||||||
|
AC_CONFIG_HEADER([config.h])
|
||||||
|
|
||||||
|
# Checks for programs.
|
||||||
|
AC_USE_SYSTEM_EXTENSIONS
|
||||||
|
AC_PROG_CXX
|
||||||
|
AC_PROG_MAKE_SET
|
||||||
|
AC_PROG_LIBTOOL
|
||||||
|
AM_GNU_GETTEXT
|
||||||
|
AM_GNU_GETTEXT_VERSION([0.17])
|
||||||
|
|
||||||
|
# Checks for emacs lisp path
|
||||||
|
AM_PATH_LISPDIR
|
||||||
|
|
||||||
|
# Check for options
|
||||||
|
AC_ARG_ENABLE(debug,
|
||||||
|
[ --enable-debug Turn on debugging],
|
||||||
|
[case "${enableval}" in
|
||||||
|
yes) debug=true ;;
|
||||||
|
no) debug=false ;;
|
||||||
|
*) AC_MSG_ERROR(bad value ${enableval} for --enable-debug) ;;
|
||||||
|
esac],[debug=false])
|
||||||
|
|
||||||
|
if [ test x$debug = xtrue ]; then
|
||||||
|
AC_DEFINE([DEBUG_MODE], [1], [Whether debugging is enabled])
|
||||||
|
fi
|
||||||
|
AM_CONDITIONAL(DEBUG, test x$debug = xtrue)
|
||||||
|
|
||||||
|
AC_ARG_ENABLE(pch,
|
||||||
|
[ --enable-pch Use GCC 4.x pre-compiled headers],
|
||||||
|
[case "${enableval}" in
|
||||||
|
yes) pch=true ;;
|
||||||
|
no) pch=false ;;
|
||||||
|
*) AC_MSG_ERROR(bad value ${enableval} for --enable-pch) ;;
|
||||||
|
esac],[pch=false])
|
||||||
|
|
||||||
|
if [ test x$pch = xtrue ]; then
|
||||||
|
AC_DEFINE([USE_PCH], [1], [Whether pre-compiled headers are being used])
|
||||||
|
fi
|
||||||
|
AM_CONDITIONAL(USE_PCH, test x$pch = xtrue)
|
||||||
|
|
||||||
|
AC_ARG_ENABLE(doxygen,
|
||||||
|
[ --enable-doxygen Turns on generation of code documentation],
|
||||||
|
[case "${enableval}" in
|
||||||
|
yes) doxygen=true ;;
|
||||||
|
no) doxygen=false ;;
|
||||||
|
*) AC_MSG_ERROR(bad value ${enableval} for --enable-doxygen) ;;
|
||||||
|
esac],[doxygen=false])
|
||||||
|
|
||||||
|
AM_CONDITIONAL(USE_DOXYGEN, test x$doxygen = xtrue)
|
||||||
|
|
||||||
|
AC_ARG_WITH(boost-suffix,
|
||||||
|
[ --with-boost-suffix=X Append X to the Boost library names],
|
||||||
|
[BOOST_SUFFIX="${withval}"],
|
||||||
|
[BOOST_SUFFIX=""])
|
||||||
|
|
||||||
|
AC_SUBST([BOOST_SUFFIX], $BOOST_SUFFIX)
|
||||||
|
|
||||||
|
# check if UNIX pipes are available
|
||||||
|
AC_CACHE_CHECK(
|
||||||
|
[if pipes can be used],
|
||||||
|
[pipes_avail_cv_],
|
||||||
|
[AC_LANG_PUSH(C++)
|
||||||
|
AC_LINK_IFELSE(
|
||||||
|
[AC_LANG_PROGRAM(
|
||||||
|
[[#include <sys/types.h>
|
||||||
|
#include <sys/wait.h>
|
||||||
|
#include <unistd.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <stdio.h>]],
|
||||||
|
[[int status, pfd[2];
|
||||||
|
status = pipe(pfd);
|
||||||
|
status = fork();
|
||||||
|
if (status < 0) {
|
||||||
|
;
|
||||||
|
} else if (status == 0) {
|
||||||
|
char *arg0 = NULL;
|
||||||
|
|
||||||
|
status = dup2(pfd[0], STDIN_FILENO);
|
||||||
|
|
||||||
|
close(pfd[1]);
|
||||||
|
close(pfd[0]);
|
||||||
|
|
||||||
|
execlp("", arg0, (char *)0);
|
||||||
|
perror("execl");
|
||||||
|
exit(1);
|
||||||
|
} else {
|
||||||
|
close(pfd[0]);
|
||||||
|
}]])],
|
||||||
|
[pipes_avail_cv_=true],
|
||||||
|
[pipes_avail_cv_=false])
|
||||||
|
AC_LANG_POP])
|
||||||
|
|
||||||
|
if [test x$pipes_avail_cv_ = xtrue ]; then
|
||||||
|
AC_DEFINE([HAVE_UNIX_PIPES], [1], [Whether UNIX pipes are available])
|
||||||
|
fi
|
||||||
|
|
||||||
|
# check for gmp
|
||||||
|
AC_CACHE_CHECK(
|
||||||
|
[if GMP is available],
|
||||||
|
[libgmp_avail_cv_],
|
||||||
|
[libgmp_save_libs=$LIBS
|
||||||
|
LIBS="-lgmp $LIBS"
|
||||||
|
AC_LANG_PUSH(C++)
|
||||||
|
AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <gmp.h>]], [[mpz_t bar;
|
||||||
|
mpz_init(bar);
|
||||||
|
mpz_clear(bar);]])],[libgmp_avail_cv_=true],[libgmp_avail_cv_=false])
|
||||||
|
AC_LANG_POP
|
||||||
|
LIBS=$libgmp_save_libs])
|
||||||
|
|
||||||
|
if [test x$libgmp_avail_cv_ = xtrue ]; then
|
||||||
|
LIBS="-lgmp $LIBS"
|
||||||
|
else
|
||||||
|
AC_MSG_FAILURE("Could not find gmp library (set CPPFLAGS and LDFLAGS?)")
|
||||||
|
fi
|
||||||
|
|
||||||
|
# check for mpfr
|
||||||
|
AC_CACHE_CHECK(
|
||||||
|
[if MPFR is available],
|
||||||
|
[libmpfr_avail_cv_],
|
||||||
|
[libmpfr_save_libs=$LIBS
|
||||||
|
LIBS="-lmpfr $LIBS"
|
||||||
|
AC_LANG_PUSH(C++)
|
||||||
|
AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <mpfr.h>]], [[mpfr_t bar;
|
||||||
|
mpfr_init(bar);
|
||||||
|
char * buf = NULL;
|
||||||
|
mpfr_asprintf(&buf, "%Rf", bar);
|
||||||
|
mpfr_clear(bar);]])],[libmpfr_avail_cv_=true],[libmpfr_avail_cv_=false])
|
||||||
|
AC_LANG_POP
|
||||||
|
LIBS=$libmpfr_save_libs])
|
||||||
|
|
||||||
|
if [test x$libmpfr_avail_cv_ = xtrue ]; then
|
||||||
|
LIBS="-lmpfr $LIBS"
|
||||||
|
else
|
||||||
|
AC_MSG_FAILURE("Could not find mpfr library 2.4.0 or higher (set CPPFLAGS and LDFLAGS?)")
|
||||||
|
fi
|
||||||
|
|
||||||
|
# check for edit
|
||||||
|
AC_CACHE_CHECK(
|
||||||
|
[if libedit is available],
|
||||||
|
[libedit_avail_cv_],
|
||||||
|
[libedit_save_libs=$LIBS
|
||||||
|
LIBS="-ledit $LIBS"
|
||||||
|
AC_LANG_PUSH(C++)
|
||||||
|
AC_LINK_IFELSE([AC_LANG_PROGRAM(
|
||||||
|
[[#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <editline/readline.h>]],
|
||||||
|
[[rl_readline_name = const_cast<char *>("foo");
|
||||||
|
char * line = readline(const_cast<char *>("foo: "));
|
||||||
|
free(line);]])],[libedit_avail_cv_=true],[libedit_avail_cv_=false])
|
||||||
|
AC_LANG_POP
|
||||||
|
LIBS=$libedit_save_libs])
|
||||||
|
|
||||||
|
if [test x$libedit_avail_cv_ = xtrue ]; then
|
||||||
|
LIBS="-ledit $LIBS"
|
||||||
|
AC_DEFINE([HAVE_LIBEDIT], [1], [If the libedit library is available])
|
||||||
|
fi
|
||||||
|
|
||||||
|
# check for boost_regex
|
||||||
|
AC_CACHE_CHECK(
|
||||||
|
[if boost_regex is available],
|
||||||
|
[boost_regex_avail_cv_],
|
||||||
|
[boost_regex_save_libs=$LIBS
|
||||||
|
LIBS="-lboost_regex$BOOST_SUFFIX $LIBS"
|
||||||
|
AC_LANG_PUSH(C++)
|
||||||
|
AC_LINK_IFELSE(
|
||||||
|
[AC_LANG_PROGRAM(
|
||||||
|
[[#include <boost/regex.hpp>]],
|
||||||
|
[[boost::regex foo_regexp("Hello, world!");]])],
|
||||||
|
[boost_regex_avail_cv_=true],
|
||||||
|
[boost_regex_avail_cv_=false])
|
||||||
|
AC_LANG_POP
|
||||||
|
LIBS=$boost_regex_save_libs])
|
||||||
|
|
||||||
|
if [test x$boost_regex_avail_cv_ = xtrue ]; then
|
||||||
|
LIBS="-lboost_regex$BOOST_SUFFIX $LIBS"
|
||||||
|
else
|
||||||
|
AC_MSG_FAILURE("Could not find boost_regex library (set CPPFLAGS and LDFLAGS?)")
|
||||||
|
fi
|
||||||
|
|
||||||
|
# check for boost_date_time
|
||||||
|
AC_CACHE_CHECK(
|
||||||
|
[if boost_date_time is available],
|
||||||
|
[boost_date_time_cpplib_avail_cv_],
|
||||||
|
[boost_date_time_save_libs=$LIBS
|
||||||
|
LIBS="-lboost_date_time$BOOST_SUFFIX $LIBS"
|
||||||
|
AC_LANG_PUSH(C++)
|
||||||
|
AC_LINK_IFELSE(
|
||||||
|
[AC_LANG_PROGRAM(
|
||||||
|
[[#include <boost/date_time/posix_time/posix_time.hpp>
|
||||||
|
#include <boost/date_time/gregorian/gregorian.hpp>
|
||||||
|
#include <boost/date_time/local_time_adjustor.hpp>
|
||||||
|
#include <boost/date_time/time_duration.hpp>
|
||||||
|
|
||||||
|
using namespace boost::posix_time;
|
||||||
|
using namespace boost::date_time;
|
||||||
|
|
||||||
|
#include <ctime>
|
||||||
|
|
||||||
|
inline ptime time_to_system_local(const ptime& when) {
|
||||||
|
struct std::tm tm_gmt = to_tm(when);
|
||||||
|
return from_time_t(mktime(&tm_gmt));
|
||||||
|
}]],
|
||||||
|
[[ptime t10 = ptime(boost::gregorian::from_string("2007-01-15"),
|
||||||
|
ptime::time_duration_type());
|
||||||
|
|
||||||
|
ptime t12 = time_to_system_local(t10);
|
||||||
|
|
||||||
|
return t10 != t12;]])],
|
||||||
|
[boost_date_time_cpplib_avail_cv_=true],
|
||||||
|
[boost_date_time_cpplib_avail_cv_=false])
|
||||||
|
AC_LANG_POP
|
||||||
|
LIBS=$boost_date_time_save_libs])
|
||||||
|
|
||||||
|
if [test x$boost_date_time_cpplib_avail_cv_ = xtrue ]; then
|
||||||
|
LIBS="-lboost_date_time$BOOST_SUFFIX $LIBS"
|
||||||
|
else
|
||||||
|
AC_MSG_FAILURE("Could not find boost_date_time library (set CPPFLAGS and LDFLAGS?)")
|
||||||
|
fi
|
||||||
|
|
||||||
|
# check for boost_filesystem
|
||||||
|
AC_CACHE_CHECK(
|
||||||
|
[if boost_filesystem is available],
|
||||||
|
[boost_filesystem_cpplib_avail_cv_],
|
||||||
|
[boost_filesystem_save_libs=$LIBS
|
||||||
|
LIBS="-lboost_filesystem$BOOST_SUFFIX -lboost_system$BOOST_SUFFIX $LIBS"
|
||||||
|
AC_LANG_PUSH(C++)
|
||||||
|
AC_LINK_IFELSE(
|
||||||
|
[AC_LANG_PROGRAM(
|
||||||
|
[[#include <boost/filesystem/path.hpp>]],
|
||||||
|
[[boost::filesystem::path this_path("Hello");]])],
|
||||||
|
[boost_filesystem_cpplib_avail_cv_=true],
|
||||||
|
[boost_filesystem_cpplib_avail_cv_=false])
|
||||||
|
AC_LANG_POP
|
||||||
|
LIBS=$boost_filesystem_save_libs])
|
||||||
|
|
||||||
|
if [test x$boost_filesystem_cpplib_avail_cv_ = xtrue ]; then
|
||||||
|
LIBS="-lboost_filesystem$BOOST_SUFFIX -lboost_system$BOOST_SUFFIX $LIBS"
|
||||||
|
else
|
||||||
|
AC_MSG_FAILURE("Could not find boost_filesystem library (set CPPFLAGS and LDFLAGS?)")
|
||||||
|
fi
|
||||||
|
|
||||||
|
# check for boost_iostreams
|
||||||
|
AC_CACHE_CHECK(
|
||||||
|
[if boost_iostreams is available],
|
||||||
|
[boost_iostreams_cpplib_avail_cv_],
|
||||||
|
[boost_iostreams_save_libs=$LIBS
|
||||||
|
LIBS="-lboost_iostreams$BOOST_SUFFIX -lboost_system$BOOST_SUFFIX $LIBS"
|
||||||
|
AC_LANG_PUSH(C++)
|
||||||
|
AC_LINK_IFELSE(
|
||||||
|
[AC_LANG_PROGRAM(
|
||||||
|
[[#include <boost/iostreams/device/file_descriptor.hpp>
|
||||||
|
#include <boost/iostreams/stream.hpp>]],
|
||||||
|
[[namespace io = boost::iostreams;
|
||||||
|
typedef io::stream<io::file_descriptor_sink> ofdstream;
|
||||||
|
ofdstream outstream(1);]])],
|
||||||
|
[boost_iostreams_cpplib_avail_cv_=true],
|
||||||
|
[boost_iostreams_cpplib_avail_cv_=false])
|
||||||
|
AC_LANG_POP
|
||||||
|
LIBS=$boost_iostreams_save_libs])
|
||||||
|
|
||||||
|
if [test x$boost_iostreams_cpplib_avail_cv_ = xtrue ]; then
|
||||||
|
LIBS="-lboost_iostreams$BOOST_SUFFIX -lboost_system$BOOST_SUFFIX $LIBS"
|
||||||
|
else
|
||||||
|
AC_MSG_FAILURE("Could not find boost_iostreams library (set CPPFLAGS and LDFLAGS?)")
|
||||||
|
fi
|
||||||
|
|
||||||
|
# check for boost_serialization
|
||||||
|
AC_CACHE_CHECK(
|
||||||
|
[if boost_serialization is available],
|
||||||
|
[boost_serialization_cpplib_avail_cv_],
|
||||||
|
[boost_serialization_save_libs=$LIBS
|
||||||
|
LIBS="-lboost_serialization$BOOST_SUFFIX -lboost_system$BOOST_SUFFIX $LIBS"
|
||||||
|
AC_LANG_PUSH(C++)
|
||||||
|
AC_LINK_IFELSE(
|
||||||
|
[AC_LANG_PROGRAM(
|
||||||
|
[[#include <boost/archive/binary_oarchive.hpp>
|
||||||
|
#include <iostream>
|
||||||
|
struct foo {
|
||||||
|
int a;
|
||||||
|
template<class Archive>
|
||||||
|
void serialize(Archive & ar, const unsigned int) {
|
||||||
|
ar & a;
|
||||||
|
}
|
||||||
|
};]],
|
||||||
|
[[boost::archive::binary_oarchive oa(std::cout);
|
||||||
|
foo x;
|
||||||
|
oa << x;]])],
|
||||||
|
[boost_serialization_cpplib_avail_cv_=true],
|
||||||
|
[boost_serialization_cpplib_avail_cv_=false])
|
||||||
|
AC_LANG_POP
|
||||||
|
LIBS=$boost_serialization_save_libs])
|
||||||
|
|
||||||
|
if [test x$boost_serialization_cpplib_avail_cv_ = xtrue ]; then
|
||||||
|
AC_DEFINE([HAVE_BOOST_SERIALIZATION], [1], [Whether Boost.Serialization is available])
|
||||||
|
LIBS="-lboost_serialization$BOOST_SUFFIX $LIBS"
|
||||||
|
fi
|
||||||
|
AM_CONDITIONAL(HAVE_BOOST_SERIALIZATION, test x$boost_serialization_cpplib_avail_cv_ = xtrue)
|
||||||
|
|
||||||
|
# check for Python
|
||||||
|
AM_PATH_PYTHON(2.4,, :)
|
||||||
|
if [test "$PYTHON" != :]; then
|
||||||
|
AM_CONDITIONAL(HAVE_PYTHON, true)
|
||||||
|
AC_CACHE_CHECK(
|
||||||
|
[if boost_python is available],
|
||||||
|
[boost_python_cpplib_avail_cv_],
|
||||||
|
[boost_python_save_libs=$LIBS
|
||||||
|
LIBS="-lboost_python$BOOST_SUFFIX -lpython$PYTHON_VERSION $LIBS"
|
||||||
|
AC_LANG_PUSH(C++)
|
||||||
|
AC_LINK_IFELSE(
|
||||||
|
[AC_LANG_PROGRAM(
|
||||||
|
[[#include <boost/python.hpp>
|
||||||
|
using namespace boost::python;
|
||||||
|
class foo {};
|
||||||
|
BOOST_PYTHON_MODULE(samp) {
|
||||||
|
class_< foo > ("foo") ;
|
||||||
|
}]],
|
||||||
|
[[return 0]])],
|
||||||
|
[boost_python_cpplib_avail_cv_=true],
|
||||||
|
[boost_python_cpplib_avail_cv_=false])
|
||||||
|
AC_LANG_POP
|
||||||
|
LIBS=$boost_python_save_libs])
|
||||||
|
|
||||||
|
if [ test x$boost_python_cpplib_avail_cv_ = xtrue ]; then
|
||||||
|
AC_DEFINE([HAVE_BOOST_PYTHON], [1], [Whether Boost.Python is available])
|
||||||
|
LIBS="-lboost_python$BOOST_SUFFIX -lpython$PYTHON_VERSION $LIBS"
|
||||||
|
fi
|
||||||
|
else
|
||||||
|
AM_CONDITIONAL(HAVE_PYTHON, false)
|
||||||
|
fi
|
||||||
|
AM_CONDITIONAL(HAVE_BOOST_PYTHON, test x$boost_python_cpplib_avail_cv_ = xtrue)
|
||||||
|
|
||||||
|
# check for CppUnit
|
||||||
|
AC_CACHE_CHECK(
|
||||||
|
[if cppunit is available],
|
||||||
|
[cppunit_avail_cv_],
|
||||||
|
[cppunit_save_libs=$LIBS
|
||||||
|
LIBS="-lcppunit $LIBS"
|
||||||
|
AC_LANG_PUSH(C++)
|
||||||
|
AC_LINK_IFELSE(
|
||||||
|
[AC_LANG_PROGRAM(
|
||||||
|
[[#include <cppunit/CompilerOutputter.h>
|
||||||
|
#include <cppunit/TestResult.h>
|
||||||
|
#include <cppunit/TestResultCollector.h>
|
||||||
|
#include <cppunit/TestRunner.h>
|
||||||
|
#include <cppunit/TextTestProgressListener.h>
|
||||||
|
#include <cppunit/BriefTestProgressListener.h>
|
||||||
|
#include <cppunit/XmlOutputter.h>
|
||||||
|
#include <cppunit/extensions/TestFactoryRegistry.h>]],
|
||||||
|
[[CPPUNIT_NS::TestResult controller;
|
||||||
|
CPPUNIT_NS::TestResultCollector result;]])],
|
||||||
|
[cppunit_avail_cv_=true],
|
||||||
|
[cppunit_avail_cv_=false])
|
||||||
|
AC_LANG_POP
|
||||||
|
LIBS=$cppunit_save_libs])
|
||||||
|
|
||||||
|
AM_CONDITIONAL(HAVE_CPPUNIT, test x$cppunit_avail_cv_ = xtrue)
|
||||||
|
|
||||||
|
# Checks for header files.
|
||||||
|
AC_HEADER_STDC
|
||||||
|
AC_HEADER_STAT
|
||||||
|
AC_CHECK_HEADERS([langinfo.h])
|
||||||
|
|
||||||
|
# Checks for typedefs, structures, and compiler characteristics.
|
||||||
|
AC_TYPE_SIZE_T
|
||||||
|
AC_STRUCT_TM
|
||||||
|
|
||||||
|
# Checks for library functions.
|
||||||
|
#AC_FUNC_MKTIME
|
||||||
|
#AC_FUNC_STAT
|
||||||
|
#AC_FUNC_STRFTIME
|
||||||
|
AC_CHECK_FUNCS([access realpath getpwuid getpwnam isatty])
|
||||||
|
|
||||||
|
# Pepare the Makefiles
|
||||||
|
AC_CONFIG_FILES([Makefile po/Makefile.in intl/Makefile])
|
||||||
|
AC_OUTPUT
|
||||||
Loading…
Add table
Reference in a new issue