Code

Imported upstream version 1.3rc4.
authorSebastian Harl <sh@tokkee.org>
Sun, 18 May 2008 17:39:16 +0000 (19:39 +0200)
committerSebastian Harl <sh@tokkee.org>
Sun, 18 May 2008 17:39:16 +0000 (19:39 +0200)
174 files changed:
CHANGES
CONTRIBUTORS
Makefile.am
Makefile.in
NEWS
acinclude.m4
aclocal.m4
bindings/Makefile.in
bindings/perl-piped/RRDp.pm
bindings/perl-shared/Makefile.PL
bindings/perl-shared/RRDs.pm
bindings/perl-shared/RRDs.xs
bindings/python/rrd_extra.h
bindings/python/rrdtoolmodule.c
bindings/python/setup.py
bindings/ruby/main.c
bindings/tcl/Makefile.am
bindings/tcl/Makefile.in
bindings/tcl/tclrrd.c
configure
configure.ac
doc/Makefile.am
doc/Makefile.in
doc/RRDs.html
doc/bin_dec_hex.1
doc/bin_dec_hex.txt
doc/cdeftutorial.1
doc/cdeftutorial.txt
doc/rpntutorial.1
doc/rpntutorial.txt
doc/rrd-beginners.1
doc/rrd-beginners.txt
doc/rrdbuild.1
doc/rrdbuild.html
doc/rrdbuild.pod
doc/rrdbuild.txt
doc/rrdcgi.1
doc/rrdcgi.txt
doc/rrdcreate.1
doc/rrdcreate.html
doc/rrdcreate.pod
doc/rrdcreate.txt
doc/rrddump.1
doc/rrddump.html
doc/rrddump.pod
doc/rrddump.txt
doc/rrdfetch.1
doc/rrdfetch.txt
doc/rrdfirst.1
doc/rrdfirst.txt
doc/rrdgraph.1
doc/rrdgraph.html
doc/rrdgraph.pod
doc/rrdgraph.txt
doc/rrdgraph_data.1
doc/rrdgraph_data.txt
doc/rrdgraph_examples.1
doc/rrdgraph_examples.html
doc/rrdgraph_examples.pod
doc/rrdgraph_examples.txt
doc/rrdgraph_graph.1
doc/rrdgraph_graph.html
doc/rrdgraph_graph.pod
doc/rrdgraph_graph.txt
doc/rrdgraph_rpn.1
doc/rrdgraph_rpn.html
doc/rrdgraph_rpn.pod
doc/rrdgraph_rpn.txt
doc/rrdinfo.1
doc/rrdinfo.txt
doc/rrdlast.1
doc/rrdlast.txt
doc/rrdlastupdate.1
doc/rrdlastupdate.txt
doc/rrdresize.1
doc/rrdresize.txt
doc/rrdrestore.1
doc/rrdrestore.txt
doc/rrdthreads.1
doc/rrdthreads.txt
doc/rrdtool.1
doc/rrdtool.txt
doc/rrdtune.1
doc/rrdtune.html
doc/rrdtune.pod
doc/rrdtune.txt
doc/rrdtutorial.1
doc/rrdtutorial.html
doc/rrdtutorial.pod
doc/rrdtutorial.txt
doc/rrdupdate.1
doc/rrdupdate.txt
doc/rrdxport.1
doc/rrdxport.txt
examples/Makefile.am
examples/Makefile.in
examples/perftest.pl.in
intltool-extract.in [new file with mode: 0644]
intltool-merge.in [new file with mode: 0644]
intltool-update.in [new file with mode: 0644]
netware/Makefile
po/ChangeLog [new file with mode: 0644]
po/LINGUAS [new file with mode: 0644]
po/Makefile.in.in [new file with mode: 0644]
po/POTFILES.in [new file with mode: 0644]
po/de.po [new file with mode: 0644]
rrd_config.h.in
rrdtool.spec
src/DejaVuSansMono-Roman.ttf [deleted file]
src/Makefile.am
src/Makefile.in
src/art_rgba_svp.c [deleted file]
src/art_rgba_svp.h [deleted file]
src/fnv.h
src/hash_32.c
src/parsetime.c
src/pngsize.c
src/rrd.h
src/rrd_afm.c [deleted file]
src/rrd_afm.h [deleted file]
src/rrd_afm_data.c [deleted file]
src/rrd_afm_data.h [deleted file]
src/rrd_cgi.c
src/rrd_create.c
src/rrd_diff.c
src/rrd_dump.c
src/rrd_error.c
src/rrd_fetch.c
src/rrd_first.c
src/rrd_format.c
src/rrd_format.h
src/rrd_getopt.c
src/rrd_getopt.h
src/rrd_getopt1.c
src/rrd_gfx.c
src/rrd_gfx.h [deleted file]
src/rrd_graph.c
src/rrd_graph.h
src/rrd_graph_helper.c
src/rrd_hw.c
src/rrd_hw.h
src/rrd_hw_math.c [new file with mode: 0644]
src/rrd_hw_math.h [new file with mode: 0644]
src/rrd_hw_update.c [new file with mode: 0644]
src/rrd_hw_update.h [new file with mode: 0644]
src/rrd_i18n.h [new file with mode: 0644]
src/rrd_info.c
src/rrd_is_thread_safe.h
src/rrd_last.c
src/rrd_lastupdate.c
src/rrd_nan_inf.c
src/rrd_nan_inf.h [deleted file]
src/rrd_not_thread_safe.c
src/rrd_open.c
src/rrd_resize.c
src/rrd_restore.c
src/rrd_rpncalc.c
src/rrd_rpncalc.h
src/rrd_thread_safe.c
src/rrd_thread_safe_nt.c
src/rrd_tool.c
src/rrd_tool.h
src/rrd_tune.c
src/rrd_update.c
src/rrd_version.c
src/rrd_xport.c
src/rrd_xport.h
src/rrdupdate.c
src/strftime.c
src/strftime.h
src/unused.h
src/win32comp.c
win32/Makefile
win32/config.h

diff --git a/CHANGES b/CHANGES
index cf537f81b5b12ea41936cf90062f67eaebe6bbfa..3e0cbc793bb64ffebc159ac9ecac6e511c990108 100644 (file)
--- a/CHANGES
+++ b/CHANGES
-2008-02-17 10:09  oetiker
-
-       * rrdtool-1.2-release: prepare for the release of rrdtool-1.2.27
-
-2008-02-17 10:08  oetiker
-
-       * bindings/perl-piped/RRDp.pm, bindings/perl-shared/RRDs.pm,
-         configure.ac, doc/rrdbuild.pod, rrdtool.spec, src/Makefile.am,
-         src/gdpng.c, src/pngsize.c, src/rrd.h, src/rrd_afm.c,
-         src/rrd_afm.h, src/rrd_afm_data.c, src/rrd_afm_data.h,
-         src/rrd_cgi.c, src/rrd_create.c, src/rrd_datalang.c,
-         src/rrd_diff.c, src/rrd_dump.c, src/rrd_error.c, src/rrd_fetch.c,
-         src/rrd_first.c, src/rrd_format.c, src/rrd_format.h,
-         src/rrd_gfx.c, src/rrd_gfx.h, src/rrd_graph.c,
-         src/rrd_graph_helper.c, src/rrd_hw.c, src/rrd_hw.h,
-         src/rrd_info.c, src/rrd_is_thread_safe.h, src/rrd_last.c,
-         src/rrd_lastupdate.c, src/rrd_not_thread_safe.c, src/rrd_open.c,
-         src/rrd_resize.c, src/rrd_restore.c, src/rrd_rpncalc.c,
-         src/rrd_rpncalc.h, src/rrd_stat.c, src/rrd_thread_safe.c,
-         src/rrd_thread_safe_nt.c, src/rrd_tool.c, src/rrd_tool.h,
-         src/rrd_tune.c, src/rrd_update.c, src/rrd_version.c,
-         src/rrd_xport.c, src/rrd_xport.h, src/rrdupdate.c: prepare for
-         1.2.27 release
-
-2008-02-14 07:25  oetiker
-
-       * doc/rrdcreate.pod, doc/rrdgraph.pod, doc/rrdgraph_graph.pod,
-         doc/rrdgraph_rpn.pod, doc/rrdtutorial.pod: fixes for better web
-         rendering
-
-2008-02-04 18:17  oetiker
-
-       * COPYRIGHT: added ZPL 2.1 to floss exception
-
-2008-02-01 06:52  oetiker
-
-       * src/rrd_graph.c, trunk/program/src/rrd_graph.c: fixed parsing of
-         fontnames with embeded spaces
-
-2008-01-14 16:47  oetiker
-
-       * bindings/tcl/tclrrd.c, configure.ac, src/rrd_cgi.c: * fix fadvice
-         and madvice inclusion ... again * fix rrdcgi warning * fix
-         warnings in tcl bindings -- Peter Breitenlohner peb mppmu.mpg.de
-
-2008-01-12 18:36  oetiker
-
-       * src/rrd_graph.c: weekday and time are too tight
-
-2007-12-08 22:17  oetiker
-
-       * configure.ac: fixing the solaris build
-
-2007-11-23 18:18  oetiker
-
-       * netware/Makefile, src/rrd_update.c, win32/Makefile: updates for
-         netware and mingw32 ... allows for crosscompilation
-
-2007-11-22 12:33  oetiker
-
-       * src/rrd_update.c: make update compile for mingw32 3.4.5
-
-2007-11-21 10:51  oetiker
-
-       * configure.ac: fixedspellingfor netbsd
-
-2007-11-21 06:57  oetiker
-
-       * bindings/perl-shared/Makefile.PL, configure.ac, src/rrd_tool.h,
-         src/rrd_update.c: * improve portability of compile environment to
-         netbsd and solaris
-
-2007-11-20 00:15  oetiker
-
-       * bindings/perl-piped/RRDp.pm, bindings/perl-shared/RRDs.pm,
-         configure.ac, doc/rrdbuild.pod, rrdtool.spec, src/Makefile.am,
-         src/gdpng.c, src/pngsize.c, src/rrd.h, src/rrd_afm.c,
-         src/rrd_afm.h, src/rrd_afm_data.c, src/rrd_afm_data.h,
-         src/rrd_cgi.c, src/rrd_create.c, src/rrd_datalang.c,
-         src/rrd_diff.c, src/rrd_dump.c, src/rrd_error.c, src/rrd_fetch.c,
-         src/rrd_first.c, src/rrd_format.c, src/rrd_format.h,
-         src/rrd_gfx.c, src/rrd_gfx.h, src/rrd_graph.c,
-         src/rrd_graph_helper.c, src/rrd_hw.c, src/rrd_hw.h,
-         src/rrd_info.c, src/rrd_is_thread_safe.h, src/rrd_last.c,
-         src/rrd_lastupdate.c, src/rrd_not_thread_safe.c, src/rrd_open.c,
-         src/rrd_resize.c, src/rrd_restore.c, src/rrd_rpncalc.c,
-         src/rrd_rpncalc.h, src/rrd_stat.c, src/rrd_thread_safe.c,
-         src/rrd_thread_safe_nt.c, src/rrd_tool.c, src/rrd_tool.h,
-         src/rrd_tune.c, src/rrd_update.c, src/rrd_version.c,
-         src/rrd_xport.c, src/rrd_xport.h, src/rrdupdate.c: prepare for the
-         release of rrdtool-1.2.26
-
-2007-11-19 23:40  oetiker
-
-       * src/rrd_graph.c: when checking if min and max were equal, the
-         action aplied was not working for negative values of min and max.
-
-2007-11-19 23:40  oetiker
-
-       * configure.ac, src/rrd_tool.h: strings was not included ev if it
-         was around
-
-2007-11-19 16:50  oetiker
-
-       * src/rrd_gfx.c: fix pointer in png image
-
-2007-11-14 13:53  oetiker
-
-       * bindings/perl-piped/RRDp.pm, bindings/perl-shared/RRDs.pm,
-         configure.ac, doc/rrdbuild.pod, rrdtool.spec, src/gdpng.c,
-         src/rrd.h, src/rrd_afm.c, src/rrd_afm.h, src/rrd_afm_data.c,
-         src/rrd_afm_data.h, src/rrd_cgi.c, src/rrd_create.c,
-         src/rrd_datalang.c, src/rrd_diff.c, src/rrd_dump.c,
-         src/rrd_error.c, src/rrd_fetch.c, src/rrd_first.c,
-         src/rrd_format.c, src/rrd_format.h, src/rrd_gfx.c, src/rrd_gfx.h,
-         src/rrd_graph.c, src/rrd_graph_helper.c, src/rrd_hw.c,
-         src/rrd_hw.h, src/rrd_info.c, src/rrd_is_thread_safe.h,
-         src/rrd_last.c, src/rrd_lastupdate.c, src/rrd_not_thread_safe.c,
-         src/rrd_resize.c, src/rrd_restore.c, src/rrd_rpncalc.c,
-         src/rrd_rpncalc.h, src/rrd_stat.c, src/rrd_thread_safe.c,
-         src/rrd_thread_safe_nt.c, src/rrd_tool.c, src/rrd_tool.h,
-         src/rrd_tune.c, src/rrd_update.c, src/rrd_version.c,
-         src/rrd_xport.c, src/rrd_xport.h, src/rrdupdate.c: prepare for the
-         release of rrdtool-1.2.25
-
-2007-11-14 13:53  oetiker
-
-       * src/pngsize.c: make aix users happy and compile there too
-
-2007-11-14 13:53  oetiker
-
-       * src/rrd_open.c: don't exit when fadvise does not work .. after all
-         we can live without it ...
-
-2007-11-13 02:21  oetiker
+2008-05-18 13:06  oetiker
 
        * bindings/perl-piped/RRDp.pm, bindings/perl-shared/RRDs.pm,
-         doc/rrdbuild.pod, rrdtool.spec, src/gdpng.c, src/pngsize.c,
-         src/rrd.h, src/rrd_afm.c, src/rrd_afm.h, src/rrd_afm_data.c,
-         src/rrd_afm_data.h, src/rrd_cgi.c, src/rrd_create.c,
+         configure.ac, doc/rrdbuild.pod, rrdtool-1.3-release, rrdtool.spec,
+         src/pngsize.c, src/rrd.h, src/rrd_cgi.c, src/rrd_create.c,
          src/rrd_datalang.c, src/rrd_diff.c, src/rrd_dump.c,
          src/rrd_error.c, src/rrd_fetch.c, src/rrd_first.c,
-         src/rrd_format.c, src/rrd_format.h, src/rrd_gfx.c, src/rrd_gfx.h,
+         src/rrd_format.c, src/rrd_format.h, src/rrd_gfx.c,
          src/rrd_graph.c, src/rrd_graph_helper.c, src/rrd_hw.c,
-         src/rrd_hw.h, src/rrd_info.c, src/rrd_is_thread_safe.h,
-         src/rrd_last.c, src/rrd_lastupdate.c, src/rrd_not_thread_safe.c,
-         src/rrd_open.c, src/rrd_resize.c, src/rrd_restore.c,
-         src/rrd_rpncalc.c, src/rrd_rpncalc.h, src/rrd_stat.c,
+         src/rrd_hw.h, src/rrd_i18n.h, src/rrd_info.c,
+         src/rrd_is_thread_safe.h, src/rrd_last.c, src/rrd_lastupdate.c,
+         src/rrd_not_thread_safe.c, src/rrd_open.c, src/rrd_resize.c,
+         src/rrd_restore.c, src/rrd_rpncalc.c, src/rrd_rpncalc.h,
          src/rrd_thread_safe.c, src/rrd_thread_safe_nt.c, src/rrd_tool.c,
          src/rrd_tool.h, src/rrd_tune.c, src/rrd_update.c,
          src/rrd_version.c, src/rrd_xport.c, src/rrd_xport.h,
-         src/rrdupdate.c: prepare for the release of rrdtool-1.2.24
-
-2007-11-13 02:18  oetiker
-
-       * configure.ac: updated for 1.2.24
-
-2007-11-13 02:16  oetiker
-
-       * src/rrd_create.c: revert the dontneed fadvise patch this is only
-         for 1.3
-
-2007-11-13 02:13  oetiker
-
-       * src/rrd_fetch.c: revert the dontneed patch ... this is for 1.3
-         exclusively
-
-2007-11-08 10:13  oetiker
-
-       * bindings/ruby/main.c: must use int2num to prevent overflows --
-         Mike Perham mperham gmail.com
-
-2007-09-02 16:47  oetiker
-
-       * doc/rrdgraph_graph.pod: horizontal is the correct spelling
-
-2007-08-01 15:25  oetiker
-
-       * src/rrd_xport.c: fixed 64bit portability error ... unigned long is
-         not equal to int
-
-2007-07-25 20:32  oetiker
-
-       * src/rrd_update.c: check if intput is integer in any case not only
-         when the previouse value wave != U
-
-2007-07-16 06:34  oetiker
-
-       * bindings/ruby/main.c: fixed rrd_featch and added rrd_info to ruby
-         bindings
-
-2007-07-12 20:33  oetiker
-
-       * doc/rrdtutorial.pod: improved wording
-
-2007-07-11 23:06  oetiker
-
-       * src/rrd_create.c: stop rrd_create from leaking on failure ... vito
-         caputo
-
-2007-07-05 15:14  oetiker
-
-       * src/rrd_graph_helper.c: fix potential segfault ... if time_t is
-         not a %li 5~
-
-2007-07-05 15:14  oetiker
-
-       * bindings/tcl/Makefile.am: fix tcl build system
-
-2007-06-15 21:41  oetiker
-
-       * rrdtool.spec: rrdtool.spec from Jarod "redhat" Wilson
-
-2007-06-13 16:50  oetiker
-
-       * bindings/ruby/main.c: be more helpful when raising rb_eTypeError
-         in string_arr string_arr_new(VALUE rb_strings). This patch
-         indicates which index is in error as well as the type you are
-         erroneously passing. --anonymous
-
-2007-05-30 11:26  oetiker
-
-       * src/rrd_update.c: dropping cache after update does not help (in
-         this implementation)
-
-2007-05-22 20:46  oetiker
-
-       * configure.ac: fixed spelling
-
-2007-05-22 20:44  oetiker
-
-       * configure.ac, src/rrd_tool.c, src/rrd_tool.h, src/rrd_update.c: *
-         better tests for madvise, fadvise and fdatasync * fix inclusion of
-         fcntl.h * clenups for configure.ac -- Bernhard Fischer rep dot nop
-         gmail com
-
-2007-05-19 05:47  oetiker
-
-       * configure.ac: update defines according to manual pageentry
-
-2007-05-18 16:40  oetiker
-
-       * configure.ac, src/rrd_update.c: added madvise MADV_RANDOM is
-         rrd_update uses mmap
-
-2007-05-18 11:56  oetiker
-
-       * configure.ac, src/rrd_create.c, src/rrd_fetch.c, src/rrd_update.c:
-         * dropping in rrd_update is probably overkill since we may be
-         dropping too much. * in create we have to flush before dropping. *
-         read fcntl.h after defining the __USE_XOPEN2K * fix drop code in
-         fetch ...
-
-2007-05-17 11:38  oetiker
-
-       * configure.ac, src/rrd_create.c, src/rrd_fetch.c, src/rrd_open.c,
-         src/rrd_update.c: now the fadvise code actually compiles ... let
-         the testing begin.
-
-2007-05-17 08:44  oetiker
-
-       * examples/perftest.pl.in: new better ? performance test ... work in
-         progress
-
-2007-05-17 08:44  oetiker
-
-       * configure.ac, src/Makefile.am, src/rrd_create.c, src/rrd_fetch.c,
-         src/rrd_open.c, src/rrd_update.c: added posix_fadvise support
-         (untested) ... this should help performance by stopping read-ahead
-         and droping buffer cache for all rrd data except the file header
-         portion. Newly created files are fdsynced to disk and released
-         from cache after creation, to soften the blow on buffer cache by
-         creating new rrds.
-
-2007-05-16 20:35  oetiker
-
-       * src/rrd_open.c: remove tabs and replace with 8 spaces
-
-2007-05-15 08:39  oetiker
+         src/rrdupdate.c: prepare for the release of rrdtool-1.3rc4
 
-       * bindings/Makefile.am: use libdir instead of exec_prefix/lib ...
-         maybe someone wants their libraries in another place
+2008-05-18 13:04  oetiker
 
-2007-05-15 08:36  oetiker
+       * src/rrd_tool.c, src/rrdupdate.c: fix year
 
-       * bindings/Makefile.am, bindings/python/setup.py: yet another
-         attempt to make the python build environment REALY cool
+2008-05-18 12:53  oetiker
 
-2007-05-09 15:26  oetiker
+       * src/rrd_graph.c: PRINT returns from rrd_graph did not work due to
+         an off by one error
 
-       * bindings/Makefile.am, bindings/python/setup.py: make sure the
-         python extension gets the final resting place of the rrdlibrary
-         compiled in ...
+2008-05-18 08:42  oetiker
 
-2007-05-08 15:10  oetiker
+       * doc/rrdbuild.pod: updated build instructions to latest libraries
 
-       * bindings/Makefile.am: ruby complained about finding a previous
-         copy of the rrdtool extension ... very odd thing actually ...
-         adding RUBYARCHDIR= seems to help ...
+2008-05-18 06:37  oetiker
 
-2007-05-06 19:38  oetiker
+       * NEWS, configure.ac, src/rrd_i18n.h, src/rrd_tool.c: improved
+         handling of libintl issues
 
-       * src/rrd_graph.c: don't use round since it is c99 ... use
-         floor(x+0.5) for positive numbers instead.
-
-2007-05-06 08:50  oetiker
-
-       * src/rrd_hw.c: print the name of the HW cf in debug mode -- Helge
-         Oldach
-
-2007-05-03 12:49  oetiker
-
-       * src/rrd_graph.c: added some more rounding for int to float
-         comparisons
-
-2007-05-03 12:43  oetiker
-
-       * src/rrd_graph.c: Testing an double and an integer for equality is
-         bound to produce odd results on times. Don't do it! --
-         rrdtool@oldach.net
-
-2007-05-02 18:06  oetiker
+2008-05-16 12:29  oetiker
 
        * bindings/perl-piped/RRDp.pm, bindings/perl-shared/RRDs.pm,
-         configure.ac, doc/rrdbuild.pod, rrdtool.spec, src/gdpng.c,
-         src/pngsize.c, src/rrd.h, src/rrd_afm.c, src/rrd_afm.h,
-         src/rrd_afm_data.c, src/rrd_afm_data.h, src/rrd_cgi.c,
-         src/rrd_create.c, src/rrd_datalang.c, src/rrd_diff.c,
-         src/rrd_dump.c, src/rrd_error.c, src/rrd_fetch.c, src/rrd_first.c,
-         src/rrd_format.c, src/rrd_format.h, src/rrd_gfx.c, src/rrd_gfx.h,
-         src/rrd_graph.c, src/rrd_graph_helper.c, src/rrd_hw.c,
-         src/rrd_hw.h, src/rrd_info.c, src/rrd_is_thread_safe.h,
-         src/rrd_last.c, src/rrd_lastupdate.c, src/rrd_not_thread_safe.c,
-         src/rrd_open.c, src/rrd_resize.c, src/rrd_restore.c,
-         src/rrd_rpncalc.c, src/rrd_rpncalc.h, src/rrd_stat.c,
+         configure.ac, doc/rrdbuild.pod, rrdtool.spec, src/pngsize.c,
+         src/rrd.h, src/rrd_cgi.c, src/rrd_create.c, src/rrd_datalang.c,
+         src/rrd_diff.c, src/rrd_dump.c, src/rrd_error.c, src/rrd_fetch.c,
+         src/rrd_first.c, src/rrd_format.c, src/rrd_format.h,
+         src/rrd_gfx.c, src/rrd_graph.c, src/rrd_graph_helper.c,
+         src/rrd_hw.c, src/rrd_hw.h, src/rrd_i18n.h, src/rrd_info.c,
+         src/rrd_is_thread_safe.h, src/rrd_last.c, src/rrd_lastupdate.c,
+         src/rrd_not_thread_safe.c, src/rrd_open.c, src/rrd_resize.c,
+         src/rrd_restore.c, src/rrd_rpncalc.c, src/rrd_rpncalc.h,
          src/rrd_thread_safe.c, src/rrd_thread_safe_nt.c, src/rrd_tool.c,
          src/rrd_tool.h, src/rrd_tune.c, src/rrd_update.c,
          src/rrd_version.c, src/rrd_xport.c, src/rrd_xport.h,
-         src/rrdupdate.c: prepare for the release of rrdtool-1.2.23
+         src/rrdupdate.c: prepare for the release of rrdtool-1.3rc3
 
-2007-05-02 18:05  oetiker
+2008-05-16 12:28  oetiker
 
-       * bindings/Makefile.am: fix python install for virgin systems
+       * doc/rrddump.pod, src/rrd_dump.c: added --no-header to
+         documentation and fixed implementation
 
-2007-05-02 15:31  oetiker
+2008-05-16 12:20  oetiker
 
-       * bindings/perl-piped/RRDp.pm, bindings/perl-shared/RRDs.pm,
-         configure.ac, doc/rrdbuild.pod, rrdtool.spec, src/gdpng.c,
-         src/pngsize.c, src/rrd.h, src/rrd_afm.c, src/rrd_afm.h,
-         src/rrd_afm_data.c, src/rrd_afm_data.h, src/rrd_cgi.c,
-         src/rrd_create.c, src/rrd_datalang.c, src/rrd_diff.c,
-         src/rrd_dump.c, src/rrd_error.c, src/rrd_fetch.c, src/rrd_first.c,
-         src/rrd_format.c, src/rrd_format.h, src/rrd_gfx.c, src/rrd_gfx.h,
-         src/rrd_graph.c, src/rrd_graph_helper.c, src/rrd_hw.c,
-         src/rrd_hw.h, src/rrd_info.c, src/rrd_is_thread_safe.h,
-         src/rrd_last.c, src/rrd_lastupdate.c, src/rrd_not_thread_safe.c,
-         src/rrd_open.c, src/rrd_resize.c, src/rrd_restore.c,
-         src/rrd_rpncalc.c, src/rrd_rpncalc.h, src/rrd_stat.c,
-         src/rrd_thread_safe.c, src/rrd_thread_safe_nt.c, src/rrd_tool.c,
-         src/rrd_tool.h, src/rrd_tune.c, src/rrd_update.c,
-         src/rrd_version.c, src/rrd_xport.c, src/rrd_xport.h,
-         src/rrdupdate.c: prepare for the release of rrdtool-1.2.22
+       * src/rrd_dump.c: fixed dump_opt implementation
 
-2007-05-02 15:31  oetiker
+2008-05-16 12:18  oetiker
 
-       * README, bindings/perl-shared/RRDs.ppd,
-         bindings/perl-shared/ntmake.pl, debian/copyright, debian/watch,
-         doc/rrdtutorial.es.pod, doc/rrdtutorial.pod, doc/see_also.inc:
-         fixed old urls in code
+       * NEWS, src/rrd_dump.c: added no-header option to rrd_dump
 
-2007-05-02 15:23  oetiker
+2008-05-16 12:07  oetiker
 
-       * bindings/Makefile.am: fix python for staged installs
+       * src/rrd_graph.c: fix handling of values <= zero for logarithmic
+         display
 
-2007-05-02 05:08  oetiker
+2008-05-15 22:39  oetiker
 
-       * bindings/tcl/tclrrd.c: fixed path to rrd_format.h in tcl bindings
+       * rrdtool-1.3-release: prepare for the release of rrdtool-1.3rc2
 
-2007-05-01 20:41  oetiker
+2008-05-15 22:39  oetiker
 
        * bindings/perl-piped/RRDp.pm, bindings/perl-shared/RRDs.pm,
-         configure.ac, doc/rrdbuild.pod, rrdtool.spec, src/gdpng.c,
-         src/pngsize.c, src/rrd.h, src/rrd_afm.c, src/rrd_afm.h,
-         src/rrd_afm_data.c, src/rrd_afm_data.h, src/rrd_cgi.c,
-         src/rrd_create.c, src/rrd_datalang.c, src/rrd_diff.c,
-         src/rrd_dump.c, src/rrd_error.c, src/rrd_fetch.c, src/rrd_first.c,
-         src/rrd_format.c, src/rrd_format.h, src/rrd_gfx.c, src/rrd_gfx.h,
-         src/rrd_graph.c, src/rrd_graph_helper.c, src/rrd_hw.c,
-         src/rrd_hw.h, src/rrd_info.c, src/rrd_is_thread_safe.h,
-         src/rrd_last.c, src/rrd_lastupdate.c, src/rrd_not_thread_safe.c,
-         src/rrd_open.c, src/rrd_resize.c, src/rrd_restore.c,
-         src/rrd_rpncalc.c, src/rrd_rpncalc.h, src/rrd_stat.c,
+         configure.ac, doc/rrdbuild.pod, rrdtool.spec, src/pngsize.c,
+         src/rrd.h, src/rrd_cgi.c, src/rrd_create.c, src/rrd_datalang.c,
+         src/rrd_diff.c, src/rrd_dump.c, src/rrd_error.c, src/rrd_fetch.c,
+         src/rrd_first.c, src/rrd_format.c, src/rrd_format.h,
+         src/rrd_gfx.c, src/rrd_graph.c, src/rrd_graph_helper.c,
+         src/rrd_hw.c, src/rrd_hw.h, src/rrd_i18n.h, src/rrd_info.c,
+         src/rrd_is_thread_safe.h, src/rrd_last.c, src/rrd_lastupdate.c,
+         src/rrd_not_thread_safe.c, src/rrd_open.c, src/rrd_resize.c,
+         src/rrd_restore.c, src/rrd_rpncalc.c, src/rrd_rpncalc.h,
          src/rrd_thread_safe.c, src/rrd_thread_safe_nt.c, src/rrd_tool.c,
          src/rrd_tool.h, src/rrd_tune.c, src/rrd_update.c,
          src/rrd_version.c, src/rrd_xport.c, src/rrd_xport.h,
-         src/rrdupdate.c: prepare for the release of rrdtool-1.2.21
-
-2007-05-01 20:40  oetiker
-
-       * src/rrd_graph.c: if the graph goes 'down' minval must be hanged
-         instead
-
-2007-05-01 16:36  oetiker
-
-       * bindings/perl-piped/RRDp.pm, bindings/perl-shared/RRDs.pm,
-         configure.ac, doc/rrdbuild.pod, rrdtool.spec, src/Makefile.am,
-         src/gdpng.c, src/pngsize.c, src/rrd.h, src/rrd_afm.c,
-         src/rrd_afm.h, src/rrd_afm_data.c, src/rrd_afm_data.h,
-         src/rrd_cgi.c, src/rrd_create.c, src/rrd_datalang.c,
-         src/rrd_diff.c, src/rrd_dump.c, src/rrd_error.c, src/rrd_fetch.c,
-         src/rrd_first.c, src/rrd_format.c, src/rrd_format.h,
-         src/rrd_gfx.c, src/rrd_gfx.h, src/rrd_graph.c,
-         src/rrd_graph_helper.c, src/rrd_hw.c, src/rrd_hw.h,
-         src/rrd_info.c, src/rrd_is_thread_safe.h, src/rrd_last.c,
-         src/rrd_lastupdate.c, src/rrd_not_thread_safe.c, src/rrd_open.c,
-         src/rrd_resize.c, src/rrd_restore.c, src/rrd_rpncalc.c,
-         src/rrd_rpncalc.h, src/rrd_stat.c, src/rrd_thread_safe.c,
-         src/rrd_thread_safe_nt.c, src/rrd_tool.c, src/rrd_tool.h,
-         src/rrd_tune.c, src/rrd_update.c, src/rrd_version.c,
-         src/rrd_xport.c, src/rrd_xport.h, src/rrdupdate.c: prepare for the
-         release of rrdtool-1.2.20
-
-2007-05-01 16:24  oetiker
-
-       * netware/Makefile, win32/Makefile: updated win32 and netware
-         Makefiles -- Guenter Knauf
-
-2007-05-01 16:23  oetiker
-
-       * src/rrd_create.c, src/rrd_update.c: added some const casts
+         src/rrdupdate.c: prepare for the release of rrdtool-1.3rc2
 
-2007-05-01 16:19  oetiker
+2008-05-15 22:37  oetiker
 
-       * doc/rrdgraph.pod, src/rrd_graph.c, src/rrd_graph.h: added
-         --alt-autoscale-min (see --alt-autoscale-max) -- Helge Oldach
+       * Makefile.am, configure.ac, rrdtool-1.3-release, src/Makefile.am:
+         fix portability to mac osx and freebsd -- tobi
 
-2007-04-10 05:43  oetiker
+2008-05-12 23:10  oetiker
 
-       * src/rrd_graph.c: untabified rrd_graph.c
+       * configure.ac: add solaris pod2man location last
 
-2007-04-10 05:41  oetiker
+2008-05-12 23:03  oetiker
 
-       * src/rrd_graph.c: use the shorthand for vidx ...
+       * configure.ac, doc/Makefile.am, doc/rrdbuild.pod: some changes to
+         make things work on opensolaris 2008.05
 
-2007-04-10 05:27  oetiker
+2008-05-12 22:42  oetiker
 
-       * src/rrd_graph.c, src/rrd_graph.h: the rrd_graph_check_vname
-         function is not used anywhere in the code ...
+       * bindings/tcl/Makefile.am: for some reason tclrrd.c does not get
+         picked up using $< at least on opensolaris
 
-2007-04-06 07:28  oetiker
+2008-05-12 22:23  oetiker
 
-       * src/rrd_gfx.c: release font resources after thy have been used ...
-         -- Travis Spencer
+       * src/Makefile.am, src/rrd_graph.h, src/rrd_info.c,
+         src/rrd_rpncalc.c, src/rrd_rpncalc.h, src/rrd_tool.c: allow
+         rrd_rpncalc to build without cairo dependencies ... fix warnings
 
-2007-04-02 06:21  oetiker
+2008-05-12 21:14  oetiker
 
-       * doc/rrdthreads.pod, src/fnv.h, src/hash_32.c, src/rrd.h,
-         src/rrd_create.c, src/rrd_fetch.c, src/rrd_format.c,
-         src/rrd_rpncalc.c, src/rrd_rpncalc.h, src/rrd_tool.h,
-         src/rrd_update.c: new function rrd_fetch_r() (and make the strings
-         const char* instead of char*). The only difference between
-         rrd_fetch_r() and rrd_fetch_fn() is that rrd_fetch_r() receives
-         the consolidation function as a string (instead of an enum cf_en)
-         and is thread-safe -- Sam Umbach
+       * Makefile.am: add intltool*in files to dist
 
-2007-04-02 06:18  oetiker
+2008-05-12 16:15  oetiker
 
-       * src/rrd_restore.c: make xml2rrd more robust on invalid input --
-         Florian Forster
+       * bindings/python/rrdtoolmodule.c, src/rrd_update.c: fixed indenting
 
-2007-03-29 19:08  oetiker
+2008-05-12 16:15  oetiker
 
-       * doc/rrdruby.pod: added vardef
+       * src/rrd_graph.c, src/rrd_hw.c, src/rrd_open.c, src/rrd_rpncalc.c,
+         src/win32comp.c: removed c++ comments //
 
-2007-03-15 21:10  oetiker
+2008-05-12 16:09  oetiker
 
-       * src/rrd_tool.c: fix the snprintf call for vtag ... it was using
-         the wrong size -- kili
+       * NEWS: added notes about rewrites in this release
 
-2007-03-15 21:03  oetiker
+2008-05-12 16:08  oetiker
 
-       * src/rrd_thread_safe.c: fixed strerror_r usage ... #85
+       * configure.ac, src/Makefile.am: improved handling of library
+         versioning
 
-2007-03-11 13:08  oetiker
+2008-05-12 15:35  oetiker
 
-       * Makefile.am, bindings/Makefile.am, doc/Makefile.am,
-         examples/Makefile.am, netware/Makefile, win32/Makefile,
-         win32/rrd.dsp, win32/rrdtool.dsp: fix netware and win32 makefiles
-         for new getopt names
+       * src/rrd_update.c: should not leave debug enabled
 
-2007-03-11 13:04  oetiker
+2008-05-12 15:33  oetiker
 
-       * src/art_rgba_svp.h, src/fnv.h, src/gdpng.c, src/hash_32.c,
-         src/parsetime.c, src/parsetime.h, src/pngsize.c, src/rrd.h,
-         src/rrd_afm.c, src/rrd_afm.h, src/rrd_afm_data.c,
-         src/rrd_afm_data.h, src/rrd_cgi.c, src/rrd_create.c,
-         src/rrd_datalang.c, src/rrd_diff.c, src/rrd_dump.c,
-         src/rrd_error.c, src/rrd_fetch.c, src/rrd_first.c,
-         src/rrd_format.c, src/rrd_format.h, src/rrd_getopt.c,
-         src/rrd_getopt.h, src/rrd_getopt1.c, src/rrd_gfx.c, src/rrd_gfx.h,
-         src/rrd_graph.c, src/rrd_graph.h, src/rrd_graph_helper.c,
-         src/rrd_hw.c, src/rrd_hw.h, src/rrd_info.c,
-         src/rrd_is_thread_safe.h, src/rrd_last.c, src/rrd_lastupdate.c,
-         src/rrd_nan_inf.c, src/rrd_nan_inf.h, src/rrd_not_thread_safe.c,
-         src/rrd_open.c, src/rrd_resize.c, src/rrd_restore.c,
-         src/rrd_rpncalc.c, src/rrd_rpncalc.h, src/rrd_stat.c,
-         src/rrd_thread_safe.c, src/rrd_thread_safe_nt.c, src/rrd_tool.c,
-         src/rrd_tool.h, src/rrd_tune.c, src/rrd_update.c,
-         src/rrd_version.c, src/rrd_xport.c, src/rrd_xport.h,
-         src/rrdupdate.c, src/strftime.c, src/strftime.h, src/unused.h,
-         src/win32comp.c: enable ID keyword in all source files
+       * branches/1.2/program/doc/rrdcreate.pod,
+         branches/1.2/program/src/rrd_update.c, doc/rrdcreate.pod,
+         src/rrd_update.c: Fixed handling of unknown data at PDP build
+         time. There was a long standing (even documented) missfeature in
+         rrdtool which caused uknown-data to be accepted as long as it was
+         less than the mrhb. This was never the intended behaviour and had
+         interesting side effects
+         (http://oss.oetiker.ch/rrdtool-trac/ticket/125): If you have a 60
+         Second step with 59s unknown data and 1 second of known data the
+         whole become known data as long as the mrhb was > step. The
+         intended behaviour was that a step should become unknown as soon
+         as it contains more than 50% of unknown data. The patch fixes both
+         the documentation and the code.
 
-2007-03-11 12:57  oetiker
+2008-05-12 13:22  oetiker
 
-       * examples/Makefile.am: do not use gnuisms in Makefile rules ($<)
+       * src/rrd_create.c: the last_ds value fuer unknown is 'U' and not
+         'UNKN'
 
-2007-03-11 12:41  oetiker
+2008-05-04 18:59  oetiker
 
-       * netware/Makefile: use Guenters latest Netware Makefile ...
+       * src/rrd_getopt.c, src/rrd_getopt1.c: fix for sun sudio 11
+         incompatibility
+         http://www.netbsd.org/cgi-bin/query-pr-single.pl?number=38555
 
-2007-03-10 17:44  oetiker
+2008-05-01 23:23  oetiker
 
-       * configure.ac: axe the double quotes on $perlcc in configure to
-         allow for program names with arguments.
+       * bindings/ruby/main.c, src/rrd.h, src/rrd_info.c, src/rrd_tool.c:
+         indenting fixes
 
-2007-03-10 17:36  oetiker
+2008-05-01 23:23  oetiker
 
-       * src/rrd_update.c: integers can be negative ... fixed the test for
-         this in rrd_update -- rians cc usu edu
+       * src/rrd_graph.c: make sure properties are shown via graph_v even
+         in --graph-only mode
 
-2007-03-03 11:03  oetiker
+2008-05-01 06:56  oetiker
 
-       * Makefile.am, bindings/ruby/extconf.rb, configure.ac: * build
-         extensions last since this seems to be most likely to fail * do
-         more testing before building the ruby extension
+       * MakeMakefile: Make the MakeMakefile script a bit more robust
 
-2007-02-24 17:23  oetiker
+2008-04-22 21:40  oetiker
 
-       * src/rrd_dump.c, src/rrd_info.c, src/rrd_tune.c: fix memmory
-         problem in rrd_dump.c
+       * bindings/python/rrd_extra.h, bindings/python/rrdtoolmodule.c: fix
+         for #148
 
-2007-02-14 18:54  oetiker
+2008-04-20 22:46  oetiker
 
-       * doc/rrdgraph_rpn.pod, src/rrd_rpncalc.c, src/rrd_rpncalc.h: new
-         operator ABS added --
+       * CONTRIBUTORS, NEWS, bindings/perl-shared/RRDs.pm,
+         bindings/perl-shared/RRDs.xs, bindings/ruby/main.c,
+         doc/rrdgraph.pod, src/rrd.h, src/rrd_graph.c, src/rrd_graph.h,
+         src/rrd_info.c, src/rrd_tool.c, src/rrd_tool.h: Introduced a
+         alternated interface to rrd_graph using rrd_info style return
+         values: rrd_graph_v The graph_v interface returnes additional
+         information about the graph including the location of the graphing
+         area within the image. When called with '-' as filename it will
+         even return the image data. The new interface is supported in the
+         rrdtool command line, RRDs perl and ruby bindings.
 
-2007-02-14 18:48  oetiker
+2008-04-17 07:54  oetiker
 
-       * src/Makefile.am, src/getopt.c, src/getopt.h, src/getopt1.c,
-         src/rrd_getopt.c, src/rrd_getopt.h, src/rrd_getopt1.c,
-         src/rrd_tool.h: renamed getopt to rrd_getopt to avoid confusion on
-         some systems ...
+       * trunk/talks/nordic-nagios-08,
+         trunk/talks/nordic-nagios-08/abstract-rrdtut.txt: added bullets
 
-2007-02-14 18:47  oetiker
+2008-04-17 05:35  oetiker
 
-       * src/rrd_tool.c: cosmetic fix for usage message -- günter knauff
+       * src/rrd_update.c: indent fix
 
-2007-02-14 18:46  oetiker
+2008-04-17 05:35  oetiker
 
-       * Makefile.am: added new win32 component to the release tarball
+       * src/rrd_tune.c: do not reset the last_ds store unless the data
+         source type is actually changed.
 
-2007-02-14 18:46  oetiker
+2008-04-16 15:50  oetiker
 
-       * src/get_ver.awk, win32/rrd.dsp, win32/rrd_config.h.msvc,
-         win32/rrdtool.dsp: updates to the windows build system by guenter
-         knauff
+       * branches/1.2/program/doc/rrdgraph.pod, doc/rrdgraph.pod: fixed 2.
+         x-grid example ... since the lable is valid for the whole day, it
+         must be 86400 wide. --tobi
 
-2007-02-14 06:53  oetiker
+2008-04-12 09:29  oetiker
 
-       * doc/rrdgraph.pod, src/rrd_graph.c, src/rrd_graph.h: allow
-         --units-length to reserve label space even when --y-grid=none is
-         in effect [#75], tobi
+       * MakeMakefile, configure.ac: alter order of header inclusion for
+         FreeBSD 4.8 compatibility
 
-2007-02-14 06:33  oetiker
+2008-04-12 09:21  oetiker
 
-       * src/parsetime.c: parsing absolute time should not send us 30,000
-         years into the future -- Tatsuki Makino tatsuki_makino hotmail.com
+       * branches/1.2/program/src/parsetime.c, src/parsetime.c: do not mess
+         with dst status after running localtime, the system gets confused
+         otherwhise when it comes to times during the switch over periode
+         as DST changes to non DST. -- tobi
 
-2007-02-14 06:31  oetiker
+2008-03-25 23:02  oetiker
 
-       * src/rrd_cgi.c: Printstrftime on rrd_cgi.c returns an illegal
-         value. It causes segmentation fault error. -- Tatsuki Makino
-         tatsuki_makino hotmail.com
+       * src/rrd_dump.c: added missing " escapes to xml header in
+         rrd_tool.c
 
-2007-02-09 22:19  oetiker
+2008-03-25 22:59  oetiker
 
-       * netware/Makefile, src/rrd_tool.h, win32/Makefile: more build
-         patches from Günter Knauf
+       * CONTRIBUTORS: added Florian octo Forster to contrib list
 
-2007-02-08 06:01  oetiker
+2008-03-25 22:59  oetiker
 
-       * netware/Makefile, win32/Makefile: updates for Win32 and NW
-         Makefiles -- Guenter Knauf
+       * doc/rrdgraph_examples.pod: added missing =back for propper pod
+         syntax
 
-2007-02-08 05:54  oetiker
+2008-03-25 22:58  oetiker
 
-       * src/Makefile.am: added get_ver.awk to release
+       * src/rrd_dump.c: fix indent
 
-2007-02-08 05:51  oetiker
+2008-03-25 22:58  oetiker
 
-       * configure.ac: there is no Makefile.in for python anymore!
+       * src/rrd_restore.c: fix broken header comment section -- Florian
+         octo Forster
 
-2007-02-07 21:35  oetiker
+2008-03-25 22:57  oetiker
 
-       * src/rrd_gfx.c: DPRINTF may not be the ideal define ... use
-         something more RRDish ... like RRDPRINTF
+       * src/rrd_graph.c: cast size_t to int to avoid warning -- Florian
+         octo Forster
 
-2007-02-07 21:35  oetiker
+2008-03-25 22:56  oetiker
 
-       * Makefile.am, configure.ac: use setup.py for python install and
-         build work instad of trying todo it on our own
+       * src/rrd_open.c: do not declare DEBUG functions unless compiled in
+         DEBUG mode -- Florian octo Forster
 
-2007-02-07 21:31  oetiker
+2008-03-25 22:55  oetiker
 
-       * bindings/Makefile.am: added Makefile targets for python
+       * src/rrd_tool.c: make helptexts read only memory
 
-2007-02-07 21:30  oetiker
+2008-03-25 22:55  oetiker
 
-       * bindings/python/Makefile.am, bindings/python/Setup.in,
-         bindings/python/setup.py: python does no get built externally
+       * src/rrd_update.c: stop complaints about unused variables if not
+         running DEBUG
 
-2007-02-02 18:22  oetiker
+2008-03-25 22:49  oetiker
 
-       * COPYRIGHT: added IBM Public License to the list of Exceptions
+       * MakeMakefile: Added check for intltool version. Use Makefile for
+         cleanup. -- Florian octo Forster
 
-2007-02-02 12:19  oetiker
+2008-03-23 13:43  oetiker
 
-       * src/rrd_gfx.c, src/rrd_rpncalc.c: increasse portability (no //
-         comment, no ... arguments for cpp)
+       * src/rrd_dump.c: added pointer to florian forsters dtd to the rrd
+         dumpt
 
-2007-02-01 22:00  oetiker
+2008-03-19 23:36  oetiker
 
-       * bindings/tcl/tclrrd.c: we should use the headers from the local
-         rrdtool setup and not the system ones!
+       * configure.ac: fix pkgconfig file name
 
-2007-02-01 05:51  oetiker
+2008-03-15 10:39  oetiker
 
-       * bindings/perl-piped/RRDp.pm, bindings/perl-shared/RRDs.pm,
-         configure.ac, doc/rrdbuild.pod, rrdtool-1.2-release, rrdtool.spec,
-         src/gdpng.c, src/pngsize.c, src/rrd.h, src/rrd_afm.c,
-         src/rrd_afm.h, src/rrd_afm_data.c, src/rrd_afm_data.h,
-         src/rrd_cgi.c, src/rrd_create.c, src/rrd_datalang.c,
+       * ., .indent.pro, 00README, CONTRIBUTORS, COPYING, COPYRIGHT,
+         MakeMakefile, Makefile.am, NEWS, PROJECTS, README, THREADS, TODO,
+         WIN32-BUILD-TIPS.txt, acinclude.m4, bindings,
+         bindings/Makefile.am, bindings/perl-piped,
+         bindings/perl-piped/MANIFEST, bindings/perl-piped/Makefile.PL,
+         bindings/perl-piped/README, bindings/perl-piped/RRDp.pm,
+         bindings/perl-piped/leaktest.pl, bindings/perl-piped/rrdpl.dsp,
+         bindings/perl-piped/rrdpl.dsw, bindings/perl-piped/t,
+         bindings/perl-piped/t/base.t, bindings/perl-shared,
+         bindings/perl-shared/MANIFEST, bindings/perl-shared/Makefile.PL,
+         bindings/perl-shared/README, bindings/perl-shared/RRDs.pm,
+         bindings/perl-shared/RRDs.ppd, bindings/perl-shared/RRDs.xs,
+         bindings/perl-shared/ntmake.pl, bindings/perl-shared/t,
+         bindings/perl-shared/t/base.t, bindings/python,
+         bindings/python/ACKNOWLEDGEMENT, bindings/python/AUTHORS,
+         bindings/python/COPYING, bindings/python/README,
+         bindings/python/rrd_extra.h, bindings/python/rrdtoolmodule.c,
+         bindings/python/setup.py, bindings/ruby, bindings/ruby/CHANGES,
+         bindings/ruby/README, bindings/ruby/extconf.rb,
+         bindings/ruby/main.c, bindings/ruby/test.rb, bindings/tcl,
+         bindings/tcl/Makefile.am, bindings/tcl/README,
+         bindings/tcl/ifOctets.tcl.in, bindings/tcl/tclrrd.c, configure.ac,
+         debian, debian/README.Debian, debian/build_freetype.sh,
+         debian/changelog, debian/control, debian/copyright,
+         debian/librrd0-dev.files, debian/librrd0.files,
+         debian/librrd0.postinst, debian/librrd0.postrm,
+         debian/librrd0.shlibs, debian/librrdp-perl.files,
+         debian/librrds-perl.files, debian/rrdtool-tcl.files,
+         debian/rrdtool.files, debian/rules, debian/watch, doc,
+         doc/Makefile.am, doc/bin_dec_hex.pod, doc/cdeftutorial.pod,
+         doc/name.inc, doc/rpntutorial.pod, doc/rrd-beginners.pod,
+         doc/rrdbuild.pod, doc/rrdcgi.pod, doc/rrdcreate.pod,
+         doc/rrddump.pod, doc/rrdfetch.pod, doc/rrdfirst.pod,
+         doc/rrdgraph-old.pod, doc/rrdgraph.pod, doc/rrdgraph_data.pod,
+         doc/rrdgraph_examples.pod, doc/rrdgraph_graph.pod,
+         doc/rrdgraph_rpn.pod, doc/rrdinfo.pod, doc/rrdlast.pod,
+         doc/rrdlastupdate.pod, doc/rrdpython.pod, doc/rrdresize.pod,
+         doc/rrdrestore.pod, doc/rrdruby.pod, doc/rrdthreads.pod,
+         doc/rrdtool-dump.dtd, doc/rrdtool-xport.dtd, doc/rrdtool.pod,
+         doc/rrdtune.pod, doc/rrdtutorial.es.pod, doc/rrdtutorial.pod,
+         doc/rrdupdate.pod, doc/rrdxport.pod, examples,
+         examples/4charts.pl.in, examples/Makefile.am,
+         examples/bigtops.pl.in, examples/cgi-demo.cgi.in,
+         examples/minmax.pl.in, examples/perftest.pl.in,
+         examples/piped-demo.pl.in, examples/shared-demo.pl.in,
+         examples/stripes.pl.in, favicon.ico, netware, netware/Makefile,
+         po, po/ChangeLog, po/LINGUAS, po/POTFILES.in, po/de.po,
+         rrdtool-1.2-release, rrdtool-1.3-release, rrdtool.spec, src,
+         src/Makefile.am, src/compile_afm.pl, src/fnv.h, src/get_ver.awk,
+         src/hash_32.c, src/parsetime.c, src/parsetime.h, src/pngsize.c,
+         src/rrd.h, src/rrd_cgi.c, src/rrd_create.c, src/rrd_datalang.c,
          src/rrd_diff.c, src/rrd_dump.c, src/rrd_error.c, src/rrd_fetch.c,
          src/rrd_first.c, src/rrd_format.c, src/rrd_format.h,
-         src/rrd_gfx.c, src/rrd_gfx.h, src/rrd_graph.c,
+         src/rrd_getopt.c, src/rrd_getopt.h, src/rrd_getopt1.c,
+         src/rrd_gfx.c, src/rrd_graph.c, src/rrd_graph.h,
          src/rrd_graph_helper.c, src/rrd_hw.c, src/rrd_hw.h,
-         src/rrd_info.c, src/rrd_is_thread_safe.h, src/rrd_last.c,
-         src/rrd_lastupdate.c, src/rrd_not_thread_safe.c, src/rrd_open.c,
+         src/rrd_hw_math.c, src/rrd_hw_math.h, src/rrd_hw_update.c,
+         src/rrd_hw_update.h, src/rrd_i18n.h, src/rrd_info.c,
+         src/rrd_is_thread_safe.h, src/rrd_last.c, src/rrd_lastupdate.c,
+         src/rrd_nan_inf.c, src/rrd_not_thread_safe.c, src/rrd_open.c,
          src/rrd_resize.c, src/rrd_restore.c, src/rrd_rpncalc.c,
-         src/rrd_rpncalc.h, src/rrd_stat.c, src/rrd_thread_safe.c,
+         src/rrd_rpncalc.h, src/rrd_thread_safe.c,
          src/rrd_thread_safe_nt.c, src/rrd_tool.c, src/rrd_tool.h,
          src/rrd_tune.c, src/rrd_update.c, src/rrd_version.c,
-         src/rrd_xport.c, src/rrd_xport.h, src/rrdupdate.c: prepare for the
-         release of rrdtool-1.2.19
-
-2007-02-01 05:45  oetiker
-
-       * bindings/python/Makefile.am: libtool builds shared libraries
-         anyway, no need for extra LDFLAGS that bite non GNU ld versions
-
-2007-01-29 16:47  oetiker
-
-       * src/rrd_tool.c: resolve snprintf overflow warning by using sizeof
-         -- Anna Bernathova suse cz
-
-2007-01-23 20:54  oetiker
-
-       * bindings/perl-piped/RRDp.pm, bindings/perl-shared/RRDs.pm,
-         configure.ac, doc/rrdbuild.pod, rrdtool.spec, src/gdpng.c,
-         src/pngsize.c, src/rrd.h, src/rrd_afm.c, src/rrd_afm.h,
-         src/rrd_afm_data.c, src/rrd_afm_data.h, src/rrd_cgi.c,
-         src/rrd_create.c, src/rrd_datalang.c, src/rrd_diff.c,
-         src/rrd_dump.c, src/rrd_error.c, src/rrd_fetch.c, src/rrd_first.c,
-         src/rrd_format.c, src/rrd_format.h, src/rrd_gfx.c, src/rrd_gfx.h,
-         src/rrd_graph.c, src/rrd_graph_helper.c, src/rrd_hw.c,
-         src/rrd_hw.h, src/rrd_info.c, src/rrd_is_thread_safe.h,
-         src/rrd_last.c, src/rrd_lastupdate.c, src/rrd_not_thread_safe.c,
-         src/rrd_open.c, src/rrd_resize.c, src/rrd_restore.c,
-         src/rrd_rpncalc.c, src/rrd_rpncalc.h, src/rrd_stat.c,
-         src/rrd_thread_safe.c, src/rrd_thread_safe_nt.c, src/rrd_tool.c,
-         src/rrd_tool.h, src/rrd_tune.c, src/rrd_update.c,
-         src/rrd_version.c, src/rrd_xport.c, src/rrd_xport.h,
-         src/rrdupdate.c: prepare for the release of rrdtool-1.2.18
-
-2007-01-23 20:52  oetiker
-
-       * src/rrd_fetch.c: the change from R920 to fetch was not helping ...
-         no low res got prefered in non full coverage situations ..
-
-2007-01-23 17:30  oetiker
-
-       * src/rrd_graph.c: another control sequence that got lost ...
-
-2007-01-23 08:28  oetiker
-
-       * src/rrd_graph_helper.c: read up to full potential length of
-         gdp->rrd
+         src/rrd_xport.c, src/rrd_xport.h, src/rrdupdate.c, src/strftime.c,
+         src/strftime.h, src/unused.h, src/win32comp.c, svn2cl.xsl, win32,
+         win32/Makefile, win32/config.h, win32/rrd.dsp, win32/rrd.vcproj,
+         win32/rrd_config.h.msvc, win32/rrdtool.dsp, win32/rrdtool.dsw,
+         win32/rrdtool.vcproj: reindent aded id keyword substitution
 
-2007-01-22 16:34  oetiker
+2008-03-15 10:32  oetiker
 
-       * doc/rrdgraph_graph.pod: added missing B formatting instruction
+       * src/rrd_rpncalc.c: reat nan as FALSE in an IF CDEF
 
-2007-01-22 10:49  oetiker
+2008-03-07 08:57  oetiker
 
-       * rrdtool-1.2-release: create non version link
+       * doc/rrdgraph_rpn.pod, src/rrd_rpncalc.c, src/rrd_rpncalc.h: a
+         nan-safe add operator (ADDNAN) into rrd. I used it to add several
+         incomplete graphs. NaN + NaN => NaN x + NaN => x NaN + y => y x +
+         y => x + y -- Timo Stripf tstripf gmx.de
 
-2007-01-22 10:33  oetiker
+2008-03-02 15:38  oetiker
 
-       * src/rrd_graph.c: prepare for the release of rrdtool-1.2.17
+       * src/rrd_graph.c: Fix error "cairo_restore without matching
+         cairo_save" when zero-time point is out of graph
 
-2007-01-22 10:29  oetiker
+2008-02-25 07:11  oetiker
 
-       * bindings/perl-piped/RRDp.pm, bindings/perl-shared/RRDs.pm,
-         configure.ac, doc/rrdbuild.pod, rrdtool.spec, src/gdpng.c,
-         src/pngsize.c, src/rrd.h, src/rrd_afm.c, src/rrd_afm.h,
-         src/rrd_afm_data.c, src/rrd_afm_data.h, src/rrd_cgi.c,
-         src/rrd_create.c, src/rrd_datalang.c, src/rrd_diff.c,
-         src/rrd_dump.c, src/rrd_error.c, src/rrd_fetch.c, src/rrd_first.c,
-         src/rrd_format.c, src/rrd_format.h, src/rrd_gfx.c, src/rrd_gfx.h,
-         src/rrd_graph.c, src/rrd_graph_helper.c, src/rrd_hw.c,
-         src/rrd_hw.h, src/rrd_info.c, src/rrd_is_thread_safe.h,
-         src/rrd_last.c, src/rrd_lastupdate.c, src/rrd_not_thread_safe.c,
-         src/rrd_open.c, src/rrd_resize.c, src/rrd_restore.c,
-         src/rrd_rpncalc.c, src/rrd_rpncalc.h, src/rrd_stat.c,
-         src/rrd_thread_safe.c, src/rrd_thread_safe_nt.c, src/rrd_tool.c,
-         src/rrd_tool.h, src/rrd_tune.c, src/rrd_update.c,
-         src/rrd_version.c, src/rrd_xport.c, src/rrd_xport.h,
-         src/rrdupdate.c: prepare for the release of rrdtool-1.2.17
-
-2007-01-22 10:28  oetiker
-
-       * doc/rrdgraph_graph.pod, src/rrd_graph.c: introduced \n as an alias
-         for \l since people seem to be using it despite the documentation
-         not talking about this ... so now it is official and I bet there
-         will soon be people asking why this was only working at the end of
-         a line. -- tobi
-
-2007-01-21 22:22  oetiker
-
-       * doc/rrdgraph_examples.pod: removed mentiones of \n ...
-
-2007-01-20 22:54  oetiker
-
-       * bindings/Makefile.am: prepare for the release of rrdtool-1.2.16
+       * branches/1.2/program/src/rrd_fetch.c, src/rrd_fetch.c: Ignore
+         RRA-end when comparing. coverage.
 
-2007-01-20 22:48  oetiker
+2008-02-24 14:27  oetiker
 
-       * bindings/Makefile.am: prepare for the release of rrdtool-1.2.16
+       * src/rrd_create.c, src/rrd_graph_helper.c, src/rrd_i18n.h,
+         src/rrd_info.c, src/rrd_restore.c, src/rrd_tool.c: fix indents
+         gone out of kileter by patching ...
 
-2007-01-20 22:22  oetiker
+2008-02-24 14:26  oetiker
 
-       * bindings/Makefile.am: prepare for the release of rrdtool-1.2.16
+       * src/rrd_dump.c, src/rrd_tool.c: get rid of a few type cast
+         warnings
 
-2007-01-20 20:19  oetiker
+2008-02-24 14:26  oetiker
 
-       * rrdtool-1.2-release: prepare for the release of rrdtool-1.2.16
+       * src/rrd_restore.c: fix one segfault while trying to restore an
+         invalid xml file. -- tobi
 
-2007-01-20 20:17  oetiker
-
-       * rrdtool-1.2-release: prepare for the release of rrdtool-1.2.16
-
-2007-01-20 20:16  oetiker
-
-       * rrdtool-1.2-release: prepare for the release of rrdtool-1.2.16
-
-2007-01-20 20:03  oetiker
-
-       * bindings/tcl/tclrrd.c: this did not compile after integrating the
-         new fetchlast command -- Andy Riebs
-
-2007-01-20 16:41  oetiker
-
-       * bindings/perl-piped/RRDp.pm, bindings/perl-shared/RRDs.pm,
-         configure.ac, doc/rrdbuild.pod, rrdtool-1.2-release, rrdtool.spec,
-         src/Makefile.am, src/gdpng.c, src/pngsize.c, src/rrd.h,
-         src/rrd_afm.c, src/rrd_afm.h, src/rrd_afm_data.c,
-         src/rrd_afm_data.h, src/rrd_cgi.c, src/rrd_create.c,
-         src/rrd_datalang.c, src/rrd_diff.c, src/rrd_dump.c,
-         src/rrd_error.c, src/rrd_fetch.c, src/rrd_first.c,
-         src/rrd_format.c, src/rrd_format.h, src/rrd_gfx.c, src/rrd_gfx.h,
-         src/rrd_graph.c, src/rrd_graph_helper.c, src/rrd_hw.c,
-         src/rrd_hw.h, src/rrd_info.c, src/rrd_is_thread_safe.h,
-         src/rrd_last.c, src/rrd_lastupdate.c, src/rrd_not_thread_safe.c,
-         src/rrd_open.c, src/rrd_resize.c, src/rrd_restore.c,
-         src/rrd_rpncalc.c, src/rrd_rpncalc.h, src/rrd_stat.c,
-         src/rrd_thread_safe.c, src/rrd_thread_safe_nt.c, src/rrd_tool.c,
-         src/rrd_tool.h, src/rrd_tune.c, src/rrd_update.c,
-         src/rrd_version.c, src/rrd_xport.c, src/rrd_xport.h,
-         src/rrdupdate.c: prepare for the release of rrdtool-1.2.16
+2008-02-21 07:20  oetiker
 
-2007-01-20 16:39  oetiker
+       * configure.ac: make ruby obey destdir
 
-       * Makefile.am, configure.ac, rrdtool-1.2-release: get ready for
-         1.2.16 release
+2008-02-21 07:18  oetiker
 
-2007-01-18 23:43  oetiker
+       * po/ChangeLog: initial
 
-       * doc/rrdlastupdate.pod: aargh another missing bit from lastupdate
-         added ...
+2008-02-21 07:12  oetiker
 
-2007-01-17 23:35  oetiker
+       * MakeMakefile, configure.ac, po/LINGUAS, po/de.po, src/rrd_tool.c:
+         make inbternationalized version actually build
 
-       * netware/Makefile, src/rrd_lastupdate.c, win32/Makefile: finish
-         integration of lastupdate commmand ...
+2008-02-21 06:59  oetiker
 
-2007-01-17 21:31  oetiker
+       * po, po/LINGUAS, po/POTFILES.in, src/rrd_i18n.h: added missing bits
+         from internationalization
 
-       * acinclude.m4, bindings/tcl/tclrrd.c, doc/Makefile.am,
-         src/Makefile.am, src/rrd_tool.c, src/rrd_tool.h, src/rrd_update.c:
-         New functions lastupdate to efficiently get the last values fed
-         into the rrd ... this also changes that the last values get stored
-         even for ABSOLUTE and GAUGE data sources ... -- andy.riebs hp.com
+2008-02-19 12:56  oetiker
 
-2006-12-16 16:14  oetiker
+       * branches/1.2/program/src/rrd_create.c,
+         branches/1.2/program/src/rrd_info.c,
+         branches/1.2/program/src/rrd_restore.c, src/rrd_create.c,
+         src/rrd_info.c, src/rrd_restore.c: Generate a random cur_row for
+         each RRA during create/restore operations. This effectively
+         randomizes the block crossings among RRDs created around the same
+         time. Previously, RRDs that were created/restored en masse would
+         cross block boundaries simultaneously, which is sub-optimal. Also,
+         this patch enables the user to see the RRA's cur_row pointer via
+         rrdinfo. This was useful during debugging. -- kevin brintnall
+         kbrint qwest.net
 
-       * src/rrd_error.c, src/rrd_thread_safe.c, src/rrd_thread_safe_nt.c:
-         add missing \0 to the end of several strncpy strings
+2008-02-18 15:04  oetiker
 
-2006-12-16 16:13  oetiker
+       * MakeMakefile, Makefile.am, configure.ac, rrdtool.spec,
+         src/Makefile.am, src/rrd_getopt.c, src/rrd_tool.c: Added I18N
+         support for messages printed by rrd_tool.c --
+         http://oss.oetiker.ch/rrdtool-trac/ticket/144
 
-       * src/rrd_update.c: replace malloc/strncpy by strdup add \0 to the
-         end of several strncpy strings add missing free fix error string
-         rendering :... makes no sense here
+2008-02-15 08:49  oetiker
 
-2006-12-16 16:11  oetiker
+       * configure.ac: check for pdf as well
 
-       * src/rrd.h: move headers around to make more sense
+2008-02-15 08:44  oetiker
 
-2006-12-16 16:10  oetiker
+       * configure.ac: check for cairo-ps and cairo-svg explicitly
 
-       * src/rrd_not_thread_safe.c: init the context on first call
+2008-02-06 00:12  oetiker
 
-2006-12-16 16:05  oetiker
+       * configure.ac: ready for beta 4
 
-       * src/rrd_graph.h: make sure there is ample space in the static
-         strings
+2008-02-06 00:10  oetiker
 
-2006-12-16 16:04  oetiker
+       * src/rrd_graph.c, src/rrd_graph_helper.c: * replaced strtok with
+         strtok_r for thread safety * fixed im initialization broken after
+         the introduction of dashes ...
 
-       * src/rrd_graph.c: oops 99 is the last item
+2008-02-04 22:34  oetiker
 
-2006-12-16 16:02  oetiker
+       * src/rrd_create.c: in rrd_create we do not use mmaping and thus
+         need to free rrd struct members in any case ...
 
-       * src/rrd_graph.c: it is sufficient to set the last item to 0
+2008-02-04 22:16  oetiker
 
-2006-12-16 16:02  oetiker
+       * src/rrd_update.c: this should help with the memory leak
 
-       * src/Makefile.am: getopt is required for rrdupdate too (there are
-         platforms where this is not in libc ... eg solaris)
+2008-02-04 18:18  oetiker
 
-2006-12-16 16:01  oetiker
+       * COPYRIGHT: added zpl 2.1 to floss exception
 
-       * src/rrdupdate.c: we have 2006 now
-
-2006-12-16 15:56  oetiker
+2008-02-01 06:52  oetiker
 
-       * src/rrd_not_thread_safe.c: it makes no sense allocating an array
-         and then asiging it to a fixed string ... this caused stuff to
-         crash badly as long error strings were assigned.
+       * branches/1.2/program/src/rrd_graph.c, src/rrd_graph.c: fixed
+         parsing of fontnames with embeded spaces
 
-2006-12-11 19:11  oetiker
+2008-01-14 17:11  oetiker
 
-       * doc/rrdbuild.pod: added note on alternate CFLAGS for Forte
+       * configure.ac: remove c++ warnings flag .. this is not c++ after
+         all
 
-2006-12-07 19:51  oetiker
+2008-01-14 16:52  oetiker
 
-       * src/rrd_graph.c: c is a valid formatting character
+       * src/rrd_cgi.c, src/rrd_create.c: fixed indenting
 
-2006-11-19 11:15  oetiker
+2008-01-14 16:51  oetiker
 
-       * src/rrd_graph.c: fixed typo
+       * src/rrd_gfx.c: fix indents
 
-2006-11-06 06:53  oetiker
+2008-01-14 16:50  oetiker
 
-       * src/rrd_fetch.c: when fetching, don't pick a higher res rra just
-         because it's coverage at the 'end' of the requested range is
-         better ... -- Sebastian Pachuta seba123 seba123.webd.pl
+       * bindings/tcl/tclrrd.c, configure.ac, src/parsetime.c,
+         src/rrd_cgi.c, src/rrd_create.c, src/rrd_nan_inf.c: * fixed
+         madvise/fadvise detection * fixed many compiler warnings -- Peter
+         Breitenlohner peb mppmu.mpg.de
 
-2006-10-27 14:03  oetiker
+2008-01-13 11:07  oetiker
 
-       * examples/perftest.pl.in: use integer time
+       * trunk/tutorial/htwchur/about-oss.odp,
+         trunk/tutorial/htwchur/m7am.odp,
+         trunk/tutorial/htwchur/rrd-exercises.tex: initial
 
-2006-10-26 22:26  oetiker
+2008-01-12 18:37  oetiker
 
-       * configure.ac, examples/Makefile.am, examples/perftest.pl.in: added
-         perftest tool
+       * src/rrd_graph.c: weekday and time are too tight
 
-2006-10-25 17:19  oetiker
+2008-01-04 22:53  oetiker
 
-       * src/Makefile.am: do not distribute windows files anymore ...
+       * src/rrd_gfx.c, src/rrd_graph.c: fontmap resolution was not
+         matching scaled_font resolution ... this killed layouting ... much
+         better now
 
-2006-10-25 17:18  oetiker
+2008-01-03 21:30  oetiker
 
-       * Makefile.am: distribute win32 and netware build files too
+       * doc/rrdgraph_examples.pod, doc/rrdgraph_graph.pod,
+         src/rrd_graph_helper.c: get rid of DASHED, only use dashes syntax.
+         less redundancy -- thomas.gutzler gmail.com
 
-2006-10-25 17:17  oetiker
+2008-01-02 22:11  oetiker
 
-       * MakeMakefile: do not remove Makefiles from win32 and netware build
-         dirs
+       * CONTRIBUTORS, NEWS, doc/rrdgraph_examples.pod,
+         doc/rrdgraph_graph.pod, src/rrd_graph.c, src/rrd_graph.h,
+         src/rrd_graph_helper.c: support for dashed lines in graphs
 
-2006-10-25 17:12  oetiker
+2008-01-02 22:06  oetiker
 
-       * MakeMakefile, bindings/Makefile.am, bindings/ruby/main.c: fix
-         build procedure for ruby (clean target) don't run autoreconf at
-         the end of MakeMakefiles as this has a tendency todo the wrong
-         things
+       * src/pngsize.c, src/rrd_graph.c: fix indenting
 
-2006-10-25 16:39  oetiker
+2008-01-02 22:06  oetiker
 
-       * MakeMakefile: added path to sepp
+       * doc/Makefile.am: ignore errors with txt doc building
 
-2006-10-25 16:30  oetiker
+2007-12-11 23:41  oetiker
 
-       * MakeMakefile: aclocal expects a space after -I ...
+       * Makefile.am, doc/rrdbuild.pod: building the docs depends on the
+         presence of pod2man ... which does not seem to be installed
+         necessarily
 
-2006-10-25 16:24  oetiker
+2007-12-08 22:15  oetiker
 
-       * MakeMakefile: tell aclocal where to find its config ...
+       * doc/rrdbuild.pod: added shared library locations into the docs
 
-2006-10-25 16:11  oetiker
+2007-12-08 21:35  oetiker
 
-       * MakeMakefile: aclocal show know where it's stuff is ...
+       * src/rrd_cgi.c: include stdlib since putenv is in there on solaris
 
-2006-10-22 21:20  oetiker
+2007-12-08 16:57  oetiker
 
-       * src/parsetime.c: make time paring more robust ... it can now deal
-         with time date date time time date + xxx date time + xxx
+       * configure.ac, doc/rrdbuild.pod, src/rrd_getopt.c: fixing solaris
+         portability * isinf and isnan definitions fixed * check if rt must
+         be linked * ordering must be read write in getopt * updated build
+         instructions
 
-2006-10-22 21:09  oetiker
+2007-12-02 17:11  oetiker
 
-       * src/rrd_graph.c: check if valid control codes are in use
+       * trunk/tutorial/htwchur/abstract-rrdtut.txt: fixed spelling
 
-2006-10-22 16:01  oetiker
+2007-12-02 16:59  oetiker
 
-       * bindings/ruby/test.rb: fixed ruby demo
+       * trunk/tutorial/htwchur,
+         trunk/tutorial/htwchur/abstract-rrdtut.txt,
+         trunk/tutorial/htwchur/m7am.odp: initial text
 
-2006-10-22 16:01  oetiker
+2007-11-26 20:12  oetiker
 
-       * bindings/perl-piped/RRDp.pm, bindings/perl-shared/RRDs.pm: fixed
-         address
+       * bindings/python/setup.py: fix libdir for python build
 
-2006-10-03 07:52  oetiker
+2007-11-21 10:51  oetiker
 
-       * src/rrdupdate.c: added missing file
+       * configure.ac: fixed NetBSD spelling
 
-2006-09-28 12:38  oetiker
+2007-11-21 06:56  oetiker
 
-       * doc/rrdruby.pod: fixed doc regarding site install
+       * configure.ac: define bsd source to get access to chroot
 
-2006-09-27 21:48  oetiker
+2007-11-21 06:47  oetiker
 
-       * bindings/Makefile.am, bindings/ruby, bindings/ruby/CHANGES,
-         bindings/ruby/README, bindings/ruby/extconf.rb,
-         bindings/ruby/main.c, bindings/ruby/test.rb, configure.ac: added
-         ruby bindings ... thanks to Loïs LHERBIER lois.lherbier covadis.ch
+       * bindings/perl-shared/Makefile.PL, configure.ac: make perlbuild
+         more portable
 
-2006-09-27 21:46  oetiker
+2007-11-21 05:54  oetiker
 
-       * src/Makefile.am, src/rrd_update.c: make rrdupdate realy light as
-         it was intended in the first place -- Peter Breitenlohner peb
-         mppmu.mpg.de
+       * trunk/talks/rrdtooltipsandtricks,
+         trunk/talks/rrdtooltipsandtricks/abstract.odt,
+         trunk/talks/rrdtooltipsandtricks/bio.txt,
+         trunk/talks/rrdtooltipsandtricks/rrdtipsandtricks.odp: initial
+         checkin
 
-2006-09-27 21:45  oetiker
+2007-11-20 22:22  oetiker
 
-       * src/parsetime.c: tod can come after the date as well as before the
-         date
+       * configure.ac: enable madvise defines in netbsd
 
-2006-09-18 05:45  oetiker
+2007-11-20 00:17  oetiker
 
-       * netware/Makefile: fix faild netware makefile merge -- Guenter
-         Knauf
+       * trunk/status/2007-11-19.txt: added 1.2.26
 
-2006-09-17 21:08  oetiker
+2007-11-20 00:08  oetiker
 
-       * src/rrd_update.c: make mvs stop complaining about uninitialized
-         variables ... -- norman wheeler bigpond.com
+       * src/rrd_format.h, src/rrd_graph.c, src/rrd_nan_inf.c: remove last
+         traces of rrd_nan_inf.h fix handling of min==max where min < 0
 
-2006-09-17 21:05  oetiker
+2007-11-19 19:05  oetiker
 
-       * doc/rrd-beginners.pod: fixed spelling -- Peter Breitenlohner
+       * trunk/status/2007-11-19.txt: spell checked
 
-2006-09-17 20:46  oetiker
+2007-11-19 19:02  oetiker
 
-       * configure.ac, examples/Makefile.am: fix generation of cgi-demo.cgi
-         -- Peter Breitenlohner peb mppmu.mpg.de
+       * trunk/status/2007-11-19.txt: added report
 
-2006-09-17 20:31  oetiker
+2007-11-15 14:39  oetiker
 
-       * MakeMakefile, bindings/Makefile.am, bindings/perl-shared/RRDs.xs,
-         configure.ac, netware/Makefile, src/getopt.c, src/getopt1.c,
-         src/rrd_afm.c, src/rrd_tool.h, win32/Makefile: make rrdtool use
-         rrd_config.h instead of config.h since this is just bound to lead
-         to confusion when the wrong config.h gets sourced -- Guenter Knauf
-         fix clean target in bindings directory
+       * bindings/ruby/main.c, src/rrd.h, src/rrd_create.c, src/rrd_dump.c,
+         src/rrd_format.h, src/rrd_graph.c, src/rrd_hw.c, src/rrd_info.c,
+         src/rrd_open.c, src/rrd_restore.c, src/rrd_tune.c,
+         src/rrd_update.c, src/rrd_xport.c: re-indented files that have
+         gone out of indent-style over the last few weeks
 
-2006-09-10 19:30  oetiker
+2007-11-15 14:36  oetiker
 
-       * win32/rrd.dsp, win32/rrd.vcproj, win32/rrdtool.dsp,
-         win32/rrdtool.dsw, win32/rrdtool.plg: the msvc files need dos file
-         endings ...
+       * src/Makefile.am, src/rrd.h, src/rrd_nan_inf.h: integrate
+         rrd_nan_inf header
 
-2006-09-10 19:26  oetiker
+2007-11-15 14:35  oetiker
 
-       * src/rrd_rpncalc.c: we want an int, so lets tell the compiler to
-         make it not complain
+       * src/rrd_open.c: Improve layout of documentation. -- Bernhard
+         Fischer
 
-2006-09-10 19:20  oetiker
+2007-11-15 14:34  oetiker
 
-       * netware/Makefile, win32/Makefile: netware und win32 fixes from
-         guenter
+       * src/rrd_update.c: * rrd_update(): Unify error path. *
+         parse_template(): Likewise. * allocate_data_structures(): Make
+         error strings use consistent punctuation. -- bernhard fischer
 
-2006-09-05 19:55  oetiker
+2007-11-15 14:32  oetiker
 
-       * doc/rrdfetch.pod: we do not need an extra echo there
+       * src/pngsize.c: make sure this compiles with aix
 
-2006-09-05 18:34  oetiker
+2007-11-13 01:45  oetiker
 
-       * confignt, netware, netware/Makefile, src/Makefile.NetWare,
-         src/Makefile.Win32, src/rrd.dsp, src/rrd.vcproj, src/rrd_afm.c,
-         src/rrd_dump.c, src/rrd_gfx.c, src/rrd_graph.c, src/rrd_tool.h,
-         src/rrdtool.dsp, src/rrdtool.dsw, src/rrdtool.sln,
-         src/rrdtool.vcproj, src/win32comp.c, win32, win32/Makefile,
-         win32/config.h, win32/rrd.dsp, win32/rrd.vcproj,
-         win32/rrdtool.dsp, win32/rrdtool.dsw, win32/rrdtool.plg,
-         win32/rrdtool.vcproj: put all the architecture specific stuff in
-         separate subdirectories ... one for netwara and one for win32 --
-         Guenter Knauf
+       * trunk/tutorial/lisa2007/m7am.odp: lisa update
 
-2006-09-05 18:19  oetiker
+2007-11-08 10:16  oetiker
 
-       * src/gifsize.c: noone needs this anymore
+       * NEWS, bindings/ruby/main.c, doc/rrdruby.pod: fixed start end time
+         in ruby fetch and added step size -- Mike Perham mperham gmail
 
-2006-09-04 21:10  oetiker
+2007-11-06 21:27  oetiker
 
-       * src/rrd_graph.c: in logarithmic mode minval must not be <= 0
+       * doc/rrdbuild.pod: updated build instructions
 
-2006-08-24 04:14  oetiker
+2007-11-04 21:56  oetiker
 
-       * doc/cdeftutorial.pod: add more submission encuragement -- alex
+       * bindings/perl-piped/RRDp.pm: handle errors properly ... in RRDp
+         read call
 
-2006-08-21 11:41  oetiker
+2007-10-08 14:36  oetiker
 
-       * NT-BUILD-TIPS.txt, WIN32-BUILD-TIPS.txt, src/Makefile.NetWare,
-         src/Makefile.Win32: updated windows build instructions from
-         guenter
+       * trunk/tutorial/lisa2007/m7am.odp,
+         trunk/tutorial/lisa2007/rrdtutorial.odp: fixed name for release
 
-2006-08-16 06:07  oetiker
+2007-10-08 14:36  oetiker
 
-       * src/rrd_graph.c: contain a potential problem with log grid
-         painting Bug #54
+       * trunk/tutorial/lisa2007/abstract-rrdtut.txt,
+         trunk/tutorial/lisa2007/rrdtutorial.odp: getting ready for release
 
-2006-08-15 05:51  oetiker
+2007-09-16 15:35  oetiker
 
-       * src/rrd_first.c: do not loose filedescriptors when rrd_first
-         errors out
+       * src/rrd_open.c: no reason to die when posixfadvise is not
+         sucessful
 
-2006-08-15 05:44  oetiker
+2007-09-11 06:28  oetiker
 
-       * src/rrd_graph_helper.c: catch empty XXXX: commands in graph
+       * doc/rrdcreate.pod, doc/rrdtune.pod, src/rrd_create.c,
+         src/rrd_dump.c, src/rrd_format.h, src/rrd_hw.c, src/rrd_info.c,
+         src/rrd_restore.c, src/rrd_tune.c: Allow to the the smoothing
+         window size other thatn the default 5%. -- Evan Miller emiller
+         imvu.com
 
-2006-08-15 05:24  oetiker
+2007-09-11 06:16  oetiker
 
-       * Makefile.am, WIN32-BUILD-TIPS.txt: windows is not NT anymore ...
-         lets call it WIN32
+       * configure.ac, src/rrd_open.c: added msync before unmap
 
-2006-08-13 16:41  oetiker
+2007-09-08 05:23  oetiker
 
-       * src/get_ver.awk: use unix fileendings here!
+       * CONTRIBUTORS, doc/rrdgraph_rpn.pod, src/rrd_graph.c,
+         src/rrd_graph.h: added STDEV aggregation function for VDEF. --
+         Patrick J Cherry patrick bytemark.co.uk
 
-2006-08-13 16:40  oetiker
+2007-09-07 22:53  oetiker
 
-       * src/Makefile.NetWare, src/Makefile.Win32: new version added by
-         Guenter Knauf
+       * Makefile.am, examples/Makefile.am, examples/perftest.pl.in: a few
+         leanups -- Bernhard Fischer
 
-2006-08-13 16:25  oetiker
+2007-09-06 09:06  oetiker
 
-       * src/rrd.h, src/rrd_version.c: added new rrdstrversion function --
-         Guenter Knauf
+       * src/rrd_open.c: added missing ;
 
-2006-08-13 16:22  oetiker
+2007-09-06 08:42  oetiker
 
-       * src/rrd_graph.c, src/strftime.c, src/strftime.h: use th OS
-         provided timezone names for %Z this should make things more
-         flexile will only work on windows, but since we are using
-         strftime.c on windows only this should not be a problem -- Guenter
-         Knauf
+       * src/rrd_open.c: * mimic write() and read() even better -- Bernhard
+         Fischer
 
-2006-08-13 16:13  oetiker
+2007-09-06 08:40  oetiker
 
-       * src/rrd_graph.c: include strftime.h for windows builds -- Guenter
-         Knauff
+       * src/rrd_open.c: rrd_open.c (rrd_read): Mimicing read() behaviour
+         for EOF case and NULL buffer case. -- Bernhard Fischer
 
-2006-08-13 16:10  oetiker
+2007-09-02 16:55  oetiker
 
-       * src/rrd_tool.h: removed mscv defines to confignt/config.h
-         completely -- Guenter Knauf
+       * doc/rrdgraph_graph.pod: fixed speling of horizon
 
-2006-08-13 16:09  oetiker
+2007-08-29 06:43  oetiker
 
-       * confignt/config.h: working windows config.h
+       * examples/perftest.pl.in: a better performance tester
 
-2006-08-13 16:07  oetiker
+2007-08-16 07:31  oetiker
 
-       * src/rrd_tool.c: can't define new variables in the middle of the
-         code (unless everyone was using c99 which is not the case)
+       * doc/rrdgraph_examples.pod: added holt winters example back into
+         the examples documentation
 
-2006-08-13 15:21  oetiker
+2007-08-14 21:59  oetiker
 
-       * src/rrd_graph.c: added special labeling for LONGTERM graphs --
-         Paul Boven p.boven sara.nl
+       * src/rrd_update.c: Fix for HoltWinters phase-shift bug described
+         below. When one or more primary data point times were missed, the
+         SEASONAL and DEVSEASONAL archives were marked as being up-to-date,
+         so that they would not be written to. It was correct not to write
+         to these archives, but the code failed to advance the pointers
+         within the SEASONAL and DEVSEASONAL archives so that future
+         updates would go to the correct location in the archives. Rather
+         than mark these archives as up-to-date (by setting
+         rra_step_cnt[rra_idx] = 0), my patch allocates a new "skip_update"
+         array that is set to 1 for SEASONAL and DEVSEASONAL archives that
+         have missed one or more primary data points. When an RRA is
+         written to, the cur_row pointer advancement happens for all
+         archives, but the skip_update array is checked just before
+         actually writing out the changes. Please give it a whirl! -- Evan
+         Miller emiller imvu.com
 
-2006-08-10 07:46  oetiker
+2007-08-13 20:06  oetiker
 
-       * acinclude.m4: it seems some headers have nan predefined ... so
-         lets just use other variable names
+       * src/rrd_update.c: Refactored rrd_update code in preparation of
+         finding the HW update problem -- Evan Miller
 
-2006-08-04 15:06  oetiker
+2007-08-07 15:02  oetiker
 
-       * acinclude.m4: copy of the solaris isnan hack from configure.ac
+       * doc/rrdbuild.pod: updated build instructions for 1.3
 
-2006-08-03 22:21  oetiker
+2007-08-03 23:46  oetiker
 
-       * configure.ac: solaris 10 has isnan defined as a sun forte builtin
-         ... gcc can not deal with this this will replace isnan with an
-         fpclass expression hopefully working around the problem
+       * trunk/talks/rrdtool13/rrdtool13.odp: initial talk
 
-2006-08-02 15:05  oetiker
+2007-08-03 21:27  oetiker
 
-       * bindings/python/rrdtoolmodule.c: fixing python bindings ... Jarod
-         Wilson jwilson redhat.com
+       * trunk/talks/rrdtool13/rrdtool13.odp: addded details
 
-2006-08-01 13:08  oetiker
+2007-08-03 19:46  oetiker
 
-       * doc/rrdxport.pod, src/rrd_tool.c, src/rrd_xport.c: unknownaszero
-         was not a good idea ... bye bye
+       * svn2cl.xsl: prepare for the release of rrdtool-1.2.99907080300
 
-2006-07-31 22:48  oetiker
+2007-08-03 19:45  oetiker
 
-       * doc/rrdxport.pod, src/rrd_tool.c, src/rrd_xport.c: new options
-         --enumds and --unknwonaszero for xport
+       * libraries, src/DejaVuSansMono-Roman.ttf, src/VeraMono.ttf: remove
+         some things we do not need anymore in 1.3
 
-2006-07-14 12:11  oetiker
+2007-08-03 19:43  oetiker
 
        * bindings/perl-piped/RRDp.pm, bindings/perl-shared/RRDs.pm,
-         configure.ac, doc/rrdbuild.pod, rrdtool.spec, src/gdpng.c,
-         src/gifsize.c, src/pngsize.c, src/rrd.h, src/rrd_afm.c,
-         src/rrd_afm.h, src/rrd_afm_data.c, src/rrd_afm_data.h,
+         doc/rrdbuild.pod, rrdtool.spec, src/pngsize.c, src/rrd.h,
          src/rrd_cgi.c, src/rrd_create.c, src/rrd_datalang.c,
          src/rrd_diff.c, src/rrd_dump.c, src/rrd_error.c, src/rrd_fetch.c,
          src/rrd_first.c, src/rrd_format.c, src/rrd_format.h,
-         src/rrd_gfx.c, src/rrd_gfx.h, src/rrd_graph.c,
-         src/rrd_graph_helper.c, src/rrd_hw.c, src/rrd_hw.h,
-         src/rrd_info.c, src/rrd_is_thread_safe.h, src/rrd_last.c,
+         src/rrd_gfx.c, src/rrd_graph.c, src/rrd_graph_helper.c,
+         src/rrd_hw.c, src/rrd_hw.h, src/rrd_info.c,
+         src/rrd_is_thread_safe.h, src/rrd_last.c, src/rrd_lastupdate.c,
          src/rrd_not_thread_safe.c, src/rrd_open.c, src/rrd_resize.c,
          src/rrd_restore.c, src/rrd_rpncalc.c, src/rrd_rpncalc.h,
-         src/rrd_stat.c, src/rrd_thread_safe.c, src/rrd_thread_safe_nt.c,
-         src/rrd_tool.c, src/rrd_tool.h, src/rrd_tune.c, src/rrd_update.c,
-         src/rrd_version.c, src/rrd_xport.c, src/rrd_xport.h: prepare for
-         the release of rrdtool-1.2.15
+         src/rrd_thread_safe.c, src/rrd_thread_safe_nt.c, src/rrd_tool.c,
+         src/rrd_tool.h, src/rrd_tune.c, src/rrd_update.c,
+         src/rrd_version.c, src/rrd_xport.c, src/rrd_xport.h,
+         src/rrdupdate.c: prepare for the release of
+         rrdtool-1.2.99907080300
 
-2006-07-14 12:06  oetiker
+2007-08-03 19:43  oetiker
 
-       * src/rrd_tool.c: we were leaking directory handles ...
+       * configure.ac, rrdtool-1.3-release: prepare for 1.3 beta 1
 
-2006-07-14 11:34  oetiker
+2007-08-03 19:26  oetiker
 
-       * doc/rrdbuild.pod: remove an excess =over
+       * src/Makefile.am: continue with the revision numbering
 
-2006-07-14 11:32  oetiker
+2007-08-03 19:17  oetiker
 
-       * doc/rrdbuild.pod: added missing =over
+       * doc/rrdgraph_graph.pod: added notes on pango inline formatting
 
-2006-07-14 11:12  oetiker
+2007-08-02 18:21  oetiker
 
-       * bindings/perl-piped/RRDp.pm, bindings/perl-shared/RRDs.pm,
-         configure.ac, doc/rrdbuild.pod, rrdtool.spec, src/Makefile.am,
-         src/gdpng.c, src/gifsize.c, src/pngsize.c, src/rrd.h,
-         src/rrd_afm.c, src/rrd_afm.h, src/rrd_afm_data.c,
-         src/rrd_afm_data.h, src/rrd_cgi.c, src/rrd_create.c,
-         src/rrd_datalang.c, src/rrd_diff.c, src/rrd_dump.c,
-         src/rrd_error.c, src/rrd_fetch.c, src/rrd_first.c,
-         src/rrd_format.c, src/rrd_format.h, src/rrd_gfx.c, src/rrd_gfx.h,
-         src/rrd_graph.c, src/rrd_graph_helper.c, src/rrd_hw.c,
-         src/rrd_hw.h, src/rrd_info.c, src/rrd_is_thread_safe.h,
-         src/rrd_last.c, src/rrd_not_thread_safe.c, src/rrd_open.c,
-         src/rrd_resize.c, src/rrd_restore.c, src/rrd_rpncalc.c,
-         src/rrd_rpncalc.h, src/rrd_stat.c, src/rrd_thread_safe.c,
-         src/rrd_thread_safe_nt.c, src/rrd_tool.c, src/rrd_tool.h,
-         src/rrd_tune.c, src/rrd_update.c, src/rrd_version.c,
-         src/rrd_xport.c, src/rrd_xport.h: prepare for the release of
-         rrdtool-1.2.14
+       * trunk/talks/rrdtool13, trunk/talks/rrdtool13/rrdtool13.odp,
+         trunk/talks/rrdtoolfast/monitoring-en.ppt,
+         trunk/talks/rrdtoolfast/onlineusv-de.ppt: talk updates
 
-2006-07-14 09:47  oetiker
+2007-08-01 15:29  oetiker
 
-       * src/rrd_graph.c: do not reset im->gdes[i].step blindly. We
-         initialize it to im->step at allocation time already ... the fix
-         in r291 was over the top. -- niels weaklogic.com
+       * src/rrd_graph.c: only release cairo stuff if we ever initialized
+         it.
 
-2006-07-14 08:56  oetiker
+2007-08-01 15:28  oetiker
 
-       * doc/rrdtool.pod, src/rrd_tool.c: added pwd command for remote
-         server reset errno to zero before each loop -- Damien.Stuart
-         usi.net
+       * src/rrd_xport.c: fix for 64bit portability problem ... unsigned
+         long is not int
 
-2006-07-13 08:44  oetiker
+2007-07-31 04:53  oetiker
 
-       * src/Makefile.NetWare, src/Makefile.Win32: fixed makefiles without
-         libcgi ... guenter knauf
+       * bindings/ruby/main.c: reindented
 
-2006-07-07 22:37  oetiker
+2007-07-30 22:29  oetiker
 
-       * CONTRIBUTORS, bindings/python/rrdtoolmodule.c: added first
-         function to python bindings ... -- Ulf Lilleengen lulf pvv.ntnu.no
+       * trunk/tutorial/lisa2007/abstract-rrdtut.txt: added toppics
 
-2006-07-05 22:00  oetiker
+2007-07-25 20:38  oetiker
 
-       * src/Makefile.NetWare, src/Makefile.Win32: we have no cgilib
-         anymore ....
+       * src/rrd_create.c, src/rrd_dump.c, src/rrd_fetch.c,
+         src/rrd_format.h, src/rrd_graph.c, src/rrd_graph_helper.c,
+         src/rrd_open.c, src/rrd_restore.c, src/rrd_rpncalc.c,
+         src/rrd_tool.h, src/rrd_tune.c: fixed indenting
 
-2006-07-04 21:04  oetiker
+2007-07-25 20:38  oetiker
 
-       * src/rrd_restore.c: let rrdtool understand <?xml ...?> headers in
-         rrdtool restore input
+       * src/rrd_update.c: make sure we check input even when the previous
+         update was a 'U' ... and some indenting fixes
 
-2006-06-18 21:21  oetiker
+2007-07-24 20:35  oetiker
 
-       * doc/rrdgraph_rpn.pod, src/rrd_rpncalc.c, src/rrd_rpncalc.h: Added
-         AVG function to CDEF language. Martin Sperl martin sperl.org
+       * trunk/contrib/php4/rrdtool_logo.h: added missing header
 
-2006-06-15 22:16  oetiker
+2007-07-22 15:51  oetiker
 
-       * doc/rrdbuild.pod: fixed libpng link
+       * src/rrd_format.h: new consolidation functions must be added last
+         or this will break binary compatibility
 
-2006-06-15 07:44  oetiker
+2007-07-22 15:50  oetiker
 
-       * doc/rrdbuild.pod: added hint for RHEL
+       * src/rrd_update.c: don't force data out ... let cache management do
+         this
 
-2006-06-13 21:20  oetiker
+2007-07-22 09:47  oetiker
 
-       * rrdtool.spec: added missing tcl files
+       * NEWS, src/rrd_create.c, src/rrd_dump.c, src/rrd_format.h,
+         src/rrd_restore.c: Only create version 4 rrd files if the new
+         holtwinters MHW.. CF is used.
 
-2006-06-07 21:01  oetiker
+2007-07-21 19:55  oetiker
 
-       * doc/cdeftutorial.pod: fix calc of fahrenheit ...
+       * src/rrd_open.c: * remove some experimental code from rrd_open *
+         rrd_dontneed will release all data except for header blocks and
+         RRA hot blocks which are going to be updated withing 10 minutes.
 
-2006-06-06 13:25  oetiker
+2007-07-21 19:53  oetiker
 
-       * doc/rrdbuild.pod: additional AIX hints from zoran.majcenic inet.hr
+       * src/rrd_fetch.c: for now, do not release fetched data ... in the
+         future we may call rrd_dontneed and let the users decied with an
+         option if they want to keep the data in cache ...
 
-2006-06-06 08:16  oetiker
+2007-07-21 19:52  oetiker
 
-       * rrdtool.spec: new, working rrdtool.spec file from Jarod Wilson
-         jwilson redhat.com
+       * src/Makefile.am: the fonts are now taken from the system. we do
+         not distribute them anympore
 
-2006-05-27 05:44  oetiker
+2007-07-21 19:37  oetiker
 
-       * bindings/python/rrdtoolmodule.c: python uses the name of the
-         module for loding, so this should better match up -- Duncan Webb
-         duncan dwebb ch
+       * NEWS: not on update rrd version
 
-2006-05-25 15:13  oetiker
+2007-07-20 22:20  oetiker
 
-       * doc/rrdbuild.pod: addeed AIX instructions
+       * src/rrd_format.h: we have a new holtwinders aggregation fucntion,
+         so we have a new version ...
 
-2006-05-23 06:52  oetiker
+2007-07-20 22:19  oetiker
 
-       * src/rrd_graph.c: adjust label spacing to make sure labels don't
-         overlap for the default font.
+       * configure.ac: check for fadvise all the time
 
-2006-05-21 22:14  oetiker
+2007-07-20 22:16  oetiker
 
-       * doc/rrdgraph_data.pod: add note about variable name picking as
-         suggested by alex
+       * doc/rrdcreate.pod: better docs on the aggregate functions
 
-2006-05-21 22:07  oetiker
+2007-07-18 22:02  oetiker
 
-       * src/Makefile.NetWare, src/Makefile.Win32: another Makefile update
-         from guenter
+       * NEWS: added note on locale
 
-2006-05-21 22:06  oetiker
+2007-07-18 21:59  oetiker
 
-       * src/Makefile.NetWare, src/Makefile.Win32: tiny updates to netware
-         and win32 makefiles -- Guenter Knauf
+       * src/rrd_graph_helper.c: some more piechart removed
 
-2006-05-21 21:53  oetiker
+2007-07-18 21:47  oetiker
 
-       * doc/rrd-beginners.pod: fixed type hte->the
+       * src/rrd_create.c, src/rrd_graph.c, src/rrd_rpncalc.c,
+         src/rrd_tune.c, src/rrd_update.c: make sure all ascii to float
+         parsing uses LC_NUMERIC = C so that we do not stuble on locales
+         confusing the , with a .
 
-2006-05-21 21:47  oetiker
+2007-07-18 00:30  oetiker
 
-       * src/rrd_graph.c: make vdef time part available in the data_calc
-         stage so that the legend printer can decide properly
+       * src/rrd_create.c, src/rrd_open.c, src/rrd_tool.h,
+         src/rrd_update.c: * rrd_open: rrd_close does not purge file from
+         cache * rrd_open: new function rrd_dontneed for purging un-needed
+         pages from core * rrd_open: in linux at least only fadivse
+         DONTNEED has the power to purge pages from cache, so letst call
+         madvise as well as fadvise * rrd_create: uses open/write/close
+         now, flushes file to disk and keeps only hot pages in core *
+         rrd_update: keeps only hot pages in core * configure enables
+         FADVISE even when mmap is in use
 
-2006-05-21 21:15  oetiker
+2007-07-17 21:46  oetiker
 
-       * doc/rrdgraph_graph.pod, src/rrd_graph.c, src/rrd_graph.h,
-         src/rrd_graph_helper.c: new GPRINT option :strftime to print time
-         associated with a VDEF value
+       * src/rrd_open.c, src/rrd_resize.c: added comment on float cookie
 
-2006-05-21 20:20  oetiker
+2007-07-16 06:37  oetiker
 
-       * configure.ac: make configure test which flags gcc actually accepts
-         ...
+       * bindings/ruby/main.c: fix for fetch in ruby bindings and support
+         for info added.
 
-2006-05-21 13:08  oetiker
+2007-07-14 13:26  oetiker
 
-       * doc/rrdgraph_graph.pod: don't deprecate HRULE anymore
+       * trunk/status/2007-07-14.txt: added report
 
-2006-05-21 12:37  oetiker
+2007-07-12 20:33  oetiker
 
-       * src/rrd_rpncalc.c: allow DS names starting with the same letters
-         as operators
+       * doc/rrdtutorial.pod: improve wording
 
-2006-05-12 13:26  oetiker
+2007-07-12 20:33  oetiker
 
-       * src/Makefile.am: we wan't to dist thread_save_nt too
+       * configure.ac: fix tcl build settup
 
-2006-05-11 11:11  oetiker
+2007-07-12 20:33  oetiker
 
-       * src/rrd_nan_inf.c: make DNAN and DINF faster by caching the result
-         of the first calculation -- pascal.gloor spale.com
+       * trunk/tutorial/emanics/rrd-exercises.tex,
+         trunk/tutorial/emanics/rrdtutorial.odp,
+         trunk/tutorial/linuxforum2007/rrdtutorial.odp: monor updates
 
-2006-05-11 07:37  oetiker
+2007-07-11 23:08  oetiker
 
-       * bindings/perl-shared/Makefile.PL: tell Makefile.PL how to store an
-         rpath under aix
+       * src/rrd_create.c: usr rrd_free for freeing the rrd structs ...
+         vito caputo
 
-2006-05-10 20:51  oetiker
+2007-07-10 05:31  oetiker
 
-       * src/rrd_graph.c: improved scaling for --logarithmic mode ... --
-         beat.zahnd space.unibe.ch
+       * trunk/tutorial/emanics/rrd-exercises.tex: fixed linebreak
 
-2006-05-09 18:46  oetiker
+2007-07-09 20:18  oetiker
 
-       * src/rrd_create.c: don't panic if the user forgets to specify the
-         name of the rrd file
+       * trunk/tutorial/emanics/rrd-exercises.tex: remove the 3.5h comment
 
-2006-05-07 10:46  oetiker
+2007-07-06 14:05  oetiker
 
-       * src/rrd_graph.c: make legend spacing more reliable. handle the
-         fact that some graph comands do not contribute to the legend --
-         tobi
+       * trunk/tutorial/emanics, trunk/tutorial/emanics/rrd-exercises.tex,
+         trunk/tutorial/emanics/rrdtutorial.odp: initial emanics versions
 
-2006-05-06 13:29  oetiker
+2007-07-05 15:19  oetiker
 
-       * doc/Makefile.am: lets have index.html -- Peter Breitenlohner <peb
-         mppmu.mpg.de>
+       * src/rrd_graph_helper.c: prevent potential segfaults on boxes where
+         time_t is not long
 
-2006-05-06 13:28  oetiker
+2007-06-24 11:42  oetiker
 
-       * src/rrd.h, src/rrd_dump.c: Avoid gcc warning (discards qualifier)
-         in tclrrd.c -- Peter Breitenlohner <peb mppmu.mpg.de>
+       * trunk/tutorial/lisa2007/abstract-rrdtut.txt: add halfday
 
-2006-05-06 13:28  oetiker
+2007-06-24 11:41  oetiker
 
-       * src/rrd_graph.c: Avoid gcc warning ("static not first") -- Peter
-         Breitenlohner <peb mppmu.mpg.de>
+       * trunk/tutorial/lisa2007/abstract-rrdtut.txt: fritz fix
 
-2006-05-06 13:24  oetiker
+2007-06-19 06:26  oetiker
 
-       * configure.ac: Avoid gcc warnings about use of "long long" -- Peter
-         Breitenlohner <peb mppmu.mpg.de>
+       * trunk/tutorial/lisa2007: updated for lisa
 
-2006-05-06 13:21  oetiker
+2007-06-18 18:25  oetiker
 
-       * bindings/tcl/Makefile.am: Use tclpkgdir instead of pkglibdir in
-         order to avoid automake warning -- Peter Breitenlohner <peb
-         mppmu.mpg.de>
+       * src/rrd_cgi.c, src/rrd_graph.c, src/rrd_tune.c, src/rrd_xport.c:
+         fix indentation
 
-2006-05-06 13:20  oetiker
+2007-06-18 16:05  oetiker
 
-       * bindings/python/Makefile.am: The rrdtoolmodule.so should be
-         installed in pyexecdir instead of pythondir (they differ if
-         prefix!=exec_prefix) -- Peter Breitenlohner <peb mppmu.mpg.de>
+       * configure.ac, src/parsetime.c, src/rrd_cgi.c, src/rrd_create.c,
+         src/rrd_fetch.c, src/rrd_first.c, src/rrd_getopt.c,
+         src/rrd_getopt1.c, src/rrd_graph.c, src/rrd_open.c,
+         src/rrd_restore.c, src/rrd_thread_safe.c, src/rrd_tune.c,
+         src/rrd_update.c, src/rrd_xport.c: Bernhard Fischer: - move
+         several static struct option out of loops and makes them
+         non-static - moves some functions from old-style definitions into
+         new-style definitions
 
-2006-05-04 20:41  oetiker
+2007-06-16 23:20  oetiker
 
-       * src/Makefile.am, src/rrd_error.c, src/rrd_restore.c,
-         src/rrd_rpncalc.c: fix for debian bug 359071 ... reporting the
-         long cdef in the error message was too much ... plus some other
-         small cleanups in this context
+       * CONTRIBUTORS: Bernhard is not Benrard
 
-2006-05-04 13:26  oetiker
+2007-06-16 05:32  oetiker
 
-       * bindings/perl-piped/RRDp.pm, bindings/perl-shared/RRDs.pm,
-         configure.ac, doc/rrdbuild.pod, rrdtool.spec, src/Makefile.am,
-         src/gdpng.c, src/gifsize.c, src/pngsize.c, src/rrd.h,
-         src/rrd_afm.c, src/rrd_afm.h, src/rrd_afm_data.c,
-         src/rrd_afm_data.h, src/rrd_cgi.c, src/rrd_create.c,
-         src/rrd_datalang.c, src/rrd_diff.c, src/rrd_dump.c,
-         src/rrd_error.c, src/rrd_fetch.c, src/rrd_first.c,
-         src/rrd_format.c, src/rrd_format.h, src/rrd_gfx.c, src/rrd_gfx.h,
-         src/rrd_graph.c, src/rrd_graph_helper.c, src/rrd_hw.c,
-         src/rrd_hw.h, src/rrd_info.c, src/rrd_is_thread_safe.h,
-         src/rrd_last.c, src/rrd_not_thread_safe.c, src/rrd_open.c,
-         src/rrd_resize.c, src/rrd_restore.c, src/rrd_rpncalc.c,
-         src/rrd_rpncalc.h, src/rrd_stat.c, src/rrd_thread_safe.c,
-         src/rrd_thread_safe_nt.c, src/rrd_tool.c, src/rrd_tool.h,
-         src/rrd_tune.c, src/rrd_update.c, src/rrd_version.c,
-         src/rrd_xport.c, src/rrd_xport.h: prepare for the release of
-         rrdtool-1.2.13
+       * trunk/contrib/php4/config.m4, trunk/contrib/php4/configure,
+         trunk/contrib/php4/ltconfig, trunk/contrib/php4/php_rrdtool.h,
+         trunk/contrib/php4/rrdtool.c: lets have just a single rrdtool
+         extension annd not two ... -- Jarod Wilson <jwilson@redhat.com>
 
-2006-05-04 13:24  oetiker
+2007-06-15 21:49  oetiker
 
-       * PROJECTS, README, acinclude.m4, configure.ac, doc/rrdbuild.pod,
-         doc/rrdcgi.pod, doc/rrdcreate.pod, doc/rrddump.pod,
-         doc/rrdfetch.pod, doc/rrdgraph-old.pod, doc/rrdgraph.pod,
-         doc/rrdgraph_data.pod, doc/rrdgraph_examples.pod,
-         doc/rrdgraph_graph.pod, doc/rrdgraph_rpn.pod, doc/rrdinfo.pod,
-         doc/rrdrestore.pod, doc/rrdtool.pod, doc/rrdtune.pod,
-         doc/rrdtutorial.pod, doc/rrdupdate.pod, doc/rrdxport.pod: fix my
-         mail address
+       * NEWS: notes on evans contribs
 
-2006-05-04 13:12  oetiker
+2007-06-15 21:41  oetiker
 
-       * src/rrd_create.c, src/rrd_open.c, src/rrd_restore.c: fewer double
-         frees ... -- slamb slamb.org
+       * rrdtool.spec: rrdtool.spec from Jarod "redhat" Wilson
 
-2006-05-04 13:02  oetiker
+2007-06-15 08:09  oetiker
+
+       * CONTRIBUTORS: updated contributors
+
+2007-06-15 08:01  oetiker
+
+       * NEWS: added note on TEXTALIGN
+
+2007-06-15 07:59  oetiker
+
+       * doc/rrdcreate.pod, doc/rrdtune.pod, src/Makefile.am,
+         src/rrd_create.c, src/rrd_dump.c, src/rrd_format.c,
+         src/rrd_format.h, src/rrd_graph.c, src/rrd_hw.c,
+         src/rrd_hw_math.c, src/rrd_hw_math.h, src/rrd_hw_update.c,
+         src/rrd_hw_update.h, src/rrd_info.c, src/rrd_restore.c,
+         src/rrd_tune.c, src/rrd_update.c: There are two popular variants
+         of the Holt-Winters forecasting method; RRDtool supports the
+         "additive" method, which means that seasonal variation is simply
+         added to the baseline. For our application, it would be more
+         appropriate to use the "multiplicative" Holt-Winters method, where
+         seasonal variation is a coefficient multiplied by the baseline.
+         Quick example to illustrate the difference: if the average doubles
+         season-over-season, the additive method would predict the delta
+         between min and max to be constant, whereas the multiplicative
+         method would predict the delta to double as well. Attached is a
+         patch against trunk to support the multiplicative method. I've
+         done this with a new consolidation function, MHWPREDICT, which is
+         essentially interchangeable with HWPREDICT. There is a noticeable
+         improvement in prediction deviations for certain types of
+         functions; the attachments show HWPREDICT and MHWPREDICT
+         predictions for a function with an x*sin(x) component. Because
+         HWPREDICT and MHWPREDICT differ only in their equations, I've
+         factored out their math into rrd_hw_math.c. The appropriate
+         smoothing functions are passed to the update functions in a
+         container of function pointers, which are called where
+         appropriate. Thus the additive and multiplicative methods use the
+         same update functions, and the right equations are evaluated
+         without having flag checks everywhere. This approach, I think,
+         makes the algorithms quite clear, with minimal duplicate code. I
+         have moved update_hwpredict, update_seasonal, update_devpredict,
+         update_devseasonal, and update_failures into a separate file,
+         rrd_hw_update.c, with some slight refactoring related to
+         rrd_hw_math.c. I ran some regression tests against trunk to make
+         sure I didn't break anything with the existing HWPREDICT code.
+         MHWPREDICT uses the same deviation smoothing and failure detection
+         algorithms as HWPREDICT. Some helpful references on the
+         multiplicative Holt-Winters method:
+         http://www.it.iitb.ac.in/~praj/acads/seminar/04329008_ExponentialSmoothing.pdf
+         (a student's quick overview of additive vs. multiplicative HW)
+         http://ideas.repec.org/p/msh/ebswps/1999-1.html (paper on
+         variations to the multiplicative Holt-Winters, including variance
+         calculations; FYI, my implementation uses "Model 1") My employer
+         and the owner of this patch (IMVU, Inc.) is happy to license it
+         under the same terms as RRDtool, i.e. give it to the project. --
+         Evan Miller emiller imvu.com
+
+2007-06-15 06:43  oetiker
+
+       * src/rrd.h: oops missed to update the in memory output interface
+         here
+
+2007-06-15 06:28  oetiker
+
+       * src/rrd.h, src/rrd_graph.c, src/rrd_graph.h: added interface to
+         get rendered image via a pointer to allocated memory ... Evan
+         Miller emmiller gmail.com
+
+2007-06-15 06:12  oetiker
+
+       * configure.ac: improve fontnaming
+
+2007-06-14 20:30  oetiker
+
+       * bindings/ruby/main.c, src/rrd_graph.c, src/rrd_graph_helper.c,
+         src/rrd_rpncalc.c: fixed indentation
+
+2007-06-14 20:28  oetiker
 
-       * src/rrd_restore.c: * fixed argument parsing for long options * no
-         more doublefree on abort * enable restore of xml dumps created
-         with rrdtool 1.0.x
+       * doc/rrdgraph_graph.pod, src/rrd_graph.c, src/rrd_graph.h,
+         src/rrd_graph_helper.c: added TEXTALIGN command to change the
+         default text alignment
 
-2006-05-04 12:11  oetiker
+2007-06-13 16:53  oetiker
 
-       * src/rrd_fetch.c: if end % step == 0 we should still fetch a full
-         step ... no need for special handling
+       * bindings/tcl/Makefile.am, bindings/tcl/tclrrd.c: fixed tcl
+         includes
 
-2006-05-04 07:48  oetiker
+2007-06-13 16:51  oetiker
 
-       * src/rrd_update.c: updated handling of subsecond resolution in
-         connection with unknown data ... bugreport #38 pointed out that
-         the old handling where the seconds were rounded could lead to
-         cases where the data stored was higher than the data input ... now
-         I always floor the unknown seconds and this will lead to the same
-         or lower data but not higher ... -- tobi
+       * bindings/ruby/main.c: be more helpful when raising rb_eTypeError
+         in string_arr string_arr_new(VALUE rb_strings). This patch
+         indicates which index is in error as well as the type you are
+         erroneously passing. -- anonymous
 
-2006-05-02 20:52  oetiker
+2007-06-12 20:36  oetiker
 
-       * src/rrd_graph.c: variables should be defined at the bein of the
-         block ... else we loose portability!
+       * src/rrd_update.c: Bernhard Fischer: - fix nulling the updvals -
+         cosmetic change to move the option struct out of the loop. - need
+         to operate on a copy of optarg
 
-2006-04-29 08:57  oetiker
+2007-06-11 19:45  oetiker
 
-       * doc/rrdbuild.pod: fixed spelling
+       * doc/rrdgraph_rpn.pod, src/rrd_rpncalc.c, src/rrd_rpncalc.h: added
+         TRENDNAN function -- Timo Stripf
 
-2006-04-27 06:37  oetiker
+2007-06-11 19:45  oetiker
 
-       * CONTRIBUTORS, doc/rrdgraph.pod, src/rrd_graph.c, src/rrd_graph.h:
-         new units=si option -- wim.heirmann elis.urgent.be
+       * src/rrd_graph.c: allow output to stdout -- Timo Stripf
 
-2006-04-25 21:00  oetiker
+2007-06-11 16:49  oetiker
 
-       * src/rrd_gfx.c: compile without multibyte support
+       * NEWS: added more news
 
-2006-04-25 20:59  oetiker
+2007-06-11 16:34  oetiker
 
-       * src/Makefile.am: lets have proper dependencies
+       * doc/rrdgraph.pod, src/rrd_graph.c: fixed indentation, added
+         documentation note on gridfitting.
 
-2006-04-24 15:14  oetiker
+2007-06-11 16:33  oetiker
 
-       * src/rrd_graph.c: make sure things are initialised ...
+       * src/rrd_graph.c: fix arrow locations
 
-2006-04-18 05:29  oetiker
+2007-06-11 16:20  oetiker
 
-       * rrdtool.spec: shared should be share !
+       * src/rrd_graph.c: disable gridfitting for vector formats
 
-2006-04-17 20:25  oetiker
+2007-06-11 16:14  oetiker
 
-       * src/rrd_graph.c: Add a second label to the Y axis if there is only
-         going to be one -- Jason A. Smith smithj4 X bnl.gov
+       * src/rrd_graph.c, src/rrd_graph.h: make pdf output work
 
-2006-04-14 10:17  oetiker
+2007-06-11 15:32  oetiker
 
-       * acinclude.m4, doc/rrdbuild.pod: no more people links!
+       * NEWS: added detail
 
-2006-04-14 09:22  oetiker
+2007-06-11 15:11  oetiker
 
-       * bindings/python/setup.py, debian/copyright, rrdtool.spec: remove
-         people references
+       * NEWS, configure.ac, doc/rrdgraph.pod, src/Makefile.am,
+         src/rrd_gfx.c, src/rrd_gfx.h, src/rrd_graph.c, src/rrd_graph.h,
+         src/rrd_graph_helper.c: --font-render-mode is back, and there is
+         also --graph-render-mode now. It allows to enable mono graphs that
+         look strikingly like rrdtool 1.0.x --tobi
 
-2006-04-07 14:37  oetiker
+2007-06-11 13:36  oetiker
 
-       * doc/rrdbuild.pod: add solaris hint to bild procedure
+       * NEWS, src/rrd_update.c: Bernhard Fischer: - NEWS mention the new
+         file accessors - rrd_update.c: remove unused some cruft
 
-2006-04-04 18:46  oetiker
+2007-06-11 10:09  oetiker
 
-       * CONTRIBUTORS, src/rrd_tool.c: allow for input lines of arbitrary
-         length in rrdtool pipe mode -- roger.meier terreactive.ch
+       * src/rrd_update.c: Bernhard Fischer: - fix maintaining our file-pos
+         when we have to wrap the rra_ptr in update(). - no need to update
+         the header-data a second time for the mmap case.
 
-2006-04-01 15:36  oetiker
+2007-06-11 00:23  oetiker
 
-       * CONTRIBUTORS, doc/rrdgraph.pod, src/rrd_graph.c, src/rrd_graph.h,
-         src/rrd_tool.c: watermartk feature for rrdgraph by Ronan Mullally
+       * NEWS: updated news
 
-2006-03-26 14:36  oetiker
+2007-06-11 00:22  oetiker
 
-       * src/rrd_rpncalc.c: vnames can be up to MAX_VNAME_LEN long ... not
-         only 30 chars ... -- Ulf Harnhammar metaur telia.com
+       * configure.ac, doc/rrdgraph.pod, src/Makefile.am: * added some
+         documentation * updated version number
 
-2006-03-26 14:29  oetiker
+2007-06-10 23:55  oetiker
 
-       * src/rrd_graph.c: potential bufferoverflow throught large windir
-         avoided
+       * acinclude.m4, configure.ac, src/Makefile.am, src/art_rgba_svp.c,
+         src/art_rgba_svp.h, src/rrd_afm.c, src/rrd_afm.h,
+         src/rrd_afm_data.c, src/rrd_afm_data.h, src/rrd_gfx.c,
+         src/rrd_gfx.h, src/rrd_graph.c, src/rrd_graph.h,
+         src/rrd_graph_helper.c: switched graphics library from arts to
+         cairo+pango
 
-2006-03-14 14:59  oetiker
+2007-06-04 11:15  oetiker
 
-       * NEWS: added note on the fact that no OK will be printed in rrdtool
-         pipe mode if an error occures.
+       * configure.ac, src/Makefile.am: Bernhard Fischer: - new configure
+         option --enable-static-programs
 
-2006-03-14 07:11  oetiker
+2007-06-01 19:11  oetiker
 
-       * doc/rrdtool.pod: RRDtool in remote mode will either print an ERROR
-         line or an OK line not both.
+       * src/rrd_open.c, src/rrd_resize.c: Bernhard: - implement resize
+         SHRINK for FD (mmap is to be done) - indent
 
-2006-03-13 23:21  oetiker
+2007-06-01 17:59  oetiker
 
-       * src/rrd_tool.c: in pipe mode, make rrd_tool send errors to STDOUT
-         (most of the time) -- tobi
+       * src/rrd_graph.c: --full-size-mode with and without --no-legend
+         should work now -- Matthew Chambers
 
-2006-03-06 07:15  oetiker
+2007-06-01 17:35  oetiker
 
-       * src/rrd_graph.c: at least freebsd will not do utf8 bits properly
-         without this
+       * src/rrd_open.c, src/rrd_resize.c: Bernhard - fill the file with
+         DNAN and add the remaining data in after the fact ...
 
-2006-03-03 23:11  oetiker
+2007-06-01 17:34  oetiker
 
-       * doc/rrdgraph_graph.pod, src/rrd_graph.c, src/rrd_graph_helper.c: *
-         simplify code for STACK function ... there were two code paths
-         (new as well as legacy from 1.0.x) * make TICK work for negative
-         fractions
+       * src/rrd_open.c, src/rrd_resize.c: Bernhard Fischer - implement
+         resize, growing part. truncation is to be done.
 
-2006-03-03 23:10  oetiker
+2007-06-01 09:10  oetiker
 
-       * configure.ac: remove ~ from my wishlist address ...
+       * src/rrd_cgi.c, src/rrd_graph_helper.c, src/rrd_open.c: Bernhard
+         Fischer - use 'z' length modifier when printing size_t - add a
+         cast to __rrd_read and document why it is there - add RANDOM hint
+         for the header
 
-2006-03-03 23:10  oetiker
+2007-05-31 18:47  oetiker
 
-       * src/rrd_gfx.c: make this compile even when HAVE_MBSTOWCS is not
-         set
+       * src/rrd_open.c: Bernhard: - plug tiny mem-leak in error path of
+         rrd_close where freeing the rrd_file was forgotten. - improve two
+         error messages - use CHECK_MADVISE_OVERLAPS per default
 
-2006-02-23 07:26  oetiker
+2007-05-30 19:56  oetiker
 
-       * src/rrd_fetch.c: separate matching of full and partial match
-         evaluation for better result stability. The fetch result was
-         dependent on the RRA ordering before. -- Jo Rhett jrhett
-         svcolo.com
+       * src/rrd_open.c, src/rrd_update.c: fix rrd_write -- Bernhard
+         Fischer
 
-2006-02-20 06:20  oetiker
+2007-05-30 12:41  oetiker
 
-       * doc/rrdgraph_examples.pod, doc/rrdgraph_graph.pod: YYYYMMDDhhmm is
-         not supported ... only YYYYMMDD
+       * src/rrd_fetch.c, src/rrd_first.c, src/rrd_graph.c,
+         src/rrd_graph.h, src/rrd_info.c, src/rrd_lastupdate.c,
+         src/rrd_open.c, src/rrd_resize.c: fix indenting ... again
 
-2006-02-08 11:35  oetiker
+2007-05-30 12:39  oetiker
 
-       * doc/rrdcgi.pod, src/rrd_cgi.c: OS and COPYRIGHT removed from the
-         rrdcgi INTERNAL function since we do not have this info
+       * src/rrd_create.c, src/rrd_dump.c, src/rrd_fetch.c,
+         src/rrd_first.c, src/rrd_info.c, src/rrd_last.c,
+         src/rrd_lastupdate.c, src/rrd_open.c, src/rrd_resize.c,
+         src/rrd_tune.c, src/rrd_update.c: From Bernhard Fischer -
+         rrd_close(): call close on the file and use rrd_close consistently
+         - clean up some error paths. The fadvise error path is leaking
+         memory (see XXX in these spots).
 
-2006-02-06 19:49  oetiker
+2007-05-30 09:28  oetiker
 
-       * doc/rrdcgi.pod, src/rrd_cgi.c: new rrdcgi function RRD::INTERNAL
-         for accessing VERSION, COPYRIGHT, COMPILETIME, OS -- Guenter Knauf
-         gk gknw.de
+       * trunk/contrib/php4/examples/rrd_fetch.php,
+         trunk/contrib/php4/php_rrdtool.h, trunk/contrib/php4/rrdtool.c:
+         make this work on recent php4 versions -- Bernhard Fischer
 
-2006-02-06 19:46  oetiker
+2007-05-30 05:23  oetiker
 
-       * COPYRIGHT, rrdtool-1.2-release, src/rrd_tool.c: we have 2006 now
-         so let's show it
+       * CONTRIBUTORS, doc/rrdgraph.pod, src/rrd_graph.c, src/rrd_graph.h:
+         switch for rrd_graph to specify the outer-size of the graph and
+         not just the size of the canvas: --full-size-mode --
+         matthew.chambers vanderbilt.edu
+
+2007-05-29 21:29  oetiker
+
+       * configure.ac, examples/perftest.pl.in, src/rrd_hw.c,
+         src/rrd_last.c, src/rrd_lastupdate.c, src/rrd_open.c,
+         src/rrd_resize.c, src/rrd_tool.c, src/rrd_tune.c,
+         src/rrd_update.c: More updates from Bernhard Fischer - flag
+         rrd_resize's old file with RRD_COPY - cleanup error-handling
+         pathes in rrd_update and fix a few typos in comments -
+         rrd_close(): implement printing mincore results for the rrd if
+         DEBUG=2 was defined - rrd_open(): madvise start addresses need to
+         be page-aligned; implement alternative path to the fine-grained
+         (i.e. exact) madvise by flagging just the first two pages as
+         needed (see TWO_PAGES). Implement alternative path that records
+         the last madvise()ed area to avoid redundant calls to madvise() on
+         identical areas (due to page-alignment constraints) -- see
+         CHECK_MADVISE_OVERLAPS. Implement path for USE_DIRECT_IO. -
+         configure: add check for O_DIRECT flag to open(2). Add option
+         --enable-direct-io. Add _GNU_SOURCE to CFLAGS to silence warnings
+         about chroot which is marked LEGACY since SUSv2 and is a non POSIX
+         extension. Make checks for posix_fadvise() dependant on
+         --disable-mmap, since we do not need fadvise for the mmap case.
+
+2007-05-25 15:24  oetiker
+
+       * src/rrd_stat.c: tobis old cruft removal program ...
+
+2007-05-25 13:14  oetiker
+
+       * src/rrd_dump.c, src/rrd_fetch.c, src/rrd_open.c, src/rrd_resize.c,
+         src/rrd_update.c: updates from Bernhard Fischer rep dot nop gmail
+         com - add some more rrd_sterror calls to failure paths. - make
+         rrdtool updatev work like 1.2.23 (i.e. multiple values are still
+         broken, but at least updating a single value works; see
+         http://oss.oetiker.ch/rrdtool-trac/ticket/8) - indent touched
+         files.
+
+2007-05-25 13:12  oetiker
+
+       * .indent.pro, Makefile.am, configure.ac, examples/perftest.pl.in,
+         src/rrd_dump.c, src/rrd_fetch.c, src/rrd_open.c, src/rrd_resize.c,
+         src/rrd_tool.h, src/rrd_update.c: Updates from Bernhard Fischer
+         rep dot nop gmail com - fix typo in rrd_fetch where rrd_read
+         result was checked against an incorrect size. - in rrd_fetch, drop
+         rrd_head_size in favour of rrd_file->header_len - in rrd_fetch,
+         make the message "post fetch" unambiguous (now past vs. post). -
+         change usage of param rdwr of rrd_open: allow for RRD_READONLY,
+         RRD_READWRITE, RRD_CREAT, RRD_READAHEAD; adjust callers
+         accordingly: + rrd_resize needs CREAT + rrd_dump may want
+         READAHEAD - implement FD based I/O in rrd_open, rrd_read,
+         rrd_write, rrd_seek. - in rrd_update, unify write_RRA_row(). -
+         sort | uniq the -T in .indent.pro (info_t was duplicated) - add
+         stub of an option to use O_DIRECT to the configury - in
+         Makefile.am, simplify the "indent" invocation of find: My find may
+         not support "-o" resp. "-or" nor braces. Using -name "*.[ch]"
+         works everywhere, AFAIK.
+
+2007-05-24 08:26  oetiker
+
+       * configure.ac: use proper preprocessor directives for the
+         config-checks. -- tobi
+
+2007-05-24 07:21  oetiker
+
+       * configure.ac: fixed version number for development
+
+2007-05-24 06:16  oetiker
+
+       * .indent.pro, Makefile.am, bindings/python/rrd_extra.h,
+         bindings/python/rrdtoolmodule.c, bindings/ruby/main.c,
+         bindings/tcl/tclrrd.c, libraries/afm/test-afm.c, src/.indent.pro,
+         src/hash_32.c, src/parsetime.c, src/rrd.h, src/rrd_afm.c,
+         src/rrd_create.c, src/rrd_dump.c, src/rrd_fetch.c, src/rrd_gfx.c,
+         src/rrd_gfx.h, src/rrd_graph.c, src/rrd_graph_helper.c,
+         src/rrd_hw.c, src/rrd_hw.h, src/rrd_info.c, src/rrd_open.c,
+         src/rrd_rpncalc.c, src/rrd_rpncalc.h, src/rrd_tool.h,
+         src/rrd_update.c, src/rrd_xport.c, win32/config.h: indent all the
+         rest of the code, and add some typedefs to indent.pro there is now
+         a indent makefile target
 
-2006-01-29 23:28  oetiker
+2007-05-23 21:40  oetiker
 
-       * src/Makefile.NetWare, src/Makefile.Win32: more makefile cleanup
-         from Guenter Knauf gk gknw.de
+       * src/gdpng.c: removed superfluouse code
 
-2006-01-25 19:09  oetiker
+2007-05-23 21:39  oetiker
 
-       * bindings/perl-piped/RRDp.pm: allow RRDp to catch errors
+       * src/.indent.pro: added more indenting rules
 
-2006-01-22 12:02  oetiker
+2007-05-23 21:33  oetiker
 
-       * doc/rrdcreate.pod: clarified the documentation of xff -- Michael
-         Bunk mb computer-leipzig.com
+       * src/.indent.pro, src/art_rgba_svp.c, src/art_rgba_svp.h,
+         src/fnv.h, src/gdpng.c, src/hash_32.c, src/parsetime.c,
+         src/pngsize.c, src/rrd.h, src/rrd_afm.c, src/rrd_afm.h,
+         src/rrd_afm_data.c, src/rrd_afm_data.h, src/rrd_cgi.c,
+         src/rrd_create.c, src/rrd_diff.c, src/rrd_dump.c, src/rrd_error.c,
+         src/rrd_fetch.c, src/rrd_first.c, src/rrd_format.c,
+         src/rrd_format.h, src/rrd_getopt.c, src/rrd_getopt.h,
+         src/rrd_getopt1.c, src/rrd_gfx.c, src/rrd_gfx.h, src/rrd_graph.c,
+         src/rrd_graph.h, src/rrd_graph_helper.c, src/rrd_hw.c,
+         src/rrd_hw.h, src/rrd_info.c, src/rrd_is_thread_safe.h,
+         src/rrd_last.c, src/rrd_lastupdate.c, src/rrd_nan_inf.c,
+         src/rrd_nan_inf.h, src/rrd_not_thread_safe.c, src/rrd_open.c,
+         src/rrd_resize.c, src/rrd_restore.c, src/rrd_rpncalc.c,
+         src/rrd_rpncalc.h, src/rrd_stat.c, src/rrd_thread_safe.c,
+         src/rrd_thread_safe_nt.c, src/rrd_tool.c, src/rrd_tool.h,
+         src/rrd_tune.c, src/rrd_update.c, src/rrd_version.c,
+         src/rrd_xport.c, src/rrd_xport.h, src/rrdupdate.c, src/strftime.c,
+         src/strftime.h, src/win32comp.c: reindented everything according
+         to .indent.pro
 
-2006-01-22 11:00  oetiker
+2007-05-23 20:57  oetiker
 
-       * doc/rrdgraph_rpn.pod: the operator in the example is * not + --
-         Nick Sharp njsharp bigpond.net.au
+       * .indent.pro, src/.indent.pro: profile must be in the source
+         directory to work
 
-2006-01-15 13:31  oetiker
+2007-05-23 20:57  oetiker
 
-       * bindings/perl-shared/RRDs.xs: make sure we pickup the correct
-         config.h ... -- Blair Zajac blair orcaware.com
+       * .indent.pro: tabs be gone!
 
-2006-01-15 12:31  oetiker
+2007-05-23 20:42  oetiker
 
-       * src/rrd_tool.c: make sure the image size only gets printed from
-         rrd_tool when --imageinfo is NOT set.
+       * configure.ac, src/Makefile.am, src/rrd.h, src/rrd_dump.c,
+         src/rrd_fetch.c, src/rrd_first.c, src/rrd_hw.c, src/rrd_hw.h,
+         src/rrd_info.c, src/rrd_last.c, src/rrd_lastupdate.c,
+         src/rrd_open.c, src/rrd_resize.c, src/rrd_restore.c,
+         src/rrd_stat.c, src/rrd_thread_safe.c, src/rrd_tool.h,
+         src/rrd_tune.c, src/rrd_update.c, src/unused.h: * progress in
+         moving all the fileaccess over to a wrapper system that can do fd
+         based and mmap based fileaccess transparently ... * small fixes
+         left and right to improve code quality and stability. -- Bernhard
+         Fischer rep dot nop gmail com
 
-2006-01-15 12:25  oetiker
+2007-05-23 16:10  oetiker
 
-       * src/rrd_graph.c: make sure gcc does not thing gridind may be
-         undefined
+       * .indent.pro: we are going to use indent from now on to keep code
+         indenting consistent throughout the project
 
-2006-01-15 11:12  oetiker
+2007-05-23 16:08  oetiker
 
-       * doc/rrdcreate.pod: HWPREDICT without reference number will
-         implicitly create the other Holt-Winters RRAs.
+       * .: new trunk based on current 1.2
 
-2006-01-15 09:03  oetiker
+2007-05-23 16:07  oetiker
 
-       * src/Makefile.NetWare, src/Makefile.Win32, src/rrd_tool.h: updated
-         NetWare and Cygwin Builds
+       * .: restarting trynk for 1.2
 
-2006-01-15 08:55  oetiker
+2007-05-22 11:03  oetiker
 
-       * src/rrd_graph.c: make sure gridind is defined under all conditions
+       * trunk/talks/rrdtoolfast/onlineusv-de.ppt: initial
 
-2006-01-14 09:10  oetiker
+2007-05-22 09:27  oetiker
 
-       * CONTRIBUTORS, bindings/perl-shared/RRDs.pm, bindings/tcl/tclrrd.c,
-         doc/rrddump.pod, src/rrd.h, src/rrd_dump.c: add perlbindings and
-         optional export filename to rrd_dump -- Nicola Worthington nicolaw
-         arwen.tfb.net
+       * trunk/talks/rrdtoolfast/fasttalk.ppt,
+         trunk/talks/rrdtoolfast/samfs-de.ppt: renamed
 
-2006-01-05 20:39  oetiker
+2007-04-10 13:49  oetiker
 
-       * bindings/Makefile.am, bindings/perl-shared/Makefile.PL: let the
-         building of the perl extension be more reliable ...
+       * trunk/status/2007-04-10.txt: added sponsors
 
-2006-01-05 20:07  oetiker
+2007-04-10 13:29  oetiker
 
-       * src/rrd_gfx.c: remove redundant if statement in rrd_gfx pdf code
-         ... -- NormW
+       * trunk/status/2007-04-10.txt: second reading ...
 
-2006-01-04 22:07  oetiker
+2007-04-10 13:14  oetiker
 
-       * src/Makefile.NetWare, src/Makefile.Win32, src/get_ver.awk,
-         src/rrd_tool.h: Compile time improvments for NetWare and Win32 --
-         Guenter Knauf gk.gknw.de
+       * trunk/status, trunk/status/2007-04-10.txt: status report initial
+         version
 
-2006-01-04 20:12  oetiker
+2007-03-19 22:01  oetiker
 
-       * src/rrd_gfx.c: make sure this actually compiles with HAVE_MBSTOWCS
-         is not defined
+       * trunk/articles/rrdtool-infoweek-2007-03.doc: infoweek artikel
+         initial
 
-2005-12-30 14:36  oetiker
+2007-03-19 14:24  oetiker
 
-       * src/rrd_tool.c: only use getuid if it is actually available ...
+       * trunk/articles, trunk/articles/rrdtool-infoweek-2007-03.doc:
+         initial
 
-2005-12-26 16:01  oetiker
+2007-03-02 06:38  oetiker
 
-       * doc/rrdcreate.pod: added heartbeat grahics
+       * trunk/talks/rrdtoolfast/monitoring-en.ppt: added english version
 
-2005-12-19 12:28  oetiker
+2007-02-20 06:53  oetiker
 
-       * bindings/tcl/Makefile.am, bindings/tcl/tclrrd.c, configure.ac: fix
-         tcl issues ... build with pre tcl8.4 ... do not try to install
-         into the tcl tree unless --enable-tcl-site is given -- tobi
+       * trunk/tutorial/linuxforum2007/rrdtutorial.odp: ready for
+         presentation at linuxforum
 
-2005-12-18 20:30  oetiker
+2007-01-31 08:29  oetiker
 
-       * bindings/perl-piped/RRDp.pm, bindings/perl-shared/RRDs.pm,
-         configure.ac, doc/rrdbuild.pod, rrdtool.spec, src/gdpng.c,
-         src/gifsize.c, src/pngsize.c, src/rrd.h, src/rrd_afm.c,
-         src/rrd_afm.h, src/rrd_afm_data.c, src/rrd_afm_data.h,
-         src/rrd_cgi.c, src/rrd_create.c, src/rrd_datalang.c,
-         src/rrd_diff.c, src/rrd_dump.c, src/rrd_error.c, src/rrd_fetch.c,
-         src/rrd_first.c, src/rrd_format.c, src/rrd_format.h,
-         src/rrd_gfx.c, src/rrd_gfx.h, src/rrd_graph.c,
-         src/rrd_graph_helper.c, src/rrd_hw.c, src/rrd_hw.h,
-         src/rrd_info.c, src/rrd_is_thread_safe.h, src/rrd_last.c,
-         src/rrd_not_thread_safe.c, src/rrd_open.c, src/rrd_resize.c,
-         src/rrd_restore.c, src/rrd_rpncalc.c, src/rrd_rpncalc.h,
-         src/rrd_stat.c, src/rrd_thread_safe.c, src/rrd_thread_safe_nt.c,
-         src/rrd_tool.c, src/rrd_tool.h, src/rrd_tune.c, src/rrd_update.c,
-         src/rrd_version.c, src/rrd_xport.c, src/rrd_xport.h: prepare for
-         the release of rrdtool-1.2.12
+       * trunk/talks/rrdtoolfast/fasttalk.ppt: updated for samfs
 
-2005-12-18 20:29  oetiker
+2007-01-30 08:36  oetiker
 
-       * COPYRIGHT: added FLOSS exception from
-         http://www.mysql.com/company/legal/licensing/foss-exception.html
-         in order to not end up in license incompatibility hell -- tobi
+       * trunk/talks/rrdtoolfast/fasttalk.ppt: added fasttalk for samfs
 
-2005-11-30 09:19  oetiker
+2007-01-30 08:34  oetiker
 
-       * src/rrd_graph_helper.c: if called with --lazy we still want to
-         PRINT ... -- Bartek Szady bszx from bszx.eu.org
+       * trunk/talks, trunk/talks/rrdtoolfast: initial
 
-2005-11-28 21:59  oetiker
+2007-01-22 17:20  oetiker
 
-       * src/rrd_update.c: we should still consider the mrhb ...
+       * trunk/tutorial, trunk/tutorial/linuxforum2007,
+         trunk/tutorial/linuxforum2007/abstract-rrdtut.txt,
+         trunk/tutorial/linuxforum2007/rrdtutorial.odp,
+         trunk/tutorial/linuxforum2007/tobi-2006.jpg: initial
 
-2005-11-20 10:16  oetiker
+2006-02-13 14:40  oetiker
 
-       * src/Makefile.Win32: improve win32 compilation -- Norm
+       * NEWS: removed extra line from top
 
-2005-11-18 20:38  oetiker
+2005-04-04 22:15  oetiker
 
-       * src/get_ver.awk: deal with versions ending in letters
+       * trunk/meta/plan-1.2.txt: plan for 1.2 is now in the 1.2 branche
 
-2005-11-16 13:14  oetiker
+2005-04-03 12:44  oetiker
 
-       * configure.ac: have indivitudal lines for generating output files,
-         so that cygwin does not choke
+       * trunk/meta/plan-1.2.txt: verified operation on debian
 
-2005-11-14 23:07  oetiker
+2005-04-03 12:44  oetiker
 
-       * configure.ac: make mmap test a little saver
+       * README, configure.ac: update build instructions and configure
+         output.
 
-2005-11-14 11:46  oetiker
+2005-04-03 11:44  oetiker
 
-       * configure.ac: cygwin can actually do mmap ... -- larryjadams with
-         comcast.net
+       * doc/rrdgraph_graph.src, src/rrd_graph_helper.c: paramters in SHIFT
+         are separated by : like everywhere else
 
-2005-11-14 07:32  oetiker
+2005-04-03 11:36  oetiker
 
-       * src/rrd_update.c: guess the option should still be called template
-         :-)
+       * doc/rrdgraph_graph.src, src/rrd_graph.c, src/rrd_graph.h,
+         src/rrd_graph_helper.c: the piechart code does not produce release
+         ready results ... hide it behind WITH_PIECHART define
 
-2005-11-13 18:32  oetiker
+2005-04-03 11:11  oetiker
 
-       * acinclude.m4, configure.ac: improve screen apperance of configure
-         output as suggested by Dale -- tobi
+       * src/rrd_gfx.c: improve png writing speed by lowering the
+         compression
 
-2005-11-13 18:31  oetiker
+2005-04-03 11:11  oetiker
 
-       * bindings/python/Makefile.am: don't use clean: target ... automake
-         wants this to be clean-local:
+       * src/rrd_graph.c: make sure the font path is shorter than the
+         buffer
 
-2005-11-12 23:36  oetiker
+2005-04-03 10:10  oetiker
 
-       * src/rrd_gfx.c: add xmlns declaration to svg output -- R.P. Aditya
-         <aditya with grot.org>
+       * CONTRIBUTORS, src/rrd_graph.c, src/rrd_graph.h: fix graph layout
+         ... especially consider text propperties propperly
 
-2005-11-12 23:30  oetiker
+2005-04-03 09:37  oetiker
 
-       * bindings/Makefile.am: clean target was broken
+       * src/rrd_graph_helper.c: the legend string of a PRINT command gets
+         renderd later by runnning it through printf.
 
-2005-11-12 23:10  oetiker
+2005-04-03 09:35  oetiker
 
-       * configure.ac, doc/rrdbuild.pod, src/Makefile.am, src/rrd_cgi.c: *
-         integrate necessary cgi functionality into rrd_cgi.c so that
-         libcgi is not required anymore ... -- D. Walsh <buildsmart at
-         daleenterprise.com> * check if we have to include malloc/malloc.h
-         to make malloc work ... -- tobi
+       * configure.ac, src/rrd_update.c: MMAP support for rrdtool this is
+         suposed to speed-up uptime 4 times. -- Radoslaw Karas
+         <rkaras@tyndall.ie>
 
-2005-11-07 19:12  oetiker
+2005-03-20 21:17  oetiker
 
-       * src/rrd_update.c: the variable template has to generic a name, it
-         clashes with other things in some environments.
+       * bindings/Makefile.am: revert to last working version
 
-2005-10-28 05:55  oetiker
+2005-03-20 21:11  oetiker
 
-       * doc/rrdbuild.pod: added openbsd note
+       * bindings/Makefile.am: fix quoting
 
-2005-10-24 20:55  oetiker
+2005-03-20 21:00  oetiker
 
-       * bindings/tcl/Makefile.am, bindings/tcl/tclrrd.c: use multithreded
-         version of librrd -- Oleg Derevenetz <oleg with vsi.ru>
+       * bindings/Makefile.am: quote sed expression
 
-2005-10-11 17:09  oetiker
+2005-03-20 20:59  oetiker
 
-       * src/rrd_graph.c, src/rrd_graph.h, src/rrd_graph_helper.c,
-         src/rrd_rpncalc.c, src/rrd_rpncalc.h: improved error messages for
-         rrd_graph commandline parsing -- Alex
+       * doc/rrdgraph.src, doc/rrdgraph_graph.src: document tabbing support
+         by adding in the textformatting notes document --tabwidth argument
+         document AXIS color
 
-2005-10-11 16:51  oetiker
+2005-03-20 20:58  oetiker
 
-       * examples/minmax.pl.in: fix file generation
+       * src/rrd_graph.c, src/rrd_graph.h, src/rrd_graph_helper.c: * allow
+         configuration of the default tab width * added new configurable
+         color AXIS * made tabbing support work with legend elements * use
+         propper font for the legend: LEGEND * fix apperance by makeing
+         grid more transparent * draw axis over the graph not under it.
 
-2005-10-11 16:41  oetiker
+2005-03-20 20:56  oetiker
 
-       * examples/4charts.pl.in, examples/bigtops.pl.in,
-         examples/minmax.pl.in, examples/shared-demo.pl.in,
-         examples/stripes.pl.in: die on error! -- Alex
+       * src/rrd_gfx.c, src/rrd_gfx.h: added tabbig support
 
-2005-10-11 16:37  oetiker
+2005-03-20 20:55  oetiker
 
-       * examples/4charts.pl.in, examples/bigtops.pl.in,
-         examples/minmax.pl.in: the images should be written to the current
-         directory ... -- Alex
+       * configure.ac: include the thread defs after they have been found
+         not before
 
-2005-10-11 16:32  oetiker
+2005-03-20 20:54  oetiker
 
-       * configure.ac: do not complain about strict aliasing issues -- Alex
+       * trunk/meta/plan-1.2.txt: sync with reality
 
-2005-10-08 21:58  oetiker
+2005-03-13 16:34  oetiker
 
-       * bindings/tcl/tclrrd.c: allow rrd::graph to write directly to a tcl
-         stream ... by Dave Bodenstab <dave with bodenstab.org>
+       * bindings/perl-shared/RRDs.xs: propperly integrate rrd_first
 
-2005-10-07 07:48  oetiker
+2005-03-13 16:13  oetiker
 
-       * CONTRIBUTORS, bindings/tcl/Makefile.am, bindings/tcl/tclrrd.c,
-         configure.ac: updates for tcl bindings by -- Dave Bodenstab <dave
-         on bodenstab.org>
+       * MakeMakefile: autotools still run after configure this is not good
+         ... run autoreconf at the end of MakeMakefile. Maybe this will
+         help
 
-2005-10-07 07:48  oetiker
+2005-03-13 16:09  oetiker
 
-       * Makefile.am, favicon.ico: included favicon in distro
+       * configure.ac: set install patch to version
 
-2005-09-26 20:33  oetiker
+2005-03-13 16:08  oetiker
 
-       * src/rrd_gfx.c: plugged two memmory leaks happening when a
-         requested font is not found.
+       * MakeMakefile: re-run autotools to make sure dependent dates are
+         correct
 
-2005-09-23 23:06  oetiker
+2005-03-13 16:00  oetiker
 
-       * src/rrd_graph.c: hmpf its the gdef step we are talking about not
-         the image step !
+       * MakeMakefile: reintroduce final header regen
 
-2005-09-22 20:18  oetiker
+2005-03-13 15:57  oetiker
 
-       * src/rrd_graph.c, src/rrd_graph.h, src/rrd_graph_helper.c: do not
-         'reload' data if you already have it!
+       * MakeMakefile: still trying to get the order of calling autotools
+         right
 
-2005-09-22 20:17  oetiker
+2005-03-13 15:54  oetiker
 
-       * src/rrd_restore.c: the -r option should not expect an argument
+       * MakeMakefile: create aclocal.m4 before libtoolize
 
-2005-09-19 07:42  oetiker
+2005-03-13 15:51  oetiker
 
-       * src/rrd_restore.c: do not free stuff that gets freed later anyway
+       * MakeMakefile: make the headers first
 
-2005-09-18 18:28  oetiker
+2005-03-13 15:16  oetiker
 
-       * src/Makefile.NetWare: Netware Build Updates --- Guenter Knauf <gk
-         with gknw.de>
+       * doc/rrdfirst.pod: add the documentation for first
 
-2005-09-18 16:59  oetiker
+2005-03-13 15:14  oetiker
 
-       * src/rrd_fetch.c: allocate memory for one more row ... fetch can
-         not return 0 reows ...
+       * src/Makefile.am: ntconfig is no more
 
-2005-09-18 15:39  oetiker
+2005-03-13 15:12  oetiker
 
-       * src/rrd_graph.c: comparing floating point numbers is dangerouse
-         ... don't do this directly!
+       * src/rrd_first.c: missed the actual code for first
 
-2005-09-01 21:23  oetiker
+2005-03-12 17:06  oetiker
 
-       * src/rrd_tool.c: since we use firstdir even without CHROOT it
-         should better be defined in any case -- Guenter Knauf
+       * bindings/perl-shared/RRDs.xs, doc/Makefile.am, src/Makefile.am,
+         src/rrd.h, src/rrd_tool.c: rrd_first code contributed by Burton
+         Strauss <Burton@ntopSupport.com>
 
-2005-08-30 05:52  oetiker
+2005-03-10 17:04  oetiker
 
-       * src/rrd_graph.c, src/rrd_graph.h: When selecting the x-axis label
-         take the length of the time shown in the graph into consideration
-         just showing %H:%M in a two day presentation is a problem ... --
-         LAUKENS Niels <Niels.LAUKENS .. VRT.BE>
+       * trunk/meta/plan-1.2.txt: updated plan ...
 
-2005-08-28 07:33  oetiker
+2005-03-10 17:03  oetiker
 
-       * doc/rrdbuild.pod: fixed location of example scripts
+       * README, acinclude.m4, bindings/Makefile.am, configure.ac,
+         examples/4charts.pl.in, examples/bigtops.pl.in,
+         examples/cgi-demo.cgi.in, examples/minmax.pl.in,
+         examples/piped-demo.pl.in, examples/shared-demo.pl.in,
+         examples/stripes.pl.in, src/rrd.h, src/rrd_last.c, src/rrd_tool.h:
+         * Updated perl compile system. It now uses Makefile.PL for
+         everything, but gets it to install the perl module in
+         @prefix@/lib/perl such that you can use the same use lib line for
+         whatever platform and perlversion you install into this directory.
+         They all live neatly next to each other. * fixed examples to work
+         with new perl install system. Added a few exec_prefix lines where
+         appropriate * fixed piped demo * fixed VeraMono.ttf file. This
+         somehow got damaged by cvs ... * added thread defines to normal
+         compile run, so that _r functions to not through errors. * tested
+         compilation and installation
 
-2005-08-27 21:29  oetiker
+2005-03-04 23:53  oetiker
 
-       * src/rrd_update.c: resolve subsecond resolution logging and
-         handling of unknown values by starting off with an unknown value
-         when building a pdp instead of starting out with 0 and then
-         turning it into unknown later on if the number of uknown seconds
-         is equal or larger than the interval ...
+       * acinclude.m4, configure.ac: revamped configure system ... lots
+         more stuff is in acinclude now still a bit of a mess, but better
+         than before ... if configure does not find the dependent libraries
+         and header it will not try to get help from pkg-config. If you
+         know where your libraries are it is best to just use CPPFLAGS and
+         LDFLAGS to specify their location.
 
-2005-08-27 20:55  oetiker
+2005-03-04 00:12  oetiker
 
-       * examples/piped-demo.pl.in: the rrdtool binary one more level up
-         the path ...
+       * MakeMakefile, acinclude.m4, bindings/Makefile.am, configure.ac,
+         src/Makefile.am: Big autotool update: * Upgraded to the latest
+         version of autoconf, automake and libtool * replaced pthread
+         detection code in configure with a more effective one * added a
+         test to see if special solaris defines are required for ctime_r to
+         behave posixly correct. * Fixed lots of warnings from autotools *
+         started adding support for pkg-config ... this will eventually
+         make the whole library finding much simpler
 
-2005-08-27 20:52  oetiker
+2005-03-04 00:05  oetiker
 
-       * examples/piped-demo.pl.in: update for new prefix setting
+       * trunk/meta/plan-1.2.txt: added warning cleanup
 
-2005-08-25 20:43  oetiker
+2005-03-03 13:56  oetiker
 
-       * src/rrd_resize.c: when resize converts a v1 rrd to v3 it should
-         also change the version number in the head ...
+       * trunk/meta/plan-1.2.txt: added notes about including stuff
 
-2005-08-23 21:18  oetiker
+2005-03-03 13:48  oetiker
 
-       * Makefile.am, src/Makefile.NetWare, src/Makefile.Win32,
-         src/Makefile.am, src/get_ver.awk, src/rrd_afm.c, src/rrd_dump.c,
-         src/rrd_tool.c, src/rrd_tool.h, src/rrd_update.c, src/rrdtool.dsp,
-         src/rrdtool.vcproj: fixes for compiling rrdtool with win32 mingw
-         and netware -- Guenter Knauf <gk with gknw.de>
+       * trunk/meta/plan-1.2.txt: spelled
 
-2005-08-16 05:30  oetiker
+2005-03-03 13:46  oetiker
 
-       * doc/rrdgraph_data.pod, doc/rrdgraph_examples.pod,
-         doc/rrdgraph_rpn.pod: added notes about VDEF expressions not being
-         general purpose
+       * trunk/meta/plan-1.2.txt: initial
 
-2005-08-11 19:18  oetiker
+2005-03-03 13:34  oetiker
 
-       * src/rrd_tool.c: only bomb is there is no chroot and someone tries
-         to use it.
+       * trunk/contrib/php4/.cvsignore, trunk/meta,
+         trunk/meta/plan-1.2.txt, ., .cvsignore, bindings/.cvsignore,
+         bindings/perl-piped/.cvsignore, bindings/perl-shared/.cvsignore,
+         bindings/tcl/.cvsignore, doc/.cvsignore, examples/.cvsignore,
+         libraries/.cvsignore, src/.cvsignore: ignorelists are a propperty
+         of an svn directory not a file
 
-2005-08-04 05:08  oetiker
+2005-03-03 13:21  oetiker
 
-       * doc/rrdgraph_rpn.pod, src/rrd_graph.c, src/rrd_graph.h: New VDEF
-         functions for least squares slope, intercept & correlation for
-         simple forecasting -- Trent Burkard <tburkard with tangentis.com>
+       * branches/gnu, branches/gpl, trunk/CVSROOT, trunk/rrdtool: post
+         cvs2svn conversion cleanup
 
-2005-08-04 04:59  oetiker
+2005-02-27 22:00  oetiker
 
-       * src/rrd_update.c: fix rounding issues that prevented UNKNOWN to
-         work as soon as subsecond resolution was used
+       * src/rrd_cgi.c: do not complain when setting environemnt variable
+         sucessfully. -- hunter@mimuw.edu.pl
 
-2005-08-04 04:58  oetiker
+2005-02-13 16:13  oetiker
 
-       * src/rrd_graph.c: avoid drawing lines where two points are in the
-         same spot. this mai be confusing libart
+       * CONTRIBUTORS, bindings/perl-shared/RRDs.xs, bindings/tcl/tclrrd.c,
+         src/rrd.h, src/rrd_cgi.c, src/rrd_graph.c, src/rrd_graph.h,
+         src/rrd_tool.c: let rrd_graph return the actual value range it
+         picked ... -- Henrik Stoerner <henrik@hswn.dk>
 
-2005-08-02 15:54  oetiker
+2005-01-28 14:02  oetiker
 
-       * bindings/Makefile.am: make sure clean works even when the perl
-         Makefile is broken
+       * src/rrd_hw.c: fix for memory leak. Rene Gallati <security ..
+         draxinusom.ch>
 
-2005-07-26 09:13  oetiker
+2005-01-03 22:25  oetiker
 
-       * src/rrd_graph.c: initialize font to empty string for deault font
-         case.
+       * TODO: update todo
 
-2005-07-25 14:12  oetiker
+2004-10-25 22:22  oetiker
 
-       * bindings/perl-piped/RRDp.pm, bindings/perl-shared/RRDs.pm,
-         doc/rrdbuild.pod, rrdtool.spec, src/gdpng.c, src/gifsize.c,
-         src/pngsize.c, src/rrd.h, src/rrd_afm.c, src/rrd_afm.h,
-         src/rrd_afm_data.c, src/rrd_afm_data.h, src/rrd_cgi.c,
-         src/rrd_create.c, src/rrd_datalang.c, src/rrd_diff.c,
-         src/rrd_dump.c, src/rrd_error.c, src/rrd_fetch.c, src/rrd_first.c,
-         src/rrd_format.c, src/rrd_format.h, src/rrd_gfx.c, src/rrd_gfx.h,
-         src/rrd_graph.c, src/rrd_graph_helper.c, src/rrd_hw.c,
-         src/rrd_hw.h, src/rrd_info.c, src/rrd_is_thread_safe.h,
-         src/rrd_last.c, src/rrd_not_thread_safe.c, src/rrd_open.c,
-         src/rrd_resize.c, src/rrd_restore.c, src/rrd_rpncalc.c,
-         src/rrd_rpncalc.h, src/rrd_stat.c, src/rrd_thread_safe.c,
-         src/rrd_thread_safe_nt.c, src/rrd_tool.c, src/rrd_tool.h,
-         src/rrd_tune.c, src/rrd_update.c, src/rrd_version.c,
-         src/rrd_xport.c, src/rrd_xport.h: prepare for the release of
-         rrdtool-1.2.11
+       * doc/rrdgraph.src, src/rrd_graph.c, src/rrd_graph.h: *
+         fore-rules-legend option -- author name missing
 
-2005-07-25 14:07  oetiker
+2004-10-25 22:21  oetiker
 
-       * configure.ac, src/Makefile.am: prepared for release
+       * src/rrd_tool.c: fixed segmentation falt problem in rrd_tool --
+         Yasuhiro Sumi <yasuhiro.sumi@hde.co.jp>
 
-2005-07-22 13:16  oetiker
+2004-10-21 19:21  oetiker
 
-       * src/rrd_tool.c: do not quit so easily when runing in interactive
-         mode
+       * src/rrd_tool.c: fix return codes in the error case -- Haroon
+         Rafique <haroon.rafique@utoronto.ca>
 
-2005-07-22 13:16  oetiker
+2004-09-24 21:11  oetiker
 
-       * src/rrd_graph.c: init ytr after all the changes have happened
+       * CONTRIBUTORS, doc/rrdgraph_data.src, doc/rrdgraph_rpn.src,
+         src/rrd_graph.c, src/rrd_graph.h, src/rrd_graph_helper.c,
+         src/rrd_resize.c, src/rrd_rpncalc.c, src/rrd_rpncalc.h,
+         src/rrd_xport.c: misc fixed and TREND and reduce functionality by
+         -- David M. Grimes <dgrimes@navisite.com>
 
-2005-07-22 13:10  oetiker
+2004-08-24 05:26  oetiker
 
-       * src/rrd_graph.c: make --no-gridfit with --only-graph work
+       * CONTRIBUTORS, doc/rrdgraph_rpn.src, src/rrd_graph.c,
+         src/rrd_graph.h, src/rrd_graph_helper.c, src/rrd_rpncalc.c,
+         src/rrd_rpncalc.h, src/rrd_xport.c: CDEF operators SHIFT, SQRT,
+         SORT, and REV (reverse). See documentation for what they do. This
+         included removal of redundant code in the rrd_xport path, replaced
+         with a call to rrd_graph_script(). -- David M. Grimes
+         <dgrimes@navisite.com>
 
-2005-07-21 22:23  oetiker
+2004-08-09 08:38  oetiker
 
-       * src/rrd_graph.c: when stacking known on unknown, then we asume
-         unknown was zero ...
+       * doc/rrdcgi.pod: added note on escaping :
 
-2005-07-20 07:20  oetiker
+2004-08-08 21:54  oetiker
 
-       * configure.ac: make sure gcc-4.0 does not optimize our tests away
-         :-)
+       * src/rrd_cgi.c: port forward of fixes from the stable version of
+         rrd_cgi
 
-2005-07-19 10:00  oetiker
+2004-08-07 23:46  oetiker
 
-       * src/rrd_graph.c: fixed some corner cases in drawing code to get
-         the same results as before with way more performance
+       * src/rrd_graph.c: when moving the data pointers we should take into
+         account how fahr off they are. Found by David M. Grimes
+         <dgrimes@navisite.com>
 
-2005-07-11 22:49  oetiker
+2004-08-05 21:24  oetiker
 
-       * src/rrd_graph.c: optimized drawing routines ... up to 6 times
-         faster (in the case of smokeping)
+       * bindings/perl-piped/MANIFEST, bindings/perl-shared/MANIFEST:
+         removed nonexisting files from manifest
 
-2005-07-07 10:27  oetiker
+2004-07-30 00:30  jake
 
-       * doc/rrdgraph.pod: colors start with # not :
+       * NT-BUILD-TIPS.txt, bindings/perl-shared/RRDs.ppd,
+         bindings/perl-shared/ntmake.pl, bindings/perl-shared/rrdpl.dsp,
+         bindings/perl-shared/rrdpl.dsw, confignt/config.h, src/rd_cgi.dsp,
+         src/rrd.dsp, src/rrd.dsw, src/rrd.vcproj, src/rrd_afm.c,
+         src/rrd_cgi.dsp, src/rrd_cgi.vcproj, src/rrd_restore.c,
+         src/rrdtool.dsp, src/rrdtool.dsw, src/rrdtool.sln,
+         src/rrdtool.suo, src/rrdtool.vcproj: Fix the Win32 build for
+         executable and perl-shared library. See NT-BUILD-TIPS.txt for step
+         by step instructions. Remove VC++ project files not being
+         maintained by anyone.
 
-2005-07-04 18:49  oetiker
+2004-07-14 10:55  oetiker
 
-       * src/rrd_graph.c: make setting just the size and not the font work
-         -- Havard Eidnes <he from uninett.no>
+       * CONTRIBUTORS: added Peter Speck
 
-2005-06-28 21:03  oetiker
+2004-06-26 09:03  oetiker
 
-       * bindings/Makefile.am, bindings/python/Makefile.am,
-         bindings/tcl/Makefile.am, configure.ac, doc/Makefile.am,
-         examples/Makefile.am: * the makefiles should not depend on gnumake
-         features * make the perl module compilation environement
-         configurable -- Stan Sinyagin ssinyagin on yahoo.com
+       * rrdtool.spec: allow building rpm from cvs where there is not
+         ChangeLog (this gets generated when the distribution tar is built)
+         -- Tobi and Mike Slifcak
 
-2005-06-25 05:24  oetiker
+2004-06-23 20:36  oetiker
 
-       * doc/rrdbuild.pod: added GNUMAKE and EGREP hints
+       * src/rrd_graph.c: It's quie enough that the title is placed on the
+         top of the graph, there's no need to emphasize it more. --
+         Stanislav Sinyagin <ssinyagin@yahoo.com>
 
-2005-06-20 09:15  oetiker
+2004-06-23 08:39  oetiker
 
-       * src/rrd_graph.c: x-axis labels should be aligned to their baseline
-         alt-y-grid labels without fractionals should have no fractionals
-         when printed
+       * src/Makefile.am: reverted ... $< does not work
 
-2005-06-17 09:05  oetiker
+2004-06-22 22:09  oetiker
 
-       * bindings/perl-piped/RRDp.pm, bindings/perl-shared/RRDs.pm,
-         configure.ac, doc/rrdbuild.pod, rrdtool.spec, src/gdpng.c,
-         src/gifsize.c, src/pngsize.c, src/rrd.h, src/rrd_afm.c,
-         src/rrd_afm.h, src/rrd_afm_data.c, src/rrd_afm_data.h,
-         src/rrd_cgi.c, src/rrd_create.c, src/rrd_datalang.c,
-         src/rrd_diff.c, src/rrd_dump.c, src/rrd_error.c, src/rrd_fetch.c,
-         src/rrd_first.c, src/rrd_format.c, src/rrd_format.h,
-         src/rrd_gfx.c, src/rrd_gfx.h, src/rrd_graph.c,
-         src/rrd_graph_helper.c, src/rrd_hw.c, src/rrd_hw.h,
-         src/rrd_info.c, src/rrd_is_thread_safe.h, src/rrd_last.c,
-         src/rrd_not_thread_safe.c, src/rrd_open.c, src/rrd_resize.c,
-         src/rrd_restore.c, src/rrd_rpncalc.c, src/rrd_rpncalc.h,
-         src/rrd_stat.c, src/rrd_thread_safe.c, src/rrd_thread_safe_nt.c,
-         src/rrd_tool.c, src/rrd_tool.h, src/rrd_tune.c, src/rrd_update.c,
-         src/rrd_version.c, src/rrd_xport.c, src/rrd_xport.h: prepare for
-         the release of rrdtool-1.2.10
+       * src/Makefile.am: The "$^" variable is GNU make-specific, and fails
+         to compile under FreeBSD 4.10. Please change it to $<, which is
+         more compatible. -- Stanislav Sinyagin <ssinyagin@yahoo.com>
 
-2005-06-16 22:09  oetiker
+2004-06-17 22:09  oetiker
 
-       * src/rrd_graph.c: when building the sgridstep in alt-y-grid mode,
-         take the --base into consideration.
+       * src/rrd_graph.h: fixed type for text_prop_conv prototype
 
-2005-06-13 21:56  oetiker
+2004-06-07 19:07  oetiker
 
-       * src/rrd_graph.c: simplify code for generating y axis labels a bit.
+       * debian/changelog, debian/control, debian/rules: Fix for debian
+         freetype linking -- Peter Hirdina <Peter.Hirdina@gmx.net>
 
-2005-06-13 13:20  oetiker
+2004-05-26 22:11  oetiker
 
-       * src/rrd_gfx.c: wide chars should better be unsigned
+       * src/fnv.h, src/parsetime.c, src/pngsize.c, src/rrd.h,
+         src/rrd_afm.c, src/rrd_afm_data.c, src/rrd_afm_data.h,
+         src/rrd_cgi.c, src/rrd_gfx.c, src/rrd_graph.c,
+         src/rrd_graph_helper.c, src/rrd_last.c, src/rrd_open.c,
+         src/rrd_resize.c, src/rrd_restore.c, src/rrd_tool.c,
+         src/rrd_tool.h, src/rrd_tune.c, src/rrd_update.c, src/rrd_xport.c:
+         reduce compiler warnings. Many small fixes. -- Mike Slifcak
+         <slif@bellsouth.net>
 
-2005-06-13 12:56  oetiker
+2004-05-26 22:10  oetiker
 
-       * src/rrd_gfx.c: fall back to assuming latin1 encoding if mbtowchar
-         conversion fails
+       * rrdtool.spec: improve redhat/fedora building -- Mike Slifcak
 
-2005-06-13 05:43  oetiker
+2004-05-26 22:09  oetiker
 
-       * doc/rrdgraph_data.pod, src/rrd_graph_helper.c: allow for VNAMES
-         starting with a number and add documentation -- Alex
+       * debian/rules: update debian build instructions -- Mike Slifcak
 
-2005-06-13 05:43  oetiker
+2004-05-25 22:08  oetiker
 
-       * doc/rrdgraph.pod: add notes about small numbers for --alt-y-grid
+       * examples/shared-demo.pl.in: The counter was the only variable
+         which needed to be an integer. -- Mike Slifcak
 
-2005-06-12 20:01  oetiker
+2004-05-25 22:07  oetiker
 
-       * src/rrd_update.c: kill the last stored counter value if the
-         updates comes after mrhb to make sure it does not get taken into
-         account accedenly later on.
+       * rrdtool.spec: The rrdtool RPM package was depending on the
+         rrdtool-perl package. These changes move the examples, which are
+         primarily perl scripts, in with the rrdtool-perl RPM package,
+         thereby de-coupling the rest of the RRDtool from Perl. Perhaps
+         this is silliness ? If there is no need for rrdtool separate from
+         the Perl modules, let me know, then I'll just create an rrdtool
+         and an rrdtool-devel RPM package (that would be a cleaner build
+         and scripting, anyway). -- Mike Slifcak
 
-2005-06-12 20:00  oetiker
+2004-05-25 22:03  oetiker
 
-       * src/rrd_graph.c: make --alt-y-grid work properly in many more
-         cases than before
+       * doc/Makefile.am, doc/rrdtool-dump.dtd, doc/rrdtool-xport.dtd:
+         added dtd descriptsion s or rrdtool xml output -- Wolfgang Schrimm
+         <wolfgang{dot}schrimm{at}urz{dot}uni-heidelberg{dot}de>
 
-2005-06-11 19:03  oetiker
+2004-05-25 21:06  oetiker
 
-       * src/rrd_open.c: be more careful when checking if a file is an
-         rrdfile
+       * bindings/perl-shared/RRDs.xs: added dump and restore ... Mike
+         Schilli <b2b@perlmeister.com>
 
-2005-06-11 06:17  oetiker
+2004-05-25 21:01  oetiker
 
-       * doc/Makefile.am: distribute all generated documentation install in
-         share and not shared drop index.html link
+       * CONTRIBUTORS: added some contributors
 
-2005-06-11 06:14  oetiker
+2004-05-25 21:00  oetiker
 
-       * examples/Makefile.am: install examples in an rrdtool specific
-         subdirectory if the prefix does not contain rrd -- Peter
-         Breitenlohner
+       * doc/rrdupdate.pod: fixed time stamp in example -- Mike Slifcak
 
-2005-06-11 05:41  oetiker
+2004-05-25 20:59  oetiker
 
-       * bindings/Makefile.am, bindings/perl-piped/t/base.t: avoid problems
-         when building with VPATH set and --disable-perl fix make test for
-         perl-piped -- Peter Breitenlohner
+       * rrdtool.spec: more fixes for rpm spec -- Mike Slifcak
 
-2005-06-11 05:40  oetiker
+2004-05-25 20:58  oetiker
 
-       * bindings/python/Makefile.am, doc/Makefile.am: let 'out-of tree'
-         builds work for everythin but the perl module -- Peter
-         Breitenlohner
+       * doc/rrdtutorial.pod: single word fix -- Mike Slifcak
 
-2005-06-11 05:37  oetiker
+2004-05-25 20:57  oetiker
 
-       * src/rrd_gfx.c: defined DPRINTF in a more compatible way -- Peter
-         Breitenlohner
+       * src/rrd_xport.c: Clear out previous legend array contents before
+         freeing legend array. Problem could manifest under extreme
+         resource limits. Not tested. -- Mike Slifcak
 
-2005-06-11 05:31  oetiker
+2004-05-25 20:55  oetiker
 
-       * acinclude.m4, configure.ac, src/Makefile.am: link libcgi only
-         against rrd_cgi since it is only needed there -- Peter
-         Breitenlohner
+       * doc/rrdcreate.pod: subordinate term was improperly formed -- Mike
+         Slifcak
 
-2005-06-11 05:29  oetiker
+2004-05-25 20:53  oetiker
 
-       * acinclude.m4, configure.ac: Make sure librrd_th properly depends
-         on libpthread. -- Peter Breitenlohner
+       * src/rrd_create.c, src/rrd_dump.c: prevent small leak when
+         resources are exhausted -- Mike Slifcak
 
-2005-06-11 05:27  oetiker
+2004-05-25 20:52  oetiker
 
-       * src/rrd_create.c: avoid gcc (3.4.3) warnings char format,
-         different type arg -- Peter Breitenlohner
+       * THREADS, doc/rrdthreads.pod, doc/rrdtutorial.pod,
+         doc/rrdupdate.pod, src/rrd_cgi.c, src/rrd_resize.c,
+         src/rrd_restore.c, src/rrd_tool.c, src/rrd_update.c: fix spelling
+         and syntax, especially in messages that are printed -- Mike
+         Slifcak
 
-2005-06-11 05:26  oetiker
+2004-05-25 20:51  oetiker
 
-       * bindings/tcl/Makefile.am, bindings/tcl/ifOctets.tcl,
-         bindings/tcl/ifOctets.tcl.in, bindings/tcl/tclrrd.c, configure.ac:
-         fix various problems with the tcl bindings -- Peter Breitenlohner
+       * src/rrd_cgi.c, src/rrd_dump.c, src/rrd_restore.c, src/rrd_tool.c,
+         src/rrd_update.c: Update displayed copyright messages to be
+         consistent. -- Mike Slifcak
 
-2005-06-11 05:22  oetiker
+2004-05-25 20:51  oetiker
 
-       * CONTRIBUTORS: added peter breitenlohner
+       * doc/Makefile.am: don't process the old rrdgraph single file
+         document -- Mike Slifcak
 
-2005-06-11 05:20  oetiker
+2004-05-25 20:50  oetiker
 
-       * src/rrd_cgi.c: remove various gcc (3.4.3) warnings such as
-         discards qualifier all due to 'char **' vs. 'const char **'
-         discrepancies. -- Peter Breitenlohner peb with mppmu.mpg.de
+       * rrdtool.spec: fix rpm rules -- Mike Slifcak
 
-2005-06-11 05:15  oetiker
+2004-05-25 20:50  oetiker
 
-       * src/rrd_first.c: re-innitializing sort of defeats the purpose
+       * debian/control: fixed debian dependencies -- Mike Slifcak
 
-2005-06-11 05:03  oetiker
+2004-05-25 16:51  oetiker
 
-       * src/rrd_open.c: be more carefull in checking for sucessful open
+       * src/rrd_rpncalc.c: The expression's head was first checking for
+         LT, and then for LTIME, and the latter was never reached. --
+         Stanislav Sinyagin <ssinyagin@yahoo.com>
 
-2005-06-10 19:25  oetiker
+2004-05-19 05:11  oetiker
 
-       * doc/rrdgraph_data.pod: vnames MUST start with a letter
+       * doc/rrd-beginners.pod: integrated from debian
 
-2005-06-10 19:24  oetiker
+2004-05-18 18:54  oetiker
 
-       * src/rrd_gfx.c: kill another warning
+       * src/parsetime.c: its 365 days in a year .... -- Mike Slifcak
 
-2005-06-10 18:44  oetiker
+2004-05-18 18:53  oetiker
 
-       * doc/rrdgraph.pod, src/rrd_graph.c: make --font more flexible: *
-         TITLE:30: just alter the size of the title *
-         DEFAULT:0:/tmp/funfont.ttf alter the font but not the size
+       * CONTRIBUTORS, NEWS, README, TODO, bindings/perl-piped/README,
+         bindings/perl-piped/RRDp.pm, bindings/perl-piped/t/base.t,
+         bindings/perl-shared/RRDs.pm, bindings/tcl/README,
+         doc/bin_dec_hex.pod, doc/cdeftutorial.pod, doc/rpntutorial.pod,
+         doc/rrdcgi.pod, doc/rrdcreate.pod, doc/rrddump.pod,
+         doc/rrdfetch.pod, doc/rrdgraph-old.pod, doc/rrdgraph.src,
+         doc/rrdgraph_data.src, doc/rrdgraph_examples.src,
+         doc/rrdgraph_graph.src, doc/rrdgraph_rpn.src, doc/rrdinfo.pod,
+         doc/rrdresize.pod, doc/rrdrestore.pod, doc/rrdthreads.pod,
+         doc/rrdtool.pod, doc/rrdtune.pod, doc/rrdtutorial.es.pod,
+         doc/rrdtutorial.pod, doc/rrdupdate.pod, src/parsetime.c,
+         src/rrd_fetch.c, src/rrd_format.c, src/rrd_gfx.c, src/rrd_graph.c:
+         big spell checking patch -- slif@bellsouth.net
 
-2005-06-10 08:42  oetiker
+2004-05-18 18:51  oetiker
 
-       * doc/rrdbuild.pod: added missing cd and replace one path with a
-         variable
+       * src/rrd_restore.c: make force option work
 
-2005-06-07 22:10  oetiker
+2004-05-18 18:51  oetiker
 
-       * src/rrd_afm.c, src/rrd_afm.h, src/rrd_gfx.c: make pdf/eps/svg
-         formats utf8 aware too -- Peter Speck
+       * doc/Makefile.am: added beginners guide off debian --
+         slif@bellsouth.net
 
-2005-06-06 05:32  oetiker
+2004-05-18 18:49  oetiker
 
-       * rrdtool.spec: sync up with Dag Wieers version from
-         http://dag.wieers.com/packages/rrdtool/rrdtool.spec
+       * configure.ac, examples/4charts.pl.in, examples/Makefile.am,
+         examples/shared-demo.pl.in, examples/stripes.pl.in: add 4chars and
+         fix two examples -- Mike Slifcak <slif@bellsouth.net>
 
-2005-06-05 22:23  oetiker
+2004-05-18 18:40  oetiker
 
-       * doc/rrdgraph_rpn.pod, src/rrd_rpncalc.c, src/rrd_rpncalc.h: New
-         functions for CDEF ATAN2 RAD2DEG and DEG2RAD -- Simon Melhuish
-         <simon mailing from melhuish.info>
+       * debian, debian/README.Debian, debian/build_freetype.sh,
+         debian/changelog, debian/control, debian/copyright,
+         debian/librrd0-dev.files, debian/librrd0.files,
+         debian/librrd0.postinst, debian/librrd0.postrm,
+         debian/librrd0.shlibs, debian/librrdp-perl.files,
+         debian/librrds-perl.files, debian/rrdtool-tcl.files,
+         debian/rrdtool.files, debian/rules, debian/watch: initial debian
+         build system added -- Mike Slifcak <slif@bellsouth.net>
 
-2005-05-31 06:22  oetiker
+2004-05-18 18:36  oetiker
 
-       * doc/rrd-beginners.pod: fixed epoch
+       * src/Makefile.am: fix library numbering -- Mike Slifcak
 
-2005-05-28 13:01  oetiker
+2004-05-18 18:25  oetiker
 
-       * bindings/perl-piped/RRDp.pm, bindings/perl-shared/RRDs.pm,
-         configure.ac, doc/rrdbuild.pod, rrdtool-1.2-release, rrdtool.spec,
-         src/Makefile.am, src/gdpng.c, src/gifsize.c, src/pngsize.c,
-         src/rrd.h, src/rrd_afm.c, src/rrd_afm.h, src/rrd_afm_data.c,
-         src/rrd_afm_data.h, src/rrd_cgi.c, src/rrd_create.c,
-         src/rrd_datalang.c, src/rrd_diff.c, src/rrd_dump.c,
-         src/rrd_error.c, src/rrd_fetch.c, src/rrd_first.c,
-         src/rrd_format.c, src/rrd_format.h, src/rrd_gfx.c, src/rrd_gfx.h,
-         src/rrd_graph.c, src/rrd_graph_helper.c, src/rrd_hw.c,
-         src/rrd_hw.h, src/rrd_info.c, src/rrd_is_thread_safe.h,
-         src/rrd_last.c, src/rrd_not_thread_safe.c, src/rrd_open.c,
-         src/rrd_resize.c, src/rrd_restore.c, src/rrd_rpncalc.c,
-         src/rrd_rpncalc.h, src/rrd_stat.c, src/rrd_thread_safe.c,
-         src/rrd_thread_safe_nt.c, src/rrd_tool.c, src/rrd_tool.h,
-         src/rrd_tune.c, src/rrd_update.c, src/rrd_version.c,
-         src/rrd_xport.c, src/rrd_xport.h: prepare for the release of
-         rrdtool-1.2.9
+       * doc/Makefile.am: better cleaning -- Mike Slifcak
 
-2005-05-28 12:53  oetiker
+2004-05-12 21:57  oetiker
 
-       * doc/rrdbuild.pod: add notes on building on Mac OS X
+       * bindings/Makefile.am, doc/Makefile.am: locate the mkinstalldirs
+         script at top level accept "configure --mandir=" settings -- Mike
+         Slifcak <slif@bellsouth.net>
 
-2005-05-28 12:52  oetiker
+2004-05-04 21:01  oetiker
 
-       * src/rrd_gfx.c, src/rrd_update.c: kill a few warnings
+       * doc/rrdgraph_rpn.src, src/rrd_rpncalc.c, src/rrd_rpncalc.h: Added
+         the ATAN function. This is being used to convert a DS for each
+         vector component of wind direction into a single direction for
+         graphing.
+         CDEF:avdir=yavg,xavg,/,ATAN,57.296,*,xavg,0,LT,180,0,IF,+,DUP,0,LT,360,0,IF,+
+         -- Daniel Shiels <dan@marge.tofubar.com>
 
-2005-05-28 12:52  oetiker
+2004-05-04 20:54  oetiker
 
-       * bindings/perl-shared/Makefile.PL: make the bindings work on os x
+       * rrdtool.spec: updated spec file -- Chris Adams
+         <cmadams@hiwaay.net>
 
-2005-05-27 19:17  oetiker
+2004-05-04 05:25  oetiker
 
-       * doc/rrdgraph_data.pod: add note on variable names
+       * MakeMakefile: die only after all the version checks are done and
+         not for each one -- Alex van den Bogaerdt <alex@ergens.op.het.net>
 
-2005-05-27 19:12  oetiker
+2004-05-03 14:05  oetiker
 
-       * src/rrd_graph_helper.c: remove one more warning
+       * Makefile.am, configure.ac, src/Makefile.am: * Allows rrdtool 1.1.x
+         (2004-04-29) to compile on freebsd. * Add configure options
+         --disable-rrdcgi disable building of rrdcgi --disable-pthread
+         disable multithread support -- Stanislav Sinyagin
+         <ssinyagin@yahoo.com>
 
-2005-05-27 19:12  oetiker
+2004-05-02 21:10  oetiker
 
-       * src/rrd_graph.h: there is realy no reason to have the vnames
-         constraind so much
+       * configure.ac, src/rrd_graph.c: See the patch, attached. It changes
+         the default angle to 90, and allows one to change it from
+         configure command line: ./configure RRDGRAPH_YLEGEND_ANGLE=270.0
+         -- Stanislav Sinyagin <ssinyagin@yahoo.com>
 
-2005-05-27 19:01  oetiker
+2004-04-18 10:21  oetiker
 
-       * src/rrd_gfx.c: only print ttf font errors when compiled with
-         -DDEBUG
+       * src/rrd_restore.c: fixed O_BINARY
 
-2005-05-22 22:29  oetiker
+2004-03-23 21:34  oetiker
 
-       * src/rrd_gfx.c: don't go into an endless loop upon finding a bad
-         character in a truetype font
+       * src/rrd_restore.c: make sure fole is opened binary on restore ...
+         to make things work on windows -- "Girod, Laurent"
+         <Laurent.Girod@pmintl.com>
 
-2005-05-20 06:20  oetiker
+2004-03-21 11:40  oetiker
 
-       * doc/rrdbuild.pod: go into rrdbuild too if we use tcsh
+       * doc/rrdgraph.src, src/rrd_graph.c, src/rrd_graph.h,
+         src/rrd_tool.c: Added --only-graph option -- Piotr Kodzis
+         <Piotr.Kodzis@inteligo.pl>
 
-2005-05-20 05:48  oetiker
+2004-03-14 20:58  oetiker
 
-       * rrdtool-1.2-release: initial checking
+       * MakeMakefile, acinclude.m4, bindings/Makefile.am,
+         bindings/perl-shared/Makefile.PL, bindings/perl-shared/RRDs.pm,
+         bindings/perl-shared/t/base.t, configure.ac, doc/Makefile.am: make
+         MakeMaker work on debian and fix some leftovers from the library
+         rip-out transition -- Tobi
 
-2005-05-20 05:46  oetiker
+2004-01-19 23:41  oetiker
 
-       * doc/bin_dec_hex.pod, doc/cdeftutorial.pod, doc/rpntutorial.pod,
-         doc/rrd-beginners.pod, doc/rrdbuild.pod, doc/rrdcgi.pod,
-         doc/rrdcreate.pod, doc/rrddump.pod, doc/rrdfetch.pod,
-         doc/rrdfirst.pod, doc/rrdgraph-old.pod, doc/rrdgraph.pod,
-         doc/rrdgraph_data.pod, doc/rrdgraph_graph.pod,
-         doc/rrdgraph_rpn.pod, doc/rrdpython.pod, doc/rrdresize.pod,
-         doc/rrdthreads.pod, doc/rrdtool.pod, doc/rrdtune.pod,
-         doc/rrdtutorial.es.pod, doc/rrdtutorial.pod, doc/rrdupdate.pod,
-         doc/rrdxport.pod: remove extra whitespace at the end of lines
+       * src/VeraMono.ttf, src/compile_afm.pl: initial
 
-2005-05-20 05:43  oetiker
+2004-01-19 23:39  oetiker
 
-       * doc/rrdbuild.pod: introduce builddir
+       * config: kill
 
-2005-05-20 05:14  oetiker
+2004-01-19 23:39  oetiker
 
-       * configure.ac: iconf is not needed so to not check for it
+       * config/Makefile.am: remove
 
-2005-05-19 23:21  oetiker
+2004-01-19 23:37  oetiker
 
-       * src/Makefile.am, src/rrd_tool.c: added propper numeric version
-         number to version
+       * libraries/cgilib-0.4: kill it
 
-2005-05-19 23:21  oetiker
+2004-01-19 23:35  oetiker
 
-       * configure.ac, src/rrd_gfx.c: add multibyte to wide char conversion
-         ability. Now every string users input should should be handled
-         propperly by rrdtool, whatever your locale says will work.
+       * libraries/Makefile.am, libraries/cgilib-0.4/Makefile.am,
+         libraries/cgilib-0.4/cgi.5, libraries/cgilib-0.4/cgi.c,
+         libraries/cgilib-0.4/cgi.h, libraries/cgilib-0.4/cgiDebug.3,
+         libraries/cgilib-0.4/cgiGetValue.3,
+         libraries/cgilib-0.4/cgiHeader.3, libraries/cgilib-0.4/cgiInit.3,
+         libraries/cgilib-0.4/cgiRedirect.3,
+         libraries/cgilib-0.4/cgilib.dsp, libraries/cgilib-0.4/cgilib.dsw,
+         libraries/cgilib-0.4/cgilib.vcproj,
+         libraries/cgilib-0.4/cgitest.c, libraries/cgilib-0.4/jumpto.c,
+         libraries/cgilib-0.4/readme, libraries/freetype-2.0.5-import.txt,
+         libraries/libart_lgpl-2.3.7, libraries/libpng-1.2.0,
+         libraries/libpng-1.2.0-import.txt, libraries/zlib-1.1.4: killem
 
-2005-05-19 23:19  oetiker
+2004-01-19 23:27  oetiker
 
-       * src/rrd_create.c: windows at least stores null terminated char
-         strings in dummychar1 -- Philippe
+       * libraries/freetype-2.0.5: all must go
 
-2005-05-18 20:20  oetiker
+2004-01-19 23:17  oetiker
 
-       * bindings/tcl/Makefile.am, bindings/tcl/tclrrd.c: make tcl compile
-         again ... don't know if it will work though
+       * MakeMakefile, Makefile.am, NEWS, README, bindings/Makefile.am,
+         bindings/perl-shared/Makefile.PL, bindings/perl-shared/RRDs.xs,
+         bindings/tcl/Makefile.am, configure.ac, doc/rrdcgi.pod,
+         libraries/Makefile.am: misc fixes to get rrdtool working without
+         included libraries.
 
-2005-05-18 19:43  oetiker
+2004-01-19 23:16  oetiker
 
-       * src/rrd.h: fix rrd_version prototype
+       * src/Makefile.am, src/rrd_gfx.h: modifications for 'no more local
+         libaries'
 
-2005-05-18 19:41  oetiker
+2004-01-15 18:14  oetiker
 
-       * configure.ac, src/Makefile.am, src/rrd.h, src/rrd_gfx.c,
-         src/rrd_is_thread_safe.h, src/rrd_tool.c, src/rrd_update.c,
-         src/rrd_version.c: cleaned up version number code and added new
-         function rrd_version -- partly by Burton Strauss
+       * bindings/perl-shared/RRDs.pm, bindings/perl-shared/RRDs.xs:
+         addition of RRDs::times -- Christophe Kalt <kalt@taranis.org>
 
-2005-05-18 19:18  oetiker
+2003-12-26 16:54  oetiker
 
-       * bindings/perl-shared/Makefile.PL: help building perl on hpux
+       * src/rrd_graph.c: using --riggid it is possible to get a case where
+         minval is bigger than maxval ... this breaks the horizontal grid
+         ...
 
-2005-05-16 20:56  oetiker
+2003-11-27 06:31  oetiker
 
-       * bindings/perl-piped/RRDp.pm, bindings/perl-shared/RRDs.pm,
-         configure.ac, doc/rrdbuild.pod, rrdtool.spec, src/gdpng.c,
-         src/gifsize.c, src/pngsize.c, src/rrd.h, src/rrd_afm.c,
-         src/rrd_afm.h, src/rrd_afm_data.c, src/rrd_afm_data.h,
-         src/rrd_cgi.c, src/rrd_create.c, src/rrd_datalang.c,
-         src/rrd_diff.c, src/rrd_dump.c, src/rrd_error.c, src/rrd_fetch.c,
-         src/rrd_first.c, src/rrd_format.c, src/rrd_format.h,
-         src/rrd_gfx.c, src/rrd_gfx.h, src/rrd_graph.c,
-         src/rrd_graph_helper.c, src/rrd_hw.c, src/rrd_hw.h,
-         src/rrd_info.c, src/rrd_is_thread_safe.h, src/rrd_last.c,
-         src/rrd_not_thread_safe.c, src/rrd_open.c, src/rrd_resize.c,
-         src/rrd_restore.c, src/rrd_rpncalc.c, src/rrd_rpncalc.h,
-         src/rrd_stat.c, src/rrd_thread_safe.c, src/rrd_thread_safe_nt.c,
-         src/rrd_tool.c, src/rrd_tool.h, src/rrd_tune.c, src/rrd_update.c,
-         src/rrd_xport.c, src/rrd_xport.h: prepare for the release of
-         rrdtool-1.2.8
+       * bindings/perl-shared/RRDs.xs: Stop RRDs for segfaulting on invalid
+         graph input -- Ian Holsman <Ian.Holsman@cnet.com>
 
-2005-05-16 20:55  oetiker
+2003-11-27 06:30  oetiker
 
-       * bindings/Makefile.am, bindings/python/Makefile.am,
-         bindings/tcl/Makefile.am, configure.ac: redo --disable-* options
-         for python and tcl add some more quotes to protect potentially
-         empty variables in tests which should make configure more robust.
+       * src/rrd_cgi.c: make rrd_cgi build again ... Ian Holsman
+         <rrd.developers@holsman.net>
 
-2005-05-16 20:04  oetiker
+2003-11-23 12:55  oetiker
 
-       * bindings/Makefile.am, configure.ac: if python stuff does not work,
-         do not die, just do not compile python
+       * doc/rrdcgi.pod, src/rrd_cgi.c: New recursive parser for rrdcgi by
+         Arend-Jan Wijtzes <ajwytzes@wise-guys.nl>
 
-2005-05-16 20:02  oetiker
+2003-11-19 07:06  oetiker
 
-       * configure.ac: fix extra argument when testing for PERLCC problem
-         -- Simon Leinen
+       * src/rrd_gfx.c: Adding attributions: * xml fix was by Ian Holsman
+         <rrd.developers@holsman.net> * font rotation was by Chris
+         Turbeville <turbo@verio.net>
 
-2005-05-16 12:18  oetiker
+2003-11-19 06:58  oetiker
 
-       * bindings/perl-piped/RRDp.pm, bindings/perl-shared/RRDs.pm,
-         configure.ac, doc/rrdbuild.pod, rrdtool.spec, src/gdpng.c,
-         src/gifsize.c, src/pngsize.c, src/rrd.h, src/rrd_afm.c,
-         src/rrd_afm.h, src/rrd_afm_data.c, src/rrd_afm_data.h,
-         src/rrd_cgi.c, src/rrd_create.c, src/rrd_datalang.c,
-         src/rrd_diff.c, src/rrd_dump.c, src/rrd_error.c, src/rrd_fetch.c,
-         src/rrd_first.c, src/rrd_format.c, src/rrd_format.h,
-         src/rrd_gfx.c, src/rrd_gfx.h, src/rrd_graph.c,
-         src/rrd_graph_helper.c, src/rrd_hw.c, src/rrd_hw.h,
-         src/rrd_info.c, src/rrd_is_thread_safe.h, src/rrd_last.c,
-         src/rrd_not_thread_safe.c, src/rrd_open.c, src/rrd_resize.c,
-         src/rrd_restore.c, src/rrd_rpncalc.c, src/rrd_rpncalc.h,
-         src/rrd_stat.c, src/rrd_thread_safe.c, src/rrd_thread_safe_nt.c,
-         src/rrd_tool.c, src/rrd_tool.h, src/rrd_tune.c, src/rrd_update.c,
-         src/rrd_xport.c, src/rrd_xport.h: prepare for the release of
-         rrdtool-1.2.7
+       * src/rrd_gfx.c: fixed svg generation
 
-2005-05-16 12:14  oetiker
+2003-11-17 11:43  oetiker
 
-       * NEWS: added note about --alt-y-mrtg
+       * src/rrd_restore.c: more correct usage added -- Eldad Zack
+         <eldad@stoneshaft.ath.cx>
 
-2005-05-16 10:12  oetiker
+2003-11-14 23:10  oetiker
 
-       * src/rrd_graph.c, src/rrd_graph_helper.c: fix the color square
-         spacing so that it works regardles of the fontsize and with
-         transparend backgrounds.
+       * src/rrd_cgi.c: handle NULL pointers gracefully
 
-2005-05-16 09:01  oetiker
+2003-11-12 22:14  oetiker
 
-       * src/rrd_graph.c: added alt-y-mrtg option as a dummy so that old
-         apps who use it do not crash when doing so.
+       * bindings/perl-shared/RRDs.xs, src/rrd.h, src/rrd_cgi.c,
+         src/rrd_graph.c, src/rrd_graph.h, src/rrd_tool.c: allow to pass an
+         open filehandle into rrd_graph as an extra argument
 
-2005-05-16 06:33  oetiker
+2003-11-12 22:13  oetiker
 
-       * doc/rrdgraph.pod, src/rrd_graph.c, src/rrd_graph.h: reintroduced
-         the FRAME color ... somehow it was lost from 1.0.x
+       * src/rrd_create.c: make create much faster .. -- David M. Grimes
+         <dgrimes@navisite.com>
 
-2005-05-15 14:16  oetiker
+2003-11-11 21:19  oetiker
 
-       * src/rrd_graph.c: make transparent backgrounds work propperly
+       * doc/rrdrestore.pod, src/rrd_restore.c, src/rrd_tool.c: Allow to
+         force overwrite when restoring from xml to rrd. -- Eldad Zack
+         <eldad@stoneshaft.ath.cx>
 
-2005-05-14 21:57  oetiker
+2003-11-11 19:46  oetiker
 
-       * src/getopt.c, src/rrd_afm.c, src/rrd_cgi.c, src/rrd_graph.c,
-         src/rrd_nan_inf.c, src/rrd_restore.c, src/rrd_rpncalc.c,
-         src/rrd_tool.c, src/rrd_tool.h, src/rrd_update.c, src/rrd_xport.c:
-         it seems that _WIN32 is more commonly defined thatn WIN32 on win32
-         ... (gifford.hesketh on gmail.com)
+       * src/fnv.h, src/parsetime.c, src/rrd.h, src/rrd_cgi.c,
+         src/rrd_create.c, src/rrd_fetch.c, src/rrd_graph.c,
+         src/rrd_graph_helper.c, src/rrd_update.c, src/rrd_xport.c:
+         replaced time_value with rrd_time_value as MacOS X introduced a
+         struct of that name in their standard headers
 
-2005-05-14 17:32  oetiker
+2003-11-11 19:38  oetiker
 
-       * src/rrd_restore.c: added a note to dump old rrd files with a
-         current rrdtool dump to get the upgraded on the fly. Adding 001
-         support should not be all that tough though. Any takers ?
+       * src/rrd_update.c: rrd files should NOT change size ever ... bulk
+         update code wa buggy. -- David M. Grimes <dgrimes@navisite.com>
 
-2005-05-14 15:07  oetiker
+2003-11-04 22:20  oetiker
 
-       * src/rrd_open.c: check cookie read for success
+       * src/rrd_tool.c: 20 chars max in a ds name -- Kuba Filipowicz
+         <amo@axit.pl>
 
-2005-05-14 09:35  oetiker
+2003-10-26 19:29  oetiker
 
-       * src/rrd_graph.c: if the y value is out of bounds, make it just a
-         wee bit larger or smaller than the bound so that the code can
-         detect this by comparing it with the bound, but make it so small
-         that it is not visible.
+       * src/rrd_gfx.c, src/rrd_gfx.h, src/rrd_graph.c: added rotation ...
 
-2005-05-12 22:27  oetiker
+2003-09-04 13:16  oetiker
 
-       * acinclude.m4: one sed is quite enough
+       * src/rrd_update.c: should not assigne but compare ... grrrrr
 
-2005-05-12 22:22  oetiker
+2003-09-02 21:58  oetiker
 
-       * acinclude.m4: [ must be quoted by [ ...
+       * src/rrd_update.c: be pickier about what we accept in rrd_update.
+         Complain if things do not work out
 
-2005-05-12 22:12  oetiker
+2003-08-28 21:48  oetiker
 
-       * acinclude.m4: add global option
+       * configure.ac: make sure we get only 1 flag -- Chris Turbeville
+         <turbo@verio.net>
 
-2005-05-12 22:06  oetiker
+2003-07-28 21:59  oetiker
 
-       * acinclude.m4: fox sed line for unsetting header cache
+       * bindings/Makefile.am, libraries/freetype-2.0.5/Makefile.am,
+         src/Makefile.am: I was just taking a look at the development
+         RRDtool build (I'm looking forward to SVG support), and had a few
+         problems with an out-of-tree build. I find using a separate build
+         directory makes things much easier to manage, especially when
+         building for multiple architectures. I've attached the minor
+         patches for the progress that I made (I couldn't get the Perl
+         modules to work, but the main binaries seem okay), and would be
+         grateful if you could commit them (or something like them!). --
+         Joseph Walton <joe@kafsemo.org>
 
-2005-05-12 22:03  oetiker
+2003-07-24 14:51  jake
 
-       * acinclude.m4, configure.ac: make sure the header gets tested twice
+       * src/rrd_graph.h: Allow hyphen character in DEF_NAM_FMT to match
+         DS_NAM_FMT.
 
-2005-05-12 22:03  oetiker
+2003-07-16 23:41  jake
 
-       * doc/rrdpython.pod: add notes on python error, and install location
+       * confignt/config.h, libraries/cgilib-0.4/cgilib.vcproj,
+         libraries/freetype-2.0.5/freetype.vcproj,
+         libraries/libart_lgpl-2.3.7/libart.vcproj,
+         libraries/libpng-1.2.0/png.vcproj,
+         libraries/zlib-1.1.4/zlib.vcproj, src/rrd.vcproj,
+         src/rrd_cgi.vcproj, src/rrd_graph.c, src/rrdtool.sln,
+         src/rrdtool.vcproj: Updated MS Visual C++ files from 7.0 to 7.1.
+         Add code to rrd_graph.c: rrd_graph_init() to use %windir%
+         environment variable to find the default font at runtime.
 
-2005-05-12 11:32  oetiker
+2003-07-15 00:58  jake
 
-       * src/rrd_graph.c: allow 3/4 component color rrdtool graph --color
-         too -- Alex
+       * src/rrd_rpncalc.h: Moved OP_COUNT to the end of the enumeration.
 
-2005-05-12 11:28  oetiker
+2003-05-20 20:51  oetiker
 
-       * src/rrd_graph.c: make the areas a little bigger still for propper
-         overlapping
+       * doc/rrdcgi.pod, src/rrd_cgi.c: I've made a patch to rrdcgi to add
+         <RRD::TIME::STRFTIME ...> which allows you to re-format start and
+         end-time at-style times using strftime. This allows easy timespans
+         in the graph (e.g. -2weeks) to be formatted into more usual times.
+         -- "Erskine, Thomas" <terskine@NRCan.gc.ca>
 
-2005-05-12 11:22  oetiker
+2003-05-03 15:41  oetiker
 
-       * src/rrd_create.c: make parsing of DS arguments more robust and
-         give more sensible error messages. -- Alex
+       * src/rrd_create.c: small patch to rrd_create.c that corrects
+         problem with the version number of the newly created files. --
+         Sasha Mikheev <sasha@avalon-net.co.il>
 
-2005-05-12 08:38  oetiker
+2003-04-29 21:56  oetiker
 
-       * src/rrd_graph.c: make the areas that makeup the graphs a little
-         larger, so that they overlap a bit and do not exhibit white lines
-         when touching each other.
+       * src/rrd_open.c: readline in rrd_open.c reads the file in 8 KB
+         blocks, and calls realloc for each block. realloc is very slow in
+         Mac OS X for huge blocks, e.g. when restoring databases from huge
+         xml files. This patch finds the size of the file, and starts out
+         with malloc'ing the full size. -- Peter Speck <speck@ruc.dk>
 
-2005-05-12 05:48  oetiker
+2003-04-29 19:37  oetiker
 
-       * bindings/python/Makefile.am, bindings/python/Makefile.in,
-         bindings/python/rrdtoolmodule.c: some more warning fixes
+       * doc/rrdfetch.pod: added comment on iso
 
-2005-05-12 05:41  oetiker
+2003-04-29 19:14  jake
 
-       * bindings/python/rrd_format.h, bindings/python/rrdtoolmodule.c: add
-         unused to prevent warnings about self
+       * MakeMakefile, doc/rrdupdate.pod, src/rrd_update.c: Change updatev
+         RRA return from index_number to cf_nam, pdp_cnt. Also revert
+         accidental addition of -I to aclocal MakeMakefile.
 
-2005-05-11 18:31  oetiker
+2003-04-26 05:11  oetiker
 
-       * doc/rrdpython.pod: intial python bindings documentation
+       * src/rrd_restore.c: only restore V2 and larger.
 
-2005-05-11 12:09  oetiker
+2003-04-25 18:35  jake
 
-       * doc/rrdcreate.pod: fix wording for min/max ... they are not
-         optional
+       * MakeMakefile, bindings/perl-shared/RRDs.pm,
+         bindings/perl-shared/RRDs.xs, doc/rrdtool.pod, doc/rrdupdate.pod,
+         src/rrd.h, src/rrd_create.c, src/rrd_info.c, src/rrd_tool.c,
+         src/rrd_tool.h, src/rrd_update.c: Alternate update interface,
+         updatev. Returns info about CDPs written to disk as result of
+         update. Output format is similar to rrd_info, a hash of
+         key-values.
 
-2005-05-10 20:19  oetiker
+2003-04-23 22:47  oetiker
 
-       * bindings/python/rrdtoolmodule.c: second installment with warning
-         fixes from alan
+       * src/rrd_restore.c: fixed version checks to only complain if xml
+         version is > than current RRD version
 
-2005-05-10 18:52  oetiker
+2003-04-11 19:43  oetiker
 
-       * CONTRIBUTORS, Makefile.am, acinclude.m4, bindings/Makefile.am,
-         bindings/python, bindings/python/ACKNOWLEDGEMENT,
-         bindings/python/AUTHORS, bindings/python/COPYING,
-         bindings/python/Makefile.am, bindings/python/Makefile.in,
-         bindings/python/README, bindings/python/Setup.in,
-         bindings/python/rrd_extra.h, bindings/python/rrd_format.h,
-         bindings/python/rrdtoolmodule.c, bindings/python/setup.py,
-         configure.ac, rrdtool.spec: python bindings add -- Alan Milligan
-         alan from balclutha.org
+       * doc/rrdcreate.pod, doc/rrdgraph-old.pod, doc/rrdgraph_rpn.src,
+         src/rrd_open.c, src/rrd_restore.c, src/rrd_rpncalc.c,
+         src/rrd_rpncalc.h, src/rrd_tool.c: New special value COUNT which
+         allows calculations based on the position of a value within a data
+         set. Bug fix in rrd_rpncalc.c. PREV returned erroneus value for
+         the second value. Bug fix in rrd_restore.c. Bug causing seek error
+         when accesing an RRD restored from an xml that holds an RRD
+         version <3. -- Ruben Justo <ruben@ainek.com>
 
-2005-05-10 18:35  oetiker
+2003-04-04 20:51  oetiker
 
-       * src/rrd_gfx.c: fix for character escaping in EPS -- Peter Speck
+       * src/rrd_gfx.c: I think I found a very small bug in rrd graph PDF
+         output : the is_stream member of pdf_buffer is not initialized,
+         making bad PDF sometimes (I found a case where is_stream was != 0
+         for the font initialization). -- lhoudard@netcourrier.com
 
-2005-05-10 06:07  oetiker
+2003-04-01 22:52  jake
 
-       * bindings/perl-piped/RRDp.pm, bindings/perl-shared/RRDs.pm,
-         configure.ac, doc/rrdbuild.pod, rrdtool.spec, src/gdpng.c,
-         src/gifsize.c, src/pngsize.c, src/rrd.h, src/rrd_afm.c,
-         src/rrd_afm.h, src/rrd_afm_data.c, src/rrd_afm_data.h,
-         src/rrd_cgi.c, src/rrd_create.c, src/rrd_datalang.c,
-         src/rrd_diff.c, src/rrd_dump.c, src/rrd_error.c, src/rrd_fetch.c,
-         src/rrd_first.c, src/rrd_format.c, src/rrd_format.h,
-         src/rrd_gfx.h, src/rrd_graph.c, src/rrd_graph_helper.c,
-         src/rrd_hw.c, src/rrd_hw.h, src/rrd_info.c,
-         src/rrd_is_thread_safe.h, src/rrd_last.c,
-         src/rrd_not_thread_safe.c, src/rrd_open.c, src/rrd_resize.c,
-         src/rrd_restore.c, src/rrd_rpncalc.c, src/rrd_rpncalc.h,
-         src/rrd_stat.c, src/rrd_thread_safe.c, src/rrd_thread_safe_nt.c,
-         src/rrd_tool.c, src/rrd_tool.h, src/rrd_tune.c, src/rrd_update.c,
-         src/rrd_xport.c, src/rrd_xport.h: prepare for the release of
-         rrdtool-1.2.6
+       * THREADS, bindings/perl-shared/ntmake.pl, src/rrd.dsp, src/rrd.h,
+         src/rrd.vcproj, src/rrd_graph.c, src/rrd_nan_inf.c,
+         src/rrd_not_thread_safe.c, src/rrd_thread_safe_nt.c,
+         src/rrd_tool.h, src/rrdtool.dsp: Fix Win32 build. VC++ 6.0 and 7.0
+         now use the thread-safe code.
 
-2005-05-10 06:06  oetiker
+2003-03-31 21:22  oetiker
 
-       * src/rrd_gfx.c: I guess the pdf entities want to be escaped chars
-         not just control caracters with a prepended backslash ...
+       * src/rrd_format.h, src/rrd_open.c, src/rrd_update.c: enables
+         RRDtool updates with microsecond or in case of windows millisecond
+         precision. This is needed to reduce time measurement error when
+         archive step is small. (<30s) -- Sasha Mikheev
+         <sasha@avalon-net.co.il>
 
-2005-05-10 05:18  oetiker
+2003-03-25 22:29  oetiker
 
-       * src/rrd_afm.c: we should not use C++ comments in c files
+       * bindings/perl-shared/ntmake.pl: use the environment variable
+         VCINSTALLDIR -- Ian Holsman <rrd.developers@holsman.net>
 
-2005-05-10 04:14  oetiker
+2003-03-24 22:08  oetiker
 
-       * src/Makefile.am: we should distribute unused.h if we use it :-)
+       * src/rrd_thread_safe.c: strerror should not turn us recursive here
+         ... -- Peter Stamfest <peter@stamfest.at>
 
-2005-05-09 20:15  oetiker
+2003-03-24 22:05  oetiker
 
-       * bindings/perl-piped/RRDp.pm, bindings/perl-shared/RRDs.pm,
-         configure.ac, doc/rrdbuild.pod, rrdtool.spec, src/Makefile.am,
-         src/gdpng.c, src/gifsize.c, src/pngsize.c, src/rrd.h,
-         src/rrd_afm.c, src/rrd_afm.h, src/rrd_afm_data.c,
-         src/rrd_afm_data.h, src/rrd_cgi.c, src/rrd_create.c,
-         src/rrd_datalang.c, src/rrd_diff.c, src/rrd_dump.c,
-         src/rrd_error.c, src/rrd_fetch.c, src/rrd_first.c,
-         src/rrd_format.c, src/rrd_format.h, src/rrd_gfx.c, src/rrd_gfx.h,
-         src/rrd_graph.c, src/rrd_graph_helper.c, src/rrd_hw.c,
-         src/rrd_hw.h, src/rrd_info.c, src/rrd_is_thread_safe.h,
-         src/rrd_last.c, src/rrd_not_thread_safe.c, src/rrd_open.c,
-         src/rrd_resize.c, src/rrd_restore.c, src/rrd_rpncalc.c,
-         src/rrd_rpncalc.h, src/rrd_stat.c, src/rrd_thread_safe.c,
-         src/rrd_thread_safe_nt.c, src/rrd_tool.c, src/rrd_tool.h,
-         src/rrd_tune.c, src/rrd_update.c, src/rrd_xport.c,
-         src/rrd_xport.h: prepare for the release of rrdtool-1.2.5
+       * src/rrd_not_thread_safe.c: strerror must not become recursive --
+         Peter Stamfest <peter@stamfest.at>
 
-2005-05-09 20:13  oetiker
+2003-03-12 20:39  oetiker
 
-       * src/art_rgba_svp.c, src/rrd_afm.c, src/rrd_gfx.c,
-         src/rrd_update.c, src/rrd_xport.c, src/unused.h: silence warnings
-         for UNUSED variables without changeing the funtion interfaces --
-         Alex
+       * doc/rrdresize.pod: remove ^M
 
-2005-05-09 19:32  oetiker
+2003-03-10 00:30  oetiker
 
-       * src/rrd_graph.c: allow decimal positions y axis labels as soon as
-         the max entry is < 10
+       * src/rrd_diff.c: handle cases with two negative numbers -- Sasha
+         Mikheev <sasha@avalon-net.co.il>
 
-2005-05-09 19:11  oetiker
+2003-03-08 18:44  oetiker
 
-       * src/rrd_graph.c, src/rrd_graph_helper.c: fix rendering of the
-         color spots especially when proportional fonts are in use.
+       * src/rrd_graph.c: don't display legends for [HV]RULEs out of graph
+         bounds (rrdgraph) -- Christophe Kalt <kalt@taranis.org>
 
-2005-05-09 14:01  oetiker
+2003-03-01 22:25  oetiker
 
-       * src/rrd_afm.c, src/rrd_afm.h, src/rrd_gfx.c: EPS/SVG/PDF code ...
-         more comments and better font finder including removal of
-         hardcoded SVG font. -- Peter Speck speck from vitality.dk
+       * src/rrd_tool.c: realy suppress size output when talking to stdout.
+         Patch from Mat Zimmerman @ debian
 
-2005-05-09 13:22  oetiker
+2003-02-24 18:26  oetiker
 
-       * src/rrd_afm.c, src/rrd_gfx.c: * switch to courier if the font is
-         unknown * fix font positioning
+       * examples/piped-demo.pl.in: fix for : in piped demo
 
-2005-05-09 05:39  oetiker
+2003-02-22 21:57  oetiker
 
-       * bindings/perl-shared/Makefile.PL: perls $^O is set to linux not
-         Linux
+       * doc/rrdthreads.pod: Initial checkin -- Peter Stamfest
+         <peter@stamfest.at>
 
-2005-05-08 22:02  oetiker
+2003-02-22 21:57  oetiker
 
-       * src/rrd_gfx.c: svg/pdf/eps rendering improvements. There are still
-         issues though ... -- peter speck
+       * doc/Makefile.am, src/Makefile.am, src/rrd_error.c: a patch to
+         avoid a memory leak and a Makefile.am patch to distribute all
+         required source files -- Peter Stamfest <peter@stamfest.at>
 
-2005-05-08 21:25  oetiker
+2003-02-21 22:40  oetiker
 
-       * libraries/afm/compile_afm.pl, src/rrd_afm.c, src/rrd_afm.h,
-         src/rrd_afm_data.c, src/rrd_afm_data.h: added support for getting
-         ascent/descent size info for ps fonts -- Peter Speck
+       * examples/piped-demo.pl.in: colons must be escaped
 
-2005-05-08 20:15  oetiker
+2003-02-20 21:48  oetiker
 
-       * src/art_rgb_affine_private.h, src/art_rgba_rgba_affine.c,
-         src/art_rgba_rgba_affine.h: we do not actually need these files
-         ... goodbye
+       * libraries/libpng-1.2.0/Makefile.am, src/Makefile.am: make the
+         threading work and compile, fix linking to libpng and update the
+         timestaps int the files
 
-2005-05-08 16:59  oetiker
+2003-02-20 21:27  oetiker
 
-       * bindings/perl-piped/RRDp.pm, bindings/perl-shared/RRDs.pm,
-         configure.ac, doc/rrdbuild.pod, rrdtool.spec, src/Makefile.am,
-         src/gdpng.c, src/gifsize.c, src/pngsize.c, src/rrd.h,
-         src/rrd_afm.c, src/rrd_afm.h, src/rrd_afm_data.c,
-         src/rrd_afm_data.h, src/rrd_cgi.c, src/rrd_create.c,
-         src/rrd_datalang.c, src/rrd_diff.c, src/rrd_dump.c,
-         src/rrd_error.c, src/rrd_fetch.c, src/rrd_first.c,
-         src/rrd_format.c, src/rrd_format.h, src/rrd_gfx.c, src/rrd_gfx.h,
-         src/rrd_graph.c, src/rrd_graph_helper.c, src/rrd_hw.c,
-         src/rrd_hw.h, src/rrd_info.c, src/rrd_is_thread_safe.h,
-         src/rrd_last.c, src/rrd_not_thread_safe.c, src/rrd_open.c,
-         src/rrd_resize.c, src/rrd_restore.c, src/rrd_rpncalc.c,
-         src/rrd_rpncalc.h, src/rrd_stat.c, src/rrd_thread_safe.c,
-         src/rrd_thread_safe_nt.c, src/rrd_tool.c, src/rrd_tool.h,
-         src/rrd_tune.c, src/rrd_update.c, src/rrd_xport.c,
-         src/rrd_xport.h: prepare for the release of rrdtool-1.2.4
+       * src/Makefile.am, src/rrd_thread_safe.c, src/rrd_tool.c: updated
+         copyrigh dates removed error.h from threaded variant added
+         compiletime to rrdtool
 
-2005-05-08 16:22  oetiker
+2003-02-16 12:32  oetiker
 
-       * src/rrd_graph.c: * adjust spacing at the left border of the graph.
-         use less white space * increasse minimal grid spacing and label
-         spacing
+       * src/rrd_restore.c: if output is - there is not need to deref the
+         handler
 
-2005-05-08 16:02  oetiker
+2003-02-16 12:31  oetiker
 
-       * src/rrd_graph.c: increase minimal vertical spacing for y-axis
-         lables
+       * src/parsetime.c: expect seems to exist on some systems in the
+         system inc files
 
-2005-05-08 16:01  oetiker
+2003-02-13 07:05  oetiker
 
-       * src/rrd_graph.c: shorten space for y-axis labels a bit
+       * Makefile.am, THREADS, configure.ac, src/Makefile.am,
+         src/parsetime.c, src/rrd.h, src/rrd_cgi.c, src/rrd_create.c,
+         src/rrd_dump.c, src/rrd_error.c, src/rrd_format.c,
+         src/rrd_graph.c, src/rrd_graph_helper.c, src/rrd_info.c,
+         src/rrd_is_thread_safe.h, src/rrd_last.c,
+         src/rrd_not_thread_safe.c, src/rrd_open.c, src/rrd_restore.c,
+         src/rrd_rpncalc.c, src/rrd_stat.c, src/rrd_thread_safe.c,
+         src/rrd_tool.c, src/rrd_tool.h, src/rrd_update.c: Find attached
+         the patch I promised to send to you. Please note that there are
+         three new source files (src/rrd_is_thread_safe.h,
+         src/rrd_thread_safe.c and src/rrd_not_thread_safe.c) and the
+         introduction of librrd_th. This library is identical to librrd,
+         but it contains support code for per-thread global variables
+         currently used for error information only. This is similar to how
+         errno per-thread variables are implemented. librrd_th must be
+         linked alongside of libpthred There is also a new file "THREADS",
+         holding some documentation. -- Peter Stamfest <peter@stamfest.at>
 
-2005-05-08 15:40  oetiker
+2003-02-12 07:06  oetiker
 
-       * src/rrd_tool.c: remove the premature fox for the unused parameter
-         in xport
+       * CONTRIBUTORS, bindings/Makefile.am, bindings/perl-shared/MANIFEST,
+         libraries/Makefile.am, src/Makefile.am: improved dist target --
+         Peter Stamfest <peter@stamfest.at>
 
-2005-05-08 15:30  oetiker
+2003-02-11 10:16  oetiker
 
-       * README: sync with reality
+       * doc/rrdgraph_graph.src: removed lg we do not allow this in the
+         code at th moment
 
-2005-05-08 15:19  oetiker
+2003-02-05 18:16  oetiker
 
-       * src/rrd_tool.c: be more portable with shorter strings
+       * src/rrd_resize.c: rrd resize SHRINK was broken :-) -- Scott Mace
+         <smace@intt.ORG>
 
-2005-05-08 15:18  oetiker
+2003-01-31 06:46  oetiker
 
-       * src/Makefile.am: we do not use the affine functions
+       * src/rrd_graph.c: The NaN check should only use lastgdes when
+         following a STACK -- Scott Mace <smace@intt.ORG>
 
-2005-05-08 15:07  oetiker
+2003-01-30 21:39  oetiker
 
-       * configure.ac, src/rrd_graph_helper.c: removed extra $ from from
-         PERLCC test
+       * src/rrd_graph.c: fix stak+nan error ... Scott Mace
+         <smace@intt.ORG>
 
-2005-05-08 08:20  oetiker
+2003-01-29 07:17  oetiker
 
-       * doc/rrdbuild.pod: fix rendering errors by removing single spaces
+       * src/rrd_graph.c: fixed the processing of
+         TICK:vname#color:frac:legend -- Scott Mace <smace@intt.ORG>
 
-2005-05-07 23:54  oetiker
+2003-01-25 22:50  oetiker
 
-       * bindings/perl-piped/RRDp.pm, bindings/perl-shared/RRDs.pm,
-         configure.ac, doc/rrdbuild.pod, rrdtool.spec, src/gdpng.c,
-         src/gifsize.c, src/pngsize.c, src/rrd.h, src/rrd_afm.c,
-         src/rrd_afm.h, src/rrd_afm_data.c, src/rrd_afm_data.h,
-         src/rrd_cgi.c, src/rrd_create.c, src/rrd_datalang.c,
-         src/rrd_diff.c, src/rrd_dump.c, src/rrd_error.c, src/rrd_fetch.c,
-         src/rrd_first.c, src/rrd_format.c, src/rrd_format.h,
-         src/rrd_gfx.c, src/rrd_gfx.h, src/rrd_graph.c,
-         src/rrd_graph_helper.c, src/rrd_hw.c, src/rrd_hw.h,
-         src/rrd_info.c, src/rrd_is_thread_safe.h, src/rrd_last.c,
-         src/rrd_not_thread_safe.c, src/rrd_open.c, src/rrd_resize.c,
-         src/rrd_restore.c, src/rrd_rpncalc.c, src/rrd_rpncalc.h,
-         src/rrd_stat.c, src/rrd_thread_safe.c, src/rrd_thread_safe_nt.c,
-         src/rrd_tool.c, src/rrd_tool.h, src/rrd_tune.c, src/rrd_update.c,
-         src/rrd_xport.c, src/rrd_xport.h: prepare for the release of
-         rrdtool-1.2.3
+       * CONTRIBUTORS, examples/4charts.pl.in, src/rrd_graph.c,
+         src/rrd_graph.h: added function (--no-minor) to turn off minor
+         gridlines on graphs -- Travis Brown <tebrown@csh.rit.edu>
 
-2005-05-07 23:26  oetiker
+2003-01-16 23:27  oetiker
 
-       * src/art_rgba_rgba_affine.c, src/art_rgba_rgba_affine.h: fix some
-         more y0, y1 complaints
+       * src/rrd_fetch.c: fix border condition in rra selection of
+         rrd_fetch -- Stanislav Sinyagin <ssinyagin@yahoo.com>
 
-2005-05-07 23:26  oetiker
+2003-01-15 19:24  oetiker
 
-       * src/rrd_graph_helper.c: When encountering an empty legend, do NOT
-         make space for drawing the color spats in front of it.
+       * doc/rrdcreate.pod, doc/rrdgraph-old.pod, doc/rrdgraph.src,
+         doc/rrdgraph_graph.src, src/rrd_graph.c: * single letter variants
+         for all graph options -- James Overbeck <grendel@gmo.jp>
 
-2005-05-07 15:57  oetiker
+2002-12-14 22:30  oetiker
 
-       * bindings/perl-piped/RRDp.pm, bindings/perl-shared/RRDs.pm,
-         configure.ac, doc/rrdbuild.pod, rrdtool.spec, src/gdpng.c,
-         src/gifsize.c, src/pngsize.c, src/rrd.h, src/rrd_afm.c,
-         src/rrd_afm.h, src/rrd_afm_data.c, src/rrd_afm_data.h,
-         src/rrd_cgi.c, src/rrd_create.c, src/rrd_datalang.c,
-         src/rrd_diff.c, src/rrd_dump.c, src/rrd_error.c, src/rrd_fetch.c,
-         src/rrd_first.c, src/rrd_format.c, src/rrd_format.h,
-         src/rrd_gfx.c, src/rrd_gfx.h, src/rrd_graph.c,
-         src/rrd_graph_helper.c, src/rrd_hw.c, src/rrd_hw.h,
-         src/rrd_info.c, src/rrd_is_thread_safe.h, src/rrd_last.c,
-         src/rrd_not_thread_safe.c, src/rrd_open.c, src/rrd_resize.c,
-         src/rrd_restore.c, src/rrd_rpncalc.c, src/rrd_rpncalc.h,
-         src/rrd_stat.c, src/rrd_thread_safe.c, src/rrd_thread_safe_nt.c,
-         src/rrd_tool.c, src/rrd_tool.h, src/rrd_tune.c, src/rrd_update.c,
-         src/rrd_xport.c, src/rrd_xport.h: prep for 1.2.2 release
+       * configure.ac: fix rrdtool compile on solaris where CC for perl is
+         "gcc -B/usr/ccs/bin/" -- Russell Van Tassell
+         <russell@loosenut.com>
 
-2005-05-07 15:51  oetiker
+2002-11-29 11:57  oetiker
 
-       * src/Makefile.am: increment library revision
+       * doc/rrdtool.pod: note on info added
 
-2005-05-07 15:45  oetiker
+2002-11-19 22:33  oetiker
 
-       * src/art_rgba_svp.c, src/rrd_gfx.c, src/rrd_gfx.h: fix these
-         annoying y0 warnings.
+       * doc/rrdgraph-old.pod, doc/rrdgraph_graph.src, src/rrd_graph.c:
+         added g as valid string format value
 
-2005-05-07 15:45  oetiker
+2002-11-18 23:37  oetiker
 
-       * src/rrd_graph.c: add rrdtool attribution string back using a
-         transparent version of the font color
+       * configure.ac: check for -OPT:IEEE_NaN_inf=ON on SGI C compiler --
+         Albert Chin-A-Young <china@thewrittenword.com>
 
-2005-05-07 15:23  oetiker
+2002-11-03 15:07  oetiker
 
-       * doc/Makefile.am, doc/rrdbuild.pod, doc/rrdgraph_graph.pod: added
-         build instructions
+       * MakeMakefile: fixed
 
-2005-05-07 10:38  oetiker
+2002-10-24 21:17  oetiker
 
-       * src/rrd_gfx.c: fix for rotation code in pdf,eps,svg formats --
-         Peter Speck <speck from vitality.dk>
+       * src/rrd_cgi.c: added patch for apache 2 compatibility
 
-2005-05-07 10:34  oetiker
+2002-10-07 06:22  oetiker
 
-       * src/rrd_graph.c, src/rrd_rpncalc.c: fix handling of PREV(x)
-         command
+       * MakeMakefile: keep up with the jhonses
 
-2005-05-06 23:00  oetiker
+2002-10-07 06:21  oetiker
 
-       * src/rrd_graph.c: * added RRDTOOL/TOBI OETIKER back in * in riggid
-         mode, cut data and 'min' and 'max' not two above * gibt ytop0 a
-         default value
+       * src/rrd_graph.c: -z does not take an option -- Tomoyuki Murakami
+         <tomoyuki@pobox.com>
 
-2005-05-06 22:59  oetiker
+2002-09-02 18:41  oetiker
 
-       * src/rrd_tool.c: fixed documentation strings for rrdgraph
+       * src/rrd_graph.c: fixed leak in VDEF_PERCENT handlin -- Perry Stoll
+         <perry_stoll@yahoo.com>
 
-2005-05-06 22:03  oetiker
+2002-08-01 05:42  oetiker
 
-       * doc/rrdgraph.pod: added doc for new slope-mode
+       * src/rrd_graph.c: fix for segfault condition in print_calc -- Paul
+         Clifford <paul.clifford@bbc.co.uk>
 
-2005-05-06 21:52  oetiker
+2002-07-31 05:42  oetiker
 
-       * src/rrd_gfx.c, src/rrd_graph.c, src/rrd_graph.h: since the drawing
-         code is now much simpler we do not need to perturbe the points or
-         rewind the graph anymore this saves quite some time ...
+       * doc/rrdfetch.pod: improved fetch explanation --
+         Nenad.Antic@era.ericsson.se
 
-2005-05-06 15:44  oetiker
+2002-07-13 18:35  oetiker
 
-       * src/rrd_graph_helper.c: * allow for 3(4) letter color names *
-         better debugging code * fix tick, line, stack parsing -- Alex van
-         den Bogaerdt <alex with ergens.op.het.net>
+       * src/rrd_graph.h, src/rrd_rpncalc.c, src/rrd_rpncalc.h: fixed
+         DEF_NAM_FMT definition added double include protection the
+         rrd_graph.h and rrd_rpncalc.h
 
-2005-05-06 15:24  oetiker
+2002-07-12 11:20  oetiker
 
-       * src/rrd_graph.c: if stacking on nothing we should not try to
-         figure out WHAT we stacked on since this will result in a segfault
-         ... -- Alex van den Bogaerdt <alex at ergens.op.het.net>
+       * src/rrd_rpncalc.c: fixed PREV parsing ... Gonzalo Augusto Arana
+         Tagle <garana@uolsinectis.com.ar>
 
-2005-05-05 22:15  oetiker
+2002-07-06 15:45  oetiker
 
-       * doc/rrdgraph_graph.pod: clarify LINE/AREA syntax -- Alex van den
-         Bogaerdt alex with ergens.op.het.net
+       * src/rrd_rpncalc.h: new operators must be added at the END of the
+         sequence ...
 
-2005-05-05 09:07  oetiker
+2002-07-05 18:57  oetiker
 
-       * src/rrd_create.c: better not to write into argv elements ...
-         Henrik Stoerner <henrik from hswn.dk>
+       * doc/cdeftutorial.pod, doc/rrdgraph_rpn.src, src/rrd_graph.c,
+         src/rrd_rpncalc.c, src/rrd_rpncalc.h: new operand on rrdgraph
+         CDEFs: PREV(xxxx) -- Gonzalo Augusto Arana Tagle
+         <garana@uolsinectis.com.ar>
 
-2005-05-03 20:23  oetiker
+2002-07-05 18:47  oetiker
 
-       * src/rrd_tool.c: do not die upon wront input when in remote mode
+       * bindings/perl-shared/RRDs.pm: explain tzset
 
-2005-05-03 18:10  oetiker
+2002-07-02 10:35  oetiker
 
-       * doc/Makefile.am: install documentation into
-         $PREFIX/shared/doc/rrdtool-$VERSION/{txt,html} but drop the
-         rrdtool-$VERSION/ bit if $PREFIX matches on rrd assuming that the
-         tool is being installed into a custom directory anyway.
+       * src/rrd_nan_inf.c: fixed DINF for win32
 
-2005-05-03 17:24  oetiker
+2002-06-29 15:33  alex
 
-       * doc/rrdgraph.pod, src/rrd_gfx.c, src/rrd_gfx.h, src/rrd_graph.c:
-         new options to tune how fontsmoothing works: -R/--font-render-mode
-         {normal,light,mono} and -B/--font-smoothing-threshold size -- John
-         yffffffff4271ef37 at f4n.org
+       * doc/rrdgraph.src, doc/rrdgraph_data.src, doc/rrdgraph_graph.src:
+         Changed DEF:...
 
-2005-05-03 17:22  oetiker
+2002-06-29 15:24  alex
 
-       * NT-BUILD-TIPS.txt: note about win32comp
+       * src/rrd_graph.c, src/rrd_graph.h, src/rrd_graph_helper.c: Changed
+         parsing again. Added a DEBUG prefix to all grapher commands
 
-2005-05-02 20:27  oetiker
+2002-06-29 14:55  alex
 
-       * confignt/config.h, src/win32comp.c: files that help getting that
-         native windows port going -- Philippe.Simonet with swisscom.com
+       * src/rrd_graph_helper.h: Not needed anymore
 
-2005-05-02 19:47  oetiker
+2002-06-27 19:34  alex
 
-       * src/rrd_gfx.c: when walking the bytes use the pitch not the width
+       * src/rrd_graph.c, src/rrd_graph.h: DEF now takes "--start" and
+         "--end" LINEx, AREA and such now take parameter "STACK"
 
-2005-05-02 19:33  oetiker
+2002-06-23 23:13  alex
 
-       * src/strftime.c: pow is alreay used as a function ... so lets call
-         it power instead
+       * doc/rrdgraph_data.src, doc/rrdgraph_examples.src: Updated docs for
+         the "DEF ... :step=nnnn" case
 
-2005-05-02 19:32  oetiker
+2002-06-23 22:29  alex
 
-       * src/rrd_graph_helper.c: no infinite line width please
+       * src/Makefile.am, src/rrd_fetch.c, src/rrd_graph.c,
+         src/rrd_resize.c: Added "step=1800" and such to "DEF" Cleaned some
+         of the signed vs. unsigned problems
 
-2005-05-01 22:07  oetiker
+2002-06-23 22:28  alex
 
-       * bindings/perl-piped/RRDp.pm, bindings/perl-shared/RRDs.pm,
-         configure.ac, rrdtool.spec, src/gdpng.c, src/gifsize.c,
-         src/pngsize.c, src/rrd.h, src/rrd_afm.c, src/rrd_afm.h,
-         src/rrd_afm_data.c, src/rrd_afm_data.h, src/rrd_cgi.c,
-         src/rrd_create.c, src/rrd_datalang.c, src/rrd_diff.c,
-         src/rrd_dump.c, src/rrd_error.c, src/rrd_fetch.c, src/rrd_first.c,
-         src/rrd_format.c, src/rrd_format.h, src/rrd_gfx.c, src/rrd_gfx.h,
-         src/rrd_graph.c, src/rrd_graph_helper.c, src/rrd_hw.c,
-         src/rrd_hw.h, src/rrd_info.c, src/rrd_is_thread_safe.h,
-         src/rrd_last.c, src/rrd_not_thread_safe.c, src/rrd_open.c,
-         src/rrd_resize.c, src/rrd_restore.c, src/rrd_rpncalc.c,
-         src/rrd_rpncalc.h, src/rrd_stat.c, src/rrd_thread_safe.c,
-         src/rrd_thread_safe_nt.c, src/rrd_tool.c, src/rrd_tool.h,
-         src/rrd_tune.c, src/rrd_update.c, src/rrd_xport.c,
-         src/rrd_xport.h: prep for 1.2.1 release
+       * src/rrd_format.h, src/rrd_nan_inf.c, src/rrd_nan_inf.h: In stead
+         of a zillion warnings, only one place gives a warning for DNAN
 
-2005-05-01 22:04  oetiker
+2002-06-20 00:21  jake
 
-       * src/rrd_graph.c: add some more vertical space above the graph if
-         no title is available
+       * NT-BUILD-TIPS.txt, bindings/perl-shared/RRDs.xs,
+         bindings/perl-shared/ntmake.pl, confignt/config.h,
+         libraries/freetype-2.0.5/freetype.dsp,
+         libraries/libart_lgpl-2.3.7/libart.dsp,
+         libraries/libpng-1.2.0/png.dsp, libraries/zlib-1.1.4/zlib.dsp,
+         src/rrd.dsp, src/rrd_open.c, src/rrd_tool.h, src/rrdtool.dsp,
+         src/rrdtool.ncb: More Win32 build changes; thanks to Kerry
+         Calvert.
 
-2005-05-01 21:24  oetiker
+2002-06-14 12:15  oetiker
 
-       * src/rrd_gfx.c: use the pen to determine string length, do not look
-         at the realy length, or space will get ignored.
+       * doc/rrdresize.pod: better explanations -- "Shipway, Steve"
+         <steve.shipway@eds.com>
 
-2005-05-01 21:16  oetiker
+2002-05-22 15:25  jake
 
-       * src/DejaVuSansMono-Roman.ttf, src/Makefile.am, src/rrd_graph.c:
-         DejaVuSansMono-Roman is a variant of VeraMono with lots of added
-         unicode glyphes ... check out http://dejavu.sourceforge.net
+       * doc/rrdtune.pod: Changed intercept to slope for beta parameter in
+         rrdtune doc.
 
-2005-05-01 20:49  oetiker
+2002-05-22 05:35  oetiker
 
-       * src/rrd_graph.c: fix spaceing ... more space for the title and
-         more space the the left of the yaxis lable
+       * bindings/perl-shared/ntmake.pl,
+         libraries/cgilib-0.4/cgilib.vcproj,
+         libraries/freetype-2.0.5/freetype.vcproj,
+         libraries/libart_lgpl-2.3.7/libart.vcproj,
+         libraries/libpng-1.2.0/png.vcproj,
+         libraries/zlib-1.1.4/zlib.vcproj, src/rrd.vcproj,
+         src/rrd_cgi.vcproj, src/rrdtool.ncb, src/rrdtool.sln,
+         src/rrdtool.suo, src/rrdtool.vcproj: VC++ .NET (7.0) project files
+         -- Eric Chamberlain <echamber@socrates.Berkeley.EDU>
 
-2005-05-01 13:19  oetiker
+2002-05-16 19:18  oetiker
 
-       * src/rrd_gfx.c: the multibyte support tried did not work ...
-         takeing it out again
+       * configure.ac: added -W ... lets have some more warnings ... with
+         gcc 3.1 985
 
-2005-05-01 13:18  oetiker
+2002-05-15 06:14  oetiker
 
-       * configure.ac: update tested library version
+       * libraries/afm/compile_afm.pl, src/rrd_afm_data.c: afm fixes --
+         Peter Speck <speck@ruc.dk>
 
-2005-05-01 11:02  oetiker
+2002-05-14 21:52  jake
 
-       * src/pngsize.c: undef jmpbuf to make compile work on AIX 5.1
+       * NT-BUILD-TIPS.txt, confignt/config.h,
+         libraries/libart_lgpl-2.3.7/libart.dsp, src/rrd.dsp,
+         src/rrd_tool.c, src/rrdtool.dsp: Fix Win32 Build compatibility.
 
-2005-05-01 11:00  oetiker
+2002-05-14 21:48  oetiker
 
-       * src/Makefile.am: increasse revision of shared library number since
-         the library source code has changed
+       * src/rrd_restore.c: double free fixed
 
-2005-05-01 11:00  oetiker
+2002-05-14 05:28  oetiker
 
-       * src/rrd_gfx.c: add wide character support
+       * configure.ac, src/rrd_tool.c: make opendir readdir chdir chroot
+         and thus the serverfunctionality a conditional compile depending
+         on the presence of the necessary function calls.
 
-2005-05-01 10:42  oetiker
+2002-05-11 09:09  oetiker
 
-       * src/rrd_graph.c: do not make the graph wider if the title does not
-         fit ... this is wagging the dog the graph is not ABOUT the title
+       * configure.ac, src/rrd_tool.c, src/rrd_tool.h: make dirent
+         sys/types and sys/stat autoconfable ....
 
-2005-05-01 10:37  oetiker
+2002-05-08 20:34  oetiker
 
-       * doc/rrdgraph_graph.pod: fix description of VRULE
+       * doc/rrdtool.pod, src/rrd_tool.c, src/rrd_tool.h: Add funtionality
+         to rrdtool to run it as a 'server' -- Hartmut.Vogler@epost.de
 
-2005-05-01 10:23  oetiker
+2002-05-07 21:58  oetiker
 
-       * bindings/perl-shared/RRDs.xs, src/rrd_cgi.c, src/rrd_create.c,
-         src/rrd_fetch.c, src/rrd_first.c, src/rrd_graph.c,
-         src/rrd_restore.c, src/rrd_tool.c, src/rrd_tune.c,
-         src/rrd_update.c, src/rrd_xport.c: reset optind opterr inside the
-         function calls ...
+       * CONTRIBUTORS, bindings/perl-shared/RRDs.xs, doc/Makefile.am,
+         doc/rrdtool.pod, doc/rrdxport.pod, examples/shared-demo.pl.in,
+         src/Makefile.am, src/rrd.h, src/rrd_graph.c, src/rrd_graph.h,
+         src/rrd_tool.c, src/rrd_xport.c, src/rrd_xport.h: new command
+         rrdtool xport integrated -- Wolfgang Schrimm
+         <Wolfgang.Schrimm@urz.uni-heidelberg.de>
 
-2005-05-01 10:22  oetiker
+2002-05-02 13:23  oetiker
 
-       * doc/rrdgraph_graph.pod: fixed documentation regarding floating
-         point line width
+       * doc/rrdcreate.pod: typo fixed
 
-2005-05-01 10:20  oetiker
+2002-04-29 17:11  oetiker
 
-       * src/rrd_graph_helper.c: relax parsing of LINE commands LINE: is
-         valid as well as LINE<double>: eg. LINE1.2323:
+       * src/rrd_graph.c: badformat parser fixed ... for good this time I
+         hope
 
-2005-05-01 09:16  oetiker
+2002-04-28 19:13  oetiker
 
-       * src/rrd_gfx.c: allow for characters over 127
+       * src/rrd_graph.c: inserted PRINT checker at the wrong point ...
 
-2005-04-30 09:56  oetiker
+2002-04-28 14:14  oetiker
 
-       * doc/rrdgraph_graph.pod: added notes on escaping colons in COMMENT
-         and put deprecated forms of command to the back and not to the
-         front
+       * src/rrd_graph.c: It's nice and simple, the error checker for the
+         PRINT stuff which is passed to printf() is not allowing certain
+         valid printf() style operations which make text alignment much
+         more fun. -- Richard A Steenbergen <ras@e-gerbil.net>
 
-2005-04-30 09:51  oetiker
+2002-04-24 21:04  oetiker
 
-       * src/rrd_open.c, src/rrd_update.c: always open with rb/wb when it
-         is a binary file ... unix and windows will work alike with this
-         ...
+       * examples/cgi-demo.cgi, libraries/libart_lgpl-2.3.7/art_config.h,
+         src/rrd_graph.c: fixed setlocale issues
 
-2005-04-30 09:48  oetiker
+2002-04-24 20:54  oetiker
 
-       * src/rrdupdate.c: this file is not required ...
+       * configure.ac, doc/rrdgraph.src: fixed adress for wishlist
 
-2005-04-30 09:41  oetiker
+2002-04-24 20:49  oetiker
 
-       * src/rrd_open.c: even better lets have rb for CYGWIN too ... one
-         never knows it is windows after all.
+       * src/rrd_gfx.c, src/rrd_gfx.h, src/rrd_graph.c: Patch for
+         supporting PDF as output format
 
-2005-04-30 09:40  oetiker
+2002-04-24 20:49  oetiker
 
-       * src/rrd_open.c: oops inverted code here ... windows needs rb unix
-         not
+       * src/rrd_graph.c, src/rrd_graph.h: Modification of rrd_graph.c/h so
+         it uses dashes for gridlines much like rrdtool 1.0 Avoids drawing
+         minor vertical gridlines where a major gridline is to avoid
+         artifacts from having the grey line beneath the red one. Patches
+         src/rrd_graph.c and src/rrd_graph.h -- Peter Speck <speck@ruc.dk
 
-2005-04-30 09:38  oetiker
+2002-04-24 20:48  oetiker
 
-       * confignt/config.h, src/rrd_graph.c: let rrd_graph honor the font
-         name (RRD_DEFAULT_FONT) defined in confignt/config.h
+       * src/rrd_gfx.c: Improvement of svg/eps dash code so it adjusts
+         dash-lengths for round caps. -- Peter Speck <speck@ruc.dk>
 
-2005-04-26 22:08  oetiker
+2002-04-24 20:43  oetiker
 
-       * doc/rrdtool.pod: use pod syntax not html syntax in pod :-)
+       * src/rrd_graph.c: fixed setlocale issues
 
-2005-04-26 22:04  oetiker
+2002-04-16 05:00  oetiker
 
-       * doc/cdeftutorial.pod, doc/rrd-beginners.pod, doc/rrdcreate.pod,
-         doc/rrdgraph.pod: more fixes by fritz
+       * doc/rrdgraph.src: doc for gridfit by peter
 
-2005-04-26 05:33  oetiker
+2002-04-15 21:29  oetiker
 
-       * CONTRIBUTORS: obfuscate email addresses
+       * src/rrd_gfx.c, src/rrd_graph.c, src/rrd_graph.h: Evenly-spaced
+         y-axis gridlines. I had to split horizontal_grid() into
+         calc_horizontal_grid and draw_horizontal_grid as the calculated
+         info is needed in the adjustment code. My previous patch had the
+         problem that it adjusted the y-axis too late, e.g. after the data
+         lines was drawn. The result of the calc is stored in struct
+         ygrid_scale_t which image_desc_t has as a member. --no-gridfit is
+         implemented. The round-to-integer coordinates for png is moved to
+         the libart code in rrd_gfx. The 'close path' code is cleaned up so
+         the node list is left unchanged if you want to save the same graph
+         in multiple formats in one run. The rounding is done on the scaled
+         coordinates (zoom). I have made a simple version for logarithmic y
+         scales as such a scale might have 5 gridlines with 4 difference
+         spacings. This version only uses y = 10^x values for modifying the
+         scale. -- Peter Speck <speck@ruc.dk>
 
-2005-04-26 05:30  oetiker
+2002-04-09 21:35  oetiker
 
-       * doc/rrdtool.pod: * remove jakes old address * add security warning
+       * doc/rrdcgi.pod: remove boguos description of goodfor and refresh
 
-2005-04-25 22:55  oetiker
+2002-04-09 21:34  oetiker
 
-       * doc/rpntutorial.pod: remove pdf link
+       * bindings/perl-shared/RRDs.xs: removed tzset as it is in rrd_graph
+         now
 
-2005-04-25 22:18  oetiker
+2002-04-09 21:34  oetiker
 
-       * src/parsetime.c: use time_t to improve portability to 64bit
-         systems -- John R Mocho <jmocho in royaldc.com>
+       * configure.ac, src/rrd_graph.c: added tzset and setlocale to
+         rrd_graph
 
-2005-04-25 21:01  oetiker
+2002-04-07 22:07  oetiker
 
-       * NEWS: added new state
+       * src/rrd_afm.c, src/rrd_afm.h, src/rrd_afm_data.c,
+         src/rrd_afm_data.h: added missing files from peters patch
 
-2005-04-25 20:45  oetiker
+2002-04-07 20:20  oetiker
 
-       * bindings/perl-piped/RRDp.pm, bindings/perl-shared/RRDs.pm,
-         configure.ac, doc/rrdgraph_graph.pod, rrdtool.spec, src/gdpng.c,
-         src/gifsize.c, src/pngsize.c, src/rrd.h, src/rrd_afm.c,
-         src/rrd_afm.h, src/rrd_afm_data.c, src/rrd_afm_data.h,
-         src/rrd_cgi.c, src/rrd_create.c, src/rrd_datalang.c,
-         src/rrd_diff.c, src/rrd_dump.c, src/rrd_error.c, src/rrd_fetch.c,
-         src/rrd_first.c, src/rrd_format.c, src/rrd_format.h,
-         src/rrd_gfx.c, src/rrd_gfx.h, src/rrd_graph.c,
-         src/rrd_graph_helper.c, src/rrd_hw.c, src/rrd_hw.h,
-         src/rrd_info.c, src/rrd_is_thread_safe.h, src/rrd_last.c,
-         src/rrd_not_thread_safe.c, src/rrd_open.c, src/rrd_resize.c,
-         src/rrd_restore.c, src/rrd_rpncalc.c, src/rrd_rpncalc.h,
-         src/rrd_stat.c, src/rrd_thread_safe.c, src/rrd_thread_safe_nt.c,
-         src/rrd_tool.c, src/rrd_tool.h, src/rrd_tune.c, src/rrd_update.c,
-         src/rrd_xport.c, src/rrd_xport.h, src/rrdupdate.c: prep for 1.2.0
-         release
+       * configure.ac, doc/rrdgraph.src, examples/4charts.pl.in,
+         examples/bigtops.pl, examples/piped-demo.pl,
+         examples/shared-demo.pl, examples/stripes.pl,
+         libraries/Makefile.am, libraries/afm, libraries/afm/COPYRIGHT.txt,
+         libraries/afm/Courier-Bold.afm,
+         libraries/afm/Courier-BoldOblique.afm,
+         libraries/afm/Courier-Oblique.afm, libraries/afm/Courier.afm,
+         libraries/afm/Helvetica-Bold.afm,
+         libraries/afm/Helvetica-BoldOblique.afm,
+         libraries/afm/Helvetica-Oblique.afm, libraries/afm/Helvetica.afm,
+         libraries/afm/Makefile.am, libraries/afm/Symbol.afm,
+         libraries/afm/Times-Bold.afm, libraries/afm/Times-BoldItalic.afm,
+         libraries/afm/Times-Italic.afm, libraries/afm/Times-Roman.afm,
+         libraries/afm/ZapfDingbats.afm, libraries/afm/compile_afm.pl,
+         libraries/afm/glyphlist.txt, libraries/afm/test-afm.c,
+         libraries/libart_lgpl-2.3.7/Makefile.in,
+         libraries/libpng-1.2.0/Makefile.in, src/Makefile.am,
+         src/rrd_gfx.c, src/rrd_gfx.h, src/rrd_graph.c, src/rrd_tool.c: 3
+         patches, #3 depends on #1 as EPS uses AFM for stringwidth too.
+         src/rrd_afm.[ch], src/rrd_afm_data.[ch] and changes to
+         rrd_gfx.[ch] to use AFM for stringwidth in SVG output.
+         libraries/afm with .afm files for the standard 14 postscript fonts
+         and perl script to create src/rrd_afm_data.c Includes small test
+         program to show examples of calculated stringwidth and actual
+         stringwidth. Adds EPS output support. Modifies rrd_tool.c as
+         rrd_graph() changes the argv pointer, and rrd_tool then always
+         wrote the 200x100 output line to the file (which probably doesn't
+         do anything for png images, but eps files fail having it after the
+         %%EOF marker). -- Peter Speck <speck@ruc.dk>
 
-2005-04-25 19:07  oetiker
+2002-04-06 12:40  alex
 
-       * doc/rpntutorial.pod, doc/rrdcgi.pod, doc/rrdfetch.pod,
-         doc/rrdgraph_data.pod, doc/rrdgraph_examples.pod,
-         doc/rrdgraph_graph.pod, doc/rrdgraph_rpn.pod, doc/rrdtutorial.pod:
-         resolved all XXX situations
+       * src/rrd_graph.c: Different default font when WIN32 is defined
 
-2005-04-25 17:31  oetiker
+2002-04-06 12:25  alex
 
-       * doc/bin_dec_hex.pod, doc/rpntutorial.pod, doc/rrdcgi.pod,
-         doc/rrdfetch.pod, doc/rrdgraph_data.pod,
-         doc/rrdgraph_examples.pod, doc/rrdgraph_graph.pod,
-         doc/rrdgraph_rpn.pod, doc/rrdtool.pod, doc/rrdtune.pod,
-         doc/rrdtutorial.pod, doc/rrdupdate.pod, doc/rrdxport.pod: another
-         batch of fixes from fritz
+       * NT-BUILD-TIPS.txt, bindings/perl-shared/Makefile.PL,
+         bindings/perl-shared/RRDs.pm, bindings/perl-shared/ntmake.pl,
+         bindings/perl-shared/t/base.t, doc/Makefile.am,
+         doc/cdeftutorial.pod, doc/rrdgraph-old.pod,
+         doc/rrdgraph_graph.src, doc/rrdtutorial.es.pod,
+         examples/cgi-demo.cgi, examples/cgi-demo.cgi.in,
+         examples/piped-demo.pl, examples/piped-demo.pl.in,
+         examples/shared-demo.pl, examples/shared-demo.pl.in,
+         src/rrd_cgi.c, src/rrd_gfx.c, src/rrd_gfx.h, src/rrd_graph.c,
+         src/rrd_graph.h, src/rrd_tool.h: Removed references to GIF Changed
+         y0 and such into Y0 and so
 
-2005-04-24 22:21  oetiker
+2002-04-05 23:51  jake
 
-       * CONTRIBUTORS: fixed contributiors listing
+       * NT-BUILD-TIPS.txt, bindings/perl-shared/RRDs.xs,
+         bindings/perl-shared/ntmake.pl, confignt, confignt/config.h,
+         libraries/freetype-2.0.5/freetype.dsp,
+         libraries/libart_lgpl-2.3.7/libart.dsp,
+         libraries/libpng-1.2.0/png.dsp, libraries/zlib-1.1.4/zlib.dsp,
+         src/ntconfig.h, src/rrd.dsp, src/rrd_gfx.c, src/rrd_graph.c,
+         src/rrd_tool.h, src/rrdtool.dsp, src/rrdtool.dsw: Updated/added
+         MVSC++ 6.0 project files for compilation of rrd.lib and
+         rrdtool.exe on Win32. Changes for RRDs compilation on Win32. Moved
+         src/ntconfig.h to confignt/config.h.
 
-2005-04-24 17:23  oetiker
+2002-04-03 14:52  oetiker
 
-       * doc/rrddump.pod, doc/rrdfirst.pod, doc/rrdinfo.pod,
-         doc/rrdlast.pod, doc/rrdresize.pod, doc/rrdrestore.pod,
-         doc/rrdthreads.pod, doc/rrdtool-xport.dtd, doc/rrdtutorial.pod:
-         big patch-up for the 1.2. Documents Revisited by Fritz Zaucker
+       * src/rrd_gfx.c, src/rrd_gfx.h, src/rrd_graph.c, src/rrd_graph.h: As
+         gfx_canvas_t now has excatly the same lifespan as image_desc_t,
+         I've made 'gfx_canvas_t canvas' a member of image_desc_t and
+         dropped it as a separate parameter in all function calls.
+         imgformat, interlaced and zoom are moved to gfx_canvas_t. I have
+         dropped my old fontlib-enum as imgformat contains that
+         information. The gfx_render_xxx switch is moved to rrd_gfx so
+         rrd_graph is (almost) only bothered with image formats in cmd line
+         parsing. gfx_close_path is added. gfx_new_dashed_line is added
+         with 2 new arguments: length of a dash and length between dashes.
+         gfx_new_line is still there for plain lines. Having dash-length ==
+         0 creates normal line. rrd_graph.c is not updated for dashed
+         lines. It's not decided how one should specify which and how lines
+         are dashed. An extension of the color specification? svg is
+         updated for dashes and opacity, but libart code is not. I've fixed
+         indent in SVG, all lines had a space before func decl. etc. Misc
+         small fixes, e.g. sscanf of gfx_color_t, position of x-axis arrow.
+         --- Peter Speck <speck@ruc.dk>
 
-2005-04-22 18:35  oetiker
+2002-04-03 05:32  oetiker
 
-       * NEWS, bindings/perl-piped/RRDp.pm, bindings/perl-shared/RRDs.pm,
-         configure.ac, rrdtool.spec, src/Makefile.am, src/gdpng.c,
-         src/gifsize.c, src/pngsize.c, src/rrd.h, src/rrd_afm.c,
-         src/rrd_afm.h, src/rrd_afm_data.c, src/rrd_afm_data.h,
-         src/rrd_cgi.c, src/rrd_create.c, src/rrd_datalang.c,
-         src/rrd_diff.c, src/rrd_dump.c, src/rrd_error.c, src/rrd_fetch.c,
-         src/rrd_first.c, src/rrd_format.c, src/rrd_format.h,
-         src/rrd_gfx.c, src/rrd_gfx.h, src/rrd_graph.c,
-         src/rrd_graph_helper.c, src/rrd_hw.c, src/rrd_hw.h,
-         src/rrd_info.c, src/rrd_is_thread_safe.h, src/rrd_last.c,
-         src/rrd_not_thread_safe.c, src/rrd_open.c, src/rrd_resize.c,
-         src/rrd_restore.c, src/rrd_rpncalc.c, src/rrd_rpncalc.h,
-         src/rrd_stat.c, src/rrd_thread_safe.c, src/rrd_thread_safe_nt.c,
-         src/rrd_tool.c, src/rrd_tool.h, src/rrd_tune.c, src/rrd_update.c,
-         src/rrd_xport.c, src/rrd_xport.h, src/rrdupdate.c: prep for 1.2rc9
-         release
+       * src/rrd_restore.c: i suck. sorry. add ,0666 to the open(). -- Paul
+         Vixie <paul@vix.com>
 
-2005-04-19 21:09  oetiker
+2002-04-02 21:32  oetiker
 
-       * doc/rrddump.pod, doc/rrdgraph.pod, doc/rrdgraph_data.pod,
-         doc/rrdgraph_graph.pod, doc/rrdinfo.pod, doc/rrdresize.pod: fix
-         titles
+       * bindings/perl-shared/RRDs.xs: added call to tzset to activate TZ
+         settings -- Paul A Vixie <vixie@vix.com>
 
-2005-04-19 21:05  oetiker
+2002-04-02 21:31  oetiker
 
-       * doc/bin_dec_hex.pod: fixed title
+       * src/rrd_restore.c: aded missing fcntl.h
 
-2005-04-18 22:39  oetiker
+2002-04-02 19:37  oetiker
 
-       * doc/Makefile.am, doc/cdeftutorial.pod, doc/rrd-beginners.pod,
-         doc/rrdgraph.pod, doc/rrdgraph.src, doc/rrdgraph_data.pod,
-         doc/rrdgraph_data.src, doc/rrdgraph_examples.pod,
-         doc/rrdgraph_examples.src, doc/rrdgraph_graph.pod,
-         doc/rrdgraph_graph.src, doc/rrdgraph_rpn.pod,
-         doc/rrdgraph_rpn.src, doc/rrdinfo.pod, doc/rrdlast.pod,
-         doc/rrdresize.pod, doc/rrdrestore.pod, doc/rrdtune.pod,
-         doc/rrdtutorial.pod, doc/rrdupdate.pod, doc/rrdxport.pod: src
-         moved back to pod. this include thing was a neat idea but it just
-         adds another twist to things which is not necessary. fixed some
-         pod errors
+       * src/rrd_restore.c: rrd restore should not burn down existing files
+         -- Paul Vixie <paul@vix.com>
 
-2005-04-18 22:13  oetiker
+2002-04-01 18:32  oetiker
 
-       * doc/rrdcgi.pod, doc/rrdcreate.pod, doc/rrddump.pod,
-         doc/rrdfetch.pod, doc/rrdfirst.pod, doc/rrdgraph.src,
-         doc/rrdgraph_data.src, doc/rrdgraph_examples.src,
-         doc/rrdgraph_graph.src, doc/rrdgraph_rpn.src, doc/rrdtool.pod:
-         misc fixes for better display
+       * NEWS: merged svg update
 
-2005-04-18 11:07  oetiker
+2002-04-01 18:31  oetiker
 
-       * doc/rrdgraph_graph.src, branches/1.2/website,
-         branches/1.2/website/bin, branches/1.2/website/doc,
-         branches/1.2/website/tut: fixed format
+       * src/rrd_diff.c: "!" takes a higher preference than "||" this means
+         rrd_update N:: would segfault -- Oliver Cook <ollie@uk.clara.net>
 
-2005-04-17 22:43  oetiker
+2002-03-28 17:33  jake
 
-       * doc/bin_dec_hex.pod, doc/rrd-beginners.pod, doc/rrdcgi.pod,
-         doc/rrdcreate.pod, doc/rrddump.pod, doc/rrdfetch.pod,
-         doc/rrdfirst.pod, doc/rrdgraph.src, doc/rrdgraph_data.src,
-         doc/rrdgraph_examples.src, doc/rrdgraph_graph.src,
-         doc/rrdgraph_rpn.src, doc/rrdinfo.pod, doc/rrdlast.pod,
-         doc/rrdresize.pod, doc/rrdrestore.pod, doc/rrdthreads.pod,
-         doc/rrdtune.pod, doc/rrdupdate.pod, doc/rrdxport.pod: fixed many
-         pod bugs while creating the new website
+       * MakeMakefile: Added comment suggesting use of -I flag with
+         aclocal.
 
-2005-04-17 17:29  oetiker
+2002-03-26 07:02  oetiker
 
-       * doc/rrdgraph.src: make sure argument descriptions comply with Bold
-         = fixed and Italics = variable
+       * doc/rrdgraph.src, src/rrd_gfx.c, src/rrd_gfx.h, src/rrd_graph.h:
+         added SVG support -- Peter Speck <speck@ruc.dk>
 
-2005-04-17 16:26  oetiker
+2002-03-23 20:41  alex
 
-       * doc/rrdcreate.pod: fix use of =item commands
+       * src/rrd_graph.c: Better positioning of the pie when it is alone on
+         the canvas
 
-2005-04-17 16:25  oetiker
+2002-03-23 20:01  alex
 
-       * doc/Makefile.am: allow to build pods (for website)
+       * NEWS: Modified rrd_graph
 
-2005-04-13 22:00  oetiker
+2002-03-23 19:59  alex
 
-       * src/rrd_graph.c: * draw the axis last to have them always on top *
-         use a smaller font for labeling the axis
+       * src/rrd_graph.c, src/rrd_graph.h: Changes in rrd_graph; see NEWS
 
-2005-04-13 19:53  oetiker
+2002-03-23 09:05  oetiker
 
-       * src/rrd_gfx.c: have better default compression
+       * doc/rrdcgi.pod, doc/rrdgraph.src, doc/rrdtutorial.pod: removed
+         reference to GIF
 
-2005-04-13 19:53  oetiker
+2002-03-23 09:01  oetiker
 
-       * src/rrd_graph.c: tune fontsizes and spacing to be more in line
-         with rrdtool 1.0
+       * src/Makefile.am, src/rrd_graph.c, src/rrd_graph.h, src/rrd_tool.c:
+         remove all traces of GIF and make PNG the default
 
-2005-04-12 21:52  oetiker
+2002-03-23 08:53  oetiker
 
-       * src/rrd_graph.c: prep for 1.2rc8 release
+       * src/rrd_graph.c: Move CDEF start pointers if start of cdef is a
+         step ahead of the start of the data -- Ashok Mandala
+         <chakri063@yahoo.com>
 
-2005-04-12 21:10  oetiker
+2002-03-21 22:39  oetiker
 
-       * bindings/perl-piped/RRDp.pm, bindings/perl-shared/RRDs.pm,
-         configure.ac, rrdtool.spec, src/gdpng.c, src/gifsize.c,
-         src/pngsize.c, src/rrd.h, src/rrd_afm.c, src/rrd_afm.h,
-         src/rrd_afm_data.c, src/rrd_afm_data.h, src/rrd_cgi.c,
-         src/rrd_create.c, src/rrd_datalang.c, src/rrd_diff.c,
-         src/rrd_dump.c, src/rrd_error.c, src/rrd_fetch.c, src/rrd_first.c,
-         src/rrd_format.c, src/rrd_format.h, src/rrd_gfx.c, src/rrd_gfx.h,
-         src/rrd_graph.c, src/rrd_graph_helper.c, src/rrd_hw.c,
-         src/rrd_hw.h, src/rrd_info.c, src/rrd_is_thread_safe.h,
-         src/rrd_last.c, src/rrd_not_thread_safe.c, src/rrd_open.c,
-         src/rrd_resize.c, src/rrd_restore.c, src/rrd_rpncalc.c,
-         src/rrd_rpncalc.h, src/rrd_stat.c, src/rrd_thread_safe.c,
-         src/rrd_thread_safe_nt.c, src/rrd_tool.c, src/rrd_tool.h,
-         src/rrd_tune.c, src/rrd_update.c, src/rrd_xport.c,
-         src/rrd_xport.h, src/rrdupdate.c: prep for 1.2rc8 release
+       * src/rrd_graph.c: fixed color area in legend and fixed color area
+         in 3d border
 
-2005-04-12 20:56  oetiker
+2002-03-21 12:00  alex
 
-       * src/rrd_graph.c, src/rrd_graph.h: * better fix for units-exponent
-         issue ... now the whole scaling happens only at print time ...
-         this is more stable -- tobi * remove the newline from ctime (%c)
-         in VDEF -- alex
+       * src/rrd_graph.c, src/rrd_graph.h: Pie charts didn't have
+         anti-aliasing; building them clockwise seems to solve this
+         problem.
 
-2005-04-11 23:23  oetiker
+2002-03-20 22:48  oetiker
 
-       * bindings/perl-piped/RRDp.pm, bindings/perl-shared/RRDs.pm,
-         configure.ac, rrdtool.spec, src/gdpng.c, src/gifsize.c,
-         src/pngsize.c, src/rrd.h, src/rrd_afm.c, src/rrd_afm.h,
-         src/rrd_afm_data.c, src/rrd_afm_data.h, src/rrd_cgi.c,
-         src/rrd_create.c, src/rrd_datalang.c, src/rrd_diff.c,
-         src/rrd_dump.c, src/rrd_error.c, src/rrd_fetch.c, src/rrd_first.c,
-         src/rrd_format.c, src/rrd_format.h, src/rrd_gfx.c, src/rrd_gfx.h,
-         src/rrd_graph.c, src/rrd_graph_helper.c, src/rrd_hw.c,
-         src/rrd_hw.h, src/rrd_info.c, src/rrd_is_thread_safe.h,
-         src/rrd_last.c, src/rrd_not_thread_safe.c, src/rrd_open.c,
-         src/rrd_resize.c, src/rrd_restore.c, src/rrd_rpncalc.c,
-         src/rrd_rpncalc.h, src/rrd_stat.c, src/rrd_thread_safe.c,
-         src/rrd_thread_safe_nt.c, src/rrd_tool.c, src/rrd_tool.h,
-         src/rrd_tune.c, src/rrd_update.c, src/rrd_xport.c,
-         src/rrd_xport.h, src/rrdupdate.c: prep for 1.2rc7 release
+       * src/rrd_rpncalc.c: fixed longstanding bug affection CDEFS where
+         values from rrds with different resolutions got mixed ..
 
-2005-04-11 23:22  oetiker
+2002-03-17 22:40  alex
 
-       * doc/rrdgraph.src, src/rrd_graph.c, src/rrd_graph.h,
-         src/rrd_tool.c: * adjusted element spacing within the graph *
-         re-intruduced --units-length option * stabilized --units-exponent
-         option by jumping to alt-y-grid mode once the default autogrid can
-         not cope with the data anymore.
+       * src/rrd_gfx.c, src/rrd_gfx.h, src/rrd_graph.c: Changed the way
+         circle sections are drawn.
 
-2005-04-11 23:20  oetiker
+2002-03-13 02:58  alex
 
-       * NEWS: added note about incompatible changes
+       * src/rrd_gfx.c, src/rrd_gfx.h, src/rrd_graph.c: New, hopefully
+         better, implementation of PART drawing
 
-2005-04-11 12:29  oetiker
+2002-03-12 07:19  oetiker
 
-       * NEWS: started change log
+       * libraries/zlib-1.1.3: realy remove zlibe 1.1.3 dir
 
-2005-04-11 12:17  oetiker
+2002-03-12 07:18  oetiker
 
-       * doc/rrdgraph_rpn.src: added notes on INF
+       * MakeMakefile, configure.ac, examples/bigtops.pl,
+         examples/piped-demo.pl, examples/shared-demo.pl,
+         examples/stripes.pl: updated
 
-2005-04-11 09:51  oetiker
+2002-03-12 07:17  oetiker
 
-       * src/Makefile.am, src/art_rgb_affine_private.h,
-         src/art_rgba_rgba_affine.c, src/art_rgba_rgba_affine.h,
-         src/art_rgba_svp.c, src/art_rgba_svp.h, src/rrd_gfx.c,
-         src/rrd_gfx.h, src/rrd_graph.c: * we are now creating true RGBA
-         pngs * removed all memory leeks from rrd_gfx
+       * libraries/libart_lgpl-2.3.7,
+         libraries/libart_lgpl-2.3.7/.cvsignore: ignore generated files
 
-2005-04-10 22:02  oetiker
+2002-03-12 07:16  oetiker
 
-       * NEWS: started updating for 1.2 release
+       * libraries/libart_lgpl-2.3.7/libart_lgpl_2.la,
+         libraries/zlib-1.1.4, libraries/zlib-1.1.4/.cvsignore,
+         libraries/zlib-1.1.4/Makefile, libraries/zlib-1.1.4/Makefile.in:
+         missing bits
 
-2005-04-10 18:11  oetiker
+2002-03-12 06:43  oetiker
 
-       * doc/rrdresize.pod: clarified output -- alex
+       * configure.ac: updated to zlib 1.1.4
 
-2005-04-10 18:10  oetiker
+2002-03-12 06:42  oetiker
 
-       * doc/name.inc, doc/rrdgraph.src, doc/rrdgraph_data.src,
-         doc/rrdgraph_examples.src, doc/rrdgraph_graph.src,
-         doc/rrdgraph_rpn.src: get the docs ready for the 1.2 release.
-         remove notes about things that never got implemented. -- alex
+       * libraries/zlib-1.1.3/ChangeLog, libraries/zlib-1.1.3/FAQ,
+         libraries/zlib-1.1.3/INDEX, libraries/zlib-1.1.3/Makefile.am,
+         libraries/zlib-1.1.3/README, libraries/zlib-1.1.3/README.rrdtool,
+         libraries/zlib-1.1.3/adler32.c,
+         libraries/zlib-1.1.3/algorithm.txt,
+         libraries/zlib-1.1.3/compress.c, libraries/zlib-1.1.3/crc32.c,
+         libraries/zlib-1.1.3/deflate.c, libraries/zlib-1.1.3/deflate.h,
+         libraries/zlib-1.1.3/descrip.mms, libraries/zlib-1.1.3/example.c,
+         libraries/zlib-1.1.3/gzio.c, libraries/zlib-1.1.3/infblock.c,
+         libraries/zlib-1.1.3/infblock.h, libraries/zlib-1.1.3/infcodes.c,
+         libraries/zlib-1.1.3/infcodes.h, libraries/zlib-1.1.3/inffast.c,
+         libraries/zlib-1.1.3/inffast.h, libraries/zlib-1.1.3/inffixed.h,
+         libraries/zlib-1.1.3/inflate.c, libraries/zlib-1.1.3/inftrees.c,
+         libraries/zlib-1.1.3/inftrees.h, libraries/zlib-1.1.3/infutil.c,
+         libraries/zlib-1.1.3/infutil.h, libraries/zlib-1.1.3/maketree.c,
+         libraries/zlib-1.1.3/minigzip.c, libraries/zlib-1.1.3/trees.c,
+         libraries/zlib-1.1.3/trees.h, libraries/zlib-1.1.3/uncompr.c,
+         libraries/zlib-1.1.3/zconf.h, libraries/zlib-1.1.3/zlib.3,
+         libraries/zlib-1.1.3/zlib.dsp, libraries/zlib-1.1.3/zlib.dsw,
+         libraries/zlib-1.1.3/zlib.h, libraries/zlib-1.1.3/zutil.c,
+         libraries/zlib-1.1.3/zutil.h, libraries/zlib-1.1.4,
+         libraries/zlib-1.1.4/ChangeLog, libraries/zlib-1.1.4/FAQ,
+         libraries/zlib-1.1.4/INDEX, libraries/zlib-1.1.4/Make_vms.com,
+         libraries/zlib-1.1.4/Makefile, libraries/zlib-1.1.4/Makefile.am,
+         libraries/zlib-1.1.4/Makefile.am~,
+         libraries/zlib-1.1.4/Makefile.in,
+         libraries/zlib-1.1.4/Makefile.riscos, libraries/zlib-1.1.4/README,
+         libraries/zlib-1.1.4/adler32.c,
+         libraries/zlib-1.1.4/algorithm.txt,
+         libraries/zlib-1.1.4/compress.c, libraries/zlib-1.1.4/crc32.c,
+         libraries/zlib-1.1.4/deflate.c, libraries/zlib-1.1.4/deflate.h,
+         libraries/zlib-1.1.4/descrip.mms, libraries/zlib-1.1.4/example.c,
+         libraries/zlib-1.1.4/gzio.c, libraries/zlib-1.1.4/infblock.c,
+         libraries/zlib-1.1.4/infblock.h, libraries/zlib-1.1.4/infcodes.c,
+         libraries/zlib-1.1.4/infcodes.h, libraries/zlib-1.1.4/inffast.c,
+         libraries/zlib-1.1.4/inffast.h, libraries/zlib-1.1.4/inffixed.h,
+         libraries/zlib-1.1.4/inflate.c, libraries/zlib-1.1.4/inftrees.c,
+         libraries/zlib-1.1.4/inftrees.h, libraries/zlib-1.1.4/infutil.c,
+         libraries/zlib-1.1.4/infutil.h, libraries/zlib-1.1.4/maketree.c,
+         libraries/zlib-1.1.4/minigzip.c, libraries/zlib-1.1.4/trees.c,
+         libraries/zlib-1.1.4/trees.h, libraries/zlib-1.1.4/uncompr.c,
+         libraries/zlib-1.1.4/zconf.h, libraries/zlib-1.1.4/zlib.3,
+         libraries/zlib-1.1.4/zlib.h, libraries/zlib-1.1.4/zlib.html,
+         libraries/zlib-1.1.4/zutil.c, libraries/zlib-1.1.4/zutil.h:
+         replace zlib 1.1.3 with zlib 1.1.4
 
-2005-04-10 18:05  oetiker
+2002-03-10 23:08  alex
 
-       * src/rrd_graph.c: do not draw AREAS that have no hight (done
-         right). draw an arrow on the positiv y axis.
+       * doc/rrdgraph_graph.src, src/rrd_graph.c, src/rrd_graph.h: Pie
+         chart support added to rrdtool graph
 
-2005-04-10 15:35  oetiker
+2002-03-10 22:49  oetiker
 
-       * doc/rrdtutorial.pod: updated for 1.2 release -- alex
+       * MakeMakefile: added quotes to echo
 
-2005-04-10 14:00  oetiker
+2002-03-10 16:22  alex
 
-       * src/rrd_gfx.c: fixed typo -- alex
+       * src/rrd_rpncalc.c: Realigned function rpn_calc() Stack checking
+         now done using a macro
 
-2005-04-10 13:57  oetiker
+2002-03-10 14:58  alex
 
-       * doc/rrdcgi.pod: G<gt> does not exist E<gt> does
+       * doc/rrdgraph.src, doc/rrdgraph_rpn.src: Fixed some typos/errors
+         Updated for the NE and ISINF operators in RPN
 
-2005-04-10 12:12  oetiker
+2002-03-10 14:53  alex
 
-       * doc/rrdcreate.pod, doc/rrdxport.pod, src/rrd_graph_helper.c,
-         src/rrd_tool.c: fixed spelling and working -- Alex van den
-         Bogaerdt alex at ergens.op.het.net
+       * src/rrd_graph.c: Using the font option resulted in a segfault.
+         Needs more care, the current change is just a hack
 
-2005-04-10 11:53  oetiker
+2002-03-10 14:48  alex
 
-       * NT-BUILD-TIPS.txt, confignt/config.h, src/strftime.c,
-         src/strftime.h: added extra strftime.[ch] which supports ISO 8601
-         week numbers, together with instructions in the NT-BUILD-TIPPS
-         file
+       * src/rrd_rpncalc.c, src/rrd_rpncalc.h: Added NE and ISINF operands
+         to RPN
 
-2005-04-10 11:33  oetiker
+2002-03-10 12:28  oetiker
 
-       * bindings/perl-piped/RRDp.pm, bindings/perl-shared/RRDs.pm,
-         configure.ac, rrdtool.spec, src/gdpng.c, src/gifsize.c,
-         src/pngsize.c, src/rrd.h, src/rrd_afm.c, src/rrd_afm.h,
-         src/rrd_afm_data.c, src/rrd_afm_data.h, src/rrd_cgi.c,
-         src/rrd_create.c, src/rrd_datalang.c, src/rrd_diff.c,
-         src/rrd_dump.c, src/rrd_error.c, src/rrd_fetch.c, src/rrd_first.c,
-         src/rrd_format.c, src/rrd_format.h, src/rrd_gfx.c, src/rrd_gfx.h,
-         src/rrd_graph.c, src/rrd_graph_helper.c, src/rrd_hw.c,
-         src/rrd_hw.h, src/rrd_info.c, src/rrd_is_thread_safe.h,
-         src/rrd_last.c, src/rrd_not_thread_safe.c, src/rrd_open.c,
-         src/rrd_resize.c, src/rrd_restore.c, src/rrd_rpncalc.c,
-         src/rrd_rpncalc.h, src/rrd_stat.c, src/rrd_thread_safe.c,
-         src/rrd_thread_safe_nt.c, src/rrd_tool.c, src/rrd_tool.h,
-         src/rrd_tune.c, src/rrd_update.c, src/rrd_xport.c,
-         src/rrd_xport.h, src/rrdupdate.c: prep for 1.2rc6 release
+       * MakeMakefile: better version check
 
-2005-04-10 11:31  oetiker
+2002-03-08 22:14  alex
 
-       * src/rrd_graph.c: remove excess comment
+       * doc/rrdtutorial.pod: Needed to escape a wildcard
 
-2005-04-10 11:30  oetiker
+2002-03-08 22:11  alex
 
-       * configure.ac, src/Makefile.am: make --disable-perl work allow
-         configuration of the default font at configure time
+       * doc/rrdtutorial.pod: Fixed some typos
 
-2005-04-10 11:29  oetiker
+2002-02-18 21:52  oetiker
 
-       * src/rrd_gfx.c, src/rrd_graph.c, src/rrd_graph_helper.c: revamped
-         drawing routines to be less complex and more stable. be kind to
-         libart
+       * MakeMakefile, examples/bigtops.pl: added autotools version check
+         to MakeMakefiles
 
-2005-04-10 09:38  oetiker
+2002-02-09 06:21  oetiker
 
-       * src/rrd_graph.c: allow --color arguments with RRGGBB and not only
-         RRGGBBAA
+       * src/rrd_gfx.c: do propper error checking and release memmory when
+         it is not required anymore
 
-2005-04-10 09:16  oetiker
+2002-02-08 18:40  oetiker
 
-       * bindings/perl-shared/Makefile.PL: everyone has other names for
-         their shared libraries, so lets drop the dependency
+       * src/rrd_cgi.c: allow rrd_cgi to deal with umlauts -- Alexander
+         Schwartz <alexander.schwartz@gmx.net>
 
-2005-04-10 09:15  oetiker
+2002-02-03 08:10  oetiker
 
-       * bindings/perl-shared/RRDs.pm: mention updatev in the synopsis
+       * doc/rrdcreate.pod: fixed spelling
 
-2005-04-09 14:21  oetiker
+2002-02-02 14:36  oetiker
 
-       * TODO: we do have 95%
+       * src/rrd_graph.c: fixed data pointer storage
 
-2005-04-07 21:35  oetiker
+2002-02-01 20:34  oetiker
 
-       * bindings/perl-piped/RRDp.pm, bindings/perl-shared/RRDs.pm,
-         configure.ac, rrdtool.spec, src/gdpng.c, src/gifsize.c,
-         src/pngsize.c, src/rrd.h, src/rrd_afm.c, src/rrd_afm.h,
-         src/rrd_afm_data.c, src/rrd_afm_data.h, src/rrd_cgi.c,
+       * src/gdpng.c, src/gifsize.c, src/pngsize.c, src/rrd_cgi.c,
          src/rrd_create.c, src/rrd_datalang.c, src/rrd_diff.c,
-         src/rrd_dump.c, src/rrd_error.c, src/rrd_fetch.c, src/rrd_first.c,
-         src/rrd_format.c, src/rrd_format.h, src/rrd_gfx.c, src/rrd_gfx.h,
-         src/rrd_graph.c, src/rrd_graph_helper.c, src/rrd_hw.c,
-         src/rrd_hw.h, src/rrd_info.c, src/rrd_is_thread_safe.h,
-         src/rrd_last.c, src/rrd_not_thread_safe.c, src/rrd_open.c,
-         src/rrd_resize.c, src/rrd_restore.c, src/rrd_rpncalc.c,
-         src/rrd_rpncalc.h, src/rrd_stat.c, src/rrd_thread_safe.c,
-         src/rrd_thread_safe_nt.c, src/rrd_tool.c, src/rrd_tool.h,
-         src/rrd_tune.c, src/rrd_update.c, src/rrd_xport.c,
-         src/rrd_xport.h, src/rrdupdate.c: prep for 1.2rc5 release
+         src/rrd_dump.c, src/rrd_error.c, src/rrd_fetch.c,
+         src/rrd_format.c, src/rrd_graph.c, src/rrd_hw.c, src/rrd_info.c,
+         src/rrd_last.c, src/rrd_open.c, src/rrd_resize.c,
+         src/rrd_restore.c, src/rrd_rpncalc.c, src/rrd_stat.c,
+         src/rrd_tool.c, src/rrd_tune.c, src/rrd_update.c: fixed version
+         number and date/time
 
-2005-04-07 21:31  oetiker
+2002-02-01 20:29  oetiker
+
+       * libraries/libart_lgpl-2.3.7/Makefile,
+         libraries/libpng-1.2.0/Makefile, src/rrd_graph.c: *** empty log
+         message ***
+
+2002-01-31 22:44  oetiker
+
+       * acinclude.m4: this file and all the external libraries
+         configurability was contributed by mat zimmermann
+
+2002-01-31 22:43  oetiker
+
+       * acinclude.m4, configure.ac, examples/minmax.pl,
+         libraries/Makefile.am, src/Makefile.am, src/rrd_graph.c: allow use
+         of libraries already installed on the system
+
+2002-01-31 11:56  oetiker
+
+       * src/parsetime.c: make "18:00 yesterday" work Pavel Mores
+         <pvl@uh.cz>
+
+2002-01-31 07:23  oetiker
+
+       * src/rrd_graph.c: weeknumber is not %V which is more appropriate
+         than %W
+
+2002-01-31 06:36  oetiker
+
+       * MakeMakefile: copy ltmain.sh
+
+2002-01-17 20:31  oetiker
+
+       * libraries/libpng-1.0.9: this also
+
+2002-01-17 20:30  oetiker
+
+       * config/libtool, libraries/gd1.3, libraries/libpng-1.0.9/ANNOUNCE,
+         libraries/libpng-1.0.9/CHANGES, libraries/libpng-1.0.9/INSTALL,
+         libraries/libpng-1.0.9/KNOWNBUG, libraries/libpng-1.0.9/LICENSE,
+         libraries/libpng-1.0.9/Makefil,
+         libraries/libpng-1.0.9/Makefile.am, libraries/libpng-1.0.9/README,
+         libraries/libpng-1.0.9/README.rrdtool,
+         libraries/libpng-1.0.9/TODO, libraries/libpng-1.0.9/Y2KINFO,
+         libraries/libpng-1.0.9/example.c, libraries/libpng-1.0.9/libpng.3,
+         libraries/libpng-1.0.9/libpng.txt,
+         libraries/libpng-1.0.9/libpngpf.3, libraries/libpng-1.0.9/png.5,
+         libraries/libpng-1.0.9/png.c, libraries/libpng-1.0.9/png.dsp,
+         libraries/libpng-1.0.9/png.dsw, libraries/libpng-1.0.9/png.h,
+         libraries/libpng-1.0.9/pngasmrd.h,
+         libraries/libpng-1.0.9/pngbar.jpg,
+         libraries/libpng-1.0.9/pngbar.png,
+         libraries/libpng-1.0.9/pngconf.h,
+         libraries/libpng-1.0.9/pngerror.c,
+         libraries/libpng-1.0.9/pnggccrd.c,
+         libraries/libpng-1.0.9/pngget.c, libraries/libpng-1.0.9/pngmem.c,
+         libraries/libpng-1.0.9/pngnow.png,
+         libraries/libpng-1.0.9/pngpread.c,
+         libraries/libpng-1.0.9/pngread.c, libraries/libpng-1.0.9/pngrio.c,
+         libraries/libpng-1.0.9/pngrtran.c,
+         libraries/libpng-1.0.9/pngrutil.c,
+         libraries/libpng-1.0.9/pngset.c, libraries/libpng-1.0.9/pngtest.c,
+         libraries/libpng-1.0.9/pngtest.png,
+         libraries/libpng-1.0.9/pngtrans.c,
+         libraries/libpng-1.0.9/pngvcrd.c, libraries/libpng-1.0.9/pngwio.c,
+         libraries/libpng-1.0.9/pngwrite.c,
+         libraries/libpng-1.0.9/pngwtran.c,
+         libraries/libpng-1.0.9/pngwutil.c: this is not needed anymore
+
+2002-01-17 20:28  oetiker
+
+       * libraries/gd1.3/.cvsignore: killing remains
+
+2002-01-16 23:11  oetiker
+
+       * MakeMakefile: added places for download
+
+2002-01-15 22:58  oetiker
+
+       * ., .cvsignore, config, config/.cvsignore: ignore irrelevant things
+
+2002-01-15 22:53  oetiker
+
+       * libraries/freetype-2.0.5, libraries/freetype-2.0.5/.cvsignore,
+         libraries/libart_lgpl-2.3.7,
+         libraries/libart_lgpl-2.3.7/.cvsignore, libraries/libpng-1.2.0,
+         libraries/libpng-1.2.0/.cvsignore: added new .cvsignore files
+
+2002-01-15 22:51  oetiker
+
+       * CONTRIBUTORS, MakeMakefile, Makefile.am, NEWS, config/acconfig.h,
+         config/aclocal.m4, config/config.guess, config/config.h.in,
+         config/config.sub, config/install-sh, config/ltconfig,
+         config/ltmain.sh, config/missing, config/mkinstalldirs,
+         config/stamp-h, config/stamp-h.in, configure.ac, configure.in,
+         doc/rrdgraph.src, doc/rrdgraph_graph.src, examples/4charts.pl.in,
+         examples/bigtops.pl, examples/bigtops.pl.in,
+         examples/cgi-demo.cgi, examples/minmax.pl, examples/minmax.pl.in,
+         examples/piped-demo.pl, examples/piped-demo.pl.in,
+         examples/shared-demo.pl, examples/shared-demo.pl.in,
+         examples/stripes.pl, examples/stripes.pl.in,
+         libraries/Makefile.am, libraries/cgilib-0.4/Makefile.am,
+         libraries/freetype-2.0.5, libraries/freetype-2.0.5-import.txt,
+         libraries/freetype-2.0.5/Makefile.am,
+         libraries/freetype-2.0.5/README,
+         libraries/freetype-2.0.5/ahangles.c,
+         libraries/freetype-2.0.5/ahglobal.c,
+         libraries/freetype-2.0.5/ahglyph.c,
+         libraries/freetype-2.0.5/ahhint.c,
+         libraries/freetype-2.0.5/ahmodule.c,
+         libraries/freetype-2.0.5/ahoptim.c,
+         libraries/freetype-2.0.5/autohint.c,
+         libraries/freetype-2.0.5/cff.c,
+         libraries/freetype-2.0.5/cffdrivr.c,
+         libraries/freetype-2.0.5/cffgload.c,
+         libraries/freetype-2.0.5/cffload.c,
+         libraries/freetype-2.0.5/cffobjs.c,
+         libraries/freetype-2.0.5/cffparse.c,
+         libraries/freetype-2.0.5/cidgload.c,
+         libraries/freetype-2.0.5/cidload.c,
+         libraries/freetype-2.0.5/cidobjs.c,
+         libraries/freetype-2.0.5/cidparse.c,
+         libraries/freetype-2.0.5/cidriver.c,
+         libraries/freetype-2.0.5/ftbase.c,
+         libraries/freetype-2.0.5/ftbbox.c,
+         libraries/freetype-2.0.5/ftcache.c,
+         libraries/freetype-2.0.5/ftcalc.c,
+         libraries/freetype-2.0.5/ftcchunk.c,
+         libraries/freetype-2.0.5/ftcglyph.c,
+         libraries/freetype-2.0.5/ftcimage.c,
+         libraries/freetype-2.0.5/ftcmanag.c,
+         libraries/freetype-2.0.5/ftcsbits.c,
+         libraries/freetype-2.0.5/ftdebug.c,
+         libraries/freetype-2.0.5/ftextend.c,
+         libraries/freetype-2.0.5/ftglyph.c,
+         libraries/freetype-2.0.5/ftgrays.c,
+         libraries/freetype-2.0.5/ftinit.c,
+         libraries/freetype-2.0.5/ftlist.c,
+         libraries/freetype-2.0.5/ftlru.c,
+         libraries/freetype-2.0.5/ftmac.c, libraries/freetype-2.0.5/ftmm.c,
+         libraries/freetype-2.0.5/ftnames.c,
+         libraries/freetype-2.0.5/ftobjs.c,
+         libraries/freetype-2.0.5/ftoutln.c,
+         libraries/freetype-2.0.5/ftraster.c,
+         libraries/freetype-2.0.5/ftrend1.c,
+         libraries/freetype-2.0.5/ftsmooth.c,
+         libraries/freetype-2.0.5/ftstream.c,
+         libraries/freetype-2.0.5/ftsynth.c,
+         libraries/freetype-2.0.5/ftsystem.c,
+         libraries/freetype-2.0.5/fttrigon.c,
+         libraries/freetype-2.0.5/include,
+         libraries/freetype-2.0.5/include/Makefile.am,
+         libraries/freetype-2.0.5/include/ahangles.h,
+         libraries/freetype-2.0.5/include/aherrors.h,
+         libraries/freetype-2.0.5/include/ahglobal.h,
+         libraries/freetype-2.0.5/include/ahglyph.h,
+         libraries/freetype-2.0.5/include/ahhint.h,
+         libraries/freetype-2.0.5/include/ahloader.h,
+         libraries/freetype-2.0.5/include/ahmodule.h,
+         libraries/freetype-2.0.5/include/ahoptim.h,
+         libraries/freetype-2.0.5/include/ahtypes.h,
+         libraries/freetype-2.0.5/include/cffdrivr.h,
+         libraries/freetype-2.0.5/include/cfferrs.h,
+         libraries/freetype-2.0.5/include/cffgload.h,
+         libraries/freetype-2.0.5/include/cffload.h,
+         libraries/freetype-2.0.5/include/cffobjs.h,
+         libraries/freetype-2.0.5/include/cffparse.h,
+         libraries/freetype-2.0.5/include/cfftoken.h,
+         libraries/freetype-2.0.5/include/ciderrs.h,
+         libraries/freetype-2.0.5/include/cidgload.h,
+         libraries/freetype-2.0.5/include/cidload.h,
+         libraries/freetype-2.0.5/include/cidobjs.h,
+         libraries/freetype-2.0.5/include/cidparse.h,
+         libraries/freetype-2.0.5/include/cidriver.h,
+         libraries/freetype-2.0.5/include/cidtoken.h,
+         libraries/freetype-2.0.5/include/fnterrs.h,
+         libraries/freetype-2.0.5/include/freetype,
+         libraries/freetype-2.0.5/include/freetype/Makefile.am,
+         libraries/freetype-2.0.5/include/freetype/cache,
+         libraries/freetype-2.0.5/include/freetype/cache/Makefile.am,
+         libraries/freetype-2.0.5/include/freetype/cache/ftcchunk.h,
+         libraries/freetype-2.0.5/include/freetype/cache/ftcglyph.h,
+         libraries/freetype-2.0.5/include/freetype/cache/ftcimage.h,
+         libraries/freetype-2.0.5/include/freetype/cache/ftcmanag.h,
+         libraries/freetype-2.0.5/include/freetype/cache/ftcsbits.h,
+         libraries/freetype-2.0.5/include/freetype/cache/ftlru.h,
+         libraries/freetype-2.0.5/include/freetype/config,
+         libraries/freetype-2.0.5/include/freetype/config/Makefile.am,
+         libraries/freetype-2.0.5/include/freetype/config/ftconfig.h,
+         libraries/freetype-2.0.5/include/freetype/config/ftheader.h,
+         libraries/freetype-2.0.5/include/freetype/config/ftmodule.h,
+         libraries/freetype-2.0.5/include/freetype/config/ftoption.h,
+         libraries/freetype-2.0.5/include/freetype/freetype.h,
+         libraries/freetype-2.0.5/include/freetype/ftbbox.h,
+         libraries/freetype-2.0.5/include/freetype/ftcache.h,
+         libraries/freetype-2.0.5/include/freetype/ftchapters.h,
+         libraries/freetype-2.0.5/include/freetype/fterrors.h,
+         libraries/freetype-2.0.5/include/freetype/ftglyph.h,
+         libraries/freetype-2.0.5/include/freetype/ftimage.h,
+         libraries/freetype-2.0.5/include/freetype/ftlist.h,
+         libraries/freetype-2.0.5/include/freetype/ftmac.h,
+         libraries/freetype-2.0.5/include/freetype/ftmm.h,
+         libraries/freetype-2.0.5/include/freetype/ftmoderr.h,
+         libraries/freetype-2.0.5/include/freetype/ftmodule.h,
+         libraries/freetype-2.0.5/include/freetype/ftoutln.h,
+         libraries/freetype-2.0.5/include/freetype/ftrender.h,
+         libraries/freetype-2.0.5/include/freetype/ftsizes.h,
+         libraries/freetype-2.0.5/include/freetype/ftsnames.h,
+         libraries/freetype-2.0.5/include/freetype/ftsynth.h,
+         libraries/freetype-2.0.5/include/freetype/ftsystem.h,
+         libraries/freetype-2.0.5/include/freetype/fttrigon.h,
+         libraries/freetype-2.0.5/include/freetype/fttypes.h,
+         libraries/freetype-2.0.5/include/freetype/internal,
+         libraries/freetype-2.0.5/include/freetype/internal/Makefile.am,
+         libraries/freetype-2.0.5/include/freetype/internal/autohint.h,
+         libraries/freetype-2.0.5/include/freetype/internal/cfftypes.h,
+         libraries/freetype-2.0.5/include/freetype/internal/fnttypes.h,
+         libraries/freetype-2.0.5/include/freetype/internal/ftcalc.h,
+         libraries/freetype-2.0.5/include/freetype/internal/ftdebug.h,
+         libraries/freetype-2.0.5/include/freetype/internal/ftdriver.h,
+         libraries/freetype-2.0.5/include/freetype/internal/ftextend.h,
+         libraries/freetype-2.0.5/include/freetype/internal/ftmemory.h,
+         libraries/freetype-2.0.5/include/freetype/internal/ftobjs.h,
+         libraries/freetype-2.0.5/include/freetype/internal/ftstream.h,
+         libraries/freetype-2.0.5/include/freetype/internal/internal.h,
+         libraries/freetype-2.0.5/include/freetype/internal/pcftypes.h,
+         libraries/freetype-2.0.5/include/freetype/internal/psaux.h,
+         libraries/freetype-2.0.5/include/freetype/internal/psnames.h,
+         libraries/freetype-2.0.5/include/freetype/internal/sfnt.h,
+         libraries/freetype-2.0.5/include/freetype/internal/t1types.h,
+         libraries/freetype-2.0.5/include/freetype/internal/tttypes.h,
+         libraries/freetype-2.0.5/include/freetype/t1tables.h,
+         libraries/freetype-2.0.5/include/freetype/ttnameid.h,
+         libraries/freetype-2.0.5/include/freetype/tttables.h,
+         libraries/freetype-2.0.5/include/freetype/tttags.h,
+         libraries/freetype-2.0.5/include/ft2build.h,
+         libraries/freetype-2.0.5/include/ftcerror.h,
+         libraries/freetype-2.0.5/include/ftgrays.h,
+         libraries/freetype-2.0.5/include/ftraster.h,
+         libraries/freetype-2.0.5/include/ftrend1.h,
+         libraries/freetype-2.0.5/include/ftsmerrs.h,
+         libraries/freetype-2.0.5/include/ftsmooth.h,
+         libraries/freetype-2.0.5/include/pcf.h,
+         libraries/freetype-2.0.5/include/pcfdriver.h,
+         libraries/freetype-2.0.5/include/pcferror.h,
+         libraries/freetype-2.0.5/include/pcfutil.h,
+         libraries/freetype-2.0.5/include/psauxerr.h,
+         libraries/freetype-2.0.5/include/psauxmod.h,
+         libraries/freetype-2.0.5/include/psmodule.h,
+         libraries/freetype-2.0.5/include/psnamerr.h,
+         libraries/freetype-2.0.5/include/psobjs.h,
+         libraries/freetype-2.0.5/include/pstables.h,
+         libraries/freetype-2.0.5/include/rasterrs.h,
+         libraries/freetype-2.0.5/include/sfdriver.h,
+         libraries/freetype-2.0.5/include/sferrors.h,
+         libraries/freetype-2.0.5/include/sfobjs.h,
+         libraries/freetype-2.0.5/include/t1afm.h,
+         libraries/freetype-2.0.5/include/t1decode.h,
+         libraries/freetype-2.0.5/include/t1driver.h,
+         libraries/freetype-2.0.5/include/t1errors.h,
+         libraries/freetype-2.0.5/include/t1gload.h,
+         libraries/freetype-2.0.5/include/t1load.h,
+         libraries/freetype-2.0.5/include/t1objs.h,
+         libraries/freetype-2.0.5/include/t1parse.h,
+         libraries/freetype-2.0.5/include/t1tokens.h,
+         libraries/freetype-2.0.5/include/ttcmap.h,
+         libraries/freetype-2.0.5/include/ttdriver.h,
+         libraries/freetype-2.0.5/include/tterrors.h,
+         libraries/freetype-2.0.5/include/ttgload.h,
+         libraries/freetype-2.0.5/include/ttinterp.h,
+         libraries/freetype-2.0.5/include/ttload.h,
+         libraries/freetype-2.0.5/include/ttobjs.h,
+         libraries/freetype-2.0.5/include/ttpload.h,
+         libraries/freetype-2.0.5/include/ttpost.h,
+         libraries/freetype-2.0.5/include/ttsbit.h,
+         libraries/freetype-2.0.5/include/winfnt.h,
+         libraries/freetype-2.0.5/license.txt,
+         libraries/freetype-2.0.5/pcf.c,
+         libraries/freetype-2.0.5/pcfdriver.c,
+         libraries/freetype-2.0.5/pcfread.c,
+         libraries/freetype-2.0.5/pcfutil.c,
+         libraries/freetype-2.0.5/psaux.c,
+         libraries/freetype-2.0.5/psauxmod.c,
+         libraries/freetype-2.0.5/psmodule.c,
+         libraries/freetype-2.0.5/psnames.c,
+         libraries/freetype-2.0.5/psobjs.c,
+         libraries/freetype-2.0.5/raster.c,
+         libraries/freetype-2.0.5/sfdriver.c,
+         libraries/freetype-2.0.5/sfnt.c,
+         libraries/freetype-2.0.5/sfobjs.c,
+         libraries/freetype-2.0.5/smooth.c,
+         libraries/freetype-2.0.5/t1afm.c,
+         libraries/freetype-2.0.5/t1decode.c,
+         libraries/freetype-2.0.5/t1driver.c,
+         libraries/freetype-2.0.5/t1gload.c,
+         libraries/freetype-2.0.5/t1load.c,
+         libraries/freetype-2.0.5/t1objs.c,
+         libraries/freetype-2.0.5/t1parse.c,
+         libraries/freetype-2.0.5/test_bbox.c,
+         libraries/freetype-2.0.5/test_trig.c,
+         libraries/freetype-2.0.5/truetype.c,
+         libraries/freetype-2.0.5/ttcmap.c,
+         libraries/freetype-2.0.5/ttdriver.c,
+         libraries/freetype-2.0.5/ttgload.c,
+         libraries/freetype-2.0.5/ttinterp.c,
+         libraries/freetype-2.0.5/ttload.c,
+         libraries/freetype-2.0.5/ttobjs.c,
+         libraries/freetype-2.0.5/ttpload.c,
+         libraries/freetype-2.0.5/ttpost.c,
+         libraries/freetype-2.0.5/ttsbit.c,
+         libraries/freetype-2.0.5/type1.c,
+         libraries/freetype-2.0.5/type1cid.c,
+         libraries/freetype-2.0.5/winfnt.c, libraries/libart_lgpl-2.3.7,
+         libraries/libart_lgpl-2.3.7/AUTHORS,
+         libraries/libart_lgpl-2.3.7/COPYING,
+         libraries/libart_lgpl-2.3.7/ChangeLog,
+         libraries/libart_lgpl-2.3.7/INSTALL,
+         libraries/libart_lgpl-2.3.7/Makefile,
+         libraries/libart_lgpl-2.3.7/Makefile.am,
+         libraries/libart_lgpl-2.3.7/Makefile.in,
+         libraries/libart_lgpl-2.3.7/NEWS,
+         libraries/libart_lgpl-2.3.7/README,
+         libraries/libart_lgpl-2.3.7/art_affine.c,
+         libraries/libart_lgpl-2.3.7/art_affine.h,
+         libraries/libart_lgpl-2.3.7/art_alphagamma.c,
+         libraries/libart_lgpl-2.3.7/art_alphagamma.h,
+         libraries/libart_lgpl-2.3.7/art_bpath.c,
+         libraries/libart_lgpl-2.3.7/art_bpath.h,
+         libraries/libart_lgpl-2.3.7/art_config.h,
+         libraries/libart_lgpl-2.3.7/art_filterlevel.h,
+         libraries/libart_lgpl-2.3.7/art_gray_svp.c,
+         libraries/libart_lgpl-2.3.7/art_gray_svp.h,
+         libraries/libart_lgpl-2.3.7/art_misc.c,
+         libraries/libart_lgpl-2.3.7/art_misc.h,
+         libraries/libart_lgpl-2.3.7/art_pathcode.h,
+         libraries/libart_lgpl-2.3.7/art_pixbuf.c,
+         libraries/libart_lgpl-2.3.7/art_pixbuf.h,
+         libraries/libart_lgpl-2.3.7/art_point.h,
+         libraries/libart_lgpl-2.3.7/art_rect.c,
+         libraries/libart_lgpl-2.3.7/art_rect.h,
+         libraries/libart_lgpl-2.3.7/art_rect_svp.c,
+         libraries/libart_lgpl-2.3.7/art_rect_svp.h,
+         libraries/libart_lgpl-2.3.7/art_rect_uta.c,
+         libraries/libart_lgpl-2.3.7/art_rect_uta.h,
+         libraries/libart_lgpl-2.3.7/art_render.c,
+         libraries/libart_lgpl-2.3.7/art_render.h,
+         libraries/libart_lgpl-2.3.7/art_render_gradient.c,
+         libraries/libart_lgpl-2.3.7/art_render_gradient.h,
+         libraries/libart_lgpl-2.3.7/art_render_svp.c,
+         libraries/libart_lgpl-2.3.7/art_render_svp.h,
+         libraries/libart_lgpl-2.3.7/art_rgb.c,
+         libraries/libart_lgpl-2.3.7/art_rgb.h,
+         libraries/libart_lgpl-2.3.7/art_rgb_a_affine.c,
+         libraries/libart_lgpl-2.3.7/art_rgb_a_affine.h,
+         libraries/libart_lgpl-2.3.7/art_rgb_affine.c,
+         libraries/libart_lgpl-2.3.7/art_rgb_affine.h,
+         libraries/libart_lgpl-2.3.7/art_rgb_affine_private.c,
+         libraries/libart_lgpl-2.3.7/art_rgb_affine_private.h,
+         libraries/libart_lgpl-2.3.7/art_rgb_bitmap_affine.c,
+         libraries/libart_lgpl-2.3.7/art_rgb_bitmap_affine.h,
+         libraries/libart_lgpl-2.3.7/art_rgb_pixbuf_affine.c,
+         libraries/libart_lgpl-2.3.7/art_rgb_pixbuf_affine.h,
+         libraries/libart_lgpl-2.3.7/art_rgb_rgba_affine.c,
+         libraries/libart_lgpl-2.3.7/art_rgb_rgba_affine.h,
+         libraries/libart_lgpl-2.3.7/art_rgb_svp.c,
+         libraries/libart_lgpl-2.3.7/art_rgb_svp.h,
+         libraries/libart_lgpl-2.3.7/art_rgba.c,
+         libraries/libart_lgpl-2.3.7/art_rgba.h,
+         libraries/libart_lgpl-2.3.7/art_svp.c,
+         libraries/libart_lgpl-2.3.7/art_svp.h,
+         libraries/libart_lgpl-2.3.7/art_svp_intersect.c,
+         libraries/libart_lgpl-2.3.7/art_svp_intersect.h,
+         libraries/libart_lgpl-2.3.7/art_svp_ops.c,
+         libraries/libart_lgpl-2.3.7/art_svp_ops.h,
+         libraries/libart_lgpl-2.3.7/art_svp_point.c,
+         libraries/libart_lgpl-2.3.7/art_svp_point.h,
+         libraries/libart_lgpl-2.3.7/art_svp_render_aa.c,
+         libraries/libart_lgpl-2.3.7/art_svp_render_aa.h,
+         libraries/libart_lgpl-2.3.7/art_svp_vpath.c,
+         libraries/libart_lgpl-2.3.7/art_svp_vpath.h,
+         libraries/libart_lgpl-2.3.7/art_svp_vpath_stroke.c,
+         libraries/libart_lgpl-2.3.7/art_svp_vpath_stroke.h,
+         libraries/libart_lgpl-2.3.7/art_svp_wind.c,
+         libraries/libart_lgpl-2.3.7/art_svp_wind.h,
+         libraries/libart_lgpl-2.3.7/art_uta.c,
+         libraries/libart_lgpl-2.3.7/art_uta.h,
+         libraries/libart_lgpl-2.3.7/art_uta_ops.c,
+         libraries/libart_lgpl-2.3.7/art_uta_ops.h,
+         libraries/libart_lgpl-2.3.7/art_uta_rect.c,
+         libraries/libart_lgpl-2.3.7/art_uta_rect.h,
+         libraries/libart_lgpl-2.3.7/art_uta_svp.c,
+         libraries/libart_lgpl-2.3.7/art_uta_svp.h,
+         libraries/libart_lgpl-2.3.7/art_uta_vpath.c,
+         libraries/libart_lgpl-2.3.7/art_uta_vpath.h,
+         libraries/libart_lgpl-2.3.7/art_vpath.c,
+         libraries/libart_lgpl-2.3.7/art_vpath.h,
+         libraries/libart_lgpl-2.3.7/art_vpath_bpath.c,
+         libraries/libart_lgpl-2.3.7/art_vpath_bpath.h,
+         libraries/libart_lgpl-2.3.7/art_vpath_dash.c,
+         libraries/libart_lgpl-2.3.7/art_vpath_dash.h,
+         libraries/libart_lgpl-2.3.7/art_vpath_svp.c,
+         libraries/libart_lgpl-2.3.7/art_vpath_svp.h,
+         libraries/libart_lgpl-2.3.7/gen_art_config.c,
+         libraries/libart_lgpl-2.3.7/install-sh,
+         libraries/libart_lgpl-2.3.7/libart-2.0.pc.in,
+         libraries/libart_lgpl-2.3.7/libart-config.in,
+         libraries/libart_lgpl-2.3.7/libart-features.c,
+         libraries/libart_lgpl-2.3.7/libart-features.h,
+         libraries/libart_lgpl-2.3.7/libart-features.h.in,
+         libraries/libart_lgpl-2.3.7/libart.h,
+         libraries/libart_lgpl-2.3.7/libart_lgpl_2.la,
+         libraries/libart_lgpl-2.3.7/missing,
+         libraries/libart_lgpl-2.3.7/mkinstalldirs,
+         libraries/libart_lgpl-2.3.7/stamp-h.in,
+         libraries/libart_lgpl-2.3.7/testart.c,
+         libraries/libart_lgpl-2.3.7/testuta.c, libraries/libpng-1.2.0,
+         libraries/libpng-1.2.0-import.txt,
+         libraries/libpng-1.2.0/ANNOUNCE, libraries/libpng-1.2.0/CHANGES,
+         libraries/libpng-1.2.0/INSTALL, libraries/libpng-1.2.0/KNOWNBUG,
+         libraries/libpng-1.2.0/LICENSE, libraries/libpng-1.2.0/Makefile,
+         libraries/libpng-1.2.0/Makefile.am,
+         libraries/libpng-1.2.0/Makefile.in, libraries/libpng-1.2.0/README,
+         libraries/libpng-1.2.0/TODO, libraries/libpng-1.2.0/Y2KINFO,
+         libraries/libpng-1.2.0/example.c, libraries/libpng-1.2.0/libpng.3,
+         libraries/libpng-1.2.0/libpng.txt,
+         libraries/libpng-1.2.0/libpngpf.3, libraries/libpng-1.2.0/png.5,
+         libraries/libpng-1.2.0/png.c, libraries/libpng-1.2.0/png.h,
+         libraries/libpng-1.2.0/pngasmrd.h,
+         libraries/libpng-1.2.0/pngbar.jpg,
+         libraries/libpng-1.2.0/pngbar.png,
+         libraries/libpng-1.2.0/pngconf.h,
+         libraries/libpng-1.2.0/pngerror.c,
+         libraries/libpng-1.2.0/pnggccrd.c,
+         libraries/libpng-1.2.0/pngget.c, libraries/libpng-1.2.0/pngmem.c,
+         libraries/libpng-1.2.0/pngnow.png,
+         libraries/libpng-1.2.0/pngpread.c,
+         libraries/libpng-1.2.0/pngread.c, libraries/libpng-1.2.0/pngrio.c,
+         libraries/libpng-1.2.0/pngrtran.c,
+         libraries/libpng-1.2.0/pngrutil.c,
+         libraries/libpng-1.2.0/pngset.c, libraries/libpng-1.2.0/pngtest.c,
+         libraries/libpng-1.2.0/pngtest.png,
+         libraries/libpng-1.2.0/pngtrans.c,
+         libraries/libpng-1.2.0/pngvcrd.c, libraries/libpng-1.2.0/pngwio.c,
+         libraries/libpng-1.2.0/pngwrite.c,
+         libraries/libpng-1.2.0/pngwtran.c,
+         libraries/libpng-1.2.0/pngwutil.c, src/Makefile.am,
+         src/rrd_format.h, src/rrd_gfx.c, src/rrd_gfx.h, src/rrd_graph.c,
+         src/rrd_graph.h, src/rrd_tool.c, src/rrd_tool.h: The BIG graph
+         update * Replace libgd with libart * Added freetype * Updated zlib
+         and libpng * rrd_gfx.c intrduced as libart wrapper * LINE takes
+         now a float as argument * rrdtool uses truetype for fonts * thanks
+         to libart there is now full alpha transparenc and antialiasing. *
+         the new option --font lets customize the font and size for various
+         graph elements * Updated to -> libtool 1.4.2 automake 2.12
+         autoconf 2.52 * new --zoom commandline option for zoom ans
+         shrinking -- tobias oetiker
+
+2002-01-04 01:11  alex
+
+       * src/rrd_graph.c, src/rrd_graph.h: Reworked rrd_graph_script()
+
+2001-12-24 06:51  alex
+
+       * src/rrd_fetch.c, src/rrd_graph.c, src/rrd_graph.h, src/rrd_tool.c:
+         A patch of size 44Kbytes... in short: Found and repaired the
+         off-by-one error in rrd_fetch_fn(). As a result I had to remove
+         the hacks in rrd_fetch_fn(), rrd_tool.c, vdef_calc(), data_calc(),
+         data_proc() and reduce_data(). There may be other places which I
+         didn't find so be careful. Enhanced debugging in rrd_fetch_fn(),
+         it shows the RRA selection process. Added the ability to print
+         VDEF timestamps. At the moment it is a hack, I needed it now to
+         fix the off-by-one error. If the format string is "%c" (and
+         nothing else!), the time will be printed by both ctime() and as a
+         long int. Moved some code around (slightly altering it) from
+         rrd_graph() initializing now in rrd_graph_init() options parsing
+         now in rrd_graph_options() script parsing now in
+         rrd_graph_script()
+
+2001-12-22 02:49  alex
+
+       * src/rrd_graph.c: Somehow eight lines were missing from function
+         rrd_graph(). Also fixed minor bug in vdef_calc().
+
+2001-12-17 12:48  oetiker
+
+       * src/rrd_fetch.c: fix overflow error ...
+
+2001-12-11 22:55  jake
+
+       * src/rrd_info.c: Fixed uninitialized ptr causing seg fault invoking
+         info for COMPUTE data sources.
+
+2001-11-18 08:41  oetiker
+
+       * src/rrd_cgi.c: return "" instead of NULL for <RRD::GETENV
+         UNKNOWN_VARIABLE> -- Michael <sysadmin@qsl.net>
+
+2001-11-17 16:57  oetiker
+
+       * bindings/Makefile.am: fixed path to mkinstalldirs -- Laurent
+         Saehyun Kim&#65533;<LKim@xo.com>
+
+2001-09-08 18:25  oetiker
+
+       * doc/cdeftutorial.pod, doc/rrdtutorial.pod: spelling updates by
+         Martin Schulze <joey@finlandia.infodrom.north.de>
+
+2001-08-22 22:29  jake
+
+       * doc/rrdtune.pod, src/rrd_create.c, src/rrd_hw.c, src/rrd_hw.h,
+         src/rrd_rpncalc.c, src/rrd_tool.c, src/rrd_tune.c: Contents of
+         this patch: (1) Adds/revises documentation for rrd tune in
+         rrd_tool.c and pod files. (2) Moves some initialization code from
+         rrd_create.c to rrd_hw.c. (3) Adds another pass to smoothing for
+         SEASONAL and DEVSEASONAL RRAs. This pass computes the coefficients
+         as deviations from an average; the average is added the baseline
+         coefficient of HWPREDICT. Statistical texts suggest this to
+         preserve algorithm stability. It will not invalidate RRD files
+         created and smoothed with the old code. (4) Adds the
+         aberrant-reset flag to rrd tune. This operation, which is
+         specified for a single data source, causes the holt-winters
+         algorithm to forget everthing it has learned and start over. (5)
+         Fixes a few out-of-date code comments.
+
+2001-08-13 18:58  oetiker
+
+       * src/rrd_graph.c: spell fix for si units (only in comments)
+
+2001-07-28 22:34  alex
+
+       * doc/rrdgraph.pod, doc/rrdgraph_data.pod,
+         doc/rrdgraph_examples.pod, doc/rrdgraph_graph.pod,
+         doc/rrdgraph_rpn.pod: Removing rrdgraph*.pod from the cvs
 
-       * src/rrd_graph.c: fix implementation of --only-graph
+2001-07-28 22:21  alex
 
-2005-04-07 21:31  oetiker
+       * doc/Makefile.am, doc/name.inc, doc/rrdgraph.pod,
+         doc/rrdgraph_graph.src, doc/rrdgraph_rpn.src: Edited Makefile.am
+         and the rrdgraph_*.src files. By mistake the previous update was
+         made on the rrdgraph_*.pod files however they are not to be
+         edited. This is now corrected.
 
-       * src/rrd_gfx.c: make libart happy by NOT adjusting coordinates and
-         by using the ART_WIND_RULE_NONZERO winding rule
+2001-07-26 02:27  alex
 
-2005-04-07 21:30  oetiker
+       * src/rrd_graph_helper.c, src/rrd_graph_helper.h: Supporting
+         functions for rrd_graph. Functions that are used frequently and/or
+         from different places should be added here in stead of repeating
+         them in rrd_graph.c over and over again.
 
-       * src/rrd_tool.c: return propper exit codes
+2001-07-26 02:25  alex
 
-2005-04-07 20:07  oetiker
+       * src/rrd_graph.h: Moved most typedefs etc. from rrd_graph.c to this
+         file
 
-       * src/rrd_graph.h: fix bitpatterns of extraflags so that they do not
-         interfear
+2001-07-26 02:22  alex
 
-2005-04-06 23:58  oetiker
+       * src/rrd_graph.c: Added VDEF TOTAL Moved most typedefs etc. to
+         rrd_graph.h
 
-       * bindings/Makefile.am: prep for 1.2rc4 release
+2001-07-26 02:19  alex
 
-2005-04-06 23:24  oetiker
+       * src/Makefile.am: Added rrd_graph_helper
 
-       * Makefile.am, bindings/Makefile.am, bindings/perl-piped/RRDp.pm,
-         bindings/perl-shared/Makefile.PL, bindings/perl-shared/RRDs.pm,
-         configure.ac, rrdtool.spec, src/gdpng.c, src/gifsize.c,
-         src/pngsize.c, src/rrd.h, src/rrd_afm.c, src/rrd_afm.h,
-         src/rrd_afm_data.c, src/rrd_afm_data.h, src/rrd_cgi.c,
-         src/rrd_create.c, src/rrd_datalang.c, src/rrd_diff.c,
-         src/rrd_dump.c, src/rrd_error.c, src/rrd_fetch.c, src/rrd_first.c,
-         src/rrd_format.c, src/rrd_format.h, src/rrd_gfx.c, src/rrd_gfx.h,
-         src/rrd_graph.c, src/rrd_graph_helper.c, src/rrd_hw.c,
-         src/rrd_hw.h, src/rrd_info.c, src/rrd_is_thread_safe.h,
-         src/rrd_last.c, src/rrd_not_thread_safe.c, src/rrd_open.c,
-         src/rrd_resize.c, src/rrd_restore.c, src/rrd_rpncalc.c,
-         src/rrd_rpncalc.h, src/rrd_stat.c, src/rrd_thread_safe.c,
-         src/rrd_thread_safe_nt.c, src/rrd_tool.c, src/rrd_tool.h,
-         src/rrd_tune.c, src/rrd_update.c, src/rrd_xport.c,
-         src/rrd_xport.h, src/rrdupdate.c: prep for 1.2rc4 release
+2001-07-26 02:15  alex
 
-2005-04-06 23:18  oetiker
+       * doc/rrdgraph_rpn.pod: Updated for VDEF TOTAL
 
-       * doc/rrdgraph.src: document RRD_DEFAULT_FONT environment variable
+2001-07-26 02:11  alex
 
-2005-04-06 22:40  oetiker
+       * NEWS: Announce of VDEF in rrd_graph
 
-       * src/rrd_afm.c, src/rrd_cgi.c, src/rrd_graph.c, src/rrd_nan_inf.c,
-         src/rrd_open.c, src/rrd_restore.c, src/rrd_rpncalc.c,
-         src/rrd_tool.c, src/rrd_tool.h, src/rrd_update.c, src/rrd_xport.c,
-         src/rrdupdate.c: make sure WIN32 sections do NOT kick in for
-         cygwin compiles
+2001-07-21 18:17  alex
 
-2005-04-05 22:49  oetiker
+       * doc/rrdgraph_graph.pod, src/rrd_graph.c: Made PRINT and GPRINT
+         aware of VDEF statements
 
-       * src/rrd_gfx.c: only unwind the areas, the lines should be fine by
-         themselves!
+2001-07-20 22:34  oetiker
 
-2005-04-05 20:32  oetiker
+       * doc/rrdgraph_data.pod, doc/rrdgraph_examples.pod,
+         doc/rrdgraph_graph.pod, doc/rrdgraph_rpn.pod: missing
+         documentation ... -- Alex van den Bogaerdt
+         <alex@slot.hollandcasino.nl>
 
-       * bindings/perl-piped/RRDp.pm, bindings/perl-shared/RRDs.pm,
-         configure.ac, rrdtool.spec, src/gdpng.c, src/gifsize.c,
-         src/pngsize.c, src/rrd.h, src/rrd_afm.c, src/rrd_afm.h,
-         src/rrd_afm_data.c, src/rrd_afm_data.h, src/rrd_cgi.c,
-         src/rrd_create.c, src/rrd_datalang.c, src/rrd_diff.c,
-         src/rrd_dump.c, src/rrd_error.c, src/rrd_fetch.c, src/rrd_first.c,
-         src/rrd_format.c, src/rrd_format.h, src/rrd_gfx.c, src/rrd_gfx.h,
-         src/rrd_graph.c, src/rrd_graph_helper.c, src/rrd_hw.c,
-         src/rrd_hw.h, src/rrd_info.c, src/rrd_is_thread_safe.h,
-         src/rrd_last.c, src/rrd_not_thread_safe.c, src/rrd_open.c,
-         src/rrd_resize.c, src/rrd_restore.c, src/rrd_rpncalc.c,
-         src/rrd_rpncalc.h, src/rrd_stat.c, src/rrd_thread_safe.c,
-         src/rrd_thread_safe_nt.c, src/rrd_tool.c, src/rrd_tool.h,
-         src/rrd_tune.c, src/rrd_update.c, src/rrd_xport.c,
-         src/rrd_xport.h, src/rrdupdate.c: prep for 1.2rc3 release
+2001-07-20 22:34  oetiker
 
-2005-04-05 20:17  oetiker
+       * src/rrd_datalang.c: only a comment
 
-       * src/rrd_gfx.c, src/rrd_graph.c: * fix transparency rendering by
-         rewinding the paths propperly * fix x-axis label drawing by
-         considering label precision
+2001-07-20 22:33  oetiker
 
-2005-04-05 19:14  oetiker
+       * src/rrd_graph.c: small fixes -- Alex van den Bogaerdt
+         <alex@slot.hollandcasino.nl>
 
-       * src/VeraMono.ttf: new originaly copy
+2001-07-18 22:30  oetiker
 
-2005-04-05 19:12  oetiker
+       * src/rrd_graph.c, src/rrd_rpncalc.c: VDEF and VRULE are comig along
+         -- Alex van den Bogaerdt <alex@slot.hollandcasino.nl>
 
-       * src/VeraMono.ttf: fixed propperties to have a RAW font
+2001-06-05 13:42  oetiker
 
-2005-04-04 21:56  oetiker
+       * doc/rrdupdate.pod: spell fix
 
-       * configure.ac: make configure work even when no prefix is specified
+2001-05-09 05:31  oetiker
 
-2005-04-04 21:40  oetiker
+       * NEWS, doc/rrdcreate.pod, src/rrd_update.c: Bug fix: when update of
+         multiple PDP/CDP RRAs coincided with interpolation of multiple
+         PDPs an incorrect value was stored as the CDP. Especially evident
+         for GAUGE data sources. Minor changes to rrdcreate.pod. -- Jake
+         Brutlag <jakeb@corp.webtv.net>
 
-       * src/gdpng.c, src/gifsize.c, src/pngsize.c, src/rrd.h,
-         src/rrd_afm.c, src/rrd_afm.h, src/rrd_afm_data.c,
-         src/rrd_afm_data.h, src/rrd_cgi.c, src/rrd_create.c,
-         src/rrd_datalang.c, src/rrd_diff.c, src/rrd_dump.c,
-         src/rrd_error.c, src/rrd_fetch.c, src/rrd_first.c,
-         src/rrd_format.c, src/rrd_format.h, src/rrd_gfx.c, src/rrd_gfx.h,
-         src/rrd_graph.c, src/rrd_graph_helper.c, src/rrd_hw.c,
-         src/rrd_hw.h, src/rrd_info.c, src/rrd_is_thread_safe.h,
-         src/rrd_last.c, src/rrd_not_thread_safe.c, src/rrd_open.c,
-         src/rrd_resize.c, src/rrd_restore.c, src/rrd_rpncalc.c,
-         src/rrd_rpncalc.h, src/rrd_stat.c, src/rrd_thread_safe.c,
-         src/rrd_thread_safe_nt.c, src/rrd_tool.c, src/rrd_tool.h,
-         src/rrd_tune.c, src/rrd_update.c, src/rrd_xport.c,
-         src/rrd_xport.h, src/rrdupdate.c: prep for 1.2rc2 release
+2001-03-31 15:21  oetiker
 
-2005-04-04 21:22  oetiker
+       * Makefile.am: added 'all' dependancy to site-perl-install rule as
+         many seem to skip this step when instaling cricket ... probably an
+         incomplete cricket doku.
 
-       * bindings/perl-piped/RRDp.pm, bindings/perl-shared/RRDs.pm,
-         configure.ac, rrdtool.spec: prepared for 1.2rc2 release
+2001-03-15 19:43  oetiker
 
-2005-04-04 21:21  oetiker
+       * PROJECTS: added PROJECTS file
 
-       * configure.ac: prepared for 1.2rc1 release
+2001-03-11 12:03  oetiker
 
-2005-04-04 21:12  oetiker
+       * src/rrd_rpncalc.c, src/rrd_rpncalc.h: reindented
 
-       * acinclude.m4, configure.ac: prepared for 1.2rc1 release
+2001-03-11 11:49  oetiker
 
-2005-04-04 21:07  oetiker
+       * src/rrd_create.c: reindented the cource for better readability
 
-       * bindings/perl-piped/RRDp.pm, bindings/perl-shared/RRDs.pm:
-         prepared for 1.2rc1 release
+2001-03-10 23:54  oetiker
 
-2005-04-04 21:05  oetiker
+       * NEWS, doc/rrdcreate.pod, doc/rrdinfo.pod, doc/rrdtune.pod,
+         doc/rrdupdate.pod, src/Makefile.am, src/rrd_create.c,
+         src/rrd_dump.c, src/rrd_format.c, src/rrd_format.h,
+         src/rrd_graph.c, src/rrd_hw.c, src/rrd_hw.h, src/rrd_info.c,
+         src/rrd_restore.c, src/rrd_rpncalc.c, src/rrd_rpncalc.h,
+         src/rrd_tool.h, src/rrd_update.c: Support for COMPUTE data sources
+         (CDEF data sources). Removes the RPN parser and calculator from
+         rrd_graph and puts then in a new file, rrd_rpncalc.c. Changes to
+         core files rrd_create and rrd_update. Some clean-up of aberrant
+         behavior stuff, including a bug fix. Documentation update
+         (rrdcreate.pod, rrdupdate.pod). Change xml format. -- Jake Brutlag
+         <jakeb@corp.webtv.net>
+
+2001-03-07 21:21  oetiker
+
+       * NEWS, doc, doc/.cvsignore, doc/Makefile.am, doc/name.inc,
+         doc/rrdgraph-old.pod, doc/rrdgraph.pod, doc/rrdgraph.src,
+         doc/rrdgraph_data.src, doc/rrdgraph_examples.src,
+         doc/rrdgraph_graph.src, doc/rrdgraph_rpn.src, doc/see_also.inc,
+         src/rrd_tune.c: complete rewrite of rrdgraph documentation. This
+         also includs info on upcomming/planned changes to the rrdgraph
+         interface and functionality -- Alex van den Bogaerdt
+         <alex@slot.hollandcasino.nl>
+
+2001-03-04 14:06  oetiker
+
+       * trunk/CVSROOT/history: want to keep a history of events
+
+2001-03-04 13:50  oetiker
 
-       * bindings/perl-piped/RRDp.pm, bindings/perl-shared/RRDs.pm:
-         prepared for 1.2rc1 release
+       * NEWS: fidex jackes adderss
 
-2005-04-04 20:56  oetiker
+2001-03-04 13:12  oetiker
 
-       * configure.ac: fixed prefix detection code again
+       * doc/rrdcreate.pod: added note on counter vs derive -- Don BAARDA
+         <don.baarda@baesystems.com>
 
-2005-04-04 20:53  oetiker
+2001-03-04 13:01  oetiker
 
-       * configure.ac: fixed autoprefix
+       * NEWS, doc/rrdcreate.pod, doc/rrdgraph.pod, doc/rrdtool.pod,
+         doc/rrdtune.pod, src/Makefile.am, src/fnv.h, src/hash_32.c,
+         src/rrd_create.c, src/rrd_dump.c, src/rrd_format.h,
+         src/rrd_graph.c, src/rrd_hw.c, src/rrd_info.c, src/rrd_open.c,
+         src/rrd_restore.c, src/rrd_tool.h, src/rrd_tune.c,
+         src/rrd_update.c, src/rrdupdate.c: Aberrant Behavior Detection
+         support. A brief overview added to rrdtool.pod. Major updates to
+         rrd_update.c, rrd_create.c. Minor update to other core files. This
+         is backwards compatible! But new files using the Aberrant stuff
+         are not readable by old rrdtool versions. See
+         http://cricket.sourceforge.net/aberrant/rrd_hw.htm -- Jake Brutlag
+         <jakeb@corp.webtv.net>
+
+2001-03-04 13:00  oetiker
+
+       * examples, examples/.cvsignore: another do not report Makefile and
+         Makefile.in
+
+2001-03-04 12:51  oetiker
+
+       * src/memtest.c: this file has no purpose
+
+2001-03-04 12:32  oetiker
+
+       * src/rrdupdate.c: rrdupdate is a generated file it has no place in
+         cvs
+
+2001-03-04 11:31  oetiker
+
+       * ., .cvsignore, CHANGES, bindings, bindings/.cvsignore,
+         bindings/perl-piped, bindings/perl-piped/.cvsignore,
+         bindings/perl-shared, bindings/perl-shared/.cvsignore,
+         bindings/tcl, bindings/tcl/.cvsignore, config, config.log,
+         config.status, config/.cvsignore, doc, doc/.cvsignore, libraries,
+         libraries/.cvsignore, libraries/cgilib-0.4,
+         libraries/cgilib-0.4/.cvsignore, libraries/gd1.3,
+         libraries/gd1.3/.cvsignore, libraries/libpng-1.0.9,
+         libraries/libpng-1.0.9/.cvsignore, libraries/zlib-1.1.3,
+         libraries/zlib-1.1.3/.cvsignore, libtool, src, src/.cvsignore:
+         repository cleanup
+
+2001-03-04 11:14  oetiker
+
+       * doc/rrdupdate.pod, src/rrd_tool.c, src/rrd_update.c: added
+         at-style-time@value:value syntax to rrd_update -- Dave Bodenstab
+         <imdave@mcs.net>
+
+2001-03-04 10:29  oetiker
+
+       * src/rrd_open.c: fixed filedescriptor leak -- Mike Franusich
+         <mike@franusich.com>
+
+2001-03-02 22:48  oetiker
+
+       * configure.in, libraries/zlib-1.1.3/Makefile.am: added test for
+         hpux. if matched, compile zlib with -fpic instead of -fPIC
+
+2001-03-01 21:37  oetiker
+
+       * configure.in: added check for the presence of the compiler used to
+         build perl modules
+
+2001-02-25 23:18  oetiker
+
+       * config/config.h, configure, doc/test1.ps, doc/test2.ps: they do
+         not belong into cvs ad they are autogenerated
+
+2001-02-25 22:57  oetiker
+
+       * doc/Makefile.am: Fixed ln for modules
+
+2001-02-25 22:53  oetiker
+
+       * Makefile.am: fixed compile order ... src before bindings
+
+2001-02-25 22:30  oetiker
+
+       * trunk/contrib, trunk/contrib/README, trunk/contrib/add_ds,
+         trunk/contrib/add_ds/README, trunk/contrib/add_ds/add_ds.pl,
+         trunk/contrib/add_ds/batch.pl, trunk/contrib/killspike,
+         trunk/contrib/killspike/README,
+         trunk/contrib/killspike/killspike.pl,
+         trunk/contrib/killspike/killspike.pl.in, trunk/contrib/log2rrd,
+         trunk/contrib/log2rrd/README, trunk/contrib/log2rrd/log2rrd.pl,
+         trunk/contrib/log2rrd/log2rrd.pl.in, trunk/contrib/php3,
+         trunk/contrib/php3/INSTALL, trunk/contrib/php3/Makefile,
+         trunk/contrib/php3/README, trunk/contrib/php3/USAGE,
+         trunk/contrib/php3/VERSION, trunk/contrib/php3/examples,
+         trunk/contrib/php3/examples/rrd_create.php,
+         trunk/contrib/php3/examples/rrd_fetch.php,
+         trunk/contrib/php3/examples/rrd_graph.php,
+         trunk/contrib/php3/examples/rrd_last.php,
+         trunk/contrib/php3/examples/rrd_update.php,
+         trunk/contrib/php3/php3_rrdtool.c,
+         trunk/contrib/php3/php3_rrdtool.h, trunk/contrib/php4,
+         trunk/contrib/php4/.cvsignore, trunk/contrib/php4/INSTALL,
+         trunk/contrib/php4/Makefile.in, trunk/contrib/php4/README,
+         trunk/contrib/php4/USAGE, trunk/contrib/php4/acinclude.m4,
+         trunk/contrib/php4/aclocal.m4, trunk/contrib/php4/build,
+         trunk/contrib/php4/build/dynlib.mk,
+         trunk/contrib/php4/build/fastgen.sh,
+         trunk/contrib/php4/build/library.mk,
+         trunk/contrib/php4/build/ltlib.mk,
+         trunk/contrib/php4/build/program.mk,
+         trunk/contrib/php4/build/rules.mk,
+         trunk/contrib/php4/build/shtool, trunk/contrib/php4/config.guess,
+         trunk/contrib/php4/config.m4, trunk/contrib/php4/config.sub,
+         trunk/contrib/php4/configure, trunk/contrib/php4/configure.in,
+         trunk/contrib/php4/dynlib.m4, trunk/contrib/php4/examples,
+         trunk/contrib/php4/examples/rrd_create.php,
+         trunk/contrib/php4/examples/rrd_fetch.php,
+         trunk/contrib/php4/examples/rrd_graph.php,
+         trunk/contrib/php4/examples/rrd_last.php,
+         trunk/contrib/php4/examples/rrd_update.php,
+         trunk/contrib/php4/install-sh, trunk/contrib/php4/ltconfig,
+         trunk/contrib/php4/ltmain.sh, trunk/contrib/php4/missing,
+         trunk/contrib/php4/mkinstalldirs,
+         trunk/contrib/php4/php_config.h.in,
+         trunk/contrib/php4/php_rrdtool.h, trunk/contrib/php4/rrdtool.c,
+         trunk/contrib/rrd-file-icon, trunk/contrib/rrd-file-icon/README,
+         trunk/contrib/rrd-file-icon/rrd.png, trunk/contrib/rrdexplorer,
+         trunk/contrib/rrdexplorer/README.txt,
+         trunk/contrib/rrdexplorer/map.cgi,
+         trunk/contrib/rrdexplorer/png.cgi, trunk/contrib/rrdfetchnames,
+         trunk/contrib/rrdfetchnames/README,
+         trunk/contrib/rrdfetchnames/rrdfetchnames.pl,
+         trunk/contrib/rrdlastds, trunk/contrib/rrdlastds/README,
+         trunk/contrib/rrdlastds/rrdlastds.pl, trunk/contrib/rrdproc,
+         trunk/contrib/rrdproc/README, trunk/contrib/rrdproc/rrdproc.c,
+         trunk/contrib/rrdview, trunk/contrib/rrdview/README,
+         trunk/contrib/rrdview/rrdview.cgi, trunk/contrib/snmpstats,
+         trunk/contrib/snmpstats/README,
+         trunk/contrib/snmpstats/SNMPstats.pl, trunk/contrib/trytime,
+         trunk/contrib/trytime/.deps,
+         trunk/contrib/trytime/.deps/trytime.P,
+         trunk/contrib/trytime/Makefile, trunk/contrib/trytime/Makefile.am,
+         trunk/contrib/trytime/Makefile.in, trunk/contrib/trytime/README,
+         trunk/contrib/trytime/trytime.c, trunk/website,
+         trunk/website/.img, trunk/website/.img/.imgdot-1x1-transp.gif,
+         trunk/website/.pics, trunk/website/.pics/CAIDAlogo.120.gif,
+         trunk/website/.pics/CAIDAlogo.120.png,
+         trunk/website/.pics/CAIDAlogo.gif,
+         trunk/website/.pics/CAIDAlogo.png,
+         trunk/website/.pics/CAIDAlogo.spons.png,
+         trunk/website/.pics/CAIDAlogo.xpm,
+         trunk/website/.pics/CAIDAlogo2.gif,
+         trunk/website/.pics/CAIDAlogo_small.gif,
+         trunk/website/.pics/b.gif, trunk/website/.pics/b.png,
+         trunk/website/.pics/background.xcf, trunk/website/.pics/bbo.gif,
+         trunk/website/.pics/bbo.png, trunk/website/.pics/bco.gif,
+         trunk/website/.pics/bco.png, trunk/website/.pics/border.gif,
+         trunk/website/.pics/bro.gif, trunk/website/.pics/bro.png,
+         trunk/website/.pics/ecke.gif, trunk/website/.pics/logo-apache.gif,
+         trunk/website/.pics/logo-apache.small.gif,
+         trunk/website/.pics/logo-extra.gif,
+         trunk/website/.pics/logo-linux.gif,
+         trunk/website/.pics/logo-wml.gif, trunk/website/.pics/rrddemo.gif,
+         trunk/website/.pics/rrdlogdemo.gif,
+         trunk/website/.pics/rrdtool.gif, trunk/website/.pics/rrdtool.xar,
+         trunk/website/.pics/unten.gif, trunk/website/.ttf,
+         trunk/website/.ttf/futurab.ttf, trunk/website/.ttf/futurabc.ttf,
+         trunk/website/.ttf/futurabi.ttf, trunk/website/.ttf/futurah.ttf,
+         trunk/website/.ttf/futurahi.ttf, trunk/website/.ttf/futurak.ttf,
+         trunk/website/.ttf/futural.ttf, trunk/website/.ttf/futuralc.ttf,
+         trunk/website/.ttf/futurali.ttf, trunk/website/.ttf/futuram.ttf,
+         trunk/website/.ttf/futuramc.ttf, trunk/website/.ttf/futurami.ttf,
+         trunk/website/.ttf/futuran.ttf, trunk/website/.ttf/futurani.ttf,
+         trunk/website/.ttf/futuraxk.ttf, trunk/website/.ttf/futurbci.ttf,
+         trunk/website/.ttf/futurlci.ttf, trunk/website/.ttf/futurmci.ttf,
+         trunk/website/.ttf/futurxkc.ttf, trunk/website/.ttf/futurxki.ttf,
+         trunk/website/.ttf/futuxkci.ttf, trunk/website/.ttf/trebuc.ttf,
+         trunk/website/.ttf/trebucbd.ttf, trunk/website/.ttf/trebucbi.ttf,
+         trunk/website/.ttf/trebucit.ttf, trunk/website/.ttf/zinjaron.ttf,
+         trunk/website/.wml, trunk/website/.wml/navbar.inc,
+         trunk/website/.wml/nestednavbar.inc,
+         trunk/website/.wml/template.inc, trunk/website/.wml/tobis.inc,
+         trunk/website/.wmlrc, trunk/website/compiling.wml,
+         trunk/website/contributors.wml, trunk/website/developers.wml,
+         trunk/website/download.wml, trunk/website/frontends,
+         trunk/website/frontends/bigsister.wml,
+         trunk/website/frontends/bronc.wml,
+         trunk/website/frontends/cricket.wml,
+         trunk/website/frontends/flowscan.wml,
+         trunk/website/frontends/fwgold.wml,
+         trunk/website/frontends/hoth.wml,
+         trunk/website/frontends/index.wml,
+         trunk/website/frontends/nmis.wml, trunk/website/frontends/nrg.wml,
+         trunk/website/frontends/ntop.wml,
+         trunk/website/frontends/orca.wml,
+         trunk/website/frontends/remstats.wml,
+         trunk/website/frontends/rrgrapher.wml,
+         trunk/website/frontends/slamon.wml, trunk/website/gallery,
+         trunk/website/gallery/alex-01.bash,
+         trunk/website/gallery/alex-01.png,
+         trunk/website/gallery/alex-01.wml,
+         trunk/website/gallery/bkw-01.gif, trunk/website/gallery/bkw-01.pl,
+         trunk/website/gallery/bkw-01.wml,
+         trunk/website/gallery/blair-01-a.png,
+         trunk/website/gallery/blair-01-b.png,
+         trunk/website/gallery/blair-01-c.png,
+         trunk/website/gallery/blair-01-d.png,
+         trunk/website/gallery/blair-01-e.png,
+         trunk/website/gallery/blair-01-f.png,
+         trunk/website/gallery/blair-01.wml,
+         trunk/website/gallery/chris-01.wml,
+         trunk/website/gallery/chris-01temp.png,
+         trunk/website/gallery/chris-01wind.png,
+         trunk/website/gallery/colleen-01.gif,
+         trunk/website/gallery/colleen-01.wml,
+         trunk/website/gallery/edvard-01.png,
+         trunk/website/gallery/edvard-01.wml,
+         trunk/website/gallery/index.wml,
+         trunk/website/gallery/jeff-01.png,
+         trunk/website/gallery/jeff-01.wml,
+         trunk/website/gallery/neal-01.png,
+         trunk/website/gallery/neal-01.wml,
+         trunk/website/gallery/simon-01.png,
+         trunk/website/gallery/simon-01.wml,
+         trunk/website/gallery/steve-01.gif,
+         trunk/website/gallery/steve-01.wml, trunk/website/index.wml,
+         trunk/website/license.wml, trunk/website/mailinglists.wml,
+         trunk/website/manual, trunk/website/manual/bin_dec_hex.wml,
+         trunk/website/manual/cdeftutorial.wml,
+         trunk/website/manual/index.wml,
+         trunk/website/manual/rpntutorial.wml,
+         trunk/website/manual/rrdcgi.wml,
+         trunk/website/manual/rrdcreate.wml,
+         trunk/website/manual/rrddump.wml,
+         trunk/website/manual/rrdfetch.wml,
+         trunk/website/manual/rrdgraph.wml,
+         trunk/website/manual/rrdinfo.wml,
+         trunk/website/manual/rrdlast.wml,
+         trunk/website/manual/rrdresize.wml,
+         trunk/website/manual/rrdrestore.wml,
+         trunk/website/manual/rrdtune.wml,
+         trunk/website/manual/rrdtutorial.es.wml,
+         trunk/website/manual/rrdtutorial.wml,
+         trunk/website/manual/rrdupdate.wml, trunk/website/news.wml,
+         trunk/website/perlbind, trunk/website/perlbind/RRDp.wml,
+         trunk/website/perlbind/RRDs.wml, trunk/website/perlbind/index.wml,
+         trunk/website/rrdcgi.wml, trunk/website/screen.wml,
+         trunk/website/site-sync, trunk/website/tutorial,
+         trunk/website/tutorial/bin_dec_hex.wml,
+         trunk/website/tutorial/cdeftutorial.wml,
+         trunk/website/tutorial/index.wml,
+         trunk/website/tutorial/rpntutorial.wml,
+         trunk/website/tutorial/rrdtutorial.es.wml,
+         trunk/website/tutorial/rrdtutorial.ps,
+         trunk/website/tutorial/rrdtutorial.wml: Initial revision
+
+2001-02-25 22:25  oetiker
+
+       * ., 00README, CHANGES, CONTRIBUTORS, COPYING, COPYRIGHT,
+         MakeMakefile, Makefile.am, NT-BUILD-TIPS.txt, README, TODO,
+         bindings, bindings/Makefile.am, bindings/perl-piped,
+         bindings/perl-piped/MANIFEST, bindings/perl-piped/Makefile.PL,
+         bindings/perl-piped/README, bindings/perl-piped/RRDp.pm,
+         bindings/perl-piped/leaktest.pl, bindings/perl-piped/rrdpl.dsp,
+         bindings/perl-piped/rrdpl.dsw, bindings/perl-piped/t,
+         bindings/perl-piped/t/base.t, bindings/perl-shared,
+         bindings/perl-shared/MANIFEST, bindings/perl-shared/Makefile.PL,
+         bindings/perl-shared/README, bindings/perl-shared/RRDs.pm,
+         bindings/perl-shared/RRDs.xs, bindings/perl-shared/ntmake.pl,
+         bindings/perl-shared/rrdpl.dsp, bindings/perl-shared/rrdpl.dsw,
+         bindings/perl-shared/t, bindings/perl-shared/t/base.t,
+         bindings/tcl, bindings/tcl/Makefile.am, bindings/tcl/README,
+         bindings/tcl/ifOctets.tcl, bindings/tcl/tclrrd.c, config,
+         config.log, config.status, config/Makefile.am, config/acconfig.h,
+         config/aclocal.m4, config/config.guess, config/config.h,
+         config/config.h.in, config/config.sub, config/install-sh,
+         config/libtool, config/libtool/libtool.m4, config/ltconfig,
+         config/ltmain.sh, config/missing, config/mkinstalldirs,
+         config/stamp-h, config/stamp-h.in, configure, configure.in, doc,
+         doc/Makefile.am, doc/bin_dec_hex.pod, doc/cdeftutorial.pod,
+         doc/rpntutorial.pod, doc/rrdcgi.pod, doc/rrdcreate.pod,
+         doc/rrddump.pod, doc/rrdfetch.pod, doc/rrdgraph.pod,
+         doc/rrdinfo.pod, doc/rrdlast.pod, doc/rrdresize.pod,
+         doc/rrdrestore.pod, doc/rrdtool.pod, doc/rrdtune.pod,
+         doc/rrdtutorial.es.pod, doc/rrdtutorial.pod, doc/rrdupdate.pod,
+         doc/test1.ps, doc/test2.ps, examples, examples/4charts.pl.in,
+         examples/Makefile.am, examples/bigtops.pl, examples/bigtops.pl.in,
+         examples/cgi-demo.cgi, examples/cgi-demo.cgi.in,
+         examples/minmax.pl, examples/minmax.pl.in, examples/piped-demo.pl,
+         examples/piped-demo.pl.in, examples/shared-demo.pl,
+         examples/shared-demo.pl.in, examples/stripes.pl,
+         examples/stripes.pl.in, libraries, libraries/Makefile.am,
+         libraries/cgilib-0.4, libraries/cgilib-0.4/Makefile.am,
+         libraries/cgilib-0.4/cgi.5, libraries/cgilib-0.4/cgi.c,
+         libraries/cgilib-0.4/cgi.h, libraries/cgilib-0.4/cgiDebug.3,
+         libraries/cgilib-0.4/cgiGetValue.3,
+         libraries/cgilib-0.4/cgiHeader.3, libraries/cgilib-0.4/cgiInit.3,
+         libraries/cgilib-0.4/cgiRedirect.3,
+         libraries/cgilib-0.4/cgilib.dsp, libraries/cgilib-0.4/cgilib.dsw,
+         libraries/cgilib-0.4/cgitest.c, libraries/cgilib-0.4/jumpto.c,
+         libraries/cgilib-0.4/readme, libraries/gd1.3,
+         libraries/gd1.3/Makefile.am, libraries/gd1.3/README.rrdtool,
+         libraries/gd1.3/demoin.gif, libraries/gd1.3/gd.c,
+         libraries/gd1.3/gd.dsp, libraries/gd1.3/gd.dsw,
+         libraries/gd1.3/gd.h, libraries/gd1.3/gddemo.c,
+         libraries/gd1.3/gdfontg.c, libraries/gd1.3/gdfontg.h,
+         libraries/gd1.3/gdfontl.c, libraries/gd1.3/gdfontl.h,
+         libraries/gd1.3/gdfontmb.c, libraries/gd1.3/gdfontmb.h,
+         libraries/gd1.3/gdfonts.c, libraries/gd1.3/gdfonts.h,
+         libraries/gd1.3/gdfontt.c, libraries/gd1.3/gdfontt.h,
+         libraries/gd1.3/gdlucidab10.c, libraries/gd1.3/gdlucidab10.h,
+         libraries/gd1.3/gdlucidab12.c, libraries/gd1.3/gdlucidab12.h,
+         libraries/gd1.3/gdlucidab14.c, libraries/gd1.3/gdlucidab14.h,
+         libraries/gd1.3/gdlucidan10.c, libraries/gd1.3/gdlucidan10.h,
+         libraries/gd1.3/gdlucidan12.c, libraries/gd1.3/gdlucidan12.h,
+         libraries/gd1.3/gdlucidan14.c, libraries/gd1.3/gdlucidan14.h,
+         libraries/gd1.3/giftogd.c, libraries/gd1.3/index.html,
+         libraries/gd1.3/mathmake.c, libraries/gd1.3/mtables.c,
+         libraries/gd1.3/readme.txt, libraries/gd1.3/webgif.c,
+         libraries/libpng-1.0.9, libraries/libpng-1.0.9/ANNOUNCE,
+         libraries/libpng-1.0.9/CHANGES, libraries/libpng-1.0.9/INSTALL,
+         libraries/libpng-1.0.9/KNOWNBUG, libraries/libpng-1.0.9/LICENSE,
+         libraries/libpng-1.0.9/Makefil,
+         libraries/libpng-1.0.9/Makefile.am, libraries/libpng-1.0.9/README,
+         libraries/libpng-1.0.9/README.rrdtool,
+         libraries/libpng-1.0.9/TODO, libraries/libpng-1.0.9/Y2KINFO,
+         libraries/libpng-1.0.9/example.c, libraries/libpng-1.0.9/libpng.3,
+         libraries/libpng-1.0.9/libpng.txt,
+         libraries/libpng-1.0.9/libpngpf.3, libraries/libpng-1.0.9/png.5,
+         libraries/libpng-1.0.9/png.c, libraries/libpng-1.0.9/png.dsp,
+         libraries/libpng-1.0.9/png.dsw, libraries/libpng-1.0.9/png.h,
+         libraries/libpng-1.0.9/pngasmrd.h,
+         libraries/libpng-1.0.9/pngbar.jpg,
+         libraries/libpng-1.0.9/pngbar.png,
+         libraries/libpng-1.0.9/pngconf.h,
+         libraries/libpng-1.0.9/pngerror.c,
+         libraries/libpng-1.0.9/pnggccrd.c,
+         libraries/libpng-1.0.9/pngget.c, libraries/libpng-1.0.9/pngmem.c,
+         libraries/libpng-1.0.9/pngnow.png,
+         libraries/libpng-1.0.9/pngpread.c,
+         libraries/libpng-1.0.9/pngread.c, libraries/libpng-1.0.9/pngrio.c,
+         libraries/libpng-1.0.9/pngrtran.c,
+         libraries/libpng-1.0.9/pngrutil.c,
+         libraries/libpng-1.0.9/pngset.c, libraries/libpng-1.0.9/pngtest.c,
+         libraries/libpng-1.0.9/pngtest.png,
+         libraries/libpng-1.0.9/pngtrans.c,
+         libraries/libpng-1.0.9/pngvcrd.c, libraries/libpng-1.0.9/pngwio.c,
+         libraries/libpng-1.0.9/pngwrite.c,
+         libraries/libpng-1.0.9/pngwtran.c,
+         libraries/libpng-1.0.9/pngwutil.c, libraries/zlib-1.1.3,
+         libraries/zlib-1.1.3/ChangeLog, libraries/zlib-1.1.3/FAQ,
+         libraries/zlib-1.1.3/INDEX, libraries/zlib-1.1.3/Makefile.am,
+         libraries/zlib-1.1.3/README, libraries/zlib-1.1.3/README.rrdtool,
+         libraries/zlib-1.1.3/adler32.c,
+         libraries/zlib-1.1.3/algorithm.txt,
+         libraries/zlib-1.1.3/compress.c, libraries/zlib-1.1.3/crc32.c,
+         libraries/zlib-1.1.3/deflate.c, libraries/zlib-1.1.3/deflate.h,
+         libraries/zlib-1.1.3/descrip.mms, libraries/zlib-1.1.3/example.c,
+         libraries/zlib-1.1.3/gzio.c, libraries/zlib-1.1.3/infblock.c,
+         libraries/zlib-1.1.3/infblock.h, libraries/zlib-1.1.3/infcodes.c,
+         libraries/zlib-1.1.3/infcodes.h, libraries/zlib-1.1.3/inffast.c,
+         libraries/zlib-1.1.3/inffast.h, libraries/zlib-1.1.3/inffixed.h,
+         libraries/zlib-1.1.3/inflate.c, libraries/zlib-1.1.3/inftrees.c,
+         libraries/zlib-1.1.3/inftrees.h, libraries/zlib-1.1.3/infutil.c,
+         libraries/zlib-1.1.3/infutil.h, libraries/zlib-1.1.3/maketree.c,
+         libraries/zlib-1.1.3/minigzip.c, libraries/zlib-1.1.3/trees.c,
+         libraries/zlib-1.1.3/trees.h, libraries/zlib-1.1.3/uncompr.c,
+         libraries/zlib-1.1.3/zconf.h, libraries/zlib-1.1.3/zlib.3,
+         libraries/zlib-1.1.3/zlib.dsp, libraries/zlib-1.1.3/zlib.dsw,
+         libraries/zlib-1.1.3/zlib.h, libraries/zlib-1.1.3/zutil.c,
+         libraries/zlib-1.1.3/zutil.h, libtool, rrdtool.spec, src,
+         src/Makefile.am, src/gdpng.c, src/getopt.c, src/getopt.h,
+         src/getopt1.c, src/gifsize.c, src/memtest.c, src/ntconfig.h,
+         src/parsetime.c, src/parsetime.h, src/pngsize.c, src/rd_cgi.dsp,
+         src/rrd.dsp, src/rrd.dsw, src/rrd.h, src/rrd_cgi.c,
+         src/rrd_cgi.dsp, src/rrd_create.c, src/rrd_diff.c, src/rrd_dump.c,
+         src/rrd_error.c, src/rrd_fetch.c, src/rrd_format.c,
+         src/rrd_format.h, src/rrd_graph.c, src/rrd_info.c, src/rrd_last.c,
+         src/rrd_open.c, src/rrd_resize.c, src/rrd_restore.c,
+         src/rrd_stat.c, src/rrd_tool.c, src/rrd_tool.h, src/rrd_tune.c,
+         src/rrd_update.c, src/rrdtool.dsp, src/rrdtool.dsw,
+         src/rrdupdate.c: Initial revision
 
-2005-04-04 20:48  oetiker
+2001-02-25 16:09  oetiker
 
-       * configure.ac: fixed config script for prefixing
+       * trunk/rrdtool, trunk/rrdtool/README: Initial revision
 
-2005-04-04 20:37  oetiker
+2001-02-25 15:29  cvs
 
-       * 00README, COPYRIGHT, NEWS, PROJECTS, README, TODO, acinclude.m4,
-         configure.ac, rrdtool.spec: get ready for 1.2
+       * trunk/CVSROOT, trunk/CVSROOT/checkoutlist,
+         trunk/CVSROOT/commitinfo, trunk/CVSROOT/config,
+         trunk/CVSROOT/cvswrappers, trunk/CVSROOT/editinfo,
+         trunk/CVSROOT/loginfo, trunk/CVSROOT/modules,
+         trunk/CVSROOT/notify, trunk/CVSROOT/rcsinfo,
+         trunk/CVSROOT/taginfo, trunk/CVSROOT/verifymsg: initial checkin
 
-2005-04-04 19:55  oetiker
+2001-02-25 15:29  
 
-       * branches/1.2: branche for 1.2
+       * branches, tags, trunk: New repository initialized by cvs2svn.
 
index aaf7718dcec9c881824ba617cbd0b8c727035338..3a33ebe377e2d1d107ef50ed8c750bfac4e0165c 100644 (file)
@@ -7,7 +7,8 @@ Alex van den Bogaerdt <alex with ergens.op.het.net> (rrd_resize.c and more)
 Amos Shapira <amos with gezernet.co.il>
 Andreas Kroomaa <andre with ml.ee>
 Andrew Turner <turner with mint.net> (LAST consolidator)
-Bernard Fischer <bfischer with syslog.ch> 64bit stuff and --alt-autoscale-max
+Bernard Fischer <bfischer with syslog.ch> 64bit stuff, --alt-autoscale-max
+Bernhard Fischer <rep dot dot dot nop with gmail.com> MMAP rewrite
 Bill Fenner <fenner with research.att.com>
 Blair Zajac <bzajac with geostaff.com>
 Bruce Campbell <bruce.campbell with apnic.net>
@@ -18,7 +19,9 @@ Dan Dunn <dandunn with computer.org>
 Dave Bodenstab <dave@bodenstab.org> AT style time in update, tclfixes
 David Grimes <dgrimes with navisite.com> SQRT/SORT/REV/SHIFT/TREND
 David L. Barker <dave with ncomtech.com> xport function bug fixes
+Evan Miller <emiller with imvu.com> Multiplicative HW Enhancements
 Frank Strauss <strauss with escape.de> TCL bindings
+Florian octo Forster <rrdtool nospam.verplant.org> rrd_restore libxml2 rewrite
 Henrik Storner <henrik with hswn.dk> functions for min/max values of data in graph
 Hermann Hueni <hueni with glue.ch> (SunOS porting)
 Jakob Ilves <jilves with se.oracle.com> HPUX 11
@@ -30,11 +33,14 @@ Joey Miller <joeym with inficad.com>php3 and php4 bindings
 Jost.Krieger <Jost.Krieger with ruhr-uni-bochum.de>
 Kai Siering <kai.siering with mediaways.net>
 Larry Leszczynski <larryl with furph.com>
+Mark Plaksin <happy@usg.edu> rrd_graph_v
+Matt Chambers <matthew.chambers with vanderbilt.edu> --full-size-mode for rrdgraph
 McCreary mccreary with xoanon.colorado.edu
 Mike Mitchell <mcm with unx.sas.com>
 Mike Slifcak <slif with bellsouth.net> many rrdtool-1.1.x fixes
 Oleg Cherevko <olwi with icyb.kiev.ua>
 Otmar Lendl <O.Lendl with Austria.EU.net> (lots of bugfixes)
+Patrick Cherry <patrick with bytemark.co.uk>
 Paul Joslin <Paul.Joslin with sdrc.com>
 Peter Speck <speck with vitality.dk> eps/svg/pdf file format code in rrdtool-1.x
 Peter Stamfest <peter with stamfest.at> initial multi-thread support
@@ -58,6 +64,7 @@ Steve Harris <steveh with wesley.com.au> AIX portability
 Steve Rader <rader with teak.wiscnet.net> (rrd_cgi debugging and LAST)
 Terminator rAT <karl_schilke with eli.net>
 Tobias Weingartner <weingart with cs.ualberta.ca>
+Thomas Gutzler <thomas.gutzler with gmail.com> dashed lines
 Tom Crawley <Tom.Crawley with hi.riotinto.com.au> (GCC&HP configuration)
 Travis Brown <tebrown with csh.rit.edu> 
 Tuc <ttsg with ttsg.com>
index 4bbab3e13a6b785dc8e7599449a3253046fd26e2..9f20a78b96833fbad4f0c68ab8656be6f56e2793 100644 (file)
@@ -2,12 +2,20 @@
 RSYNC = rsync --rsh=ssh
 
 # build the following subdirectories
-SUBDIRS = src doc examples bindings
+if BUILD_LIBINTL
+PO=po
+else
+PO=
+endif
 
-  # the following files are not mentioned in any other Makefile
+SUBDIRS = $(PO) src examples doc bindings
+
+ # the following files are not mentioned in any other Makefile
 EXTRA_DIST = COPYRIGHT CHANGES WIN32-BUILD-TIPS.txt TODO CONTRIBUTORS THREADS \
-            rrdtool.spec favicon.ico win32/config.h win32/rrd.dsp win32/rrd.vcproj \
-            win32/rrdtool.dsp win32/rrdtool.dsw win32/rrdtool.vcproj win32/Makefile \
+             intltool-extract.in  intltool-merge.in    intltool-update.in \
+            rrdtool.spec favicon.ico win32/config.h win32/rrd.dsp \
+            win32/rrd.vcproj win32/rrdtool.dsp win32/rrdtool.dsw \
+            win32/rrdtool.vcproj win32/Makefile \
             win32/rrd_config.h.msvc netware/Makefile
 
             
@@ -47,4 +55,8 @@ site-tcl-install: all
 site-python-install: all
        cd bindings/python && $(PYTHON) setup.py install
 
+# find . -name "*.c" -or -name "*.h" | xargs perl -0777 -n -e 'while (s/typedef\s+(?:unsigned\s+|signed\s+|unival\s+)?\S+\s+\*?([^{}\s;(]+)//){print "-T$1\n"}'
+indent:
+       find ./ -name "*.[ch]" | xargs indent
+
 ##END##
index 0fd18902396c46d47f43ef3a5d476b1a0fc63c44..549bcbd7464674b3950b756e90305d8c05c0f68e 100644 (file)
@@ -60,7 +60,7 @@ RECURSIVE_TARGETS = all-recursive check-recursive dvi-recursive \
        uninstall-recursive
 ETAGS = etags
 CTAGS = ctags
-DIST_SUBDIRS = $(SUBDIRS)
+DIST_SUBDIRS = po src examples doc bindings
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 distdir = $(PACKAGE)-$(VERSION)
 top_distdir = $(distdir)
@@ -74,6 +74,7 @@ distuninstallcheck_listfiles = find . -type f -print
 distcleancheck_listfiles = find . -type f -print
 ACLOCAL = @ACLOCAL@
 ALL_LIBS = @ALL_LIBS@
+ALL_LINGUAS = @ALL_LINGUAS@
 AMDEP_FALSE = @AMDEP_FALSE@
 AMDEP_TRUE = @AMDEP_TRUE@
 AMTAR = @AMTAR@
@@ -82,6 +83,8 @@ AUTOCONF = @AUTOCONF@
 AUTOHEADER = @AUTOHEADER@
 AUTOMAKE = @AUTOMAKE@
 AWK = @AWK@
+BUILD_LIBINTL_FALSE = @BUILD_LIBINTL_FALSE@
+BUILD_LIBINTL_TRUE = @BUILD_LIBINTL_TRUE@
 BUILD_MULTITHREAD_FALSE = @BUILD_MULTITHREAD_FALSE@
 BUILD_MULTITHREAD_TRUE = @BUILD_MULTITHREAD_TRUE@
 BUILD_RRDCGI_FALSE = @BUILD_RRDCGI_FALSE@
@@ -90,6 +93,8 @@ BUILD_TCL_FALSE = @BUILD_TCL_FALSE@
 BUILD_TCL_SITE_FALSE = @BUILD_TCL_SITE_FALSE@
 BUILD_TCL_SITE_TRUE = @BUILD_TCL_SITE_TRUE@
 BUILD_TCL_TRUE = @BUILD_TCL_TRUE@
+CATALOGS = @CATALOGS@
+CATOBJEXT = @CATOBJEXT@
 CC = @CC@
 CCDEPMODE = @CCDEPMODE@
 CFLAGS = @CFLAGS@
@@ -104,6 +109,7 @@ CXXCPP = @CXXCPP@
 CXXDEPMODE = @CXXDEPMODE@
 CXXFLAGS = @CXXFLAGS@
 CYGPATH_W = @CYGPATH_W@
+DATADIRNAME = @DATADIRNAME@
 DEFS = @DEFS@
 DEPDIR = @DEPDIR@
 ECHO = @ECHO@
@@ -114,18 +120,57 @@ EGREP = @EGREP@
 EXEEXT = @EXEEXT@
 F77 = @F77@
 FFLAGS = @FFLAGS@
+GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
+GMOFILES = @GMOFILES@
+GMSGFMT = @GMSGFMT@
 GREP = @GREP@
 INSTALL_DATA = @INSTALL_DATA@
 INSTALL_PROGRAM = @INSTALL_PROGRAM@
 INSTALL_SCRIPT = @INSTALL_SCRIPT@
 INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INSTOBJEXT = @INSTOBJEXT@
+INTLLIBS = @INTLLIBS@
+INTLTOOL_CAVES_RULE = @INTLTOOL_CAVES_RULE@
+INTLTOOL_DESKTOP_RULE = @INTLTOOL_DESKTOP_RULE@
+INTLTOOL_DIRECTORY_RULE = @INTLTOOL_DIRECTORY_RULE@
+INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@
+INTLTOOL_ICONV = @INTLTOOL_ICONV@
+INTLTOOL_KBD_RULE = @INTLTOOL_KBD_RULE@
+INTLTOOL_KEYS_RULE = @INTLTOOL_KEYS_RULE@
+INTLTOOL_MERGE = @INTLTOOL_MERGE@
+INTLTOOL_MSGFMT = @INTLTOOL_MSGFMT@
+INTLTOOL_MSGMERGE = @INTLTOOL_MSGMERGE@
+INTLTOOL_OAF_RULE = @INTLTOOL_OAF_RULE@
+INTLTOOL_PERL = @INTLTOOL_PERL@
+INTLTOOL_PONG_RULE = @INTLTOOL_PONG_RULE@
+INTLTOOL_PROP_RULE = @INTLTOOL_PROP_RULE@
+INTLTOOL_SCHEMAS_RULE = @INTLTOOL_SCHEMAS_RULE@
+INTLTOOL_SERVER_RULE = @INTLTOOL_SERVER_RULE@
+INTLTOOL_SERVICE_RULE = @INTLTOOL_SERVICE_RULE@
+INTLTOOL_SHEET_RULE = @INTLTOOL_SHEET_RULE@
+INTLTOOL_SOUNDLIST_RULE = @INTLTOOL_SOUNDLIST_RULE@
+INTLTOOL_THEME_RULE = @INTLTOOL_THEME_RULE@
+INTLTOOL_UI_RULE = @INTLTOOL_UI_RULE@
+INTLTOOL_UPDATE = @INTLTOOL_UPDATE@
+INTLTOOL_XAM_RULE = @INTLTOOL_XAM_RULE@
+INTLTOOL_XGETTEXT = @INTLTOOL_XGETTEXT@
+INTLTOOL_XML_NOMERGE_RULE = @INTLTOOL_XML_NOMERGE_RULE@
+INTLTOOL_XML_RULE = @INTLTOOL_XML_RULE@
 LDFLAGS = @LDFLAGS@
 LIBOBJS = @LIBOBJS@
 LIBS = @LIBS@
 LIBTOOL = @LIBTOOL@
+LIBVERS = @LIBVERS@
+LIB_LIBINTL = @LIB_LIBINTL@
 LN_S = @LN_S@
 LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@
+MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@
 MAKEINFO = @MAKEINFO@
+MKINSTALLDIRS = @MKINSTALLDIRS@
+MSGFMT = @MSGFMT@
+MSGFMT_OPTS = @MSGFMT_OPTS@
 MULTITHREAD_CFLAGS = @MULTITHREAD_CFLAGS@
 MULTITHREAD_LDFLAGS = @MULTITHREAD_LDFLAGS@
 NROFF = @NROFF@
@@ -148,6 +193,12 @@ PERL_CC = @PERL_CC@
 PERL_MAKE_OPTIONS = @PERL_MAKE_OPTIONS@
 PERL_VERSION = @PERL_VERSION@
 PKGCONFIG = @PKGCONFIG@
+POD2HTML = @POD2HTML@
+POD2MAN = @POD2MAN@
+POFILES = @POFILES@
+POSUB = @POSUB@
+PO_IN_DATADIR_FALSE = @PO_IN_DATADIR_FALSE@
+PO_IN_DATADIR_TRUE = @PO_IN_DATADIR_TRUE@
 PTHREAD_CC = @PTHREAD_CC@
 PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
 PTHREAD_LIBS = @PTHREAD_LIBS@
@@ -165,7 +216,10 @@ RUBY = @RUBY@
 RUBY_MAKE_OPTIONS = @RUBY_MAKE_OPTIONS@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
+STATIC_PROGRAMS_FALSE = @STATIC_PROGRAMS_FALSE@
+STATIC_PROGRAMS_TRUE = @STATIC_PROGRAMS_TRUE@
 STRIP = @STRIP@
+TCL_INC_DIR = @TCL_INC_DIR@
 TCL_LD_SEARCH_FLAGS = @TCL_LD_SEARCH_FLAGS@
 TCL_PACKAGE_DIR = @TCL_PACKAGE_DIR@
 TCL_PACKAGE_PATH = @TCL_PACKAGE_PATH@
@@ -176,7 +230,9 @@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@
 TCL_STUB_LIB_SPEC = @TCL_STUB_LIB_SPEC@
 TCL_VERSION = @TCL_VERSION@
 TROFF = @TROFF@
+USE_NLS = @USE_NLS@
 VERSION = @VERSION@
+XGETTEXT = @XGETTEXT@
 ac_ct_CC = @ac_ct_CC@
 ac_ct_CXX = @ac_ct_CXX@
 ac_ct_F77 = @ac_ct_F77@
@@ -234,12 +290,16 @@ target_cpu = @target_cpu@
 target_os = @target_os@
 target_vendor = @target_vendor@
 RSYNC = rsync --rsh=ssh
+@BUILD_LIBINTL_FALSE@PO = 
 
 # build the following subdirectories
-SUBDIRS = src doc examples bindings
+@BUILD_LIBINTL_TRUE@PO = po
+SUBDIRS = $(PO) src examples doc bindings
 EXTRA_DIST = COPYRIGHT CHANGES WIN32-BUILD-TIPS.txt TODO CONTRIBUTORS THREADS \
-            rrdtool.spec favicon.ico win32/config.h win32/rrd.dsp win32/rrd.vcproj \
-            win32/rrdtool.dsp win32/rrdtool.dsw win32/rrdtool.vcproj win32/Makefile \
+             intltool-extract.in  intltool-merge.in    intltool-update.in \
+            rrdtool.spec favicon.ico win32/config.h win32/rrd.dsp \
+            win32/rrd.vcproj win32/rrdtool.dsp win32/rrdtool.dsw \
+            win32/rrdtool.vcproj win32/Makefile \
             win32/rrd_config.h.msvc netware/Makefile
 
 CLEANFILES = config.cache
@@ -255,7 +315,7 @@ all: rrd_config.h
 .SUFFIXES:
 am--refresh:
        @:
-$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
        @for dep in $?; do \
          case '$(am__configure_deps)' in \
            *$$dep*) \
@@ -282,9 +342,9 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
 $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
        $(SHELL) ./config.status --recheck
 
-$(top_srcdir)/configure:  $(am__configure_deps)
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
        cd $(srcdir) && $(AUTOCONF)
-$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
        cd $(srcdir) && $(ACLOCAL) $(ACLOCAL_AMFLAGS)
 
 rrd_config.h: stamp-h1
@@ -296,7 +356,7 @@ rrd_config.h: stamp-h1
 stamp-h1: $(srcdir)/rrd_config.h.in $(top_builddir)/config.status
        @rm -f stamp-h1
        cd $(top_builddir) && $(SHELL) ./config.status rrd_config.h
-$(srcdir)/rrd_config.h.in:  $(am__configure_deps) 
+$(srcdir)/rrd_config.h.in: @MAINTAINER_MODE_TRUE@ $(am__configure_deps) 
        cd $(top_srcdir) && $(AUTOHEADER)
        rm -f stamp-h1
        touch $@
@@ -449,7 +509,7 @@ distclean-tags:
 distdir: $(DISTFILES)
        $(am__remove_distdir)
        mkdir $(distdir)
-       $(mkdir_p) $(distdir)/bindings/tcl $(distdir)/examples $(distdir)/netware $(distdir)/win32
+       $(mkdir_p) $(distdir)/bindings/tcl $(distdir)/examples $(distdir)/netware $(distdir)/po $(distdir)/win32
        @srcdirstrip=`echo "$(srcdir)" | sed 's|.|.|g'`; \
        topsrcdirstrip=`echo "$(top_srcdir)" | sed 's|.|.|g'`; \
        list='$(DISTFILES)'; for file in $$list; do \
@@ -686,7 +746,7 @@ uninstall-info: uninstall-info-recursive
        tags tags-recursive uninstall uninstall-am uninstall-info-am
 
 
 # the following files are not mentioned in any other Makefile
+ # the following files are not mentioned in any other Makefile
 #AUTOHEADER = @AUTOHEADER@ --localdir=$(top_srcdir)/config
 #AUTOCONF = @AUTOCONF@ --localdir=$(top_srcdir)/config
 
@@ -713,6 +773,10 @@ site-tcl-install: all
 
 site-python-install: all
        cd bindings/python && $(PYTHON) setup.py install
+
+# find . -name "*.c" -or -name "*.h" | xargs perl -0777 -n -e 'while (s/typedef\s+(?:unsigned\s+|signed\s+|unival\s+)?\S+\s+\*?([^{}\s;(]+)//){print "-T$1\n"}'
+indent:
+       find ./ -name "*.[ch]" | xargs indent
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
 # Otherwise a system limit (for SysV at least) may be exceeded.
 .NOEXPORT:
diff --git a/NEWS b/NEWS
index 156864e7f855a28165ec662c4145ab185ba8a7bd..2d2abf789e59bb12c268f2dacf9fe3f8911bb480 100644 (file)
--- a/NEWS
+++ b/NEWS
@@ -1,3 +1,81 @@
+RRDTOOL NEWS
+============
+Major Changes between 1.2.x and 1.3.x
+
+RRdtool dump / restore Incompatibilities
+----------------------------------------
+rrdtool dump 1.3 does emit completely legal xml. Basically this means that
+it contains an xml header and a DOCTYPE definition. Unfortunately this
+causes older versions of rrdtool restore to be unhappy.
+
+To restore a new dump with ann old rrdtool restore version, either remove
+the xml header and the doctype by hand (both on the first line of the dump)
+or use rrdtool dump --no-header.
+
+NEW File access methods (Bernhard Fischer)
+-------------------
+* introduced file-accessor functions rrd_read/rrd_seek/rrd_write
+* implemented full mmap-based file access with madvise hints for improved
+  scalability, much reduced memory-footprint and much less blocking on
+  disk
+* implemented optional full file-descriptor access instead of FILE* access
+
+NEW Graphing (Tobi Oetiker)
+--------
+* libart has been replaced by cairo/pango
+* pango markup is supported
+* full gridfitting 
+* --graph-render-mode=mono for non antialiased graphing
+* --font-render-mode=mono for non antialiased fonts
+* fonts come through fontconfig, use the Pango fontnameing
+  scheme -> 'Times 20' ... it is not possible to use
+  truetype fonts directly anymore.
+* Tabs are position independent.
+* TRENDNAN filter that ignores NAN values while caculating the TREND data. (Timo Stripf)
+* --full-size-mode to specify the outer border of the image and not just of the graphing canvas (Matthew Chambers)
+* TEXTALIGN command to alter default text alignment behaviour
+* C API in-memory graphing with rrd_graph_v (Evan Miller)
+* draw dashed lines in graphs (Thomas Gutzler)
+* new interface graphv which returns inforamation using the rrd_info
+  interface (Tobi Oetiker and Mark Plaksin)
+
+NEW Forecasting (Evan Miller)
+-----------
+* the new MHWPREDICT consolidation function uses a variation of the Holt-Winters
+  method. It is a drop-in replacement for HWPREDICT, and is better suited for
+  data whose seasonal variations grow or shrink in proportion to the average.
+
+* If you create an RRD with the new MHWPREDICT function, the resulting
+  rrdfile will be version 0004 and can only be used in rrdtool 1.3.
+
+Rewrites
+--------
+* rrd_restore now uses libxml for parsing which makes things much more
+  tolerant towards xml variations. The old code could mostly just parse the
+  xml as it was output by rrdtool dump. See also: 'incompatibilities' at the
+  top of this document. (by Florian octo Forster)
+
+* rrd_update rewritten to make it more modular. Fixed two longstanding
+  HW bugs in the process (Evan Miller)
+
+Internationalization (Takao Fujiwara and Tobi Oetiker)
+--------------------
+* The help output by rrdtool has been internationalized. There are no real
+  translations included with rrdtool yet, contributions are welcome.
+* The internationalization will only be compiled if libintl and friends are
+  available on your system. Use the configure option --disable-libintl if
+  you want to disable this feature
+
+Misc
+----
+* ruby rrd_fetch will return step as a last property -- Mike Perham
+
+Locale Independent Numeric Input
+--------------------------------
+* Regardles of locale you are in, rrdtool always expects input to be numbers
+  (LC_NUMERIC) in C or POSIX locale for numbers. (not 1,1 but 1.1) this is
+  necessary to make things like RPN work as it uses , as a separator.
+
 RRDTOOL NEWS
 ============
 Major Changes between 1.0.x and 1.2.x
index b71fe8e8058dd75b7414fcbcf3b37b18739c8ed1..38ee0c29f69347d63e9e6f25d50d116822925558 100644 (file)
@@ -36,9 +36,9 @@ AC_DEFUN([EX_CHECK_ALL],
              LDFLAGS=${LDFLAGS}" "`$PKGCONFIG --libs-only-other $4`
              LIBS=${LIBS}" "`$PKGCONFIG --libs-only-l $4`
             dnl remove the cached value and test again
-            unset ac_cv_lib_$1_$2
+            unset ac_cv_lib_`echo $1 | sed ['s/[^_a-zA-Z0-9]/_/g;s/^[0-9]/_/']`_$2
              AC_CHECK_LIB($1,$2,[
-                unset ac_cv_header_`echo $3 | sed ['s/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/']`
+                unset ac_cv_header_`echo $3 | sed ['s/[^_a-zA-Z0-9]/_/g;s/^[0-9]/_/']`
                 AC_CHECK_HEADER($3,[EX_CHECK_STATE=YES],[])
             ],[])
           else
index 8401174980236559a3f6de49e34db0a542e61f9f..54e8388e516b8de6ac644058e9afdb1227a764a7 100644 (file)
 # even the implied warranty of MERCHANTABILITY or FITNESS FOR A
 # PARTICULAR PURPOSE.
 
+# Copyright (C) 1995-2002 Free Software Foundation, Inc.
+# Copyright (C) 2001-2003,2004 Red Hat, Inc.
+#
+# This file is free software, distributed under the terms of the GNU
+# General Public License.  As a special exception to the GNU General
+# Public License, this file may be distributed as part of a program
+# that contains a configuration script generated by Autoconf, under
+# the same distribution terms as the rest of that program.
+#
+# This file can be copied and used freely without restrictions.  It can
+# be used in projects which are not available under the GNU Public License
+# but which still want to provide support for the GNU gettext functionality.
+#
+# Macro to add for using GNU gettext.
+# Ulrich Drepper <drepper@cygnus.com>, 1995, 1996
+#
+# Modified to never use included libintl. 
+# Owen Taylor <otaylor@redhat.com>, 12/15/1998
+#
+# Major rework to remove unused code
+# Owen Taylor <otaylor@redhat.com>, 12/11/2002
+#
+# Added better handling of ALL_LINGUAS from GNU gettext version 
+# written by Bruno Haible, Owen Taylor <otaylor.redhat.com> 5/30/3002
+#
+# Modified to require ngettext
+# Matthias Clasen <mclasen@redhat.com> 08/06/2004
+#
+# We need this here as well, since someone might use autoconf-2.5x
+# to configure GLib then an older version to configure a package
+# using AM_GLIB_GNU_GETTEXT
+AC_PREREQ(2.53)
+
+dnl
+dnl We go to great lengths to make sure that aclocal won't 
+dnl try to pull in the installed version of these macros
+dnl when running aclocal in the glib directory.
+dnl
+m4_copy([AC_DEFUN],[glib_DEFUN])
+m4_copy([AC_REQUIRE],[glib_REQUIRE])
+dnl
+dnl At the end, if we're not within glib, we'll define the public
+dnl definitions in terms of our private definitions.
+dnl
+
+# GLIB_LC_MESSAGES
+#--------------------
+glib_DEFUN([GLIB_LC_MESSAGES],
+  [AC_CHECK_HEADERS([locale.h])
+    if test $ac_cv_header_locale_h = yes; then
+    AC_CACHE_CHECK([for LC_MESSAGES], am_cv_val_LC_MESSAGES,
+      [AC_TRY_LINK([#include <locale.h>], [return LC_MESSAGES],
+       am_cv_val_LC_MESSAGES=yes, am_cv_val_LC_MESSAGES=no)])
+    if test $am_cv_val_LC_MESSAGES = yes; then
+      AC_DEFINE(HAVE_LC_MESSAGES, 1,
+        [Define if your <locale.h> file defines LC_MESSAGES.])
+    fi
+  fi])
+
+# GLIB_PATH_PROG_WITH_TEST
+#----------------------------
+dnl GLIB_PATH_PROG_WITH_TEST(VARIABLE, PROG-TO-CHECK-FOR,
+dnl   TEST-PERFORMED-ON-FOUND_PROGRAM [, VALUE-IF-NOT-FOUND [, PATH]])
+glib_DEFUN([GLIB_PATH_PROG_WITH_TEST],
+[# Extract the first word of "$2", so it can be a program name with args.
+set dummy $2; ac_word=[$]2
+AC_MSG_CHECKING([for $ac_word])
+AC_CACHE_VAL(ac_cv_path_$1,
+[case "[$]$1" in
+  /*)
+  ac_cv_path_$1="[$]$1" # Let the user override the test with a path.
+  ;;
+  *)
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+  for ac_dir in ifelse([$5], , $PATH, [$5]); do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      if [$3]; then
+       ac_cv_path_$1="$ac_dir/$ac_word"
+       break
+      fi
+    fi
+  done
+  IFS="$ac_save_ifs"
+dnl If no 4th arg is given, leave the cache variable unset,
+dnl so AC_PATH_PROGS will keep looking.
+ifelse([$4], , , [  test -z "[$]ac_cv_path_$1" && ac_cv_path_$1="$4"
+])dnl
+  ;;
+esac])dnl
+$1="$ac_cv_path_$1"
+if test ifelse([$4], , [-n "[$]$1"], ["[$]$1" != "$4"]); then
+  AC_MSG_RESULT([$]$1)
+else
+  AC_MSG_RESULT(no)
+fi
+AC_SUBST($1)dnl
+])
+
+# GLIB_WITH_NLS
+#-----------------
+glib_DEFUN([GLIB_WITH_NLS],
+  dnl NLS is obligatory
+  [AC_REQUIRE([AC_CANONICAL_HOST])dnl
+    USE_NLS=yes
+    AC_SUBST(USE_NLS)
+
+    gt_cv_have_gettext=no
+
+    CATOBJEXT=NONE
+    XGETTEXT=:
+    INTLLIBS=
+
+    AC_CHECK_HEADER(libintl.h,
+     [gt_cv_func_dgettext_libintl="no"
+      libintl_extra_libs=""
+
+      #
+      # First check in libc
+      #
+      AC_CACHE_CHECK([for ngettext in libc], gt_cv_func_ngettext_libc,
+        [AC_TRY_LINK([
+#include <libintl.h>
+],
+         [return !ngettext ("","", 1)],
+         gt_cv_func_ngettext_libc=yes,
+          gt_cv_func_ngettext_libc=no)
+        ])
+  
+      if test "$gt_cv_func_ngettext_libc" = "yes" ; then
+             AC_CACHE_CHECK([for dgettext in libc], gt_cv_func_dgettext_libc,
+               [AC_TRY_LINK([
+#include <libintl.h>
+],
+                 [return !dgettext ("","")],
+                 gt_cv_func_dgettext_libc=yes,
+                 gt_cv_func_dgettext_libc=no)
+               ])
+      fi
+  
+      if test "$gt_cv_func_ngettext_libc" = "yes" ; then
+        AC_CHECK_FUNCS(bind_textdomain_codeset)
+      fi
+
+      #
+      # If we don't have everything we want, check in libintl
+      #
+      if test "$gt_cv_func_dgettext_libc" != "yes" \
+        || test "$gt_cv_func_ngettext_libc" != "yes" \
+         || test "$ac_cv_func_bind_textdomain_codeset" != "yes" ; then
+        
+        AC_CHECK_LIB(intl, bindtextdomain,
+           [AC_CHECK_LIB(intl, ngettext,
+                   [AC_CHECK_LIB(intl, dgettext,
+                                 gt_cv_func_dgettext_libintl=yes)])])
+
+       if test "$gt_cv_func_dgettext_libintl" != "yes" ; then
+         AC_MSG_CHECKING([if -liconv is needed to use gettext])
+         AC_MSG_RESULT([])
+         AC_CHECK_LIB(intl, ngettext,
+               [AC_CHECK_LIB(intl, dcgettext,
+                      [gt_cv_func_dgettext_libintl=yes
+                       libintl_extra_libs=-liconv],
+                       :,-liconv)],
+               :,-liconv)
+        fi
+
+        #
+        # If we found libintl, then check in it for bind_textdomain_codeset();
+        # we'll prefer libc if neither have bind_textdomain_codeset(),
+        # and both have dgettext and ngettext
+        #
+        if test "$gt_cv_func_dgettext_libintl" = "yes" ; then
+          glib_save_LIBS="$LIBS"
+          LIBS="$LIBS -lintl $libintl_extra_libs"
+          unset ac_cv_func_bind_textdomain_codeset
+          AC_CHECK_FUNCS(bind_textdomain_codeset)
+          LIBS="$glib_save_LIBS"
+
+          if test "$ac_cv_func_bind_textdomain_codeset" = "yes" ; then
+            gt_cv_func_dgettext_libc=no
+          else
+            if test "$gt_cv_func_dgettext_libc" = "yes" \
+               && test "$gt_cv_func_ngettext_libc" = "yes"; then
+              gt_cv_func_dgettext_libintl=no
+            fi
+          fi
+        fi
+      fi
+
+      if test "$gt_cv_func_dgettext_libc" = "yes" \
+       || test "$gt_cv_func_dgettext_libintl" = "yes"; then
+        gt_cv_have_gettext=yes
+      fi
+  
+      if test "$gt_cv_func_dgettext_libintl" = "yes"; then
+        INTLLIBS="-lintl $libintl_extra_libs"
+      fi
+  
+      if test "$gt_cv_have_gettext" = "yes"; then
+       AC_DEFINE(HAVE_GETTEXT,1,
+         [Define if the GNU gettext() function is already present or preinstalled.])
+       GLIB_PATH_PROG_WITH_TEST(MSGFMT, msgfmt,
+         [test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"], no)dnl
+       if test "$MSGFMT" != "no"; then
+          glib_save_LIBS="$LIBS"
+          LIBS="$LIBS $INTLLIBS"
+         AC_CHECK_FUNCS(dcgettext)
+         MSGFMT_OPTS=
+         AC_MSG_CHECKING([if msgfmt accepts -c])
+         GLIB_RUN_PROG([msgfmt -c -o /dev/null],[
+msgid ""
+msgstr ""
+"Content-Type: text/plain; charset=UTF-8\n"
+"Project-Id-Version: test 1.0\n"
+"PO-Revision-Date: 2007-02-15 12:01+0100\n"
+"Last-Translator: test <foo@bar.xx>\n"
+"Language-Team: C <LL@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Transfer-Encoding: 8bit\n"
+], [MSGFMT_OPTS=-c; AC_MSG_RESULT([yes])], [AC_MSG_RESULT([no])])
+         AC_SUBST(MSGFMT_OPTS)
+         AC_PATH_PROG(GMSGFMT, gmsgfmt, $MSGFMT)
+         GLIB_PATH_PROG_WITH_TEST(XGETTEXT, xgettext,
+           [test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"], :)
+         AC_TRY_LINK(, [extern int _nl_msg_cat_cntr;
+                        return _nl_msg_cat_cntr],
+           [CATOBJEXT=.gmo 
+             DATADIRNAME=share],
+           [case $host in
+           *-*-solaris*)
+           dnl On Solaris, if bind_textdomain_codeset is in libc,
+           dnl GNU format message catalog is always supported,
+            dnl since both are added to the libc all together.
+           dnl Hence, we'd like to go with DATADIRNAME=share and
+           dnl and CATOBJEXT=.gmo in this case.
+            AC_CHECK_FUNC(bind_textdomain_codeset,
+             [CATOBJEXT=.gmo 
+               DATADIRNAME=share],
+             [CATOBJEXT=.mo
+               DATADIRNAME=lib])
+           ;;
+           *)
+           CATOBJEXT=.mo
+            DATADIRNAME=lib
+           ;;
+           esac])
+          LIBS="$glib_save_LIBS"
+         INSTOBJEXT=.mo
+       else
+         gt_cv_have_gettext=no
+       fi
+      fi
+    ])
+
+    if test "$gt_cv_have_gettext" = "yes" ; then
+      AC_DEFINE(ENABLE_NLS, 1,
+        [always defined to indicate that i18n is enabled])
+    fi
+
+    dnl Test whether we really found GNU xgettext.
+    if test "$XGETTEXT" != ":"; then
+      dnl If it is not GNU xgettext we define it as : so that the
+      dnl Makefiles still can work.
+      if $XGETTEXT --omit-header /dev/null 2> /dev/null; then
+        : ;
+      else
+        AC_MSG_RESULT(
+         [found xgettext program is not GNU xgettext; ignore it])
+        XGETTEXT=":"
+      fi
+    fi
+
+    # We need to process the po/ directory.
+    POSUB=po
+
+    AC_OUTPUT_COMMANDS(
+      [case "$CONFIG_FILES" in *po/Makefile.in*)
+        sed -e "/POTFILES =/r po/POTFILES" po/Makefile.in > po/Makefile
+      esac])
+
+    dnl These rules are solely for the distribution goal.  While doing this
+    dnl we only have to keep exactly one list of the available catalogs
+    dnl in configure.in.
+    for lang in $ALL_LINGUAS; do
+      GMOFILES="$GMOFILES $lang.gmo"
+      POFILES="$POFILES $lang.po"
+    done
+
+    dnl Make all variables we use known to autoconf.
+    AC_SUBST(CATALOGS)
+    AC_SUBST(CATOBJEXT)
+    AC_SUBST(DATADIRNAME)
+    AC_SUBST(GMOFILES)
+    AC_SUBST(INSTOBJEXT)
+    AC_SUBST(INTLLIBS)
+    AC_SUBST(PO_IN_DATADIR_TRUE)
+    AC_SUBST(PO_IN_DATADIR_FALSE)
+    AC_SUBST(POFILES)
+    AC_SUBST(POSUB)
+  ])
+
+# AM_GLIB_GNU_GETTEXT
+# -------------------
+# Do checks necessary for use of gettext. If a suitable implementation 
+# of gettext is found in either in libintl or in the C library,
+# it will set INTLLIBS to the libraries needed for use of gettext
+# and AC_DEFINE() HAVE_GETTEXT and ENABLE_NLS. (The shell variable
+# gt_cv_have_gettext will be set to "yes".) It will also call AC_SUBST()
+# on various variables needed by the Makefile.in.in installed by 
+# glib-gettextize.
+dnl
+glib_DEFUN([GLIB_GNU_GETTEXT],
+  [AC_REQUIRE([AC_PROG_CC])dnl
+   AC_REQUIRE([AC_HEADER_STDC])dnl
+   
+   GLIB_LC_MESSAGES
+   GLIB_WITH_NLS
+
+   if test "$gt_cv_have_gettext" = "yes"; then
+     if test "x$ALL_LINGUAS" = "x"; then
+       LINGUAS=
+     else
+       AC_MSG_CHECKING(for catalogs to be installed)
+       NEW_LINGUAS=
+       for presentlang in $ALL_LINGUAS; do
+         useit=no
+         if test "%UNSET%" != "${LINGUAS-%UNSET%}"; then
+           desiredlanguages="$LINGUAS"
+         else
+           desiredlanguages="$ALL_LINGUAS"
+         fi
+         for desiredlang in $desiredlanguages; do
+          # Use the presentlang catalog if desiredlang is
+           #   a. equal to presentlang, or
+           #   b. a variant of presentlang (because in this case,
+           #      presentlang can be used as a fallback for messages
+           #      which are not translated in the desiredlang catalog).
+           case "$desiredlang" in
+             "$presentlang"*) useit=yes;;
+           esac
+         done
+         if test $useit = yes; then
+           NEW_LINGUAS="$NEW_LINGUAS $presentlang"
+         fi
+       done
+       LINGUAS=$NEW_LINGUAS
+       AC_MSG_RESULT($LINGUAS)
+     fi
+
+     dnl Construct list of names of catalog files to be constructed.
+     if test -n "$LINGUAS"; then
+       for lang in $LINGUAS; do CATALOGS="$CATALOGS $lang$CATOBJEXT"; done
+     fi
+   fi
+
+   dnl If the AC_CONFIG_AUX_DIR macro for autoconf is used we possibly
+   dnl find the mkinstalldirs script in another subdir but ($top_srcdir).
+   dnl Try to locate is.
+   MKINSTALLDIRS=
+   if test -n "$ac_aux_dir"; then
+     MKINSTALLDIRS="$ac_aux_dir/mkinstalldirs"
+   fi
+   if test -z "$MKINSTALLDIRS"; then
+     MKINSTALLDIRS="\$(top_srcdir)/mkinstalldirs"
+   fi
+   AC_SUBST(MKINSTALLDIRS)
+
+   dnl Generate list of files to be processed by xgettext which will
+   dnl be included in po/Makefile.
+   test -d po || mkdir po
+   if test "x$srcdir" != "x."; then
+     if test "x`echo $srcdir | sed 's@/.*@@'`" = "x"; then
+       posrcprefix="$srcdir/"
+     else
+       posrcprefix="../$srcdir/"
+     fi
+   else
+     posrcprefix="../"
+   fi
+   rm -f po/POTFILES
+   sed -e "/^#/d" -e "/^\$/d" -e "s,.*,        $posrcprefix& \\\\," -e "\$s/\(.*\) \\\\/\1/" \
+       < $srcdir/po/POTFILES.in > po/POTFILES
+  ])
+
+# AM_GLIB_DEFINE_LOCALEDIR(VARIABLE)
+# -------------------------------
+# Define VARIABLE to the location where catalog files will
+# be installed by po/Makefile.
+glib_DEFUN([GLIB_DEFINE_LOCALEDIR],
+[glib_REQUIRE([GLIB_GNU_GETTEXT])dnl
+glib_save_prefix="$prefix"
+glib_save_exec_prefix="$exec_prefix"
+glib_save_datarootdir="$datarootdir"
+test "x$prefix" = xNONE && prefix=$ac_default_prefix
+test "x$exec_prefix" = xNONE && exec_prefix=$prefix
+datarootdir=`eval echo "${datarootdir}"`
+if test "x$CATOBJEXT" = "x.mo" ; then
+  localedir=`eval echo "${libdir}/locale"`
+else
+  localedir=`eval echo "${datadir}/locale"`
+fi
+prefix="$glib_save_prefix"
+exec_prefix="$glib_save_exec_prefix"
+datarootdir="$glib_save_datarootdir"
+AC_DEFINE_UNQUOTED($1, "$localedir",
+  [Define the location where the catalogs will be installed])
+])
+
+dnl
+dnl Now the definitions that aclocal will find
+dnl
+ifdef(glib_configure_in,[],[
+AC_DEFUN([AM_GLIB_GNU_GETTEXT],[GLIB_GNU_GETTEXT($@)])
+AC_DEFUN([AM_GLIB_DEFINE_LOCALEDIR],[GLIB_DEFINE_LOCALEDIR($@)])
+])dnl
+
+# GLIB_RUN_PROG(PROGRAM, TEST-FILE, [ACTION-IF-PASS], [ACTION-IF-FAIL])
+# 
+# Create a temporary file with TEST-FILE as its contents and pass the
+# file name to PROGRAM.  Perform ACTION-IF-PASS if PROGRAM exits with
+# 0 and perform ACTION-IF-FAIL for any other exit status.
+AC_DEFUN([GLIB_RUN_PROG],
+[cat >conftest.foo <<_ACEOF
+$2
+_ACEOF
+if AC_RUN_LOG([$1 conftest.foo]); then
+  m4_ifval([$3], [$3], [:])
+m4_ifvaln([$4], [else $4])dnl
+echo "$as_me: failed input was:" >&AS_MESSAGE_LOG_FD
+sed 's/^/| /' conftest.foo >&AS_MESSAGE_LOG_FD
+fi])
+
+
+
+dnl IT_PROG_INTLTOOL([MINIMUM-VERSION], [no-xml])
+# serial 35 IT_PROG_INTLTOOL
+AC_DEFUN([IT_PROG_INTLTOOL],
+[AC_PREREQ([2.50])dnl
+
+case "$am__api_version" in
+    1.[01234])
+       AC_MSG_ERROR([Automake 1.5 or newer is required to use intltool])
+    ;;
+    *)
+    ;;
+esac
+
+if test -n "$1"; then
+    AC_MSG_CHECKING(for intltool >= $1)
+
+    INTLTOOL_REQUIRED_VERSION_AS_INT=`echo $1 | awk -F. '{ print $ 1 * 1000 + $ 2 * 100 + $ 3; }'`
+    INTLTOOL_APPLIED_VERSION=`awk -F\" '/\\$VERSION / { print $ 2; }' ${ac_aux_dir}/intltool-update.in`
+    [INTLTOOL_APPLIED_VERSION_AS_INT=`awk -F\" '/\\$VERSION / { split($ 2, VERSION, "."); print VERSION[1] * 1000 + VERSION[2] * 100 + VERSION[3];}' ${ac_aux_dir}/intltool-update.in`
+    ]
+    AC_MSG_RESULT([$INTLTOOL_APPLIED_VERSION found])
+    test "$INTLTOOL_APPLIED_VERSION_AS_INT" -ge "$INTLTOOL_REQUIRED_VERSION_AS_INT" ||
+       AC_MSG_ERROR([Your intltool is too old.  You need intltool $1 or later.])
+fi
+
+  INTLTOOL_DESKTOP_RULE='%.desktop:   %.desktop.in   $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@' 
+INTLTOOL_DIRECTORY_RULE='%.directory: %.directory.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@' 
+     INTLTOOL_KEYS_RULE='%.keys:      %.keys.in      $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -k -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@' 
+     INTLTOOL_PROP_RULE='%.prop:      %.prop.in      $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@' 
+      INTLTOOL_OAF_RULE='%.oaf:       %.oaf.in       $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -o -p $(top_srcdir)/po $< [$]@'
+     INTLTOOL_PONG_RULE='%.pong:      %.pong.in      $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -x -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@' 
+   INTLTOOL_SERVER_RULE='%.server:    %.server.in    $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -o -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@' 
+    INTLTOOL_SHEET_RULE='%.sheet:     %.sheet.in     $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -x -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@' 
+INTLTOOL_SOUNDLIST_RULE='%.soundlist: %.soundlist.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@' 
+       INTLTOOL_UI_RULE='%.ui:        %.ui.in        $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -x -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@' 
+      INTLTOOL_XML_RULE='%.xml:       %.xml.in       $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -x -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@' 
+      INTLTOOL_XML_NOMERGE_RULE='%.xml:       %.xml.in       $(INTLTOOL_MERGE) ; LC_ALL=C $(INTLTOOL_MERGE) -x -u /tmp $< [$]@' 
+      INTLTOOL_XAM_RULE='%.xam:       %.xml.in       $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -x -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@' 
+      INTLTOOL_KBD_RULE='%.kbd:       %.kbd.in       $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -x -u -m -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@' 
+    INTLTOOL_CAVES_RULE='%.caves:     %.caves.in     $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@' 
+  INTLTOOL_SCHEMAS_RULE='%.schemas:   %.schemas.in   $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -s -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@' 
+    INTLTOOL_THEME_RULE='%.theme:     %.theme.in     $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@' 
+    INTLTOOL_SERVICE_RULE='%.service: %.service.in   $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< [$]@'
+
+AC_SUBST(INTLTOOL_DESKTOP_RULE)
+AC_SUBST(INTLTOOL_DIRECTORY_RULE)
+AC_SUBST(INTLTOOL_KEYS_RULE)
+AC_SUBST(INTLTOOL_PROP_RULE)
+AC_SUBST(INTLTOOL_OAF_RULE)
+AC_SUBST(INTLTOOL_PONG_RULE)
+AC_SUBST(INTLTOOL_SERVER_RULE)
+AC_SUBST(INTLTOOL_SHEET_RULE)
+AC_SUBST(INTLTOOL_SOUNDLIST_RULE)
+AC_SUBST(INTLTOOL_UI_RULE)
+AC_SUBST(INTLTOOL_XAM_RULE)
+AC_SUBST(INTLTOOL_KBD_RULE)
+AC_SUBST(INTLTOOL_XML_RULE)
+AC_SUBST(INTLTOOL_XML_NOMERGE_RULE)
+AC_SUBST(INTLTOOL_CAVES_RULE)
+AC_SUBST(INTLTOOL_SCHEMAS_RULE)
+AC_SUBST(INTLTOOL_THEME_RULE)
+AC_SUBST(INTLTOOL_SERVICE_RULE)
+
+# Use the tools built into the package, not the ones that are installed.
+AC_SUBST(INTLTOOL_EXTRACT, '$(top_builddir)/intltool-extract')
+AC_SUBST(INTLTOOL_MERGE, '$(top_builddir)/intltool-merge')
+AC_SUBST(INTLTOOL_UPDATE, '$(top_builddir)/intltool-update')
+
+AC_PATH_PROG(INTLTOOL_PERL, perl)
+if test -z "$INTLTOOL_PERL"; then
+   AC_MSG_ERROR([perl not found; required for intltool])
+fi
+if test -z "`$INTLTOOL_PERL -v | fgrep '5.' 2> /dev/null`"; then
+   AC_MSG_ERROR([perl 5.x required for intltool])
+fi
+if test "x$2" != "xno-xml"; then
+   AC_MSG_CHECKING([for XML::Parser])
+   if `$INTLTOOL_PERL -e "require XML::Parser" 2>/dev/null`; then
+       AC_MSG_RESULT([ok])
+   else
+       AC_MSG_ERROR([XML::Parser perl module is required for intltool])
+   fi
+fi
+
+AC_PATH_PROG(INTLTOOL_ICONV, iconv, iconv)
+AC_PATH_PROG(INTLTOOL_MSGFMT, msgfmt, msgfmt)
+AC_PATH_PROG(INTLTOOL_MSGMERGE, msgmerge, msgmerge)
+AC_PATH_PROG(INTLTOOL_XGETTEXT, xgettext, xgettext)
+
+# Substitute ALL_LINGUAS so we can use it in po/Makefile
+AC_SUBST(ALL_LINGUAS)
+
+# Set DATADIRNAME correctly if it is not set yet
+# (copied from glib-gettext.m4)
+if test -z "$DATADIRNAME"; then
+  AC_TRY_LINK(, [extern int _nl_msg_cat_cntr;
+                 return _nl_msg_cat_cntr],
+    [DATADIRNAME=share],
+    [case $host in
+    *-*-solaris*)
+    dnl On Solaris, if bind_textdomain_codeset is in libc,
+    dnl GNU format message catalog is always supported,
+    dnl since both are added to the libc all together.
+    dnl Hence, we'd like to go with DATADIRNAME=share
+    dnl in this case.
+    AC_CHECK_FUNC(bind_textdomain_codeset,
+      [DATADIRNAME=share], [DATADIRNAME=lib])
+    ;;
+    *)
+    [DATADIRNAME=lib]
+    ;;
+    esac])
+fi
+AC_SUBST(DATADIRNAME)
+
+IT_PO_SUBDIR([po])
+
+dnl The following is very similar to
+dnl
+dnl    AC_CONFIG_FILES([intltool-extract intltool-merge intltool-update])
+dnl
+dnl with the following slight differences:
+dnl  - the *.in files are in ac_aux_dir,
+dnl  - if the file haven't changed upon reconfigure, it's not touched,
+dnl  - the evaluation of the third parameter enables a hack which computes
+dnl    the actual value of $libdir,
+dnl  - the user sees "executing intltool commands", instead of
+dnl    "creating intltool-extract" and such.
+dnl
+dnl Nothing crucial here, and we could use AC_CONFIG_FILES, if there were
+dnl a reason for it.
+
+AC_CONFIG_COMMANDS([intltool], [
+
+for file in intltool-extract intltool-merge intltool-update; do
+  sed -e "s|@INTLTOOL_EXTRACT@|`pwd`/intltool-extract|g" \
+      -e "s|@INTLTOOL_LIBDIR@|${INTLTOOL_LIBDIR}|g" \
+      -e "s|@INTLTOOL_ICONV@|${INTLTOOL_ICONV}|g" \
+      -e "s|@INTLTOOL_MSGFMT@|${INTLTOOL_MSGFMT}|g" \
+      -e "s|@INTLTOOL_MSGMERGE@|${INTLTOOL_MSGMERGE}|g" \
+      -e "s|@INTLTOOL_XGETTEXT@|${INTLTOOL_XGETTEXT}|g" \
+      -e "s|@INTLTOOL_PERL@|${INTLTOOL_PERL}|g" \
+       < ${ac_aux_dir}/${file}.in > ${file}.out
+  if cmp -s ${file} ${file}.out 2>/dev/null; then
+    rm -f ${file}.out
+  else
+    mv -f ${file}.out ${file}
+  fi
+  chmod ugo+x ${file}
+  chmod u+w ${file}
+done
+
+],
+[INTLTOOL_PERL='${INTLTOOL_PERL}' ac_aux_dir='${ac_aux_dir}'
+prefix="$prefix" exec_prefix="$exec_prefix" INTLTOOL_LIBDIR="$libdir" 
+INTLTOOL_EXTRACT='${INTLTOOL_EXTRACT}' INTLTOOL_ICONV='${INTLTOOL_ICONV}'
+INTLTOOL_MSGFMT='${INTLTOOL_MSGFMT}' INTLTOOL_MSGMERGE='${INTLTOOL_MSGMERGE}'
+INTLTOOL_XGETTEXT='${INTLTOOL_XGETTEXT}'])
+
+])
+
+
+# IT_PO_SUBDIR(DIRNAME)
+# ---------------------
+# All po subdirs have to be declared with this macro; the subdir "po" is
+# declared by IT_PROG_INTLTOOL.
+#
+AC_DEFUN([IT_PO_SUBDIR],
+[AC_PREREQ([2.53])dnl We use ac_top_srcdir inside AC_CONFIG_COMMANDS.
+dnl
+dnl The following CONFIG_COMMANDS should be exetuted at the very end
+dnl of config.status.
+AC_CONFIG_COMMANDS_PRE([
+  AC_CONFIG_COMMANDS([$1/stamp-it], [
+    rm -f "$1/stamp-it" "$1/stamp-it.tmp" "$1/POTFILES" "$1/Makefile.tmp"
+    >"$1/stamp-it.tmp"
+    [sed '/^#/d
+        s/^[[].*] *//
+        /^[    ]*$/d
+       '"s|^|  $ac_top_srcdir/|" \
+      "$srcdir/$1/POTFILES.in" | sed '$!s/$/ \\/' >"$1/POTFILES"
+    ]
+    if test ! -f "$1/Makefile"; then
+      AC_MSG_ERROR([$1/Makefile is not ready.])
+    fi
+    mv "$1/Makefile" "$1/Makefile.tmp"
+    [sed '/^POTFILES =/,/[^\\]$/ {
+               /^POTFILES =/!d
+               r $1/POTFILES
+         }
+        ' "$1/Makefile.tmp" >"$1/Makefile"]
+    rm -f "$1/Makefile.tmp"
+    mv "$1/stamp-it.tmp" "$1/stamp-it"
+  ])
+])dnl
+])
+
+
+# deprecated macros
+AU_ALIAS([AC_PROG_INTLTOOL], [IT_PROG_INTLTOOL])
+# A hint is needed for aclocal from Automake <= 1.9.4:
+# AC_DEFUN([AC_PROG_INTLTOOL], ...)
+
+
 # libtool.m4 - Configure libtool for the host system. -*-Autoconf-*-
 
 # serial 48 Debian 1.5.22-4 AC_PROG_LIBTOOL
@@ -6858,6 +7497,35 @@ fi
 rmdir .tst 2>/dev/null
 AC_SUBST([am__leading_dot])])
 
+# Add --enable-maintainer-mode option to configure.         -*- Autoconf -*-
+# From Jim Meyering
+
+# Copyright (C) 1996, 1998, 2000, 2001, 2002, 2003, 2004, 2005
+# Free Software Foundation, Inc.
+#
+# This file is free software; the Free Software Foundation
+# gives unlimited permission to copy and/or distribute it,
+# with or without modifications, as long as this notice is preserved.
+
+# serial 4
+
+AC_DEFUN([AM_MAINTAINER_MODE],
+[AC_MSG_CHECKING([whether to enable maintainer-specific portions of Makefiles])
+  dnl maintainer-mode is disabled by default
+  AC_ARG_ENABLE(maintainer-mode,
+[  --enable-maintainer-mode  enable make rules and dependencies not useful
+                         (and sometimes confusing) to the casual installer],
+      USE_MAINTAINER_MODE=$enableval,
+      USE_MAINTAINER_MODE=no)
+  AC_MSG_RESULT([$USE_MAINTAINER_MODE])
+  AM_CONDITIONAL(MAINTAINER_MODE, [test $USE_MAINTAINER_MODE = yes])
+  MAINT=$MAINTAINER_MODE_TRUE
+  AC_SUBST(MAINT)dnl
+]
+)
+
+AU_DEFUN([jm_MAINTAINER_MODE], [AM_MAINTAINER_MODE])
+
 # Check to see how 'make' treats includes.                 -*- Autoconf -*-
 
 # Copyright (C) 2001, 2002, 2003, 2005  Free Software Foundation, Inc.
index ce62cd13338e8b5b9f2ec0000501e7f636f1b598..968822c4689af71bbded23fd45cee21c783ec1de 100644 (file)
@@ -60,6 +60,7 @@ DIST_SUBDIRS = tcl
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 ACLOCAL = @ACLOCAL@
 ALL_LIBS = @ALL_LIBS@
+ALL_LINGUAS = @ALL_LINGUAS@
 AMDEP_FALSE = @AMDEP_FALSE@
 AMDEP_TRUE = @AMDEP_TRUE@
 AMTAR = @AMTAR@
@@ -68,6 +69,8 @@ AUTOCONF = @AUTOCONF@
 AUTOHEADER = @AUTOHEADER@
 AUTOMAKE = @AUTOMAKE@
 AWK = @AWK@
+BUILD_LIBINTL_FALSE = @BUILD_LIBINTL_FALSE@
+BUILD_LIBINTL_TRUE = @BUILD_LIBINTL_TRUE@
 BUILD_MULTITHREAD_FALSE = @BUILD_MULTITHREAD_FALSE@
 BUILD_MULTITHREAD_TRUE = @BUILD_MULTITHREAD_TRUE@
 BUILD_RRDCGI_FALSE = @BUILD_RRDCGI_FALSE@
@@ -76,6 +79,8 @@ BUILD_TCL_FALSE = @BUILD_TCL_FALSE@
 BUILD_TCL_SITE_FALSE = @BUILD_TCL_SITE_FALSE@
 BUILD_TCL_SITE_TRUE = @BUILD_TCL_SITE_TRUE@
 BUILD_TCL_TRUE = @BUILD_TCL_TRUE@
+CATALOGS = @CATALOGS@
+CATOBJEXT = @CATOBJEXT@
 CC = @CC@
 CCDEPMODE = @CCDEPMODE@
 CFLAGS = @CFLAGS@
@@ -90,6 +95,7 @@ CXXCPP = @CXXCPP@
 CXXDEPMODE = @CXXDEPMODE@
 CXXFLAGS = @CXXFLAGS@
 CYGPATH_W = @CYGPATH_W@
+DATADIRNAME = @DATADIRNAME@
 DEFS = @DEFS@
 DEPDIR = @DEPDIR@
 ECHO = @ECHO@
@@ -100,18 +106,57 @@ EGREP = @EGREP@
 EXEEXT = @EXEEXT@
 F77 = @F77@
 FFLAGS = @FFLAGS@
+GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
+GMOFILES = @GMOFILES@
+GMSGFMT = @GMSGFMT@
 GREP = @GREP@
 INSTALL_DATA = @INSTALL_DATA@
 INSTALL_PROGRAM = @INSTALL_PROGRAM@
 INSTALL_SCRIPT = @INSTALL_SCRIPT@
 INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INSTOBJEXT = @INSTOBJEXT@
+INTLLIBS = @INTLLIBS@
+INTLTOOL_CAVES_RULE = @INTLTOOL_CAVES_RULE@
+INTLTOOL_DESKTOP_RULE = @INTLTOOL_DESKTOP_RULE@
+INTLTOOL_DIRECTORY_RULE = @INTLTOOL_DIRECTORY_RULE@
+INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@
+INTLTOOL_ICONV = @INTLTOOL_ICONV@
+INTLTOOL_KBD_RULE = @INTLTOOL_KBD_RULE@
+INTLTOOL_KEYS_RULE = @INTLTOOL_KEYS_RULE@
+INTLTOOL_MERGE = @INTLTOOL_MERGE@
+INTLTOOL_MSGFMT = @INTLTOOL_MSGFMT@
+INTLTOOL_MSGMERGE = @INTLTOOL_MSGMERGE@
+INTLTOOL_OAF_RULE = @INTLTOOL_OAF_RULE@
+INTLTOOL_PERL = @INTLTOOL_PERL@
+INTLTOOL_PONG_RULE = @INTLTOOL_PONG_RULE@
+INTLTOOL_PROP_RULE = @INTLTOOL_PROP_RULE@
+INTLTOOL_SCHEMAS_RULE = @INTLTOOL_SCHEMAS_RULE@
+INTLTOOL_SERVER_RULE = @INTLTOOL_SERVER_RULE@
+INTLTOOL_SERVICE_RULE = @INTLTOOL_SERVICE_RULE@
+INTLTOOL_SHEET_RULE = @INTLTOOL_SHEET_RULE@
+INTLTOOL_SOUNDLIST_RULE = @INTLTOOL_SOUNDLIST_RULE@
+INTLTOOL_THEME_RULE = @INTLTOOL_THEME_RULE@
+INTLTOOL_UI_RULE = @INTLTOOL_UI_RULE@
+INTLTOOL_UPDATE = @INTLTOOL_UPDATE@
+INTLTOOL_XAM_RULE = @INTLTOOL_XAM_RULE@
+INTLTOOL_XGETTEXT = @INTLTOOL_XGETTEXT@
+INTLTOOL_XML_NOMERGE_RULE = @INTLTOOL_XML_NOMERGE_RULE@
+INTLTOOL_XML_RULE = @INTLTOOL_XML_RULE@
 LDFLAGS = @LDFLAGS@
 LIBOBJS = @LIBOBJS@
 LIBS = @LIBS@
 LIBTOOL = @LIBTOOL@
+LIBVERS = @LIBVERS@
+LIB_LIBINTL = @LIB_LIBINTL@
 LN_S = @LN_S@
 LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@
+MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@
 MAKEINFO = @MAKEINFO@
+MKINSTALLDIRS = @MKINSTALLDIRS@
+MSGFMT = @MSGFMT@
+MSGFMT_OPTS = @MSGFMT_OPTS@
 MULTITHREAD_CFLAGS = @MULTITHREAD_CFLAGS@
 MULTITHREAD_LDFLAGS = @MULTITHREAD_LDFLAGS@
 NROFF = @NROFF@
@@ -134,6 +179,12 @@ PERL_CC = @PERL_CC@
 PERL_MAKE_OPTIONS = @PERL_MAKE_OPTIONS@
 PERL_VERSION = @PERL_VERSION@
 PKGCONFIG = @PKGCONFIG@
+POD2HTML = @POD2HTML@
+POD2MAN = @POD2MAN@
+POFILES = @POFILES@
+POSUB = @POSUB@
+PO_IN_DATADIR_FALSE = @PO_IN_DATADIR_FALSE@
+PO_IN_DATADIR_TRUE = @PO_IN_DATADIR_TRUE@
 PTHREAD_CC = @PTHREAD_CC@
 PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
 PTHREAD_LIBS = @PTHREAD_LIBS@
@@ -151,7 +202,10 @@ RUBY = @RUBY@
 RUBY_MAKE_OPTIONS = @RUBY_MAKE_OPTIONS@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
+STATIC_PROGRAMS_FALSE = @STATIC_PROGRAMS_FALSE@
+STATIC_PROGRAMS_TRUE = @STATIC_PROGRAMS_TRUE@
 STRIP = @STRIP@
+TCL_INC_DIR = @TCL_INC_DIR@
 TCL_LD_SEARCH_FLAGS = @TCL_LD_SEARCH_FLAGS@
 TCL_PACKAGE_DIR = @TCL_PACKAGE_DIR@
 TCL_PACKAGE_PATH = @TCL_PACKAGE_PATH@
@@ -162,7 +216,9 @@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@
 TCL_STUB_LIB_SPEC = @TCL_STUB_LIB_SPEC@
 TCL_VERSION = @TCL_VERSION@
 TROFF = @TROFF@
+USE_NLS = @USE_NLS@
 VERSION = @VERSION@
+XGETTEXT = @XGETTEXT@
 ac_ct_CC = @ac_ct_CC@
 ac_ct_CXX = @ac_ct_CXX@
 ac_ct_F77 = @ac_ct_F77@
@@ -231,7 +287,7 @@ EXTRA_DIST = perl-piped/MANIFEST perl-piped/README perl-piped/Makefile.PL perl-p
 all: all-recursive
 
 .SUFFIXES:
-$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
        @for dep in $?; do \
          case '$(am__configure_deps)' in \
            *$$dep*) \
@@ -256,9 +312,9 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
 $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
        cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
 
-$(top_srcdir)/configure:  $(am__configure_deps)
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
        cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
        cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
 
 mostlyclean-libtool:
index bc95a1289918d923243a89b394d6755b58b4146c..e37104bd78f88fb351a9a06919122b2d724a760a 100644 (file)
@@ -120,7 +120,7 @@ sub cmd (@);
 sub end ();
 sub read ();
 
-$VERSION=1.2027;
+$VERSION=1.299908051800;
 
 sub start ($){
   croak "rrdtool is already running"
@@ -146,7 +146,6 @@ sub read () {
   my $buffer;
   my $nfound;
   my $timeleft;
-  my $ERR = 0;
   vec($inmask,fileno(RRDreadHand),1) = 1; # setup select mask for Reader
   while (1) {
     my $rout;    
@@ -163,11 +162,14 @@ sub read () {
       $RRDp::error = undef;
       if ($line =~  m|^ERROR|) {       
        $RRDp::error_mode eq 'catch' ? $RRDp::error = $line : croak $line;
-       $ERR = 1;
+        $RRDp::sys = undef;
+        $RRDp::user = undef;
+        $RRDp::real = undef;
+       return undef;
       } 
-      elsif ($line =~ m|^OK u:([\d\.]+) s:([\d\.]+) r:([\d\.]+)|){
+      elsif ($line =~ m|^OK(?: u:([\d\.]+) s:([\d\.]+) r:([\d\.]+))?|){
        ($RRDp::sys,$RRDp::user,$RRDp::real)=($1,$2,$3);
-       return $ERR == 1 ? undef : \$buffer;
+       return \$buffer;
       } else {
        $buffer .= $line. "\n";
       }
index c31f3b9d649686dbd87db0ccd8f176bce692c5b9..8793dd8fb78874e62e3877396cd77cee4a836e69 100644 (file)
@@ -30,11 +30,10 @@ WriteMakefile(
     'VERSION_FROM' => 'RRDs.pm', # finds $VERSION
     'DEFINE'      => "-DPERLPATCHLEVEL=$Config{PATCHLEVEL}",
     'INC'          => '-I../../src',
-    'LIBS'         => '-lm -lpng -lz -lfreetype',
     # Perl will figure out which one is valid
     #'dynamic_lib'  => {'OTHERLDFLAGS' => "$librrd -lm"},
     'depend'       => {'RRDs.c' => "../../src/librrd.la"},
-    'LDFROM'       => '$(OBJECT) '.$librrd,        
+    'LDFROM'       => '$(OBJECT) '.$librrd, 
     'realclean'    => {FILES => 't/demo?.rrd t/demo?.png' }
 );
 
index 44b4d8cfc0277a4847e26dd89746213da4d56d79..b75c9f0a9268f6ca49c1f6f33edf79e78b8c0345 100644 (file)
@@ -7,7 +7,7 @@ use vars qw(@ISA $VERSION);
 
 require DynaLoader;
 
-$VERSION=1.2027;
+$VERSION=1.299908051800;
 
 bootstrap RRDs $VERSION;
 
@@ -98,6 +98,12 @@ the values of the properties.
    print "$key = $$hash{$key}\n";
  }
 
+B<RRDs::graphv> takes the same paramters as B<RRDs::graph> but it returns a
+pointer to hash. The hash returned contains meta information about the
+graph. Like its size as well as the position of the graph area on the image.
+When calling with and empty filename than the contents of the graph will be
+returned in the hash as well (key 'image').
+
 B<RRDs::updatev> also returns a pointer to hash. The keys of the hash
 are concatenated strings of a timestamp, RRA index, and data source name for
 each consolidated data point (CDP) written to disk as a result of the
index f84efef67419f876f2c0ff0035eefee0176801cd..5eeba18444e55609674100e660ae4b780ad35d55 100644 (file)
@@ -99,6 +99,10 @@ extern "C" {
                        hvs(newSVpv(data->value.u_str,0)); \
                        rrd_freemem(data->value.u_str); \
                        break; \
+                   case RD_I_BLO: \
+                       hvs(newSVpv(data->value.u_blo.ptr,data->value.u_blo.size)); \
+                       rrd_freemem(data->value.u_blo.ptr); \
+                       break; \
                    } \
                    rrd_freemem(data->key); \
                    data = data->next; \
@@ -407,6 +411,19 @@ rrd_updatev(...)
     OUTPUT:
           RETVAL
 
+SV*
+rrd_graphv(...)
+       PROTOTYPE: @    
+       PREINIT:
+               info_t *data,*save;
+                int i;
+                char **argv;
+               HV *hash;
+       CODE:
+               rrdinfocode(rrd_graph_v);       
+    OUTPUT:
+          RETVAL
+
 int
 rrd_dump(...)
        PROTOTYPE: @
index 99b5aa078c810718ec51c0d51714d8c824b8505d..2af673b5af12de6daf1ed362e57145f4044c6609 100644 (file)
@@ -28,7 +28,7 @@
  *
  *****************************************************************************/
 #ifdef  __cplusplus
-extern "C" {
+extern    "C" {
 #endif
 
 #ifndef _RRD_EXTRA_H
@@ -37,19 +37,28 @@ extern "C" {
 #include "rrd_format.h"
 
 #ifndef WIN32
-#ifndef isnan /* POSIX */
-int isnan(double value);
+#ifndef isnan           /* POSIX */
+    int       isnan(
+    double value);
 #endif
-#else /* Windows only */
+#else                   /* Windows only */
 #include <float.h>
 #define isnan _isnan
 #endif
 
-void rrd_free(rrd_t *rrd);
-void rrd_init(rrd_t *rrd);
+    void      rrd_free(
+    rrd_t *rrd);
+    void      rrd_init(
+    rrd_t *rrd);
 
-int rrd_open(char *file_name, FILE **in_file, rrd_t *rrd, int rdwr);
-int readfile(char *file, char **buffer, int skipfirst);
+    int       rrd_open(
+    char *file_name,
+    rrd_t *rrd,
+    int rdwr);
+    int       readfile(
+    char *file,
+    char **buffer,
+    int skipfirst);
 
 #define RRD_READONLY    0
 #define RRD_READWRITE   1
index 6f5b36c50e70aebf3027695a89a23e4b6e8a1520..f82973436a8c23063567247d845d36832243d2e7 100644 (file)
@@ -48,16 +48,22 @@ extern int optind;
 extern int opterr;
 
 /* forward declaration to keep compiler happy */
-void initrrdtool(void);
-
-static int
-create_args(char *command, PyObject *args, int *argc, char ***argv)
+void      initrrdtool(
+    void);
+
+static int create_args(
+    char *command,
+    PyObject * args,
+    int *argc,
+    char ***argv)
 {
-    PyObject        *o;
-    int              size, i;
-    
-    size    = PyTuple_Size(args);
-    *argv   = PyMem_New(char *, size + 1);
+    PyObject *o;
+    int       size, i;
+
+    size = PyTuple_Size(args);
+    *argv = PyMem_New(char *,
+                      size + 1);
+
     if (*argv == NULL)
         return -1;
 
@@ -80,25 +86,26 @@ create_args(char *command, PyObject *args, int *argc, char ***argv)
     return 0;
 }
 
-static void
-destroy_args(char ***argv)
+static void destroy_args(
+    char ***argv)
 {
     PyMem_Del(*argv);
     *argv = NULL;
 }
 
 static char PyRRD_create__doc__[] =
-"create(args..): Set up a new Round Robin Database\n\
+    "create(args..): Set up a new Round Robin Database\n\
     create filename [--start|-b start time] \
 [--step|-s step] [DS:ds-name:DST:heartbeat:min:max] \
 [RRA:CF:xff:steps:rows]";
 
-static PyObject *
-PyRRD_create(PyObject UNUSED(*self), PyObject *args)
+static PyObject *PyRRD_create(
+    PyObject UNUSED(*self),
+    PyObject * args)
 {
-    PyObject        *r;
-    char           **argv;
-    int              argc;
+    PyObject *r;
+    char    **argv;
+    int       argc;
 
     if (create_args("create", args, &argc, &argv) < 0)
         return NULL;
@@ -117,16 +124,17 @@ PyRRD_create(PyObject UNUSED(*self), PyObject *args)
 }
 
 static char PyRRD_update__doc__[] =
-"update(args..): Store a new set of values into the rrd\n"
-"    update filename [--template|-t ds-name[:ds-name]...] "
-"N|timestamp:value[:value...] [timestamp:value[:value...] ...]";
+    "update(args..): Store a new set of values into the rrd\n"
+    "    update filename [--template|-t ds-name[:ds-name]...] "
+    "N|timestamp:value[:value...] [timestamp:value[:value...] ...]";
 
-static PyObject *
-PyRRD_update(PyObject UNUSED(*self), PyObject *args)
+static PyObject *PyRRD_update(
+    PyObject UNUSED(*self),
+    PyObject * args)
 {
-    PyObject        *r;
-    char           **argv;
-    int              argc;
+    PyObject *r;
+    char    **argv;
+    int       argc;
 
     if (create_args("update", args, &argc, &argv) < 0)
         return NULL;
@@ -145,19 +153,20 @@ PyRRD_update(PyObject UNUSED(*self), PyObject *args)
 }
 
 static char PyRRD_fetch__doc__[] =
-"fetch(args..): fetch data from an rrd.\n"
-"    fetch filename CF [--resolution|-r resolution] "
-"[--start|-s start] [--end|-e end]";
+    "fetch(args..): fetch data from an rrd.\n"
+    "    fetch filename CF [--resolution|-r resolution] "
+    "[--start|-s start] [--end|-e end]";
 
-static PyObject *
-PyRRD_fetch(PyObject UNUSED(*self), PyObject *args)
+static PyObject *PyRRD_fetch(
+    PyObject UNUSED(*self),
+    PyObject * args)
 {
-    PyObject        *r;
-    rrd_value_t     *data, *datai;
-    unsigned long    step, ds_cnt;
-    time_t           start, end;
-    int              argc;
-    char           **argv, **ds_namv;
+    PyObject *r;
+    rrd_value_t *data, *datai;
+    unsigned long step, ds_cnt;
+    time_t    start, end;
+    int       argc;
+    char    **argv, **ds_namv;
 
     if (create_args("fetch", args, &argc, &argv) < 0)
         return NULL;
@@ -169,10 +178,10 @@ PyRRD_fetch(PyObject UNUSED(*self), PyObject *args)
         r = NULL;
     } else {
         /* Return :
-          ((start, end, step), (name1, name2, ...), [(data1, data2, ..), ...]) */
-        PyObject    *range_tup, *dsnam_tup, *data_list, *t;
-        unsigned long          i, j, row;
-        rrd_value_t  dv;
+           ((start, end, step), (name1, name2, ...), [(data1, data2, ..), ...]) */
+        PyObject *range_tup, *dsnam_tup, *data_list, *t;
+        unsigned long i, j, row;
+        rrd_value_t dv;
 
         row = ((end - start) / step + 1);
 
@@ -186,14 +195,14 @@ PyRRD_fetch(PyObject UNUSED(*self), PyObject *args)
 
         datai = data;
 
-        PyTuple_SET_ITEM(range_tup, 0, PyInt_FromLong((long)start));
-        PyTuple_SET_ITEM(range_tup, 1, PyInt_FromLong((long)end));
-        PyTuple_SET_ITEM(range_tup, 2, PyInt_FromLong((long)step));
+        PyTuple_SET_ITEM(range_tup, 0, PyInt_FromLong((long) start));
+        PyTuple_SET_ITEM(range_tup, 1, PyInt_FromLong((long) end));
+        PyTuple_SET_ITEM(range_tup, 2, PyInt_FromLong((long) step));
 
         for (i = 0; i < ds_cnt; i++)
             PyTuple_SET_ITEM(dsnam_tup, i, PyString_FromString(ds_namv[i]));
 
-        for (i = 0; i < row; i ++) {
+        for (i = 0; i < row; i++) {
             t = PyTuple_New(ds_cnt);
             PyList_SET_ITEM(data_list, i, t);
 
@@ -203,14 +212,14 @@ PyRRD_fetch(PyObject UNUSED(*self), PyObject *args)
                     PyTuple_SET_ITEM(t, j, Py_None);
                     Py_INCREF(Py_None);
                 } else {
-                    PyTuple_SET_ITEM(t, j, PyFloat_FromDouble((double)dv));
+                    PyTuple_SET_ITEM(t, j, PyFloat_FromDouble((double) dv));
                 }
             }
         }
 
         for (i = 0; i < ds_cnt; i++)
             free(ds_namv[i]);
-        free(ds_namv); /* rrdtool don't use PyMem_Malloc :) */
+        free(ds_namv);  /* rrdtool don't use PyMem_Malloc :) */
         free(data);
     }
 
@@ -219,54 +228,56 @@ PyRRD_fetch(PyObject UNUSED(*self), PyObject *args)
 }
 
 static char PyRRD_graph__doc__[] =
-"graph(args..): Create a graph based on data from one or several RRD\n"
-"    graph filename [-s|--start seconds] "
-"[-e|--end seconds] [-x|--x-grid x-axis grid and label] "
-"[-y|--y-grid y-axis grid and label] [--alt-y-grid] [--alt-y-mrtg] "
-"[--alt-autoscale] [--alt-autoscale-max] [--units-exponent] value "
-"[-v|--vertical-label text] [-w|--width pixels] [-h|--height pixels] "
-"[-i|--interlaced] "
-"[-f|--imginfo formatstring] [-a|--imgformat GIF|PNG|GD] "
-"[-B|--background value] [-O|--overlay value] "
-"[-U|--unit value] [-z|--lazy] [-o|--logarithmic] "
-"[-u|--upper-limit value] [-l|--lower-limit value] "
-"[-g|--no-legend] [-r|--rigid] [--step value] "
-"[-b|--base value] [-c|--color COLORTAG#rrggbb] "
-"[-t|--title title] [DEF:vname=rrd:ds-name:CF] "
-"[CDEF:vname=rpn-expression] [PRINT:vname:CF:format] "
-"[GPRINT:vname:CF:format] [COMMENT:text] "
-"[HRULE:value#rrggbb[:legend]] [VRULE:time#rrggbb[:legend]] "
-"[LINE{1|2|3}:vname[#rrggbb[:legend]]] "
-"[AREA:vname[#rrggbb[:legend]]] "
-"[STACK:vname[#rrggbb[:legend]]]";
-
-static PyObject *
-PyRRD_graph(PyObject UNUSED(*self), PyObject *args)
+    "graph(args..): Create a graph based on data from one or several RRD\n"
+    "    graph filename [-s|--start seconds] "
+    "[-e|--end seconds] [-x|--x-grid x-axis grid and label] "
+    "[-y|--y-grid y-axis grid and label] [--alt-y-grid] [--alt-y-mrtg] "
+    "[--alt-autoscale] [--alt-autoscale-max] [--units-exponent] value "
+    "[-v|--vertical-label text] [-w|--width pixels] [-h|--height pixels] "
+    "[-i|--interlaced] "
+    "[-f|--imginfo formatstring] [-a|--imgformat GIF|PNG|GD] "
+    "[-B|--background value] [-O|--overlay value] "
+    "[-U|--unit value] [-z|--lazy] [-o|--logarithmic] "
+    "[-u|--upper-limit value] [-l|--lower-limit value] "
+    "[-g|--no-legend] [-r|--rigid] [--step value] "
+    "[-b|--base value] [-c|--color COLORTAG#rrggbb] "
+    "[-t|--title title] [DEF:vname=rrd:ds-name:CF] "
+    "[CDEF:vname=rpn-expression] [PRINT:vname:CF:format] "
+    "[GPRINT:vname:CF:format] [COMMENT:text] "
+    "[HRULE:value#rrggbb[:legend]] [VRULE:time#rrggbb[:legend]] "
+    "[LINE{1|2|3}:vname[#rrggbb[:legend]]] "
+    "[AREA:vname[#rrggbb[:legend]]] " "[STACK:vname[#rrggbb[:legend]]]";
+
+static PyObject *PyRRD_graph(
+    PyObject UNUSED(*self),
+    PyObject * args)
 {
-    PyObject        *r;
-    char           **argv, **calcpr;
-    int              argc, xsize, ysize, i;
-    double          ymin, ymax;
+    PyObject *r;
+    char    **argv, **calcpr;
+    int       argc, xsize, ysize, i;
+    double    ymin, ymax;
+
     if (create_args("graph", args, &argc, &argv) < 0)
         return NULL;
 
-    if (rrd_graph(argc, argv, &calcpr, &xsize, &ysize, NULL, &ymin, &ymax) == -1) {
+    if (rrd_graph(argc, argv, &calcpr, &xsize, &ysize, NULL, &ymin, &ymax) ==
+        -1) {
         PyErr_SetString(ErrorObject, rrd_get_error());
         rrd_clear_error();
         r = NULL;
     } else {
         r = PyTuple_New(3);
 
-        PyTuple_SET_ITEM(r, 0, PyInt_FromLong((long)xsize));
-        PyTuple_SET_ITEM(r, 1, PyInt_FromLong((long)ysize));
+        PyTuple_SET_ITEM(r, 0, PyInt_FromLong((long) xsize));
+        PyTuple_SET_ITEM(r, 1, PyInt_FromLong((long) ysize));
 
         if (calcpr) {
-            PyObject    *e, *t;
-            
+            PyObject *e, *t;
+
             e = PyList_New(0);
             PyTuple_SET_ITEM(r, 2, e);
 
-            for(i = 0; calcpr[i]; i++) {
+            for (i = 0; calcpr[i]; i++) {
                 t = PyString_FromString(calcpr[i]);
                 PyList_Append(e, t);
                 Py_DECREF(t);
@@ -284,17 +295,18 @@ PyRRD_graph(PyObject UNUSED(*self), PyObject *args)
 }
 
 static char PyRRD_tune__doc__[] =
-"tune(args...): Modify some basic properties of a Round Robin Database\n"
-"    tune filename [--heartbeat|-h ds-name:heartbeat] "
-"[--minimum|-i ds-name:min] [--maximum|-a ds-name:max] "
-"[--data-source-type|-d ds-name:DST] [--data-source-rename|-r old-name:new-name]";
-
-static PyObject *
-PyRRD_tune(PyObject UNUSED(*self), PyObject *args)
+    "tune(args...): Modify some basic properties of a Round Robin Database\n"
+    "    tune filename [--heartbeat|-h ds-name:heartbeat] "
+    "[--minimum|-i ds-name:min] [--maximum|-a ds-name:max] "
+    "[--data-source-type|-d ds-name:DST] [--data-source-rename|-r old-name:new-name]";
+
+static PyObject *PyRRD_tune(
+    PyObject UNUSED(*self),
+    PyObject * args)
 {
-    PyObject        *r;
-    char           **argv;
-    int              argc;
+    PyObject *r;
+    char    **argv;
+    int       argc;
 
     if (create_args("tune", args, &argc, &argv) < 0)
         return NULL;
@@ -313,14 +325,15 @@ PyRRD_tune(PyObject UNUSED(*self), PyObject *args)
 }
 
 static char PyRRD_first__doc__[] =
-"first(filename): Return the timestamp of the first data sample in an RRD";
+    "first(filename): Return the timestamp of the first data sample in an RRD";
 
-static PyObject *
-PyRRD_first(PyObject UNUSED(*self), PyObject *args)
+static PyObject *PyRRD_first(
+    PyObject UNUSED(*self),
+    PyObject * args)
 {
-    PyObject        *r;
-    int              argc, ts;
-    char           **argv;
+    PyObject *r;
+    int       argc, ts;
+    char    **argv;
 
     if (create_args("first", args, &argc, &argv) < 0)
         return NULL;
@@ -330,21 +343,22 @@ PyRRD_first(PyObject UNUSED(*self), PyObject *args)
         rrd_clear_error();
         r = NULL;
     } else
-        r = PyInt_FromLong((long)ts);
+        r = PyInt_FromLong((long) ts);
 
     destroy_args(&argv);
     return r;
 }
 
 static char PyRRD_last__doc__[] =
-"last(filename): Return the timestamp of the last data sample in an RRD";
+    "last(filename): Return the timestamp of the last data sample in an RRD";
 
-static PyObject *
-PyRRD_last(PyObject UNUSED(*self), PyObject *args)
+static PyObject *PyRRD_last(
+    PyObject UNUSED(*self),
+    PyObject * args)
 {
-    PyObject        *r;
-    int              argc, ts;
-    char           **argv;
+    PyObject *r;
+    int       argc, ts;
+    char    **argv;
 
     if (create_args("last", args, &argc, &argv) < 0)
         return NULL;
@@ -354,22 +368,23 @@ PyRRD_last(PyObject UNUSED(*self), PyObject *args)
         rrd_clear_error();
         r = NULL;
     } else
-        r = PyInt_FromLong((long)ts);
+        r = PyInt_FromLong((long) ts);
 
     destroy_args(&argv);
     return r;
 }
 
 static char PyRRD_resize__doc__[] =
-"resize(args...): alters the size of an RRA.\n"
-"    resize filename rra-num GROW|SHRINK rows";
+    "resize(args...): alters the size of an RRA.\n"
+    "    resize filename rra-num GROW|SHRINK rows";
 
-static PyObject *
-PyRRD_resize(PyObject UNUSED(*self), PyObject *args)
+static PyObject *PyRRD_resize(
+    PyObject UNUSED(*self),
+    PyObject * args)
 {
-    PyObject        *r;
-    char           **argv;
-    int              argc, ts;
+    PyObject *r;
+    char    **argv;
+    int       argc, ts;
 
     if (create_args("resize", args, &argc, &argv) < 0)
         return NULL;
@@ -388,27 +403,25 @@ PyRRD_resize(PyObject UNUSED(*self), PyObject *args)
 }
 
 static char PyRRD_info__doc__[] =
-"info(filename): extract header information from an rrd";
+    "info(filename): extract header information from an rrd";
 
-static PyObject *
-PyRRD_info(PyObject UNUSED(*self), PyObject *args)
+static PyObject *PyRRD_info(
+    PyObject UNUSED(*self),
+    PyObject * args)
 {
-    PyObject        *r, *t, *ds;
-    rrd_t            rrd;
-    FILE            *in_file;
-    char            *filename;
-    unsigned long   i, j;
+    PyObject *r, *t, *ds;
+    rrd_t     rrd;
+    char     *filename;
+    unsigned long i, j;
 
-    if (! PyArg_ParseTuple(args, "s:info", &filename))
+    if (!PyArg_ParseTuple(args, "s:info", &filename))
         return NULL;
 
-    if (rrd_open(filename, &in_file, &rrd, RRD_READONLY) == -1) {
+    if (!rrd_open(filename, &rrd, RRD_READONLY) == -1) {
         PyErr_SetString(ErrorObject, rrd_get_error());
         rrd_clear_error();
         return NULL;
     }
-    fclose(in_file);
-
 #define DICTSET_STR(dict, name, value) \
     t = PyString_FromString(value); \
     PyDict_SetItemString(dict, name, t); \
@@ -437,7 +450,7 @@ PyRRD_info(PyObject UNUSED(*self), PyObject *args)
     Py_DECREF(ds);
 
     for (i = 0; i < rrd.stat_head->ds_cnt; i++) {
-        PyObject    *d;
+        PyObject *d;
 
         d = PyDict_New();
         PyDict_SetItemString(ds, rrd.ds_def[i].ds_nam, d);
@@ -445,12 +458,14 @@ PyRRD_info(PyObject UNUSED(*self), PyObject *args)
 
         DICTSET_STR(d, "ds_name", rrd.ds_def[i].ds_nam);
         DICTSET_STR(d, "type", rrd.ds_def[i].dst);
-        DICTSET_CNT(d, "minimal_heartbeat", rrd.ds_def[i].par[DS_mrhb_cnt].u_cnt);
+        DICTSET_CNT(d, "minimal_heartbeat",
+                    rrd.ds_def[i].par[DS_mrhb_cnt].u_cnt);
         DICTSET_VAL(d, "min", rrd.ds_def[i].par[DS_min_val].u_val);
         DICTSET_VAL(d, "max", rrd.ds_def[i].par[DS_max_val].u_val);
         DICTSET_STR(d, "last_ds", rrd.pdp_prep[i].last_ds);
         DICTSET_VAL(d, "value", rrd.pdp_prep[i].scratch[PDP_val].u_val);
-        DICTSET_CNT(d, "unknown_sec", rrd.pdp_prep[i].scratch[PDP_unkn_sec_cnt].u_cnt);
+        DICTSET_CNT(d, "unknown_sec",
+                    rrd.pdp_prep[i].scratch[PDP_unkn_sec_cnt].u_cnt);
     }
 
     ds = PyList_New(rrd.stat_head->rra_cnt);
@@ -458,7 +473,7 @@ PyRRD_info(PyObject UNUSED(*self), PyObject *args)
     Py_DECREF(ds);
 
     for (i = 0; i < rrd.stat_head->rra_cnt; i++) {
-        PyObject    *d, *cdp;
+        PyObject *d, *cdp;
 
         d = PyDict_New();
         PyList_SET_ITEM(ds, i, d);
@@ -473,15 +488,17 @@ PyRRD_info(PyObject UNUSED(*self), PyObject *args)
         Py_DECREF(cdp);
 
         for (j = 0; j < rrd.stat_head->ds_cnt; j++) {
-            PyObject    *cdd;
+            PyObject *cdd;
 
             cdd = PyDict_New();
             PyList_SET_ITEM(cdp, j, cdd);
 
             DICTSET_VAL(cdd, "value",
-                    rrd.cdp_prep[i*rrd.stat_head->ds_cnt+j].scratch[CDP_val].u_val);
+                        rrd.cdp_prep[i * rrd.stat_head->ds_cnt +
+                                     j].scratch[CDP_val].u_val);
             DICTSET_CNT(cdd, "unknown_datapoints",
-                    rrd.cdp_prep[i*rrd.stat_head->ds_cnt+j].scratch[CDP_unkn_pdp_cnt].u_cnt);
+                        rrd.cdp_prep[i * rrd.stat_head->ds_cnt +
+                                     j].scratch[CDP_unkn_pdp_cnt].u_cnt);
         }
     }
 
@@ -494,16 +511,16 @@ PyRRD_info(PyObject UNUSED(*self), PyObject *args)
 #define meth(name, func, doc) {name, (PyCFunction)func, METH_VARARGS, doc}
 
 static PyMethodDef _rrdtool_methods[] = {
-    meth("create",  PyRRD_create,   PyRRD_create__doc__),
-    meth("update",  PyRRD_update,   PyRRD_update__doc__),
-    meth("fetch",   PyRRD_fetch,    PyRRD_fetch__doc__),
-    meth("graph",   PyRRD_graph,    PyRRD_graph__doc__),
-    meth("tune",    PyRRD_tune,     PyRRD_tune__doc__),
-    meth("first",   PyRRD_first,    PyRRD_first__doc__),
-    meth("last",    PyRRD_last,     PyRRD_last__doc__),
-    meth("resize",  PyRRD_resize,   PyRRD_resize__doc__),
-    meth("info",    PyRRD_info,     PyRRD_info__doc__),
-    {NULL, NULL,0,NULL}
+    meth("create", PyRRD_create, PyRRD_create__doc__),
+    meth("update", PyRRD_update, PyRRD_update__doc__),
+    meth("fetch", PyRRD_fetch, PyRRD_fetch__doc__),
+    meth("graph", PyRRD_graph, PyRRD_graph__doc__),
+    meth("tune", PyRRD_tune, PyRRD_tune__doc__),
+    meth("first", PyRRD_first, PyRRD_first__doc__),
+    meth("last", PyRRD_last, PyRRD_last__doc__),
+    meth("resize", PyRRD_resize, PyRRD_resize__doc__),
+    meth("info", PyRRD_info, PyRRD_info__doc__),
+    {NULL, NULL, 0, NULL}
 };
 
 #define SET_INTCONSTANT(dict, value) \
@@ -516,10 +533,10 @@ static PyMethodDef _rrdtool_methods[] = {
             Py_DECREF(t);
 
 /* Initialization function for the module */
-void
-initrrdtool(void)
+void initrrdtool(
+    void)
 {
-    PyObject    *m, *d, *t;
+    PyObject *m, *d, *t;
 
     /* Create the module and add the functions */
     m = Py_InitModule("rrdtool", _rrdtool_methods);
index 7a41a113c9b9c809b2a8d029226330acc7bcb73b..83f35b6caff85cdc1492d6fcffba62bfe6029f29 100644 (file)
@@ -32,7 +32,7 @@ from distutils.core import setup, Extension
 import sys, os
 
 RRDBASE = os.environ.get('LOCALBASE', '../../src')
-library_dir = os.environ.get('BUILDLIBDIR', os.path.join(RRDBASE, 'lib'))
+library_dir = os.environ.get('BUILDLIBDIR', os.path.join(RRDBASE, '.libs'))
 include_dir = os.environ.get('INCDIR', RRDBASE)
 
 setup(name = "py-rrdtool",
index 8a762ada459201a2d86e9194f6cb60ca449dce77..b3922d4a970cd7c271978b92693e70433516deee 100644 (file)
@@ -1,4 +1,4 @@
-/* $Id: main.c 1212 2007-11-08 10:13:48Z oetiker $
+/* $Id: main.c 1335 2008-05-01 23:23:35Z oetiker $
  * Substantial penalty for early withdrawal.
  */
 
@@ -7,33 +7,39 @@
 #include "../../src/rrd_tool.h"
 
 typedef struct string_arr_t {
-    int len;
-    char **strings;
+    int       len;
+    char    **strings;
 } string_arr;
 
-VALUE mRRD;
-VALUE rb_eRRDError;
+VALUE     mRRD;
+VALUE     rb_eRRDError;
+
+typedef int (
+    *RRDFUNC) (
+    int argc,
+    char **argv);
 
-typedef int (*RRDFUNC)(int argc, char ** argv);
 #define RRD_CHECK_ERROR  \
     if (rrd_test_error()) \
       rb_raise(rb_eRRDError, rrd_get_error()); \
     rrd_clear_error();
 
-string_arr string_arr_new(VALUE rb_strings)
+string_arr string_arr_new(
+    VALUE rb_strings)
 {
     string_arr a;
-    char buf[64];
-    int i;
-   
+    char      buf[64];
+    int       i;
+
     Check_Type(rb_strings, T_ARRAY);
     a.len = RARRAY(rb_strings)->len + 1;
 
     a.strings = malloc(a.len * sizeof(char *));
-    a.strings[0] = "dummy";     /* first element is a dummy element */
+    a.strings[0] = "dummy"; /* first element is a dummy element */
 
     for (i = 0; i < a.len - 1; i++) {
-        VALUE v = rb_ary_entry(rb_strings, i);
+        VALUE     v = rb_ary_entry(rb_strings, i);
+
         switch (TYPE(v)) {
         case T_STRING:
             a.strings[i + 1] = strdup(STR2CSTR(v));
@@ -43,7 +49,9 @@ string_arr string_arr_new(VALUE rb_strings)
             a.strings[i + 1] = strdup(buf);
             break;
         default:
-            rb_raise(rb_eTypeError, "invalid argument - %s, expected T_STRING or T_FIXNUM on index %d", rb_class2name(CLASS_OF(v)), i);
+            rb_raise(rb_eTypeError,
+                     "invalid argument - %s, expected T_STRING or T_FIXNUM on index %d",
+                     rb_class2name(CLASS_OF(v)), i);
             break;
         }
     }
@@ -51,9 +59,10 @@ string_arr string_arr_new(VALUE rb_strings)
     return a;
 }
 
-void string_arr_delete(string_arr a)
+void string_arr_delete(
+    string_arr a)
 {
-    int i;
+    int       i;
 
     /* skip dummy first entry */
     for (i = 1; i < a.len; i++) {
@@ -63,14 +72,19 @@ void string_arr_delete(string_arr a)
     free(a.strings);
 }
 
-void reset_rrd_state()
+void reset_rrd_state(
+    )
 {
-    optind = 0; 
+    optind = 0;
     opterr = 0;
     rrd_clear_error();
 }
 
-VALUE rrd_call(RRDFUNC func, VALUE args)
+/* Simple Calls */
+
+VALUE rrd_call(
+    RRDFUNC func,
+    VALUE args)
 {
     string_arr a;
 
@@ -79,38 +93,143 @@ VALUE rrd_call(RRDFUNC func, VALUE args)
     func(a.len, a.strings);
     string_arr_delete(a);
 
-    RRD_CHECK_ERROR
-
-    return Qnil;
+    RRD_CHECK_ERROR return Qnil;
 }
 
-VALUE rb_rrd_create(VALUE self, VALUE args)
+VALUE rb_rrd_create(
+    VALUE self,
+    VALUE args)
 {
     return rrd_call(rrd_create, args);
 }
 
-VALUE rb_rrd_dump(VALUE self, VALUE args)
+VALUE rb_rrd_dump(
+    VALUE self,
+    VALUE args)
 {
     return rrd_call(rrd_dump, args);
 }
 
-VALUE rb_rrd_fetch(VALUE self, VALUE args)
+VALUE rb_rrd_resize(
+    VALUE self,
+    VALUE args)
+{
+    return rrd_call(rrd_resize, args);
+}
+
+VALUE rb_rrd_restore(
+    VALUE self,
+    VALUE args)
+{
+    return rrd_call(rrd_restore, args);
+}
+
+VALUE rb_rrd_tune(
+    VALUE self,
+    VALUE args)
+{
+    return rrd_call(rrd_tune, args);
+}
+
+VALUE rb_rrd_update(
+    VALUE self,
+    VALUE args)
+{
+    return rrd_call(rrd_update, args);
+}
+
+
+/* Calls Returning Data via the Info Interface */
+
+VALUE rb_rrd_infocall(
+    RRDFUNC func,
+    VALUE args)
+{
+    string_arr a;
+    info_t   *p, *data;
+    VALUE     result;
+
+    a = string_arr_new(args);
+    data = func(a.len, a.strings);
+    string_arr_delete(a);
+
+    RRD_CHECK_ERROR result = rb_hash_new();
+
+    while (data) {
+        VALUE     key = rb_str_new2(data->key);
+
+        switch (data->type) {
+        case RD_I_VAL:
+            if (isnan(data->value.u_val)) {
+                rb_hash_aset(result, key, Qnil);
+            } else {
+                rb_hash_aset(result, key, rb_float_new(data->value.u_val));
+            }
+            break;
+        case RD_I_CNT:
+            rb_hash_aset(result, key, INT2FIX(data->value.u_cnt));
+            break;
+        case RD_I_STR:
+            rb_hash_aset(result, key, rb_str_new2(data->value.u_str));
+            free(data->value.u_str);
+            break;
+        case RD_I_BLO:
+            rb_hash_aset(result, key,
+                         rb_str_new(data->value.u_blo.ptr,
+                                    data->value.u_blo.size));
+            free(data->value.u_blo.ptr);
+            break;
+        }
+        p = data;
+        data = data->next;
+        free(p);
+    }
+    return result;
+}
+
+VALUE rb_rrd_info(
+    VALUE self,
+    VALUE args)
+{
+    return rrd_infocall(rrd_info, args);
+}
+
+VALUE rb_rrd_updatev(
+    VALUE self,
+    VALUE args)
+{
+    return rrd_infocall(rrd_update_v, args);
+}
+
+VALUE rb_rrd_graphv(
+    VALUE self,
+    VALUE args)
+{
+    return rrd_infocall(rrd_graph_v, args);
+}
+
+
+/* Other Calls */
+
+VALUE rb_rrd_fetch(
+    VALUE self,
+    VALUE args)
 {
     string_arr a;
     unsigned long i, j, k, step, ds_cnt;
     rrd_value_t *raw_data;
-    char **raw_names;
-    VALUE data, names, result;
-    time_t start, end;
+    char    **raw_names;
+    VALUE     data, names, result;
+    time_t    start, end;
 
     a = string_arr_new(args);
     reset_rrd_state();
-    rrd_fetch(a.len, a.strings, &start, &end, &step, &ds_cnt, &raw_names, &raw_data);
+    rrd_fetch(a.len, a.strings, &start, &end, &step, &ds_cnt, &raw_names,
+              &raw_data);
     string_arr_delete(a);
 
-    RRD_CHECK_ERROR
+    RRD_CHECK_ERROR names = rb_ary_new();
 
-    names = rb_ary_new();
     for (i = 0; i < ds_cnt; i++) {
         rb_ary_push(names, rb_str_new2(raw_names[i]));
         free(raw_names[i]);
@@ -120,7 +239,8 @@ VALUE rb_rrd_fetch(VALUE self, VALUE args)
     k = 0;
     data = rb_ary_new();
     for (i = start; i <= end; i += step) {
-        VALUE line = rb_ary_new2(ds_cnt);
+        VALUE     line = rb_ary_new2(ds_cnt);
+
         for (j = 0; j < ds_cnt; j++) {
             rb_ary_store(line, j, rb_float_new(raw_data[k]));
             k++;
@@ -128,31 +248,33 @@ VALUE rb_rrd_fetch(VALUE self, VALUE args)
         rb_ary_push(data, line);
     }
     free(raw_data);
-   
-    result = rb_ary_new2(4);
+
+    result = rb_ary_new2(5);
     rb_ary_store(result, 0, INT2NUM(start));
     rb_ary_store(result, 1, INT2NUM(end));
     rb_ary_store(result, 2, names);
     rb_ary_store(result, 3, data);
+    rb_ary_store(result, 4, INT2FIX(step));
     return result;
 }
 
-VALUE rb_rrd_graph(VALUE self, VALUE args)
+VALUE rb_rrd_graph(
+    VALUE self,
+    VALUE args)
 {
     string_arr a;
-    char **calcpr, **p;
-    VALUE result, print_results;
-    int xsize, ysize;
-    double ymin, ymax;
+    char    **calcpr, **p;
+    VALUE     result, print_results;
+    int       xsize, ysize;
+    double    ymin, ymax;
 
     a = string_arr_new(args);
     reset_rrd_state();
     rrd_graph(a.len, a.strings, &calcpr, &xsize, &ysize, NULL, &ymin, &ymax);
     string_arr_delete(a);
 
-    RRD_CHECK_ERROR
+    RRD_CHECK_ERROR result = rb_ary_new2(3);
 
-    result = rb_ary_new2(3);
     print_results = rb_ary_new();
     p = calcpr;
     for (p = calcpr; p && *p; p++) {
@@ -166,49 +288,13 @@ VALUE rb_rrd_graph(VALUE self, VALUE args)
     return result;
 }
 
-VALUE rb_rrd_info(VALUE self, VALUE args)
-{
-    string_arr a;
-    info_t *p, *data;
-    VALUE result;
-
-    a = string_arr_new(args);
-    data = rrd_info(a.len, a.strings);
-    string_arr_delete(a);
-
-    RRD_CHECK_ERROR
 
-    result = rb_hash_new();
-    while (data) {
-        VALUE key = rb_str_new2(data->key);
-        switch (data->type) {
-        case RD_I_VAL:
-            if (isnan(data->value.u_val)) {
-                rb_hash_aset(result, key, Qnil);
-            }
-            else {
-                rb_hash_aset(result, key, rb_float_new(data->value.u_val));
-            }
-            break;
-        case RD_I_CNT:
-            rb_hash_aset(result, key, INT2FIX(data->value.u_cnt));
-            break;
-        case RD_I_STR:
-            rb_hash_aset(result, key, rb_str_new2(data->value.u_str));
-            free(data->value.u_str);
-            break;
-        }
-        p = data;
-        data = data->next;
-        free(p);
-    }
-    return result;
-}
-
-VALUE rb_rrd_last(VALUE self, VALUE args)
+VALUE rb_rrd_last(
+    VALUE self,
+    VALUE args)
 {
     string_arr a;
-    time_t last;
+    time_t    last;
 
     a = string_arr_new(args);
     reset_rrd_state();
@@ -216,31 +302,11 @@ VALUE rb_rrd_last(VALUE self, VALUE args)
     string_arr_delete(a);
 
     RRD_CHECK_ERROR
-
-    return rb_funcall(rb_cTime, rb_intern("at"), 1, INT2FIX(last));
-}
-
-VALUE rb_rrd_resize(VALUE self, VALUE args)
-{
-    return rrd_call(rrd_resize, args);
-}
-
-VALUE rb_rrd_restore(VALUE self, VALUE args)
-{
-    return rrd_call(rrd_restore, args);
-}
-
-VALUE rb_rrd_tune(VALUE self, VALUE args)
-{
-    return rrd_call(rrd_tune, args);
-}
-
-VALUE rb_rrd_update(VALUE self, VALUE args)
-{
-    return rrd_call(rrd_update, args);
+        return rb_funcall(rb_cTime, rb_intern("at"), 1, INT2FIX(last));
 }
 
-void Init_RRD() 
+void Init_RRD(
+    )
 {
     mRRD = rb_define_module("RRD");
     rb_eRRDError = rb_define_class("RRDError", rb_eStandardError);
@@ -255,4 +321,6 @@ void Init_RRD()
     rb_define_module_function(mRRD, "tune", rb_rrd_tune, -2);
     rb_define_module_function(mRRD, "update", rb_rrd_update, -2);
     rb_define_module_function(mRRD, "info", rb_rrd_info, -2);
+    rb_define_module_function(mRRD, "updatev", rb_rrd_updatev, -2);
+    rb_define_module_function(mRRD, "graphv", rb_rrd_graphv, -2);
 }
index 3e183c681eb58efa04c378df5d026729639a3682..b30736b9884d9190b29b53851e526e229b770b6c 100644 (file)
@@ -46,7 +46,7 @@ $(TCL_RRD_LIB): tclrrd.o
        $(TCL_SHLIB_LD) $(TCL_LD_SEARCH_FLAGS) $(LIBDIRS) $< -o $@ -lrrd_th -lm $(TCL_STUB_LIB_SPEC) $(LDFLAGS) $(LIBS)
 
 tclrrd.o: tclrrd.c
-       $(CC) $(AM_CFLAGS) $(CFLAGS) $(TCL_SHLIB_CFLAGS) $(AM_CPPFLAGS) -c $< -DVERSION=\"$(VERSION)\"
+       $(CC) $(AM_CFLAGS) $(CFLAGS) $(TCL_SHLIB_CFLAGS) $(AM_CPPFLAGS) -c tclrrd.c -DVERSION=\"$(VERSION)\"
 
 pkgIndex.tcl:
        echo "package ifneeded Rrd $(VERSION) \"load $(libdir)/tclrrd$(VERSION)[info sharedlibextension]\"" > $@
index 08fc7147e9908ec6b3908647c48c0108d0a6e11c..3945c83b79aaa498f9cbbb2e8a2a943da897edb8 100644 (file)
@@ -72,6 +72,7 @@ DATA = $(pkglib_DATA) $(tclpkg_DATA)
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 ACLOCAL = @ACLOCAL@
 ALL_LIBS = @ALL_LIBS@
+ALL_LINGUAS = @ALL_LINGUAS@
 AMDEP_FALSE = @AMDEP_FALSE@
 AMDEP_TRUE = @AMDEP_TRUE@
 AMTAR = @AMTAR@
@@ -80,6 +81,8 @@ AUTOCONF = @AUTOCONF@
 AUTOHEADER = @AUTOHEADER@
 AUTOMAKE = @AUTOMAKE@
 AWK = @AWK@
+BUILD_LIBINTL_FALSE = @BUILD_LIBINTL_FALSE@
+BUILD_LIBINTL_TRUE = @BUILD_LIBINTL_TRUE@
 BUILD_MULTITHREAD_FALSE = @BUILD_MULTITHREAD_FALSE@
 BUILD_MULTITHREAD_TRUE = @BUILD_MULTITHREAD_TRUE@
 BUILD_RRDCGI_FALSE = @BUILD_RRDCGI_FALSE@
@@ -88,6 +91,8 @@ BUILD_TCL_FALSE = @BUILD_TCL_FALSE@
 BUILD_TCL_SITE_FALSE = @BUILD_TCL_SITE_FALSE@
 BUILD_TCL_SITE_TRUE = @BUILD_TCL_SITE_TRUE@
 BUILD_TCL_TRUE = @BUILD_TCL_TRUE@
+CATALOGS = @CATALOGS@
+CATOBJEXT = @CATOBJEXT@
 CC = @CC@
 CCDEPMODE = @CCDEPMODE@
 CFLAGS = @CFLAGS@
@@ -102,6 +107,7 @@ CXXCPP = @CXXCPP@
 CXXDEPMODE = @CXXDEPMODE@
 CXXFLAGS = @CXXFLAGS@
 CYGPATH_W = @CYGPATH_W@
+DATADIRNAME = @DATADIRNAME@
 DEFS = @DEFS@
 DEPDIR = @DEPDIR@
 ECHO = @ECHO@
@@ -112,18 +118,57 @@ EGREP = @EGREP@
 EXEEXT = @EXEEXT@
 F77 = @F77@
 FFLAGS = @FFLAGS@
+GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
+GMOFILES = @GMOFILES@
+GMSGFMT = @GMSGFMT@
 GREP = @GREP@
 INSTALL_DATA = @INSTALL_DATA@
 INSTALL_PROGRAM = @INSTALL_PROGRAM@
 INSTALL_SCRIPT = @INSTALL_SCRIPT@
 INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INSTOBJEXT = @INSTOBJEXT@
+INTLLIBS = @INTLLIBS@
+INTLTOOL_CAVES_RULE = @INTLTOOL_CAVES_RULE@
+INTLTOOL_DESKTOP_RULE = @INTLTOOL_DESKTOP_RULE@
+INTLTOOL_DIRECTORY_RULE = @INTLTOOL_DIRECTORY_RULE@
+INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@
+INTLTOOL_ICONV = @INTLTOOL_ICONV@
+INTLTOOL_KBD_RULE = @INTLTOOL_KBD_RULE@
+INTLTOOL_KEYS_RULE = @INTLTOOL_KEYS_RULE@
+INTLTOOL_MERGE = @INTLTOOL_MERGE@
+INTLTOOL_MSGFMT = @INTLTOOL_MSGFMT@
+INTLTOOL_MSGMERGE = @INTLTOOL_MSGMERGE@
+INTLTOOL_OAF_RULE = @INTLTOOL_OAF_RULE@
+INTLTOOL_PERL = @INTLTOOL_PERL@
+INTLTOOL_PONG_RULE = @INTLTOOL_PONG_RULE@
+INTLTOOL_PROP_RULE = @INTLTOOL_PROP_RULE@
+INTLTOOL_SCHEMAS_RULE = @INTLTOOL_SCHEMAS_RULE@
+INTLTOOL_SERVER_RULE = @INTLTOOL_SERVER_RULE@
+INTLTOOL_SERVICE_RULE = @INTLTOOL_SERVICE_RULE@
+INTLTOOL_SHEET_RULE = @INTLTOOL_SHEET_RULE@
+INTLTOOL_SOUNDLIST_RULE = @INTLTOOL_SOUNDLIST_RULE@
+INTLTOOL_THEME_RULE = @INTLTOOL_THEME_RULE@
+INTLTOOL_UI_RULE = @INTLTOOL_UI_RULE@
+INTLTOOL_UPDATE = @INTLTOOL_UPDATE@
+INTLTOOL_XAM_RULE = @INTLTOOL_XAM_RULE@
+INTLTOOL_XGETTEXT = @INTLTOOL_XGETTEXT@
+INTLTOOL_XML_NOMERGE_RULE = @INTLTOOL_XML_NOMERGE_RULE@
+INTLTOOL_XML_RULE = @INTLTOOL_XML_RULE@
 LDFLAGS = @LDFLAGS@
 LIBOBJS = @LIBOBJS@
 LIBS = @LIBS@
 LIBTOOL = @LIBTOOL@
+LIBVERS = @LIBVERS@
+LIB_LIBINTL = @LIB_LIBINTL@
 LN_S = @LN_S@
 LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@
+MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@
 MAKEINFO = @MAKEINFO@
+MKINSTALLDIRS = @MKINSTALLDIRS@
+MSGFMT = @MSGFMT@
+MSGFMT_OPTS = @MSGFMT_OPTS@
 MULTITHREAD_CFLAGS = @MULTITHREAD_CFLAGS@
 MULTITHREAD_LDFLAGS = @MULTITHREAD_LDFLAGS@
 NROFF = @NROFF@
@@ -146,6 +191,12 @@ PERL_CC = @PERL_CC@
 PERL_MAKE_OPTIONS = @PERL_MAKE_OPTIONS@
 PERL_VERSION = @PERL_VERSION@
 PKGCONFIG = @PKGCONFIG@
+POD2HTML = @POD2HTML@
+POD2MAN = @POD2MAN@
+POFILES = @POFILES@
+POSUB = @POSUB@
+PO_IN_DATADIR_FALSE = @PO_IN_DATADIR_FALSE@
+PO_IN_DATADIR_TRUE = @PO_IN_DATADIR_TRUE@
 PTHREAD_CC = @PTHREAD_CC@
 PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
 PTHREAD_LIBS = @PTHREAD_LIBS@
@@ -163,7 +214,10 @@ RUBY = @RUBY@
 RUBY_MAKE_OPTIONS = @RUBY_MAKE_OPTIONS@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
+STATIC_PROGRAMS_FALSE = @STATIC_PROGRAMS_FALSE@
+STATIC_PROGRAMS_TRUE = @STATIC_PROGRAMS_TRUE@
 STRIP = @STRIP@
+TCL_INC_DIR = @TCL_INC_DIR@
 TCL_LD_SEARCH_FLAGS = @TCL_LD_SEARCH_FLAGS@
 TCL_PACKAGE_DIR = @TCL_PACKAGE_DIR@
 TCL_PACKAGE_PATH = @TCL_PACKAGE_PATH@
@@ -174,7 +228,9 @@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@
 TCL_STUB_LIB_SPEC = @TCL_STUB_LIB_SPEC@
 TCL_VERSION = @TCL_VERSION@
 TROFF = @TROFF@
+USE_NLS = @USE_NLS@
 VERSION = @VERSION@
+XGETTEXT = @XGETTEXT@
 ac_ct_CC = @ac_ct_CC@
 ac_ct_CXX = @ac_ct_CXX@
 ac_ct_F77 = @ac_ct_F77@
@@ -233,7 +289,6 @@ target_os = @target_os@
 target_vendor = @target_vendor@
 EXTRA_DIST = README tclrrd.c
 AM_CFLAGS = @CFLAGS@
-TCL_INC_DIR = @TCL_INC_DIR@
 CLEANFILES = tclrrd.o tclrrd.so
 SRC_DIR = $(top_srcdir)/src
 AM_CPPFLAGS = -I$(TCL_INC_DIR) -I$(SRC_DIR) -DUSE_TCL_STUBS
@@ -256,7 +311,7 @@ lib_LIBRARIES =
 all: all-am
 
 .SUFFIXES:
-$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
        @for dep in $?; do \
          case '$(am__configure_deps)' in \
            *$$dep*) \
@@ -281,9 +336,9 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
 $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
        cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
 
-$(top_srcdir)/configure:  $(am__configure_deps)
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
        cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
        cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
 ifOctets.tcl: $(top_builddir)/config.status $(srcdir)/ifOctets.tcl.in
        cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
@@ -536,7 +591,7 @@ $(TCL_RRD_LIB): tclrrd.o
        $(TCL_SHLIB_LD) $(TCL_LD_SEARCH_FLAGS) $(LIBDIRS) $< -o $@ -lrrd_th -lm $(TCL_STUB_LIB_SPEC) $(LDFLAGS) $(LIBS)
 
 tclrrd.o: tclrrd.c
-       $(CC) $(AM_CFLAGS) $(CFLAGS) $(TCL_SHLIB_CFLAGS) $(AM_CPPFLAGS) -c $< -DVERSION=\"$(VERSION)\"
+       $(CC) $(AM_CFLAGS) $(CFLAGS) $(TCL_SHLIB_CFLAGS) $(AM_CPPFLAGS) -c tclrrd.c -DVERSION=\"$(VERSION)\"
 
 pkgIndex.tcl:
        echo "package ifneeded Rrd $(VERSION) \"load $(libdir)/tclrrd$(VERSION)[info sharedlibextension]\"" > $@
index 0086cc82205bf4322111a5339b50c0a1433d2956..0f3ba6041901e1b25c19a1c7e6c19c9f3ebc26fc 100644 (file)
@@ -8,7 +8,7 @@
  * See the file "COPYING" for information on usage and redistribution
  * of this file, and for a DISCLAIMER OF ALL WARRANTIES.
  *
- * $Id: tclrrd.c 1268 2008-01-14 16:47:23Z oetiker $
+ * $Id: tclrrd.c 1306 2008-03-15 10:39:48Z oetiker $
  */
 
 
@@ -18,6 +18,7 @@
 #include <time.h>
 #include <unistd.h>
 #include <tcl.h>
+#include <stdlib.h>
 #include "../../src/rrd_tool.h"
 #include "../../src/rrd_format.h"
 
 #   define CONST84
 #endif
 
-extern int Tclrrd_Init(Tcl_Interp *interp);
-extern int Tclrrd_SafeInit(Tcl_Interp *interp);
+extern int Tclrrd_Init(
+    Tcl_Interp *interp);
+extern int Tclrrd_SafeInit(
+    Tcl_Interp *interp);
 
 
 /*
@@ -37,149 +40,161 @@ extern int Tclrrd_SafeInit(Tcl_Interp *interp);
  * Hence, we need to do some preparation before
  * calling the rrd library functions.
  */
-static char ** getopt_init(int argc, CONST84 char *argv[])
+static char **getopt_init(
+    int argc,
+    CONST84 char *argv[])
 {
-    char **argv2;
-    int i;
-    
+    char    **argv2;
+    int       i;
+
     argv2 = calloc(argc, sizeof(char *));
     for (i = 0; i < argc; i++) {
-       argv2[i] = strdup(argv[i]);
+        argv2[i] = strdup(argv[i]);
     }
     return argv2;
 }
 
-static void getopt_cleanup(int argc, char **argv2)
+static void getopt_cleanup(
+    int argc,
+    char **argv2)
 {
-    int i;
-    
+    int       i;
+
     for (i = 0; i < argc; i++) {
-       if (argv2[i] != NULL) {
-           free(argv2[i]);
-       }
+        if (argv2[i] != NULL) {
+            free(argv2[i]);
+        }
     }
     free(argv2);
 }
 
-static void getopt_free_element(argv2, argn)
-    char *argv2[];
-    int  argn;
+static void getopt_free_element(
+    char *argv2[],
+    int argn)
 {
     if (argv2[argn] != NULL) {
-       free(argv2[argn]);
-       argv2[argn] = NULL;
+        free(argv2[argn]);
+        argv2[argn] = NULL;
     }
 }
 
-static void getopt_squieeze(argc, argv2)
-    int  *argc;
-    char *argv2[];
+static void getopt_squieeze(
+    int *argc,
+    char *argv2[])
 {
-    int i, null_i = 0, argc_tmp = *argc;
+    int       i, null_i = 0, argc_tmp = *argc;
 
     for (i = 0; i < argc_tmp; i++) {
-       if (argv2[i] == NULL) {
-           (*argc)--;
-       } else {
-           argv2[null_i++] = argv2[i];
-       }
+        if (argv2[i] == NULL) {
+            (*argc)--;
+        } else {
+            argv2[null_i++] = argv2[i];
+        }
     }
 }
 
 
 
 /* Thread-safe version */
-static int
-Rrd_Create(ClientData clientData, Tcl_Interp *interp, int argc, CONST84 char *argv[])
+static int Rrd_Create(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int argc,
+    CONST84 char *argv[])
 {
-    int                                argv_i;
-    char                       **argv2;
-    char                       *parsetime_error = NULL;
-    time_t                     last_up = time(NULL) - 10;
-    long int                   long_tmp;
-    unsigned long int          pdp_step = 300;
-    struct rrd_time_value      last_up_tv;
-
-    (void) clientData; /* slience gcc */
+    int       argv_i;
+    char    **argv2;
+    char     *parsetime_error = NULL;
+    time_t    last_up = time(NULL) - 10;
+    long int  long_tmp;
+    unsigned long int pdp_step = 300;
+    struct rrd_time_value last_up_tv;
 
     argv2 = getopt_init(argc, argv);
 
     for (argv_i = 1; argv_i < argc; argv_i++) {
-       if (!strcmp(argv2[argv_i], "--start") || !strcmp(argv2[argv_i], "-b")) {
-           if (argv_i++>=argc) {
-               Tcl_AppendResult(interp, "RRD Error: option '",
-                                argv2[argv_i - 1], "' needs an argument", (char *) NULL);
-               getopt_cleanup(argc, argv2);
-               return TCL_ERROR;
-           }
-           if ((parsetime_error = parsetime(argv2[argv_i], &last_up_tv))) {
-               Tcl_AppendResult(interp, "RRD Error: invalid time format: '",
-                                argv2[argv_i], "'", (char *) NULL);
-               getopt_cleanup(argc, argv2);
-               return TCL_ERROR;
-           }
-           if (last_up_tv.type == RELATIVE_TO_END_TIME ||
-               last_up_tv.type == RELATIVE_TO_START_TIME) {
-               Tcl_AppendResult(interp, "RRD Error: specifying time relative to the 'start' ",
-                                "or 'end' makes no sense here", (char *) NULL);
-               getopt_cleanup(argc, argv2);
-               return TCL_ERROR;
-           }
-           last_up = mktime(&last_up_tv.tm) + last_up_tv.offset;
-           if (last_up < 3600*24*365*10) {
-               Tcl_AppendResult(interp, "RRD Error: the first entry to the RRD should be after 1980",
-                                (char *) NULL);
-               getopt_cleanup(argc, argv2);
-               return TCL_ERROR;
-           }
-           getopt_free_element(argv2, argv_i - 1);
-           getopt_free_element(argv2, argv_i);
-       } else if (!strcmp(argv2[argv_i], "--step") || !strcmp(argv2[argv_i], "-s")) {
-           if (argv_i++>=argc) {
-               Tcl_AppendResult(interp, "RRD Error: option '",
-                                argv2[argv_i - 1], "' needs an argument", (char *) NULL);
-               getopt_cleanup(argc, argv2);
-               return TCL_ERROR;
-           }
-           long_tmp = atol(argv2[argv_i]);
-           if (long_tmp < 1) {
-               Tcl_AppendResult(interp, "RRD Error: step size should be no less than one second",
-                                (char *) NULL);
-               getopt_cleanup(argc, argv2);
-               return TCL_ERROR;
-           }
-           pdp_step = long_tmp;
-           getopt_free_element(argv2, argv_i - 1);
-           getopt_free_element(argv2, argv_i);
-       } else if (!strcmp(argv2[argv_i], "--")) {
-           getopt_free_element(argv2, argv_i);
-           break;
-       } else if (argv2[argv_i][0]=='-') {
-           Tcl_AppendResult(interp, "RRD Error: unknown option '",
-                            argv2[argv_i], "'", (char *) NULL);
-           getopt_cleanup(argc, argv2);
-           return TCL_ERROR;
-       }
+        if (!strcmp(argv2[argv_i], "--start") || !strcmp(argv2[argv_i], "-b")) {
+            if (argv_i++ >= argc) {
+                Tcl_AppendResult(interp, "RRD Error: option '",
+                                 argv2[argv_i - 1], "' needs an argument",
+                                 (char *) NULL);
+                getopt_cleanup(argc, argv2);
+                return TCL_ERROR;
+            }
+            if ((parsetime_error = parsetime(argv2[argv_i], &last_up_tv))) {
+                Tcl_AppendResult(interp, "RRD Error: invalid time format: '",
+                                 argv2[argv_i], "'", (char *) NULL);
+                getopt_cleanup(argc, argv2);
+                return TCL_ERROR;
+            }
+            if (last_up_tv.type == RELATIVE_TO_END_TIME ||
+                last_up_tv.type == RELATIVE_TO_START_TIME) {
+                Tcl_AppendResult(interp,
+                                 "RRD Error: specifying time relative to the 'start' ",
+                                 "or 'end' makes no sense here",
+                                 (char *) NULL);
+                getopt_cleanup(argc, argv2);
+                return TCL_ERROR;
+            }
+            last_up = mktime(&last_up_tv.tm) +last_up_tv.offset;
+            if (last_up < 3600 * 24 * 365 * 10) {
+                Tcl_AppendResult(interp,
+                                 "RRD Error: the first entry to the RRD should be after 1980",
+                                 (char *) NULL);
+                getopt_cleanup(argc, argv2);
+                return TCL_ERROR;
+            }
+            getopt_free_element(argv2, argv_i - 1);
+            getopt_free_element(argv2, argv_i);
+        } else if (!strcmp(argv2[argv_i], "--step")
+                   || !strcmp(argv2[argv_i], "-s")) {
+            if (argv_i++ >= argc) {
+                Tcl_AppendResult(interp, "RRD Error: option '",
+                                 argv2[argv_i - 1], "' needs an argument",
+                                 (char *) NULL);
+                getopt_cleanup(argc, argv2);
+                return TCL_ERROR;
+            }
+            long_tmp = atol(argv2[argv_i]);
+            if (long_tmp < 1) {
+                Tcl_AppendResult(interp,
+                                 "RRD Error: step size should be no less than one second",
+                                 (char *) NULL);
+                getopt_cleanup(argc, argv2);
+                return TCL_ERROR;
+            }
+            pdp_step = long_tmp;
+            getopt_free_element(argv2, argv_i - 1);
+            getopt_free_element(argv2, argv_i);
+        } else if (!strcmp(argv2[argv_i], "--")) {
+            getopt_free_element(argv2, argv_i);
+            break;
+        } else if (argv2[argv_i][0] == '-') {
+            Tcl_AppendResult(interp, "RRD Error: unknown option '",
+                             argv2[argv_i], "'", (char *) NULL);
+            getopt_cleanup(argc, argv2);
+            return TCL_ERROR;
+        }
     }
 
     getopt_squieeze(&argc, argv2);
 
     if (argc < 2) {
-       Tcl_AppendResult(interp, "RRD Error: needs rrd filename",
-                        (char *) NULL);
-       getopt_cleanup(argc, argv2);
-       return TCL_ERROR;
+        Tcl_AppendResult(interp, "RRD Error: needs rrd filename",
+                         (char *) NULL);
+        getopt_cleanup(argc, argv2);
+        return TCL_ERROR;
     }
 
-    rrd_create_r(argv2[1], pdp_step, last_up, argc - 2, (const char **) argv2 + 2);
+    rrd_create_r(argv2[1], pdp_step, last_up, argc - 2, argv2 + 2);
 
     getopt_cleanup(argc, argv2);
-    
+
     if (rrd_test_error()) {
-       Tcl_AppendResult(interp, "RRD Error: ",
-                        rrd_get_error(), (char *) NULL);
+        Tcl_AppendResult(interp, "RRD Error: ",
+                         rrd_get_error(), (char *) NULL);
         rrd_clear_error();
-       return TCL_ERROR;
+        return TCL_ERROR;
     }
 
     return TCL_OK;
@@ -188,15 +203,16 @@ Rrd_Create(ClientData clientData, Tcl_Interp *interp, int argc, CONST84 char *ar
 
 
 /* Thread-safe version */
-static int
-Rrd_Dump(ClientData clientData, Tcl_Interp *interp, int argc, CONST84 char *argv[])
+static int Rrd_Dump(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int argc,
+    CONST84 char *argv[])
 {
-    (void) clientData; /* slience gcc */
-
     if (argc < 2) {
-       Tcl_AppendResult(interp, "RRD Error: needs rrd filename",
-                        (char *) NULL);
-       return TCL_ERROR;
+        Tcl_AppendResult(interp, "RRD Error: needs rrd filename",
+                         (char *) NULL);
+        return TCL_ERROR;
     }
 
     rrd_dump_r(argv[1], NULL);
@@ -204,10 +220,10 @@ Rrd_Dump(ClientData clientData, Tcl_Interp *interp, int argc, CONST84 char *argv
     /* NOTE: rrd_dump() writes to stdout. No interaction with TCL. */
 
     if (rrd_test_error()) {
-       Tcl_AppendResult(interp, "RRD Error: ",
-                        rrd_get_error(), (char *) NULL);
+        Tcl_AppendResult(interp, "RRD Error: ",
+                         rrd_get_error(), (char *) NULL);
         rrd_clear_error();
-       return TCL_ERROR;
+        return TCL_ERROR;
     }
 
     return TCL_OK;
@@ -216,26 +232,27 @@ Rrd_Dump(ClientData clientData, Tcl_Interp *interp, int argc, CONST84 char *argv
 
 
 /* Thread-safe version */
-static int
-Rrd_Last(ClientData clientData, Tcl_Interp *interp, int argc, CONST84 char *argv[])
+static int Rrd_Last(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int argc,
+    CONST84 char *argv[])
 {
-    (void) clientData; /* slience gcc */
+    time_t    t;
 
-    time_t t;
-    
     if (argc < 2) {
-       Tcl_AppendResult(interp, "RRD Error: needs rrd filename",
-                        (char *) NULL);
-       return TCL_ERROR;
+        Tcl_AppendResult(interp, "RRD Error: needs rrd filename",
+                         (char *) NULL);
+        return TCL_ERROR;
     }
 
     t = rrd_last_r(argv[1]);
 
     if (rrd_test_error()) {
-       Tcl_AppendResult(interp, "RRD Error: ",
-                        rrd_get_error(), (char *) NULL);
+        Tcl_AppendResult(interp, "RRD Error: ",
+                         rrd_get_error(), (char *) NULL);
         rrd_clear_error();
-       return TCL_ERROR;
+        return TCL_ERROR;
     }
 
     Tcl_SetIntObj(Tcl_GetObjResult(interp), t);
@@ -246,153 +263,159 @@ Rrd_Last(ClientData clientData, Tcl_Interp *interp, int argc, CONST84 char *argv
 
 
 /* Thread-safe version */
-static int
-Rrd_Update(ClientData clientData, Tcl_Interp *interp, int argc, CONST84 char *argv[])
+static int Rrd_Update(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int argc,
+    CONST84 char *argv[])
 {
-    int                argv_i;
-    char       **argv2, *template = NULL;
-    
-    (void) clientData; /* slience gcc */
+    int       argv_i;
+    char    **argv2, *template = NULL;
 
     argv2 = getopt_init(argc, argv);
 
     for (argv_i = 1; argv_i < argc; argv_i++) {
-       if (!strcmp(argv2[argv_i], "--template") || !strcmp(argv2[argv_i], "-t")) {
-           if (argv_i++>=argc) {
-               Tcl_AppendResult(interp, "RRD Error: option '",
-                                argv2[argv_i - 1], "' needs an argument", (char *) NULL);
-               if (template != NULL) {
-                   free(template);
-               }
-               getopt_cleanup(argc, argv2);
-               return TCL_ERROR;
-           }
-           if (template != NULL) {
-               free(template);
-           }
-           template = strdup(argv2[argv_i]);
-           getopt_free_element(argv2, argv_i - 1);
-           getopt_free_element(argv2, argv_i);
-       } else if (!strcmp(argv2[argv_i], "--")) {
-           getopt_free_element(argv2, argv_i);
-           break;
-       } else if (argv2[argv_i][0]=='-') {
-           Tcl_AppendResult(interp, "RRD Error: unknown option '",
-                            argv2[argv_i], "'", (char *) NULL);
-           if (template != NULL) {
-               free(template);
-           }
-           getopt_cleanup(argc, argv2);
-           return TCL_ERROR;
-       }
+        if (!strcmp(argv2[argv_i], "--template")
+            || !strcmp(argv2[argv_i], "-t")) {
+            if (argv_i++ >= argc) {
+                Tcl_AppendResult(interp, "RRD Error: option '",
+                                 argv2[argv_i - 1], "' needs an argument",
+                                 (char *) NULL);
+                if (template != NULL) {
+                    free(template);
+                }
+                getopt_cleanup(argc, argv2);
+                return TCL_ERROR;
+            }
+            if (template != NULL) {
+                free(template);
+            }
+            template = strdup(argv2[argv_i]);
+            getopt_free_element(argv2, argv_i - 1);
+            getopt_free_element(argv2, argv_i);
+        } else if (!strcmp(argv2[argv_i], "--")) {
+            getopt_free_element(argv2, argv_i);
+            break;
+        } else if (argv2[argv_i][0] == '-') {
+            Tcl_AppendResult(interp, "RRD Error: unknown option '",
+                             argv2[argv_i], "'", (char *) NULL);
+            if (template != NULL) {
+                free(template);
+            }
+            getopt_cleanup(argc, argv2);
+            return TCL_ERROR;
+        }
     }
 
     getopt_squieeze(&argc, argv2);
 
     if (argc < 2) {
-       Tcl_AppendResult(interp, "RRD Error: needs rrd filename",
-                        (char *) NULL);
-       if (template != NULL) {
-           free(template);
-       }
-       getopt_cleanup(argc, argv2);
-       return TCL_ERROR;
+        Tcl_AppendResult(interp, "RRD Error: needs rrd filename",
+                         (char *) NULL);
+        if (template != NULL) {
+            free(template);
+        }
+        getopt_cleanup(argc, argv2);
+        return TCL_ERROR;
     }
 
-    rrd_update_r(argv2[1], template, argc - 2, (const char **) argv2 + 2);
+    rrd_update_r(argv2[1], template, argc - 2, argv2 + 2);
 
     if (template != NULL) {
-       free(template);
+        free(template);
     }
     getopt_cleanup(argc, argv2);
 
     if (rrd_test_error()) {
-       Tcl_AppendResult(interp, "RRD Error: ",
-                        rrd_get_error(), (char *) NULL);
+        Tcl_AppendResult(interp, "RRD Error: ",
+                         rrd_get_error(), (char *) NULL);
         rrd_clear_error();
-       return TCL_ERROR;
+        return TCL_ERROR;
     }
 
     return TCL_OK;
 }
 
-static int
-Rrd_Lastupdate(ClientData clientData, Tcl_Interp *interp, int argc, CONST84 char *argv[])
+static int Rrd_Lastupdate(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int argc,
+    CONST84 char *argv[])
 {
-   time_t last_update;
-   char **argv2;
-   char **ds_namv;
-   char **last_ds;
-   char s[30];
-   Tcl_Obj *listPtr;
-   unsigned long ds_cnt, i;
-
-   (void) clientData;  /* slience gcc */
-
-   argv2 = getopt_init(argc, argv);
-   if (rrd_lastupdate(argc-1, argv2, &last_update,
-       &ds_cnt, &ds_namv, &last_ds) == 0) {
-          listPtr = Tcl_GetObjResult(interp);
-           for (i=0; i<ds_cnt; i++) {
-              sprintf(s, " %28s", ds_namv[i]);
-              Tcl_ListObjAppendElement(interp, listPtr,
-                      Tcl_NewStringObj(s, -1));
-           sprintf(s, "\n\n%10lu:", last_update);
-              Tcl_ListObjAppendElement(interp, listPtr,
-                      Tcl_NewStringObj(s, -1));
-           for (i=0; i<ds_cnt; i++) {
-               sprintf(s, " %s", last_ds[i]);
-              Tcl_ListObjAppendElement(interp, listPtr,
-                      Tcl_NewStringObj(s, -1));
-               free(last_ds[i]);
-               free(ds_namv[i]);
-           }
-           sprintf(s, "\n");
-          Tcl_ListObjAppendElement(interp, listPtr,
-                   Tcl_NewStringObj(s, -1));
-           free(last_ds);
-           free(ds_namv);
-          }
+    time_t    last_update;
+    char    **argv2;
+    char    **ds_namv;
+    char    **last_ds;
+    char      s[30];
+    Tcl_Obj  *listPtr;
+    unsigned long ds_cnt, i;
+
+    argv2 = getopt_init(argc, argv);
+    if (rrd_lastupdate(argc - 1, argv2, &last_update,
+                       &ds_cnt, &ds_namv, &last_ds) == 0) {
+        listPtr = Tcl_GetObjResult(interp);
+        for (i = 0; i < ds_cnt; i++) {
+            sprintf(s, " %28s", ds_namv[i]);
+            Tcl_ListObjAppendElement(interp, listPtr,
+                                     Tcl_NewStringObj(s, -1));
+            sprintf(s, "\n\n%10lu:", last_update);
+            Tcl_ListObjAppendElement(interp, listPtr,
+                                     Tcl_NewStringObj(s, -1));
+            for (i = 0; i < ds_cnt; i++) {
+                sprintf(s, " %s", last_ds[i]);
+                Tcl_ListObjAppendElement(interp, listPtr,
+                                         Tcl_NewStringObj(s, -1));
+                free(last_ds[i]);
+                free(ds_namv[i]);
+            }
+            sprintf(s, "\n");
+            Tcl_ListObjAppendElement(interp, listPtr,
+                                     Tcl_NewStringObj(s, -1));
+            free(last_ds);
+            free(ds_namv);
+        }
     }
     return TCL_OK;
 }
 
-static int
-Rrd_Fetch(ClientData clientData, Tcl_Interp *interp, int argc, CONST84 char *argv[])
+static int Rrd_Fetch(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int argc,
+    CONST84 char *argv[])
 {
-    time_t start, end, j;
+    time_t    start, end, j;
     unsigned long step, ds_cnt, i, ii;
     rrd_value_t *data, *datai;
-    char **ds_namv;
-    Tcl_Obj *listPtr;
-    char s[30];
-    char **argv2;
-    
-    (void) clientData; /* slience gcc */
+    char    **ds_namv;
+    Tcl_Obj  *listPtr;
+    char      s[30];
+    char    **argv2;
 
     argv2 = getopt_init(argc, argv);
     if (rrd_fetch(argc, argv2, &start, &end, &step,
-                 &ds_cnt, &ds_namv, &data) != -1) {
+                  &ds_cnt, &ds_namv, &data) != -1) {
         datai = data;
         listPtr = Tcl_GetObjResult(interp);
         for (j = start; j <= end; j += step) {
             for (ii = 0; ii < ds_cnt; ii++) {
-               sprintf(s, "%.2f", *(datai++));
+                sprintf(s, "%.2f", *(datai++));
                 Tcl_ListObjAppendElement(interp, listPtr,
-                                        Tcl_NewStringObj(s, -1));
+                                         Tcl_NewStringObj(s, -1));
             }
         }
-        for (i=0; i<ds_cnt; i++) free(ds_namv[i]);
+        for (i = 0; i < ds_cnt; i++)
+            free(ds_namv[i]);
         free(ds_namv);
         free(data);
     }
     getopt_cleanup(argc, argv2);
 
     if (rrd_test_error()) {
-       Tcl_AppendResult(interp, "RRD Error: ",
-                        rrd_get_error(), (char *) NULL);
+        Tcl_AppendResult(interp, "RRD Error: ",
+                         rrd_get_error(), (char *) NULL);
         rrd_clear_error();
-       return TCL_ERROR;
+        return TCL_ERROR;
     }
 
     return TCL_OK;
@@ -400,104 +423,109 @@ Rrd_Fetch(ClientData clientData, Tcl_Interp *interp, int argc, CONST84 char *arg
 
 
 
-static int
-Rrd_Graph(ClientData clientData, Tcl_Interp *interp, int argc, CONST84 char *argv[])
+static int Rrd_Graph(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int argc,
+    CONST84 char *argv[])
 {
     Tcl_Channel channel;
-    int mode, fd2;
+    int       mode, fd2;
     ClientData fd1;
-    FILE *stream = NULL;
-    char **calcpr = NULL;
-    int rc, xsize, ysize;
-    double ymin, ymax;
-    char dimensions[50];
-    char **argv2;
+    FILE     *stream = NULL;
+    char    **calcpr = NULL;
+    int       rc, xsize, ysize;
+    double    ymin, ymax;
+    char      dimensions[50];
+    char    **argv2;
     CONST84 char *save;
-    
-    (void) clientData; /* slience gcc */
 
     /*
      * If the "filename" is a Tcl fileID, then arrange for rrd_graph() to write to
      * that file descriptor.  Will this work with windoze?  I have no idea.
      */
     if ((channel = Tcl_GetChannel(interp, argv[1], &mode)) != NULL) {
-       /*
-        * It >is< a Tcl fileID
-        */
-       if (!(mode & TCL_WRITABLE)) {
-           Tcl_AppendResult(interp, "channel \"", argv[1],
-               "\" wasn't opened for writing", (char *) NULL);
-           return TCL_ERROR;
-       }
-       /*
-        * Must flush channel to make sure any buffered data is written before
-        * rrd_graph() writes to the stream
-        */
-       if (Tcl_Flush(channel) != TCL_OK) {
-           Tcl_AppendResult(interp, "flush failed for \"", argv[1], "\": ",
-               strerror(Tcl_GetErrno()), (char *) NULL);
-           return TCL_ERROR;
-       }
-       if (Tcl_GetChannelHandle(channel, TCL_WRITABLE, &fd1) != TCL_OK) {
-           Tcl_AppendResult(interp, "cannot get file descriptor associated with \"",
-               argv[1], "\"", (char *) NULL);
-           return TCL_ERROR;
-       }
-       /*
-        * Must dup() file descriptor so we can fclose(stream), otherwise the fclose()
-        * would close Tcl's file descriptor
-        */
-       if ((fd2 = dup((int)fd1)) == -1) {
-           Tcl_AppendResult(interp, "dup() failed for file descriptor associated with \"",
-               argv[1], "\": ", strerror(errno), (char *) NULL);
-           return TCL_ERROR;
-       }
-       /*
-        * rrd_graph() wants a FILE*
-        */
-       if ((stream = fdopen(fd2, "wb")) == NULL) {
-           Tcl_AppendResult(interp, "fdopen() failed for file descriptor associated with \"",
-               argv[1], "\": ", strerror(errno), (char *) NULL);
-           close(fd2);         /* plug potential file descriptor leak */
-           return TCL_ERROR;
-       }
-
-       save = argv[1];
-       argv[1] = "-";
-       argv2 = getopt_init(argc, argv);
-       argv[1] = save;
+        /*
+         * It >is< a Tcl fileID
+         */
+        if (!(mode & TCL_WRITABLE)) {
+            Tcl_AppendResult(interp, "channel \"", argv[1],
+                             "\" wasn't opened for writing", (char *) NULL);
+            return TCL_ERROR;
+        }
+        /*
+         * Must flush channel to make sure any buffered data is written before
+         * rrd_graph() writes to the stream
+         */
+        if (Tcl_Flush(channel) != TCL_OK) {
+            Tcl_AppendResult(interp, "flush failed for \"", argv[1], "\": ",
+                             strerror(Tcl_GetErrno()), (char *) NULL);
+            return TCL_ERROR;
+        }
+        if (Tcl_GetChannelHandle(channel, TCL_WRITABLE, &fd1) != TCL_OK) {
+            Tcl_AppendResult(interp,
+                             "cannot get file descriptor associated with \"",
+                             argv[1], "\"", (char *) NULL);
+            return TCL_ERROR;
+        }
+        /*
+         * Must dup() file descriptor so we can fclose(stream), otherwise the fclose()
+         * would close Tcl's file descriptor
+         */
+        if ((fd2 = dup((int) fd1)) == -1) {
+            Tcl_AppendResult(interp,
+                             "dup() failed for file descriptor associated with \"",
+                             argv[1], "\": ", strerror(errno), (char *) NULL);
+            return TCL_ERROR;
+        }
+        /*
+         * rrd_graph() wants a FILE*
+         */
+        if ((stream = fdopen(fd2, "wb")) == NULL) {
+            Tcl_AppendResult(interp,
+                             "fdopen() failed for file descriptor associated with \"",
+                             argv[1], "\": ", strerror(errno), (char *) NULL);
+            close(fd2); /* plug potential file descriptor leak */
+            return TCL_ERROR;
+        }
+
+        save = argv[1];
+        argv[1] = "-";
+        argv2 = getopt_init(argc, argv);
+        argv[1] = save;
     } else {
-       Tcl_ResetResult(interp);        /* clear error from Tcl_GetChannel() */
-       argv2 = getopt_init(argc, argv);
+        Tcl_ResetResult(interp);    /* clear error from Tcl_GetChannel() */
+        argv2 = getopt_init(argc, argv);
     }
 
-    rc = rrd_graph(argc, argv2, &calcpr, &xsize, &ysize, stream, &ymin, &ymax);
+    rc = rrd_graph(argc, argv2, &calcpr, &xsize, &ysize, stream, &ymin,
+                   &ymax);
     getopt_cleanup(argc, argv2);
 
     if (stream != NULL)
-       fclose(stream);         /* plug potential malloc & file descriptor leak */
+        fclose(stream); /* plug potential malloc & file descriptor leak */
 
     if (rc != -1) {
         sprintf(dimensions, "%d %d", xsize, ysize);
         Tcl_AppendResult(interp, dimensions, (char *) NULL);
         if (calcpr) {
 #if 0
-           int i;
-           
-            for(i = 0; calcpr[i]; i++){
+            int       i;
+
+            for (i = 0; calcpr[i]; i++) {
                 printf("%s\n", calcpr[i]);
                 free(calcpr[i]);
-            } 
+            }
 #endif
             free(calcpr);
         }
     }
 
     if (rrd_test_error()) {
-       Tcl_AppendResult(interp, "RRD Error: ",
-                        rrd_get_error(), (char *) NULL);
+        Tcl_AppendResult(interp, "RRD Error: ",
+                         rrd_get_error(), (char *) NULL);
         rrd_clear_error();
-       return TCL_ERROR;
+        return TCL_ERROR;
     }
 
     return TCL_OK;
@@ -505,22 +533,23 @@ Rrd_Graph(ClientData clientData, Tcl_Interp *interp, int argc, CONST84 char *arg
 
 
 
-static int
-Rrd_Tune(ClientData clientData, Tcl_Interp *interp, int argc, CONST84 char *argv[])
+static int Rrd_Tune(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int argc,
+    CONST84 char *argv[])
 {
-    char **argv2;
-    
-    (void) clientData; /* slience gcc */
+    char    **argv2;
 
     argv2 = getopt_init(argc, argv);
     rrd_tune(argc, argv2);
     getopt_cleanup(argc, argv2);
 
     if (rrd_test_error()) {
-       Tcl_AppendResult(interp, "RRD Error: ",
-                        rrd_get_error(), (char *) NULL);
+        Tcl_AppendResult(interp, "RRD Error: ",
+                         rrd_get_error(), (char *) NULL);
         rrd_clear_error();
-       return TCL_ERROR;
+        return TCL_ERROR;
     }
 
     return TCL_OK;
@@ -528,22 +557,23 @@ Rrd_Tune(ClientData clientData, Tcl_Interp *interp, int argc, CONST84 char *argv
 
 
 
-static int
-Rrd_Resize(ClientData clientData, Tcl_Interp *interp, int argc, CONST84 char *argv[])
+static int Rrd_Resize(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int argc,
+    CONST84 char *argv[])
 {
-    char **argv2;
-    
-    (void) clientData; /* slience gcc */
+    char    **argv2;
 
     argv2 = getopt_init(argc, argv);
     rrd_resize(argc, argv2);
     getopt_cleanup(argc, argv2);
 
     if (rrd_test_error()) {
-       Tcl_AppendResult(interp, "RRD Error: ",
-                        rrd_get_error(), (char *) NULL);
+        Tcl_AppendResult(interp, "RRD Error: ",
+                         rrd_get_error(), (char *) NULL);
         rrd_clear_error();
-       return TCL_ERROR;
+        return TCL_ERROR;
     }
 
     return TCL_OK;
@@ -551,22 +581,23 @@ Rrd_Resize(ClientData clientData, Tcl_Interp *interp, int argc, CONST84 char *ar
 
 
 
-static int
-Rrd_Restore(ClientData clientData, Tcl_Interp *interp, int argc, CONST84 char *argv[])
+static int Rrd_Restore(
+    ClientData clientData,
+    Tcl_Interp *interp,
+    int argc,
+    CONST84 char *argv[])
 {
-    char **argv2;
-    
-    (void) clientData; /* slience gcc */
+    char    **argv2;
 
     argv2 = getopt_init(argc, argv);
     rrd_restore(argc, argv2);
     getopt_cleanup(argc, argv2);
 
     if (rrd_test_error()) {
-       Tcl_AppendResult(interp, "RRD Error: ",
-                        rrd_get_error(), (char *) NULL);
+        Tcl_AppendResult(interp, "RRD Error: ",
+                         rrd_get_error(), (char *) NULL);
         rrd_clear_error();
-       return TCL_ERROR;
+        return TCL_ERROR;
     }
 
     return TCL_OK;
@@ -579,39 +610,40 @@ Rrd_Restore(ClientData clientData, Tcl_Interp *interp, int argc, CONST84 char *a
  */
 
 typedef struct {
-    char *name;                        /* Name of the command. */
-    Tcl_CmdProc *proc;         /* Procedure for command. */
-    int hide;                  /* Hide if safe interpreter */
+    char     *name;     /* Name of the command. */
+    Tcl_CmdProc *proc;  /* Procedure for command. */
+    int       hide;     /* Hide if safe interpreter */
 } CmdInfo;
 
 static CmdInfo rrdCmds[] = {
-    { "Rrd::create",    Rrd_Create,     1 }, /* Thread-safe version */
-    { "Rrd::dump",      Rrd_Dump,       0 }, /* Thread-safe version */
-    { "Rrd::last",      Rrd_Last,       0 }, /* Thread-safe version */
-    { "Rrd::lastupdate", Rrd_Lastupdate, 0 }, /* Thread-safe version */
-    { "Rrd::update",    Rrd_Update,     1 }, /* Thread-safe version */
-    { "Rrd::fetch",     Rrd_Fetch,      0 },
-    { "Rrd::graph",     Rrd_Graph,      1 }, /* Due to RRD's API, a safe
-                                               interpreter cannot create
-                                               a graph since it writes to
-                                               a filename supplied by the
-                                               caller */
-    { "Rrd::tune",      Rrd_Tune,       1 },
-    { "Rrd::resize",    Rrd_Resize,     1 },
-    { "Rrd::restore",   Rrd_Restore,    1 },
-    { (char *) NULL,   (Tcl_CmdProc *)  NULL, 0        }
+    {"Rrd::create", Rrd_Create, 1}, /* Thread-safe version */
+    {"Rrd::dump", Rrd_Dump, 0}, /* Thread-safe version */
+    {"Rrd::last", Rrd_Last, 0}, /* Thread-safe version */
+    {"Rrd::lastupdate", Rrd_Lastupdate, 0}, /* Thread-safe version */
+    {"Rrd::update", Rrd_Update, 1}, /* Thread-safe version */
+    {"Rrd::fetch", Rrd_Fetch, 0},
+    {"Rrd::graph", Rrd_Graph, 1},   /* Due to RRD's API, a safe
+                                       interpreter cannot create
+                                       a graph since it writes to
+                                       a filename supplied by the
+                                       caller */
+    {"Rrd::tune", Rrd_Tune, 1},
+    {"Rrd::resize", Rrd_Resize, 1},
+    {"Rrd::restore", Rrd_Restore, 1},
+    {(char *) NULL, (Tcl_CmdProc *) NULL, 0}
 };
 
 
 
-static int
-init(Tcl_Interp *interp, int safe)
-{ 
-    CmdInfo *cmdInfoPtr;
+static int init(
+    Tcl_Interp *interp,
+    int safe)
+{
+    CmdInfo  *cmdInfoPtr;
     Tcl_CmdInfo info;
 
-    if ( Tcl_InitStubs(interp,TCL_VERSION,0) == NULL )
-       return TCL_ERROR;
+    if (Tcl_InitStubs(interp, TCL_VERSION, 0) == NULL)
+        return TCL_ERROR;
 
     if (Tcl_PkgRequire(interp, "Tcl", TCL_VERSION, 1) == NULL) {
         return TCL_ERROR;
@@ -624,65 +656,65 @@ init(Tcl_Interp *interp, int safe)
     Tcl_SetVar2(interp, "rrd", "version", VERSION, TCL_GLOBAL_ONLY);
 
     for (cmdInfoPtr = rrdCmds; cmdInfoPtr->name != NULL; cmdInfoPtr++) {
-       /*
-        * Check if the command already exists and return an error
-        * to ensure we detect name clashes while loading the Rrd
-        * extension.
-        */
-       if (Tcl_GetCommandInfo(interp, cmdInfoPtr->name, &info)) {
-           Tcl_AppendResult(interp, "command \"", cmdInfoPtr->name,
-                            "\" already exists", (char *) NULL);
-           return TCL_ERROR;
-       }
-       if (safe && cmdInfoPtr->hide) {
+        /*
+         * Check if the command already exists and return an error
+         * to ensure we detect name clashes while loading the Rrd
+         * extension.
+         */
+        if (Tcl_GetCommandInfo(interp, cmdInfoPtr->name, &info)) {
+            Tcl_AppendResult(interp, "command \"", cmdInfoPtr->name,
+                             "\" already exists", (char *) NULL);
+            return TCL_ERROR;
+        }
+        if (safe && cmdInfoPtr->hide) {
 #if 0
-           /*
-            * Turns out the one cannot hide a command in a namespace
-            * due to a limitation of Tcl, one can only hide global
-            * commands.  Thus, if we created the commands without
-            * the Rrd:: namespace in a safe interpreter, then the
-            * "unsafe" commands could be hidden -- which would allow
-            * an owning interpreter either un-hiding them or doing
-            * an "interp invokehidden".  If the Rrd:: namespace is
-            * used, then it's still possible for the owning interpreter
-            * to fake out the missing commands:
-            *
-            *   # Make all Rrd::* commands available in master interperter
-            *   package require Rrd
-            *   set safe [interp create -safe]
-            *   # Make safe Rrd::* commands available in safe interperter
-            *   interp invokehidden $safe -global load ./tclrrd1.2.11.so
-            *   # Provide the safe interpreter with the missing commands
-            *   $safe alias Rrd::update do_update $safe
-            *   proc do_update {which_interp $args} {
-            *     # Do some checking maybe...
-            *       :
-            *     return [eval Rrd::update $args]
-            *   }
-            *
-            * Our solution for now is to just not create the "unsafe"
-            * commands in a safe interpreter.
-            */
-           if (Tcl_HideCommand(interp, cmdInfoPtr->name, cmdInfoPtr->name) != TCL_OK)
-               return TCL_ERROR;
+            /*
+             * Turns out the one cannot hide a command in a namespace
+             * due to a limitation of Tcl, one can only hide global
+             * commands.  Thus, if we created the commands without
+             * the Rrd:: namespace in a safe interpreter, then the
+             * "unsafe" commands could be hidden -- which would allow
+             * an owning interpreter either un-hiding them or doing
+             * an "interp invokehidden".  If the Rrd:: namespace is
+             * used, then it's still possible for the owning interpreter
+             * to fake out the missing commands:
+             *
+             *   # Make all Rrd::* commands available in master interperter
+             *   package require Rrd
+             *   set safe [interp create -safe]
+             *   # Make safe Rrd::* commands available in safe interperter
+             *   interp invokehidden $safe -global load ./tclrrd1.2.11.so
+             *   # Provide the safe interpreter with the missing commands
+             *   $safe alias Rrd::update do_update $safe
+             *   proc do_update {which_interp $args} {
+             *     # Do some checking maybe...
+             *       :
+             *     return [eval Rrd::update $args]
+             *   }
+             *
+             * Our solution for now is to just not create the "unsafe"
+             * commands in a safe interpreter.
+             */
+            if (Tcl_HideCommand(interp, cmdInfoPtr->name, cmdInfoPtr->name) !=
+                TCL_OK)
+                return TCL_ERROR;
 #endif
-       }
-       else
-           Tcl_CreateCommand(interp, cmdInfoPtr->name, cmdInfoPtr->proc,
-                         (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
+        } else
+            Tcl_CreateCommand(interp, cmdInfoPtr->name, cmdInfoPtr->proc,
+                              (ClientData) NULL, (Tcl_CmdDeleteProc *) NULL);
     }
 
     if (Tcl_PkgProvide(interp, "Rrd", VERSION) != TCL_OK) {
-       return TCL_ERROR;
+        return TCL_ERROR;
     }
 
     return TCL_OK;
 }
 
-int
-Tclrrd_Init(Tcl_Interp *interp)
-{ 
-  return init(interp, 0);
+int Tclrrd_Init(
+    Tcl_Interp *interp)
+{
+    return init(interp, 0);
 }
 
 /*
@@ -690,8 +722,8 @@ Tclrrd_Init(Tcl_Interp *interp)
  * Using rrdtool in a safe interpreter has very limited functionality.  It's
  * tempting to just return TCL_ERROR and forget about it.
  */
-int
-Tclrrd_SafeInit(Tcl_Interp *interp)
-{ 
-  return init(interp, 1);
+int Tclrrd_SafeInit(
+    Tcl_Interp *interp)
+{
+    return init(interp, 1);
 }
index 105dfce5d17f9fa0109b9c400acc5f6184931ee7..acfddca7a306f305741b712d7d26a60a1e1861fb 100755 (executable)
--- a/configure
+++ b/configure
@@ -1,6 +1,6 @@
 #! /bin/sh
 # Guess values for system-dependent variables and create Makefiles.
-# Generated by GNU Autoconf 2.61 for rrdtool 1.2.27.
+# Generated by GNU Autoconf 2.61 for rrdtool 1.3rc4.
 #
 # Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
 # 2002, 2003, 2004, 2005, 2006 Free Software Foundation, Inc.
@@ -726,8 +726,8 @@ SHELL=${CONFIG_SHELL-/bin/sh}
 # Identity of this package.
 PACKAGE_NAME='rrdtool'
 PACKAGE_TARNAME='rrdtool'
-PACKAGE_VERSION='1.2.27'
-PACKAGE_STRING='rrdtool 1.2.27'
+PACKAGE_VERSION='1.3rc4'
+PACKAGE_STRING='rrdtool 1.3rc4'
 PACKAGE_BUGREPORT=''
 
 ac_default_prefix=/usr/local/rrdtool-$PACKAGE_VERSION
@@ -806,6 +806,7 @@ build_alias
 host_alias
 target_alias
 NUMVERS
+LIBVERS
 build
 build_cpu
 build_vendor
@@ -839,7 +840,12 @@ am__leading_dot
 AMTAR
 am__tar
 am__untar
+MAINTAINER_MODE_TRUE
+MAINTAINER_MODE_FALSE
+MAINT
 RRDGRAPH_YLEGEND_ANGLE
+STATIC_PROGRAMS_TRUE
+STATIC_PROGRAMS_FALSE
 CC
 CFLAGS
 LDFLAGS
@@ -875,6 +881,53 @@ FFLAGS
 ac_ct_F77
 LIBTOOL
 RRD_DEFAULT_FONT
+GETTEXT_PACKAGE
+USE_NLS
+MSGFMT
+MSGFMT_OPTS
+GMSGFMT
+XGETTEXT
+CATALOGS
+CATOBJEXT
+DATADIRNAME
+GMOFILES
+INSTOBJEXT
+INTLLIBS
+PO_IN_DATADIR_TRUE
+PO_IN_DATADIR_FALSE
+POFILES
+POSUB
+MKINSTALLDIRS
+INTLTOOL_DESKTOP_RULE
+INTLTOOL_DIRECTORY_RULE
+INTLTOOL_KEYS_RULE
+INTLTOOL_PROP_RULE
+INTLTOOL_OAF_RULE
+INTLTOOL_PONG_RULE
+INTLTOOL_SERVER_RULE
+INTLTOOL_SHEET_RULE
+INTLTOOL_SOUNDLIST_RULE
+INTLTOOL_UI_RULE
+INTLTOOL_XAM_RULE
+INTLTOOL_KBD_RULE
+INTLTOOL_XML_RULE
+INTLTOOL_XML_NOMERGE_RULE
+INTLTOOL_CAVES_RULE
+INTLTOOL_SCHEMAS_RULE
+INTLTOOL_THEME_RULE
+INTLTOOL_SERVICE_RULE
+INTLTOOL_EXTRACT
+INTLTOOL_MERGE
+INTLTOOL_UPDATE
+INTLTOOL_PERL
+INTLTOOL_ICONV
+INTLTOOL_MSGFMT
+INTLTOOL_MSGMERGE
+INTLTOOL_XGETTEXT
+ALL_LINGUAS
+LIB_LIBINTL
+BUILD_LIBINTL_TRUE
+BUILD_LIBINTL_FALSE
 MULTITHREAD_CFLAGS
 MULTITHREAD_LDFLAGS
 acx_pthread_config
@@ -889,6 +942,8 @@ PKGCONFIG
 CORE_LIBS
 ALL_LIBS
 PERL
+POD2MAN
+POD2HTML
 PERLCC
 PERLCCFLAGS
 PERLLD
@@ -913,6 +968,7 @@ TCL_LD_SEARCH_FLAGS
 TCL_STUB_LIB_SPEC
 TCL_VERSION
 TCL_PACKAGE_DIR
+TCL_INC_DIR
 PYTHON
 PYTHON_VERSION
 PYTHON_PREFIX
@@ -1453,7 +1509,7 @@ if test "$ac_init_help" = "long"; then
   # Omit some internal or obsolete options to make the list less imposing.
   # This message is too long to be a string in the A/UX 3.1 sh.
   cat <<_ACEOF
-\`configure' configures rrdtool 1.2.27 to adapt to many kinds of systems.
+\`configure' configures rrdtool 1.3rc4 to adapt to many kinds of systems.
 
 Usage: $0 [OPTION]... [VAR=VALUE]...
 
@@ -1524,16 +1580,19 @@ fi
 
 if test -n "$ac_init_help"; then
   case $ac_init_help in
-     short | recursive ) echo "Configuration of rrdtool 1.2.27:";;
+     short | recursive ) echo "Configuration of rrdtool 1.3rc4:";;
    esac
   cat <<\_ACEOF
 
 Optional Features:
   --disable-FEATURE       do not include FEATURE (same as --enable-FEATURE=no)
   --enable-FEATURE[=ARG]  include FEATURE [ARG=yes]
+  --enable-maintainer-mode  enable make rules and dependencies not useful
+                         (and sometimes confusing) to the casual installer
   --disable-rrdcgi        disable building of rrdcgi
   --disable-mmap          disable mmap in rrd_update, use seek+write instead
   --disable-pthread       disable multithread support
+  --enable-static-programs  Build static programs
   --disable-dependency-tracking  speeds up one-time build
   --enable-dependency-tracking   do not reject slow dependency extractors
   --enable-shared[=PKGS]  build shared libraries [default=yes]
@@ -1541,6 +1600,7 @@ Optional Features:
   --enable-fast-install[=PKGS]
                           optimize for fast installation [default=yes]
   --disable-libtool-lock  avoid locking (might break parallel builds)
+  --disable-libintl        i18n support (libintl)
   --disable-perl          do not build the perl modules
   --enable-perl-site-install   by default the rrdtool perl modules are installed
                          together with rrdtool in $prefix/lib/perl. You have to
@@ -1577,7 +1637,7 @@ Optional Packages:
 
 Some influential environment variables:
   RRDGRAPH_YLEGEND_ANGLE
-              Vertical label angle: 90.0 (default) or 270.0
+              Vertical label angle: -90.0 (default) or 90.0
   CC          C compiler command
   CFLAGS      C compiler flags
   LDFLAGS     linker flags, e.g. -L<lib dir> if you have libraries in a
@@ -1660,7 +1720,7 @@ fi
 test -n "$ac_init_help" && exit $ac_status
 if $ac_init_version; then
   cat <<\_ACEOF
-rrdtool configure 1.2.27
+rrdtool configure 1.3rc4
 generated by GNU Autoconf 2.61
 
 Copyright (C) 1992, 1993, 1994, 1995, 1996, 1998, 1999, 2000, 2001,
@@ -1674,7 +1734,7 @@ cat >config.log <<_ACEOF
 This file contains any messages produced by compilers while
 running configure, to aid debugging if configure makes a mistake.
 
-It was created by rrdtool $as_me 1.2.27, which was
+It was created by rrdtool $as_me 1.3rc4, which was
 generated by GNU Autoconf 2.61.  Invocation command line was
 
   $ $0 $@
@@ -2027,7 +2087,12 @@ ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $
 ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
 
-NUMVERS=1.2027
+
+NUMVERS=1.299908051800
+
+
+LIBVERS=3:2:1
+
 
 ac_aux_dir=
 for ac_dir in "$srcdir" "$srcdir/.." "$srcdir/../.."; do
@@ -2472,7 +2537,7 @@ fi
 
 # Define the identity of the package.
  PACKAGE='rrdtool'
- VERSION='1.2.27'
+ VERSION='1.3rc4'
 
 
 cat >>confdefs.h <<_ACEOF
@@ -2618,6 +2683,31 @@ am__tar='${AMTAR} chof - "$$tardir"'; am__untar='${AMTAR} xf -'
 
 
 
+{ echo "$as_me:$LINENO: checking whether to enable maintainer-specific portions of Makefiles" >&5
+echo $ECHO_N "checking whether to enable maintainer-specific portions of Makefiles... $ECHO_C" >&6; }
+    # Check whether --enable-maintainer-mode was given.
+if test "${enable_maintainer_mode+set}" = set; then
+  enableval=$enable_maintainer_mode; USE_MAINTAINER_MODE=$enableval
+else
+  USE_MAINTAINER_MODE=no
+fi
+
+  { echo "$as_me:$LINENO: result: $USE_MAINTAINER_MODE" >&5
+echo "${ECHO_T}$USE_MAINTAINER_MODE" >&6; }
+
+
+if test $USE_MAINTAINER_MODE = yes; then
+  MAINTAINER_MODE_TRUE=
+  MAINTAINER_MODE_FALSE='#'
+else
+  MAINTAINER_MODE_TRUE='#'
+  MAINTAINER_MODE_FALSE=
+fi
+
+  MAINT=$MAINTAINER_MODE_TRUE
+
+
+
 ac_config_headers="$ac_config_headers rrd_config.h"
 
 
@@ -2662,7 +2752,7 @@ else
   if test -d ${WINDIR:-nodir}/cour.ttf ; then
        RRD_DEFAULT_FONT=`cd $WINDIR;pwd`/cour.ttf
   else
-       RRD_DEFAULT_FONT='$(fontsdir)/$(fonts_DATA)'
+       RRD_DEFAULT_FONT='"DejaVu Sans Mono,Bitstream Vera Sans Mono,monospace,Courier"'
   fi
 
 fi
@@ -2676,8 +2766,7 @@ else
 fi
 
 
-
- # Check whether --enable-pthread was given.
+# Check whether --enable-pthread was given.
 if test "${enable_pthread+set}" = set; then
   enableval=$enable_pthread;
 else
@@ -2685,6 +2774,29 @@ else
 fi
 
 
+# Check whether --enable-static-programs was given.
+if test "${enable_static_programs+set}" = set; then
+  enableval=$enable_static_programs; case "${enableval}" in
+       yes) staticprogs=yes ;;
+       no)  staticprogs=no ;;
+       *) { { echo "$as_me:$LINENO: error: bad value ${enableval} for --enable-static-programs" >&5
+echo "$as_me: error: bad value ${enableval} for --enable-static-programs" >&2;}
+   { (exit 1); exit 1; }; } ;;
+     esac
+else
+  staticprogs=no
+fi
+
+
+
+if test "x$staticprogs" = "xyes"; then
+  STATIC_PROGRAMS_TRUE=
+  STATIC_PROGRAMS_FALSE='#'
+else
+  STATIC_PROGRAMS_TRUE='#'
+  STATIC_PROGRAMS_FALSE=
+fi
+
 
 
 
@@ -4746,7 +4858,7 @@ ia64-*-hpux*)
   ;;
 *-*-irix6*)
   # Find out which ABI we are using.
-  echo '#line 4749 "configure"' > conftest.$ac_ext
+  echo '#line 4861 "configure"' > conftest.$ac_ext
   if { (eval echo "$as_me:$LINENO: \"$ac_compile\"") >&5
   (eval $ac_compile) 2>&5
   ac_status=$?
@@ -7243,11 +7355,11 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:7246: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:7358: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:7250: \$? = $ac_status" >&5
+   echo "$as_me:7362: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings other than the usual output.
@@ -7511,11 +7623,11 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:7514: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:7626: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:7518: \$? = $ac_status" >&5
+   echo "$as_me:7630: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings other than the usual output.
@@ -7615,11 +7727,11 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:7618: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:7730: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>out/conftest.err)
    ac_status=$?
    cat out/conftest.err >&5
-   echo "$as_me:7622: \$? = $ac_status" >&5
+   echo "$as_me:7734: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s out/conftest2.$ac_objext
    then
      # The compiler can only warn and ignore the option if not recognized
@@ -9912,7 +10024,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<EOF
-#line 9915 "configure"
+#line 10027 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -10012,7 +10124,7 @@ else
   lt_dlunknown=0; lt_dlno_uscore=1; lt_dlneed_uscore=2
   lt_status=$lt_dlunknown
   cat > conftest.$ac_ext <<EOF
-#line 10015 "configure"
+#line 10127 "configure"
 #include "confdefs.h"
 
 #if HAVE_DLFCN_H
@@ -12348,11 +12460,11 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:12351: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:12463: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:12355: \$? = $ac_status" >&5
+   echo "$as_me:12467: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings other than the usual output.
@@ -12452,11 +12564,11 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:12455: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:12567: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>out/conftest.err)
    ac_status=$?
    cat out/conftest.err >&5
-   echo "$as_me:12459: \$? = $ac_status" >&5
+   echo "$as_me:12571: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s out/conftest2.$ac_objext
    then
      # The compiler can only warn and ignore the option if not recognized
@@ -14013,11 +14125,11 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:14016: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:14128: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:14020: \$? = $ac_status" >&5
+   echo "$as_me:14132: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings other than the usual output.
@@ -14117,11 +14229,11 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:14120: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:14232: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>out/conftest.err)
    ac_status=$?
    cat out/conftest.err >&5
-   echo "$as_me:14124: \$? = $ac_status" >&5
+   echo "$as_me:14236: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s out/conftest2.$ac_objext
    then
      # The compiler can only warn and ignore the option if not recognized
@@ -16304,11 +16416,11 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:16307: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:16419: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:16311: \$? = $ac_status" >&5
+   echo "$as_me:16423: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings other than the usual output.
@@ -16572,11 +16684,11 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:16575: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:16687: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>conftest.err)
    ac_status=$?
    cat conftest.err >&5
-   echo "$as_me:16579: \$? = $ac_status" >&5
+   echo "$as_me:16691: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s "$ac_outfile"; then
      # The compiler can only warn and ignore the option if not recognized
      # So say no if there are warnings other than the usual output.
@@ -16676,11 +16788,11 @@ else
    -e 's:.*FLAGS}\{0,1\} :&$lt_compiler_flag :; t' \
    -e 's: [^ ]*conftest\.: $lt_compiler_flag&:; t' \
    -e 's:$: $lt_compiler_flag:'`
-   (eval echo "\"\$as_me:16679: $lt_compile\"" >&5)
+   (eval echo "\"\$as_me:16791: $lt_compile\"" >&5)
    (eval "$lt_compile" 2>out/conftest.err)
    ac_status=$?
    cat out/conftest.err >&5
-   echo "$as_me:16683: \$? = $ac_status" >&5
+   echo "$as_me:16795: \$? = $ac_status" >&5
    if (exit $ac_status) && test -s out/conftest2.$ac_objext
    then
      # The compiler can only warn and ignore the option if not recognized
@@ -19328,9 +19440,11 @@ LIBTOOL='$(SHELL) $(top_builddir)/libtool'
 
 
 
-if test "$GCC" = "yes"; then
-  for flag in -fno-strict-aliasing -Wall -std=gnu99 -pedantic -Wshadow -Wpointer-arith -Wcast-align -Wmissing-prototypes -Wmissing-declarations -Wnested-externs -Winline -W; do
-    oCFLAGS=$CFLAGS
+CFLAGS="$CFLAGS -D_GNU_SOURCE"
+
+if test "x$GCC" = "xyes"; then
+  for flag in -fno-strict-aliasing -Wall -std=c99 -pedantic -Wundef -Wshadow -Wpointer-arith -Wcast-align -Wmissing-prototypes -Wmissing-declarations -Wnested-externs -Winline -Wold-style-definition -W; do
+    oCFLAGS="$CFLAGS"
     CFLAGS="$CFLAGS $flag"
     cachename=rd_cv_gcc_flag_`echo $flag|sed 's/[^A-Za-z]/_/g'`
     { echo "$as_me:$LINENO: checking if gcc likes the $flag flag" >&5
@@ -19384,7 +19498,7 @@ ac_res=`eval echo '${'$cachename'}'`
               { echo "$as_me:$LINENO: result: $ac_res" >&5
 echo "${ECHO_T}$ac_res" >&6; }
     if eval test \$$cachename = no; then
-         CFLAGS=$oCFLAGS
+         CFLAGS="$oCFLAGS"
     fi
   done
 fi
 
 
 
-for ac_header in features.h sys/stat.h sys/types.h fcntl.h locale.h fp_class.h malloc.h unistd.h ieeefp.h math.h sys/times.h sys/param.h sys/resource.h float.h strings.h
+
+
+
+
+
+for ac_header in features.h sys/stat.h sys/types.h fcntl.h locale.h fp_class.h malloc.h unistd.h ieeefp.h math.h sys/times.h sys/param.h sys/resource.h signal.h float.h stdio.h stdlib.h errno.h string.h ctype.h
 do
 as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
 if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
@@ -20214,6 +20333,28 @@ _ACEOF
 fi
 
 
+
+case $TERM in
+       #   for the most important terminal types we directly know the sequences
+       xterm|xterm*|vt220|vt220*)
+               T_MD=`awk 'BEGIN { printf("%c%c%c%c", 27, 91, 49, 109); }' </dev/null 2>/dev/null`
+               T_ME=`awk 'BEGIN { printf("%c%c%c", 27, 91, 109); }' </dev/null 2>/dev/null`
+       ;;
+       vt100|vt100*|cygwin)
+               T_MD=`awk 'BEGIN { printf("%c%c%c%c%c%c", 27, 91, 49, 109, 0, 0); }' </dev/null 2>/dev/null`
+               T_ME=`awk 'BEGIN { printf("%c%c%c%c%c", 27, 91, 109, 0, 0); }' </dev/null 2>/dev/null`
+       ;;
+       *)
+               T_MD=''
+               T_ME=''
+       ;;
+esac
+  { echo "$as_me:$LINENO: result: " >&5
+echo "${ECHO_T}" >&6; }
+  { echo "$as_me:$LINENO: result: ${T_MD}Test Library Functions${T_ME}" >&5
+echo "${ECHO_T}${T_MD}Test Library Functions${T_ME}" >&6; }
+
+
 { echo "$as_me:$LINENO: checking for acos" >&5
 echo $ECHO_N "checking for acos... $ECHO_C" >&6; }
 if test "${ac_cv_func_acos+set}" = set; then
 fi
 
 
-eval `./libtool --config | grep pic_flag`
-CFLAGS="$CFLAGS $pic_flag"
 
 
-case $TERM in
-       #   for the most important terminal types we directly know the sequences
-       xterm|xterm*|vt220|vt220*)
-               T_MD=`awk 'BEGIN { printf("%c%c%c%c", 27, 91, 49, 109); }' </dev/null 2>/dev/null`
-               T_ME=`awk 'BEGIN { printf("%c%c%c", 27, 91, 109); }' </dev/null 2>/dev/null`
-       ;;
-       vt100|vt100*|cygwin)
-               T_MD=`awk 'BEGIN { printf("%c%c%c%c%c%c", 27, 91, 49, 109, 0, 0); }' </dev/null 2>/dev/null`
-               T_ME=`awk 'BEGIN { printf("%c%c%c%c%c", 27, 91, 109, 0, 0); }' </dev/null 2>/dev/null`
-       ;;
-       *)
-               T_MD=''
-               T_ME=''
-       ;;
-esac
-  { echo "$as_me:$LINENO: result: " >&5
-echo "${ECHO_T}" >&6; }
-  { echo "$as_me:$LINENO: result: ${T_MD}Test Library Functions${T_ME}" >&5
-echo "${ECHO_T}${T_MD}Test Library Functions${T_ME}" >&6; }
+eval `./libtool --config | grep pic_flag`
+CFLAGS="$CFLAGS $pic_flag"
 
 
 
@@ -21007,8 +21129,7 @@ esac
 
 
 
-
-for ac_func in tzset mbstowcs opendir readdir chdir chroot getuid setlocale strerror strerror_r snprintf vsnprintf fpclass class fp_class isnan memmove strchr mktime getrusage gettimeofday posix_fadvise madvise
+for ac_func in tzset fsync mbstowcs opendir readdir chdir chroot getuid setlocale strerror strerror_r snprintf vsnprintf fpclass class fp_class isnan memmove strchr mktime getrusage gettimeofday
 do
 as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
 { echo "$as_me:$LINENO: checking for $ac_func" >&5
 done
 
 
-{ echo "$as_me:$LINENO: checking whether fdatasync is declared" >&5
-echo $ECHO_N "checking whether fdatasync is declared... $ECHO_C" >&6; }
-if test "${ac_cv_have_decl_fdatasync+set}" = set; then
+
+case $TERM in
+       #   for the most important terminal types we directly know the sequences
+       xterm|xterm*|vt220|vt220*)
+               T_MD=`awk 'BEGIN { printf("%c%c%c%c", 27, 91, 49, 109); }' </dev/null 2>/dev/null`
+               T_ME=`awk 'BEGIN { printf("%c%c%c", 27, 91, 109); }' </dev/null 2>/dev/null`
+       ;;
+       vt100|vt100*|cygwin)
+               T_MD=`awk 'BEGIN { printf("%c%c%c%c%c%c", 27, 91, 49, 109, 0, 0); }' </dev/null 2>/dev/null`
+               T_ME=`awk 'BEGIN { printf("%c%c%c%c%c", 27, 91, 109, 0, 0); }' </dev/null 2>/dev/null`
+       ;;
+       *)
+               T_MD=''
+               T_ME=''
+       ;;
+esac
+  { echo "$as_me:$LINENO: result: " >&5
+echo "${ECHO_T}" >&6; }
+  { echo "$as_me:$LINENO: result: ${T_MD}Map/Fadvis/Madvise checking${T_ME}" >&5
+echo "${ECHO_T}${T_MD}Map/Fadvis/Madvise checking${T_ME}" >&6; }
+
+
+
+
+
+for ac_func in fdatasync
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+{ echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; }
+if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
   cat >conftest.$ac_ext <<_ACEOF
@@ -21113,27 +21262,53 @@ _ACEOF
 cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
-#include <unistd.h>
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined __stub_$ac_func || defined __stub___$ac_func
+choke me
+#endif
 
 int
 main ()
 {
-#ifndef fdatasync
-  (void) fdatasync;
-#endif
-
+return $ac_func ();
   ;
   return 0;
 }
 _ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
 case "(($ac_try" in
   *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
   *) ac_try_echo=$ac_try;;
 esac
 eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_compile") 2>conftest.er1
+  (eval "$ac_link") 2>conftest.er1
   ac_status=$?
   grep -v '^ *+' conftest.er1 >conftest.err
   rm -f conftest.er1
@@ -21142,42 +21317,101 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
   (exit $ac_status); } && {
         test -z "$ac_c_werror_flag" ||
         test ! -s conftest.err
-       } && test -s conftest.$ac_objext; then
-  ac_cv_have_decl_fdatasync=yes
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
+  eval "$as_ac_var=yes"
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-       ac_cv_have_decl_fdatasync=no
+       eval "$as_ac_var=no"
 fi
 
-rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
 fi
-{ echo "$as_me:$LINENO: result: $ac_cv_have_decl_fdatasync" >&5
-echo "${ECHO_T}$ac_cv_have_decl_fdatasync" >&6; }
-if test $ac_cv_have_decl_fdatasync = yes; then
-
-cat >>confdefs.h <<_ACEOF
-#define HAVE_DECL_FDATASYNC 1
+ac_res=`eval echo '${'$as_ac_var'}'`
+              { echo "$as_me:$LINENO: result: $ac_res" >&5
+echo "${ECHO_T}$ac_res" >&6; }
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
 _ACEOF
 
-
 else
-  cat >>confdefs.h <<_ACEOF
-#define HAVE_DECL_FDATASYNC 0
+  { echo "$as_me:$LINENO: checking for fdatasync in -lrt" >&5
+echo $ECHO_N "checking for fdatasync in -lrt... $ECHO_C" >&6; }
+if test "${ac_cv_lib_rt_fdatasync+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lrt  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char fdatasync ();
+int
+main ()
+{
+return fdatasync ();
+  ;
+  return 0;
+}
 _ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
+  ac_cv_lib_rt_fdatasync=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
 
+       ac_cv_lib_rt_fdatasync=no
+fi
 
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
 fi
+{ echo "$as_me:$LINENO: result: $ac_cv_lib_rt_fdatasync" >&5
+echo "${ECHO_T}$ac_cv_lib_rt_fdatasync" >&6; }
+if test $ac_cv_lib_rt_fdatasync = yes; then
+  LIBS="${LIBS} -lrt"; cat >>confdefs.h <<\_ACEOF
+#define HAVE_FDATASYNC 1
+_ACEOF
 
+fi
 
+fi
+done
 
-if test "x$enable_mmap" = "xyes"; then
-  case "$host" in
-  *cygwin*)
-    # the normal mmap test does not work in cygwin
 
-for ac_func in mmap
+for ac_func in fsync
 do
 as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
 { echo "$as_me:$LINENO: checking for $ac_func" >&5
@@ -21270,40 +21504,140 @@ _ACEOF
 fi
 done
 
-    if test "x$ac_cv_func_mmap" = "xyes"; then
-      ac_cv_func_mmap_fixed_mapped=yes
-    fi
-  ;;
-  *)
 
-for ac_header in sys/mman.h
+
+if test "x$enable_mmap" = "xyes"; then
+  case "$host" in
+  *cygwin*)
+    # the normal mmap test does not work in cygwin
+
+for ac_func in mmap
 do
-as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
-  { echo "$as_me:$LINENO: checking for $ac_header" >&5
-echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
-if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+{ echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; }
+if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
-fi
-ac_res=`eval echo '${'$as_ac_Header'}'`
-              { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
 else
-  # Is the header compilable?
-{ echo "$as_me:$LINENO: checking $ac_header usability" >&5
-echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; }
-cat >conftest.$ac_ext <<_ACEOF
+  cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
 cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
-$ac_includes_default
-#include <$ac_header>
-_ACEOF
-rm -f conftest.$ac_objext
-if { (ac_try="$ac_compile"
-case "(($ac_try" in
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined __stub_$ac_func || defined __stub___$ac_func
+choke me
+#endif
+
+int
+main ()
+{
+return $ac_func ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       eval "$as_ac_var=no"
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+ac_res=`eval echo '${'$as_ac_var'}'`
+              { echo "$as_me:$LINENO: result: $ac_res" >&5
+echo "${ECHO_T}$ac_res" >&6; }
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+fi
+done
+
+    if test "x$ac_cv_func_mmap" = "xyes"; then
+      ac_cv_func_mmap_fixed_mapped=yes
+    fi
+  ;;
+  *)
+
+for ac_header in sys/mman.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+  { echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+ac_res=`eval echo '${'$as_ac_Header'}'`
+              { echo "$as_me:$LINENO: result: $ac_res" >&5
+echo "${ECHO_T}$ac_res" >&6; }
+else
+  # Is the header compilable?
+{ echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
   *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
   *) ac_try_echo=$ac_try;;
 esac
@@ -21944,8 +22278,8 @@ cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
 #ifdef HAVE_SYS_MMAN_H
-                                     # include <sys/mman.h>
-                                     #endif
+                                    # include <sys/mman.h>
+                                    #endif
 
 int
 main ()
 done
 
 
-if test "x$enable_mmap" = xyes; then
-  case "$host" in
-    *cygwin*)
-       # the normal mmap test does not work in cygwin
-
-for ac_func in mmap
-do
-as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
-{ echo "$as_me:$LINENO: checking for $ac_func" >&5
-echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; }
-if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
-   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
-#define $ac_func innocuous_$ac_func
-
-/* System header to define __stub macros and hopefully few prototypes,
-    which can conflict with char $ac_func (); below.
-    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
-    <limits.h> exists even on freestanding compilers.  */
 
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
+case $TERM in
+       #   for the most important terminal types we directly know the sequences
+       xterm|xterm*|vt220|vt220*)
+               T_MD=`awk 'BEGIN { printf("%c%c%c%c", 27, 91, 49, 109); }' </dev/null 2>/dev/null`
+               T_ME=`awk 'BEGIN { printf("%c%c%c", 27, 91, 109); }' </dev/null 2>/dev/null`
+       ;;
+       vt100|vt100*|cygwin)
+               T_MD=`awk 'BEGIN { printf("%c%c%c%c%c%c", 27, 91, 49, 109, 0, 0); }' </dev/null 2>/dev/null`
+               T_ME=`awk 'BEGIN { printf("%c%c%c%c%c", 27, 91, 109, 0, 0); }' </dev/null 2>/dev/null`
+       ;;
+       *)
+               T_MD=''
+               T_ME=''
+       ;;
+esac
+  { echo "$as_me:$LINENO: result: " >&5
+echo "${ECHO_T}" >&6; }
+  { echo "$as_me:$LINENO: result: ${T_MD}Libintl Processing${T_ME}" >&5
+echo "${ECHO_T}${T_MD}Libintl Processing${T_ME}" >&6; }
 
-#undef $ac_func
 
-/* Override any GCC internal prototype to avoid an error.
-   Use char because int might match the return type of a GCC
-   builtin and then its argument prototype would still apply.  */
-#ifdef __cplusplus
-extern "C"
-#endif
-char $ac_func ();
-/* The GNU C library defines this for functions which it implements
-    to always fail with ENOSYS.  Some functions are actually named
-    something starting with __ and the normal name is an alias.  */
-#if defined __stub_$ac_func || defined __stub___$ac_func
-choke me
-#endif
 
-int
-main ()
-{
-return $ac_func ();
-  ;
-  return 0;
-}
-_ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_link") 2>conftest.er1
-  ac_status=$?
-  grep -v '^ *+' conftest.er1 >conftest.err
-  rm -f conftest.er1
-  cat conftest.err >&5
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && {
-        test -z "$ac_c_werror_flag" ||
-        test ! -s conftest.err
-       } && test -s conftest$ac_exeext &&
-       $as_test_x conftest$ac_exeext; then
-  eval "$as_ac_var=yes"
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
+GETTEXT_PACKAGE=rrdtool
 
-       eval "$as_ac_var=no"
-fi
 
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
-      conftest$ac_exeext conftest.$ac_ext
-fi
-ac_res=`eval echo '${'$as_ac_var'}'`
-              { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-if test `eval echo '${'$as_ac_var'}'` = yes; then
-  cat >>confdefs.h <<_ACEOF
-#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+cat >>confdefs.h <<_ACEOF
+#define GETTEXT_PACKAGE "$GETTEXT_PACKAGE"
 _ACEOF
 
-fi
-done
 
-       if  "x${ac_cv_func_mmap}" = xyes ; then
-         ac_cv_func_mmap_fixed_mapped=yes
-       fi
-    ;;
-    *)
 
 
-for ac_header in stdlib.h unistd.h
+for ac_header in locale.h
 do
 as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
 if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
 
 done
 
-
-for ac_func in getpagesize
-do
-as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
-{ echo "$as_me:$LINENO: checking for $ac_func" >&5
-echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; }
-if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then
+    if test $ac_cv_header_locale_h = yes; then
+    { echo "$as_me:$LINENO: checking for LC_MESSAGES" >&5
+echo $ECHO_N "checking for LC_MESSAGES... $ECHO_C" >&6; }
+if test "${am_cv_val_LC_MESSAGES+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
   cat >conftest.$ac_ext <<_ACEOF
@@ -22633,41 +22892,11 @@ _ACEOF
 cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
-/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
-   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
-#define $ac_func innocuous_$ac_func
-
-/* System header to define __stub macros and hopefully few prototypes,
-    which can conflict with char $ac_func (); below.
-    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
-    <limits.h> exists even on freestanding compilers.  */
-
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
-
-#undef $ac_func
-
-/* Override any GCC internal prototype to avoid an error.
-   Use char because int might match the return type of a GCC
-   builtin and then its argument prototype would still apply.  */
-#ifdef __cplusplus
-extern "C"
-#endif
-char $ac_func ();
-/* The GNU C library defines this for functions which it implements
-    to always fail with ENOSYS.  Some functions are actually named
-    something starting with __ and the normal name is an alias.  */
-#if defined __stub_$ac_func || defined __stub___$ac_func
-choke me
-#endif
-
+#include <locale.h>
 int
 main ()
 {
-return $ac_func ();
+return LC_MESSAGES
   ;
   return 0;
 }
@@ -22690,291 +22919,186 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
         test ! -s conftest.err
        } && test -s conftest$ac_exeext &&
        $as_test_x conftest$ac_exeext; then
-  eval "$as_ac_var=yes"
+  am_cv_val_LC_MESSAGES=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-       eval "$as_ac_var=no"
+       am_cv_val_LC_MESSAGES=no
 fi
 
 rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
       conftest$ac_exeext conftest.$ac_ext
 fi
-ac_res=`eval echo '${'$as_ac_var'}'`
-              { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-if test `eval echo '${'$as_ac_var'}'` = yes; then
-  cat >>confdefs.h <<_ACEOF
-#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+{ echo "$as_me:$LINENO: result: $am_cv_val_LC_MESSAGES" >&5
+echo "${ECHO_T}$am_cv_val_LC_MESSAGES" >&6; }
+    if test $am_cv_val_LC_MESSAGES = yes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_LC_MESSAGES 1
 _ACEOF
 
-fi
-done
+    fi
+  fi
+         USE_NLS=yes
 
-{ echo "$as_me:$LINENO: checking for working mmap" >&5
-echo $ECHO_N "checking for working mmap... $ECHO_C" >&6; }
-if test "${ac_cv_func_mmap_fixed_mapped+set}" = set; then
+
+    gt_cv_have_gettext=no
+
+    CATOBJEXT=NONE
+    XGETTEXT=:
+    INTLLIBS=
+
+    if test "${ac_cv_header_libintl_h+set}" = set; then
+  { echo "$as_me:$LINENO: checking for libintl.h" >&5
+echo $ECHO_N "checking for libintl.h... $ECHO_C" >&6; }
+if test "${ac_cv_header_libintl_h+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_header_libintl_h" >&5
+echo "${ECHO_T}$ac_cv_header_libintl_h" >&6; }
 else
-  if test "$cross_compiling" = yes; then
-  ac_cv_func_mmap_fixed_mapped=no
-else
-  cat >conftest.$ac_ext <<_ACEOF
+  # Is the header compilable?
+{ echo "$as_me:$LINENO: checking libintl.h usability" >&5
+echo $ECHO_N "checking libintl.h usability... $ECHO_C" >&6; }
+cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
 cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
 $ac_includes_default
-/* malloc might have been renamed as rpl_malloc. */
-#undef malloc
-
-/* Thanks to Mike Haertel and Jim Avera for this test.
-   Here is a matrix of mmap possibilities:
-       mmap private not fixed
-       mmap private fixed at somewhere currently unmapped
-       mmap private fixed at somewhere already mapped
-       mmap shared not fixed
-       mmap shared fixed at somewhere currently unmapped
-       mmap shared fixed at somewhere already mapped
-   For private mappings, we should verify that changes cannot be read()
-   back from the file, nor mmap's back from the file at a different
-   address.  (There have been systems where private was not correctly
-   implemented like the infamous i386 svr4.0, and systems where the
-   VM page cache was not coherent with the file system buffer cache
-   like early versions of FreeBSD and possibly contemporary NetBSD.)
-   For shared mappings, we should conversely verify that changes get
-   propagated back to all the places they're supposed to be.
-
-   Grep wants private fixed already mapped.
-   The main things grep needs to know about mmap are:
-   * does it exist and is it safe to write into the mmap'd area
-   * how to use it (BSD variants)  */
-
-#include <fcntl.h>
-#include <sys/mman.h>
-
-#if !defined STDC_HEADERS && !defined HAVE_STDLIB_H
-char *malloc ();
-#endif
-
-/* This mess was copied from the GNU getpagesize.h.  */
-#ifndef HAVE_GETPAGESIZE
-/* Assume that all systems that can run configure have sys/param.h.  */
-# ifndef HAVE_SYS_PARAM_H
-#  define HAVE_SYS_PARAM_H 1
-# endif
-
-# ifdef _SC_PAGESIZE
-#  define getpagesize() sysconf(_SC_PAGESIZE)
-# else /* no _SC_PAGESIZE */
-#  ifdef HAVE_SYS_PARAM_H
-#   include <sys/param.h>
-#   ifdef EXEC_PAGESIZE
-#    define getpagesize() EXEC_PAGESIZE
-#   else /* no EXEC_PAGESIZE */
-#    ifdef NBPG
-#     define getpagesize() NBPG * CLSIZE
-#     ifndef CLSIZE
-#      define CLSIZE 1
-#     endif /* no CLSIZE */
-#    else /* no NBPG */
-#     ifdef NBPC
-#      define getpagesize() NBPC
-#     else /* no NBPC */
-#      ifdef PAGESIZE
-#       define getpagesize() PAGESIZE
-#      endif /* PAGESIZE */
-#     endif /* no NBPC */
-#    endif /* no NBPG */
-#   endif /* no EXEC_PAGESIZE */
-#  else /* no HAVE_SYS_PARAM_H */
-#   define getpagesize() 8192  /* punt totally */
-#  endif /* no HAVE_SYS_PARAM_H */
-# endif /* no _SC_PAGESIZE */
-
-#endif /* no HAVE_GETPAGESIZE */
-
-int
-main ()
-{
-  char *data, *data2, *data3;
-  int i, pagesize;
-  int fd;
-
-  pagesize = getpagesize ();
-
-  /* First, make a file with some known garbage in it. */
-  data = (char *) malloc (pagesize);
-  if (!data)
-    return 1;
-  for (i = 0; i < pagesize; ++i)
-    *(data + i) = rand ();
-  umask (0);
-  fd = creat ("conftest.mmap", 0600);
-  if (fd < 0)
-    return 1;
-  if (write (fd, data, pagesize) != pagesize)
-    return 1;
-  close (fd);
-
-  /* Next, try to mmap the file at a fixed address which already has
-     something else allocated at it.  If we can, also make sure that
-     we see the same garbage.  */
-  fd = open ("conftest.mmap", O_RDWR);
-  if (fd < 0)
-    return 1;
-  data2 = (char *) malloc (2 * pagesize);
-  if (!data2)
-    return 1;
-  data2 += (pagesize - ((long int) data2 & (pagesize - 1))) & (pagesize - 1);
-  if (data2 != mmap (data2, pagesize, PROT_READ | PROT_WRITE,
-                    MAP_PRIVATE | MAP_FIXED, fd, 0L))
-    return 1;
-  for (i = 0; i < pagesize; ++i)
-    if (*(data + i) != *(data2 + i))
-      return 1;
-
-  /* Finally, make sure that changes to the mapped area do not
-     percolate back to the file as seen by read().  (This is a bug on
-     some variants of i386 svr4.0.)  */
-  for (i = 0; i < pagesize; ++i)
-    *(data2 + i) = *(data2 + i) + 1;
-  data3 = (char *) malloc (pagesize);
-  if (!data3)
-    return 1;
-  if (read (fd, data3, pagesize) != pagesize)
-    return 1;
-  for (i = 0; i < pagesize; ++i)
-    if (*(data + i) != *(data3 + i))
-      return 1;
-  close (fd);
-  return 0;
-}
+#include <libintl.h>
 _ACEOF
-rm -f conftest$ac_exeext
-if { (ac_try="$ac_link"
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
 case "(($ac_try" in
   *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
   *) ac_try_echo=$ac_try;;
 esac
 eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_link") 2>&5
+  (eval "$ac_compile") 2>conftest.er1
   ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
-  { (case "(($ac_try" in
+  (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       ac_header_compiler=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ echo "$as_me:$LINENO: checking libintl.h presence" >&5
+echo $ECHO_N "checking libintl.h presence... $ECHO_C" >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <libintl.h>
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
   *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
   *) ac_try_echo=$ac_try;;
 esac
 eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
+  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
   ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  ac_cv_func_mmap_fixed_mapped=yes
+  (exit $ac_status); } >/dev/null && {
+        test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       }; then
+  ac_header_preproc=yes
 else
-  echo "$as_me: program exited with status $ac_status" >&5
-echo "$as_me: failed program was:" >&5
+  echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-( exit $ac_status )
-ac_cv_func_mmap_fixed_mapped=no
-fi
-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+  ac_header_preproc=no
 fi
 
+rm -f conftest.err conftest.$ac_ext
+{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6; }
 
-fi
-{ echo "$as_me:$LINENO: result: $ac_cv_func_mmap_fixed_mapped" >&5
-echo "${ECHO_T}$ac_cv_func_mmap_fixed_mapped" >&6; }
-if test $ac_cv_func_mmap_fixed_mapped = yes; then
-
-cat >>confdefs.h <<\_ACEOF
-#define HAVE_MMAP 1
-_ACEOF
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: libintl.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: libintl.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: libintl.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: libintl.h: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: libintl.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: libintl.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: libintl.h:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: libintl.h:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: libintl.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: libintl.h: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: libintl.h:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: libintl.h:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: libintl.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: libintl.h: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: libintl.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: libintl.h: in the future, the compiler will take precedence" >&2;}
 
+    ;;
+esac
+{ echo "$as_me:$LINENO: checking for libintl.h" >&5
+echo $ECHO_N "checking for libintl.h... $ECHO_C" >&6; }
+if test "${ac_cv_header_libintl_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_libintl_h=$ac_header_preproc
 fi
-rm -f conftest.mmap
+{ echo "$as_me:$LINENO: result: $ac_cv_header_libintl_h" >&5
+echo "${ECHO_T}$ac_cv_header_libintl_h" >&6; }
 
-    ;;
-  esac
 fi
+if test $ac_cv_header_libintl_h = yes; then
+  gt_cv_func_dgettext_libintl="no"
+      libintl_extra_libs=""
 
+      #
+      # First check in libc
+      #
+      { echo "$as_me:$LINENO: checking for ngettext in libc" >&5
+echo $ECHO_N "checking for ngettext in libc... $ECHO_C" >&6; }
+if test "${gt_cv_func_ngettext_libc+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
 
-
-case $TERM in
-       #   for the most important terminal types we directly know the sequences
-       xterm|xterm*|vt220|vt220*)
-               T_MD=`awk 'BEGIN { printf("%c%c%c%c", 27, 91, 49, 109); }' </dev/null 2>/dev/null`
-               T_ME=`awk 'BEGIN { printf("%c%c%c", 27, 91, 109); }' </dev/null 2>/dev/null`
-       ;;
-       vt100|vt100*|cygwin)
-               T_MD=`awk 'BEGIN { printf("%c%c%c%c%c%c", 27, 91, 49, 109, 0, 0); }' </dev/null 2>/dev/null`
-               T_ME=`awk 'BEGIN { printf("%c%c%c%c%c", 27, 91, 109, 0, 0); }' </dev/null 2>/dev/null`
-       ;;
-       *)
-               T_MD=''
-               T_ME=''
-       ;;
-esac
-  { echo "$as_me:$LINENO: result: " >&5
-echo "${ECHO_T}" >&6; }
-  { echo "$as_me:$LINENO: result: ${T_MD}IEEE Math Checks${T_ME}" >&5
-echo "${ECHO_T}${T_MD}IEEE Math Checks${T_ME}" >&6; }
-
-
-
-for ac_func in fpclassify
-do
-as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
-{ echo "$as_me:$LINENO: checking for $ac_func" >&5
-echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; }
-if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
-   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
-#define $ac_func innocuous_$ac_func
-
-/* System header to define __stub macros and hopefully few prototypes,
-    which can conflict with char $ac_func (); below.
-    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
-    <limits.h> exists even on freestanding compilers.  */
-
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
-
-#undef $ac_func
-
-/* Override any GCC internal prototype to avoid an error.
-   Use char because int might match the return type of a GCC
-   builtin and then its argument prototype would still apply.  */
-#ifdef __cplusplus
-extern "C"
-#endif
-char $ac_func ();
-/* The GNU C library defines this for functions which it implements
-    to always fail with ENOSYS.  Some functions are actually named
-    something starting with __ and the normal name is an alias.  */
-#if defined __stub_$ac_func || defined __stub___$ac_func
-choke me
-#endif
+#include <libintl.h>
 
 int
 main ()
 {
-return $ac_func ();
+return !ngettext ("","", 1)
   ;
   return 0;
 }
@@ -22997,40 +23121,40 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
         test ! -s conftest.err
        } && test -s conftest$ac_exeext &&
        $as_test_x conftest$ac_exeext; then
-  eval "$as_ac_var=yes"
+  gt_cv_func_ngettext_libc=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-       eval "$as_ac_var=no"
+       gt_cv_func_ngettext_libc=no
 fi
 
 rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
       conftest$ac_exeext conftest.$ac_ext
+
 fi
-ac_res=`eval echo '${'$as_ac_var'}'`
-              { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-if test `eval echo '${'$as_ac_var'}'` = yes; then
-  cat >>confdefs.h <<_ACEOF
-#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
-_ACEOF
+{ echo "$as_me:$LINENO: result: $gt_cv_func_ngettext_libc" >&5
+echo "${ECHO_T}$gt_cv_func_ngettext_libc" >&6; }
 
+      if test "$gt_cv_func_ngettext_libc" = "yes" ; then
+             { echo "$as_me:$LINENO: checking for dgettext in libc" >&5
+echo $ECHO_N "checking for dgettext in libc... $ECHO_C" >&6; }
+if test "${gt_cv_func_dgettext_libc+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
 else
-  { echo "$as_me:$LINENO: checking for fpclassify with <math.h>" >&5
-echo $ECHO_N "checking for fpclassify with <math.h>... $ECHO_C" >&6; }
-    cat >conftest.$ac_ext <<_ACEOF
+  cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
 cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
-#include <math.h>
-volatile int x;volatile float f;
+
+#include <libintl.h>
+
 int
 main ()
 {
-x = fpclassify(f)
+return !dgettext ("","")
   ;
   return 0;
 }
@@ -23053,27 +23177,25 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
         test ! -s conftest.err
        } && test -s conftest$ac_exeext &&
        $as_test_x conftest$ac_exeext; then
-  { echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6; }
-      cat >>confdefs.h <<\_ACEOF
-#define HAVE_FPCLASSIFY 1
-_ACEOF
-
+  gt_cv_func_dgettext_libc=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-       { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
+       gt_cv_func_dgettext_libc=no
 fi
 
 rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
       conftest$ac_exeext conftest.$ac_ext
+
 fi
-done
+{ echo "$as_me:$LINENO: result: $gt_cv_func_dgettext_libc" >&5
+echo "${ECHO_T}$gt_cv_func_dgettext_libc" >&6; }
+      fi
 
+      if test "$gt_cv_func_ngettext_libc" = "yes" ; then
 
-for ac_func in finite
+for ac_func in bind_textdomain_codeset
 do
 as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
 { echo "$as_me:$LINENO: checking for $ac_func" >&5
@@ -23163,38 +23285,31 @@ if test `eval echo '${'$as_ac_var'}'` = yes; then
 #define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
 _ACEOF
 
-else
+fi
+done
 
-for ac_func in isfinite
-do
-as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
-{ echo "$as_me:$LINENO: checking for $ac_func" >&5
-echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; }
-if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then
+      fi
+
+      #
+      # If we don't have everything we want, check in libintl
+      #
+      if test "$gt_cv_func_dgettext_libc" != "yes" \
+        || test "$gt_cv_func_ngettext_libc" != "yes" \
+         || test "$ac_cv_func_bind_textdomain_codeset" != "yes" ; then
+
+        { echo "$as_me:$LINENO: checking for bindtextdomain in -lintl" >&5
+echo $ECHO_N "checking for bindtextdomain in -lintl... $ECHO_C" >&6; }
+if test "${ac_cv_lib_intl_bindtextdomain+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
-  cat >conftest.$ac_ext <<_ACEOF
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lintl  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
 cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
-/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
-   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
-#define $ac_func innocuous_$ac_func
-
-/* System header to define __stub macros and hopefully few prototypes,
-    which can conflict with char $ac_func (); below.
-    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
-    <limits.h> exists even on freestanding compilers.  */
-
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
-
-#undef $ac_func
 
 /* Override any GCC internal prototype to avoid an error.
    Use char because int might match the return type of a GCC
@@ -23202,18 +23317,11 @@ cat >>conftest.$ac_ext <<_ACEOF
 #ifdef __cplusplus
 extern "C"
 #endif
-char $ac_func ();
-/* The GNU C library defines this for functions which it implements
-    to always fail with ENOSYS.  Some functions are actually named
-    something starting with __ and the normal name is an alias.  */
-#if defined __stub_$ac_func || defined __stub___$ac_func
-choke me
-#endif
-
+char bindtextdomain ();
 int
 main ()
 {
-return $ac_func ();
+return bindtextdomain ();
   ;
   return 0;
 }
@@ -23236,40 +23344,46 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
         test ! -s conftest.err
        } && test -s conftest$ac_exeext &&
        $as_test_x conftest$ac_exeext; then
-  eval "$as_ac_var=yes"
+  ac_cv_lib_intl_bindtextdomain=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-       eval "$as_ac_var=no"
+       ac_cv_lib_intl_bindtextdomain=no
 fi
 
 rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
       conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
 fi
-ac_res=`eval echo '${'$as_ac_var'}'`
-              { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-if test `eval echo '${'$as_ac_var'}'` = yes; then
-  cat >>confdefs.h <<_ACEOF
-#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
-_ACEOF
-
+{ echo "$as_me:$LINENO: result: $ac_cv_lib_intl_bindtextdomain" >&5
+echo "${ECHO_T}$ac_cv_lib_intl_bindtextdomain" >&6; }
+if test $ac_cv_lib_intl_bindtextdomain = yes; then
+  { echo "$as_me:$LINENO: checking for ngettext in -lintl" >&5
+echo $ECHO_N "checking for ngettext in -lintl... $ECHO_C" >&6; }
+if test "${ac_cv_lib_intl_ngettext+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
 else
-  { echo "$as_me:$LINENO: checking for isfinite with <math.h>" >&5
-echo $ECHO_N "checking for isfinite with <math.h>... $ECHO_C" >&6; }
-    cat >conftest.$ac_ext <<_ACEOF
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lintl  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
 cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
-#include <math.h>
-volatile int x;volatile float f;
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char ngettext ();
 int
 main ()
 {
-x = isfinite(f)
+return ngettext ();
   ;
   return 0;
 }
@@ -23292,59 +23406,34 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
         test ! -s conftest.err
        } && test -s conftest$ac_exeext &&
        $as_test_x conftest$ac_exeext; then
-  { echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6; }
-      cat >>confdefs.h <<\_ACEOF
-#define HAVE_ISFINITE 1
-_ACEOF
-
+  ac_cv_lib_intl_ngettext=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-       { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
+       ac_cv_lib_intl_ngettext=no
 fi
 
 rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
       conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
 fi
-done
-
-fi
-done
-
-
-for ac_func in isinf
-do
-as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
-{ echo "$as_me:$LINENO: checking for $ac_func" >&5
-echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; }
-if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then
+{ echo "$as_me:$LINENO: result: $ac_cv_lib_intl_ngettext" >&5
+echo "${ECHO_T}$ac_cv_lib_intl_ngettext" >&6; }
+if test $ac_cv_lib_intl_ngettext = yes; then
+  { echo "$as_me:$LINENO: checking for dgettext in -lintl" >&5
+echo $ECHO_N "checking for dgettext in -lintl... $ECHO_C" >&6; }
+if test "${ac_cv_lib_intl_dgettext+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
-  cat >conftest.$ac_ext <<_ACEOF
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lintl  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
 cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
-/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
-   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
-#define $ac_func innocuous_$ac_func
-
-/* System header to define __stub macros and hopefully few prototypes,
-    which can conflict with char $ac_func (); below.
-    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
-    <limits.h> exists even on freestanding compilers.  */
-
-#ifdef __STDC__
-# include <limits.h>
-#else
-# include <assert.h>
-#endif
-
-#undef $ac_func
 
 /* Override any GCC internal prototype to avoid an error.
    Use char because int might match the return type of a GCC
@@ -23352,18 +23441,11 @@ cat >>conftest.$ac_ext <<_ACEOF
 #ifdef __cplusplus
 extern "C"
 #endif
-char $ac_func ();
-/* The GNU C library defines this for functions which it implements
-    to always fail with ENOSYS.  Some functions are actually named
-    something starting with __ and the normal name is an alias.  */
-#if defined __stub_$ac_func || defined __stub___$ac_func
-choke me
-#endif
-
+char dgettext ();
 int
 main ()
 {
-return $ac_func ();
+return dgettext ();
   ;
   return 0;
 }
@@ -23386,40 +23468,59 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
         test ! -s conftest.err
        } && test -s conftest$ac_exeext &&
        $as_test_x conftest$ac_exeext; then
-  eval "$as_ac_var=yes"
+  ac_cv_lib_intl_dgettext=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-       eval "$as_ac_var=no"
+       ac_cv_lib_intl_dgettext=no
 fi
 
 rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
       conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
 fi
-ac_res=`eval echo '${'$as_ac_var'}'`
-              { echo "$as_me:$LINENO: result: $ac_res" >&5
-echo "${ECHO_T}$ac_res" >&6; }
-if test `eval echo '${'$as_ac_var'}'` = yes; then
-  cat >>confdefs.h <<_ACEOF
-#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
-_ACEOF
+{ echo "$as_me:$LINENO: result: $ac_cv_lib_intl_dgettext" >&5
+echo "${ECHO_T}$ac_cv_lib_intl_dgettext" >&6; }
+if test $ac_cv_lib_intl_dgettext = yes; then
+  gt_cv_func_dgettext_libintl=yes
+fi
+
+fi
+
+fi
+
 
+       if test "$gt_cv_func_dgettext_libintl" != "yes" ; then
+         { echo "$as_me:$LINENO: checking if -liconv is needed to use gettext" >&5
+echo $ECHO_N "checking if -liconv is needed to use gettext... $ECHO_C" >&6; }
+         { echo "$as_me:$LINENO: result: " >&5
+echo "${ECHO_T}" >&6; }
+         { echo "$as_me:$LINENO: checking for ngettext in -lintl" >&5
+echo $ECHO_N "checking for ngettext in -lintl... $ECHO_C" >&6; }
+if test "${ac_cv_lib_intl_ngettext+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
 else
-  { echo "$as_me:$LINENO: checking for isinf with <math.h>" >&5
-echo $ECHO_N "checking for isinf with <math.h>... $ECHO_C" >&6; }
-    cat >conftest.$ac_ext <<_ACEOF
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lintl -liconv $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
 cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
-#include <math.h>
-volatile int x;volatile float f;
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char ngettext ();
 int
 main ()
 {
-x = isinf(f)
+return ngettext ();
   ;
   return 0;
 }
@@ -23442,172 +23543,112 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
         test ! -s conftest.err
        } && test -s conftest$ac_exeext &&
        $as_test_x conftest$ac_exeext; then
-  { echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6; }
-      cat >>confdefs.h <<\_ACEOF
-#define HAVE_ISINF 1
-_ACEOF
-
+  ac_cv_lib_intl_ngettext=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-       { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
+       ac_cv_lib_intl_ngettext=no
 fi
 
 rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
       conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
 fi
-done
-
-
-
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-_cflags=${CFLAGS}
-
-{ echo "$as_me:$LINENO: checking if IEEE math works out of the box" >&5
-echo $ECHO_N "checking if IEEE math works out of the box... $ECHO_C" >&6; }
-if test "${rd_cv_ieee_works+set}" = set; then
+{ echo "$as_me:$LINENO: result: $ac_cv_lib_intl_ngettext" >&5
+echo "${ECHO_T}$ac_cv_lib_intl_ngettext" >&6; }
+if test $ac_cv_lib_intl_ngettext = yes; then
+  { echo "$as_me:$LINENO: checking for dcgettext in -lintl" >&5
+echo $ECHO_N "checking for dcgettext in -lintl... $ECHO_C" >&6; }
+if test "${ac_cv_lib_intl_dcgettext+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
-  if test "$cross_compiling" = yes; then
-  :
-else
-  cat >conftest.$ac_ext <<_ACEOF
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lintl -liconv $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
 cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
 
-
-#if HAVE_MATH_H
-#  include <math.h>
-#endif
-
-#if HAVE_FLOAT_H
-#  include <float.h>
-#endif
-
-#if HAVE_IEEEFP_H
-#  include <ieeefp.h>
-#endif
-
-#if HAVE_FP_CLASS_H
-#  include <fp_class.h>
-#endif
-
-/* Solaris */
-#if (! defined(HAVE_ISINF) && defined(HAVE_FPCLASS))
-#  define HAVE_ISINF 1
-#  define isinf(a) (fpclass(a) == FP_NINF || fpclass(a) == FP_PINF)
-#endif
-
-/* solaris 10 it defines isnan such that only forte can compile it ... bad bad  */
-#if (defined(HAVE_ISNAN) && defined(isnan) && defined(HAVE_FPCLASS))
-#  undef isnan
-#  define isnan(a) (fpclass(a) == FP_SNAN || fpclass(a) == FP_QNAN)
-#endif
-
-/* Digital UNIX */
-#if (! defined(HAVE_ISINF) && defined(HAVE_FP_CLASS) && defined(HAVE_FP_CLASS_H))
-#  define HAVE_ISINF 1
-#  define isinf(a) (fp_class(a) == FP_NEG_INF || fp_class(a) == FP_POS_INF)
-#endif
-
-/* AIX */
-#if (! defined(HAVE_ISINF) && defined(HAVE_CLASS))
-#  define HAVE_ISINF 1
-#  define isinf(a) (class(a) == FP_MINUS_INF || class(a) == FP_PLUS_INF)
-#endif
-
-#if (! defined(HAVE_ISINF) && defined(HAVE_FPCLASSIFY) && defined(FP_PLUS_INF) && defined(FP_MINUS_INF))
-#  define HAVE_ISINF 1
-#  define isinf(a) (fpclassify(a) == FP_MINUS_INF || fpclassify(a) == FP_PLUS_INF)
-#endif
-
-#if (! defined(HAVE_ISINF) && defined(HAVE_FPCLASSIFY) && defined(FP_INFINITE))
-#  define HAVE_ISINF 1
-#  define isinf(a) (fpclassify(a) == FP_INFINITE)
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
 #endif
-
-#include <stdio.h>
-int main(void){
-    double rrdnan,rrdinf,rrdc,rrdzero;
-    ;
-    /* some math to see if we get a floating point exception */
-    rrdzero=sin(0.0); /* don't let the compiler optimize us away */
-    rrdnan=0.0/rrdzero; /* especially here */
-    rrdinf=1.0/rrdzero; /* and here. I want to know if it can do the magic */
-                 /* at run time without sig fpe */
-    rrdc = rrdinf + rrdnan;
-    rrdc = rrdinf / rrdnan;
-    if (! isnan(rrdnan)) {printf ("not isnan(NaN) ... "); return 1;}
-    if (rrdnan == rrdnan) {printf ("nan == nan ... "); return 1;}
-    if (! isinf(rrdinf)) {printf ("not isinf(oo) ... "); return 1;}
-    if (! isinf(-rrdinf)) {printf ("not isinf(-oo) ... "); return 1;}
-    if (! rrdinf > 0) {printf ("not inf > 0 ... "); return 1;}
-    if (! -rrdinf < 0) {printf ("not -inf < 0 ... "); return 1;}
-    return 0;
- }
+char dcgettext ();
+int
+main ()
+{
+return dcgettext ();
+  ;
+  return 0;
+}
 _ACEOF
-rm -f conftest$ac_exeext
+rm -f conftest.$ac_objext conftest$ac_exeext
 if { (ac_try="$ac_link"
 case "(($ac_try" in
   *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
   *) ac_try_echo=$ac_try;;
 esac
 eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_link") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
+  (eval "$ac_link") 2>conftest.er1
   ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  rd_cv_ieee_works=yes
+  (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
+  ac_cv_lib_intl_dcgettext=yes
 else
-  echo "$as_me: program exited with status $ac_status" >&5
-echo "$as_me: failed program was:" >&5
+  echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-( exit $ac_status )
-rd_cv_ieee_works=no
-fi
-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+       ac_cv_lib_intl_dcgettext=no
 fi
 
-
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
 fi
-
-if test x${rd_cv_ieee_works} = "xyes"; then
- { echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6; }
-
+{ echo "$as_me:$LINENO: result: $ac_cv_lib_intl_dcgettext" >&5
+echo "${ECHO_T}$ac_cv_lib_intl_dcgettext" >&6; }
+if test $ac_cv_lib_intl_dcgettext = yes; then
+  gt_cv_func_dgettext_libintl=yes
+                       libintl_extra_libs=-liconv
 else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
- CFLAGS="$_cflags -ieee"
+  :
+fi
 
-{ echo "$as_me:$LINENO: checking if IEEE math works with the -ieee switch" >&5
-echo $ECHO_N "checking if IEEE math works with the -ieee switch... $ECHO_C" >&6; }
-if test "${rd_cv_ieee_switch+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
 else
-  if test "$cross_compiling" = yes; then
   :
+fi
+
+        fi
+
+        #
+        # If we found libintl, then check in it for bind_textdomain_codeset();
+        # we'll prefer libc if neither have bind_textdomain_codeset(),
+        # and both have dgettext and ngettext
+        #
+        if test "$gt_cv_func_dgettext_libintl" = "yes" ; then
+          glib_save_LIBS="$LIBS"
+          LIBS="$LIBS -lintl $libintl_extra_libs"
+          unset ac_cv_func_bind_textdomain_codeset
+
+for ac_func in bind_textdomain_codeset
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+{ echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; }
+if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
 else
   cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
@@ -23615,129 +23656,159 @@ _ACEOF
 cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define $ac_func innocuous_$ac_func
 
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
 
-#if HAVE_MATH_H
-#  include <math.h>
-#endif
-
-#if HAVE_FLOAT_H
-#  include <float.h>
-#endif
-
-#if HAVE_IEEEFP_H
-#  include <ieeefp.h>
-#endif
-
-#if HAVE_FP_CLASS_H
-#  include <fp_class.h>
-#endif
-
-/* Solaris */
-#if (! defined(HAVE_ISINF) && defined(HAVE_FPCLASS))
-#  define HAVE_ISINF 1
-#  define isinf(a) (fpclass(a) == FP_NINF || fpclass(a) == FP_PINF)
-#endif
-
-/* solaris 10 it defines isnan such that only forte can compile it ... bad bad  */
-#if (defined(HAVE_ISNAN) && defined(isnan) && defined(HAVE_FPCLASS))
-#  undef isnan
-#  define isnan(a) (fpclass(a) == FP_SNAN || fpclass(a) == FP_QNAN)
-#endif
-
-/* Digital UNIX */
-#if (! defined(HAVE_ISINF) && defined(HAVE_FP_CLASS) && defined(HAVE_FP_CLASS_H))
-#  define HAVE_ISINF 1
-#  define isinf(a) (fp_class(a) == FP_NEG_INF || fp_class(a) == FP_POS_INF)
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
 #endif
 
-/* AIX */
-#if (! defined(HAVE_ISINF) && defined(HAVE_CLASS))
-#  define HAVE_ISINF 1
-#  define isinf(a) (class(a) == FP_MINUS_INF || class(a) == FP_PLUS_INF)
-#endif
+#undef $ac_func
 
-#if (! defined(HAVE_ISINF) && defined(HAVE_FPCLASSIFY) && defined(FP_PLUS_INF) && defined(FP_MINUS_INF))
-#  define HAVE_ISINF 1
-#  define isinf(a) (fpclassify(a) == FP_MINUS_INF || fpclassify(a) == FP_PLUS_INF)
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
 #endif
-
-#if (! defined(HAVE_ISINF) && defined(HAVE_FPCLASSIFY) && defined(FP_INFINITE))
-#  define HAVE_ISINF 1
-#  define isinf(a) (fpclassify(a) == FP_INFINITE)
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined __stub_$ac_func || defined __stub___$ac_func
+choke me
 #endif
 
-#include <stdio.h>
-int main(void){
-    double rrdnan,rrdinf,rrdc,rrdzero;
-    ;
-    /* some math to see if we get a floating point exception */
-    rrdzero=sin(0.0); /* don't let the compiler optimize us away */
-    rrdnan=0.0/rrdzero; /* especially here */
-    rrdinf=1.0/rrdzero; /* and here. I want to know if it can do the magic */
-                 /* at run time without sig fpe */
-    rrdc = rrdinf + rrdnan;
-    rrdc = rrdinf / rrdnan;
-    if (! isnan(rrdnan)) {printf ("not isnan(NaN) ... "); return 1;}
-    if (rrdnan == rrdnan) {printf ("nan == nan ... "); return 1;}
-    if (! isinf(rrdinf)) {printf ("not isinf(oo) ... "); return 1;}
-    if (! isinf(-rrdinf)) {printf ("not isinf(-oo) ... "); return 1;}
-    if (! rrdinf > 0) {printf ("not inf > 0 ... "); return 1;}
-    if (! -rrdinf < 0) {printf ("not -inf < 0 ... "); return 1;}
-    return 0;
- }
+int
+main ()
+{
+return $ac_func ();
+  ;
+  return 0;
+}
 _ACEOF
-rm -f conftest$ac_exeext
+rm -f conftest.$ac_objext conftest$ac_exeext
 if { (ac_try="$ac_link"
 case "(($ac_try" in
   *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
   *) ac_try_echo=$ac_try;;
 esac
 eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_link") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
+  (eval "$ac_link") 2>conftest.er1
   ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  rd_cv_ieee_switch=yes
+  (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
+  eval "$as_ac_var=yes"
 else
-  echo "$as_me: program exited with status $ac_status" >&5
-echo "$as_me: failed program was:" >&5
+  echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-( exit $ac_status )
-rd_cv_ieee_switch=no
-fi
-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+       eval "$as_ac_var=no"
 fi
 
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+ac_res=`eval echo '${'$as_ac_var'}'`
+              { echo "$as_me:$LINENO: result: $ac_res" >&5
+echo "${ECHO_T}$ac_res" >&6; }
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
 
 fi
+done
 
-if test x${rd_cv_ieee_switch} = "xyes"; then
- { echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6; }
+          LIBS="$glib_save_LIBS"
+
+          if test "$ac_cv_func_bind_textdomain_codeset" = "yes" ; then
+            gt_cv_func_dgettext_libc=no
+          else
+            if test "$gt_cv_func_dgettext_libc" = "yes" \
+               && test "$gt_cv_func_ngettext_libc" = "yes"; then
+              gt_cv_func_dgettext_libintl=no
+            fi
+          fi
+        fi
+      fi
+
+      if test "$gt_cv_func_dgettext_libc" = "yes" \
+       || test "$gt_cv_func_dgettext_libintl" = "yes"; then
+        gt_cv_have_gettext=yes
+      fi
+
+      if test "$gt_cv_func_dgettext_libintl" = "yes"; then
+        INTLLIBS="-lintl $libintl_extra_libs"
+      fi
+
+      if test "$gt_cv_have_gettext" = "yes"; then
 
+cat >>confdefs.h <<\_ACEOF
+#define HAVE_GETTEXT 1
+_ACEOF
+
+       # Extract the first word of "msgfmt", so it can be a program name with args.
+set dummy msgfmt; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_path_MSGFMT+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
 else
- { echo "$as_me:$LINENO: result: no" >&5
+  case "$MSGFMT" in
+  /*)
+  ac_cv_path_MSGFMT="$MSGFMT" # Let the user override the test with a path.
+  ;;
+  *)
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+  for ac_dir in $PATH; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      if test -z "`$ac_dir/$ac_word -h 2>&1 | grep 'dv '`"; then
+       ac_cv_path_MSGFMT="$ac_dir/$ac_word"
+       break
+      fi
+    fi
+  done
+  IFS="$ac_save_ifs"
+  test -z "$ac_cv_path_MSGFMT" && ac_cv_path_MSGFMT="no"
+  ;;
+esac
+fi
+MSGFMT="$ac_cv_path_MSGFMT"
+if test "$MSGFMT" != "no"; then
+  { echo "$as_me:$LINENO: result: $MSGFMT" >&5
+echo "${ECHO_T}$MSGFMT" >&6; }
+else
+  { echo "$as_me:$LINENO: result: no" >&5
 echo "${ECHO_T}no" >&6; }
- CFLAGS="$_cflags -qfloat=nofold"
+fi
+       if test "$MSGFMT" != "no"; then
+          glib_save_LIBS="$LIBS"
+          LIBS="$LIBS $INTLLIBS"
 
-{ echo "$as_me:$LINENO: checking if IEEE math works with the -qfloat=nofold switch" >&5
-echo $ECHO_N "checking if IEEE math works with the -qfloat=nofold switch... $ECHO_C" >&6; }
-if test "${rd_cv_ieee_nofold+set}" = set; then
+for ac_func in dcgettext
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+{ echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; }
+if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  if test "$cross_compiling" = yes; then
-  :
 else
   cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
@@ -23745,259 +23816,237 @@ _ACEOF
 cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define $ac_func innocuous_$ac_func
 
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
 
-#if HAVE_MATH_H
-#  include <math.h>
-#endif
-
-#if HAVE_FLOAT_H
-#  include <float.h>
-#endif
-
-#if HAVE_IEEEFP_H
-#  include <ieeefp.h>
-#endif
-
-#if HAVE_FP_CLASS_H
-#  include <fp_class.h>
-#endif
-
-/* Solaris */
-#if (! defined(HAVE_ISINF) && defined(HAVE_FPCLASS))
-#  define HAVE_ISINF 1
-#  define isinf(a) (fpclass(a) == FP_NINF || fpclass(a) == FP_PINF)
-#endif
-
-/* solaris 10 it defines isnan such that only forte can compile it ... bad bad  */
-#if (defined(HAVE_ISNAN) && defined(isnan) && defined(HAVE_FPCLASS))
-#  undef isnan
-#  define isnan(a) (fpclass(a) == FP_SNAN || fpclass(a) == FP_QNAN)
-#endif
-
-/* Digital UNIX */
-#if (! defined(HAVE_ISINF) && defined(HAVE_FP_CLASS) && defined(HAVE_FP_CLASS_H))
-#  define HAVE_ISINF 1
-#  define isinf(a) (fp_class(a) == FP_NEG_INF || fp_class(a) == FP_POS_INF)
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
 #endif
 
-/* AIX */
-#if (! defined(HAVE_ISINF) && defined(HAVE_CLASS))
-#  define HAVE_ISINF 1
-#  define isinf(a) (class(a) == FP_MINUS_INF || class(a) == FP_PLUS_INF)
-#endif
+#undef $ac_func
 
-#if (! defined(HAVE_ISINF) && defined(HAVE_FPCLASSIFY) && defined(FP_PLUS_INF) && defined(FP_MINUS_INF))
-#  define HAVE_ISINF 1
-#  define isinf(a) (fpclassify(a) == FP_MINUS_INF || fpclassify(a) == FP_PLUS_INF)
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
 #endif
-
-#if (! defined(HAVE_ISINF) && defined(HAVE_FPCLASSIFY) && defined(FP_INFINITE))
-#  define HAVE_ISINF 1
-#  define isinf(a) (fpclassify(a) == FP_INFINITE)
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined __stub_$ac_func || defined __stub___$ac_func
+choke me
 #endif
 
-#include <stdio.h>
-int main(void){
-    double rrdnan,rrdinf,rrdc,rrdzero;
-    ;
-    /* some math to see if we get a floating point exception */
-    rrdzero=sin(0.0); /* don't let the compiler optimize us away */
-    rrdnan=0.0/rrdzero; /* especially here */
-    rrdinf=1.0/rrdzero; /* and here. I want to know if it can do the magic */
-                 /* at run time without sig fpe */
-    rrdc = rrdinf + rrdnan;
-    rrdc = rrdinf / rrdnan;
-    if (! isnan(rrdnan)) {printf ("not isnan(NaN) ... "); return 1;}
-    if (rrdnan == rrdnan) {printf ("nan == nan ... "); return 1;}
-    if (! isinf(rrdinf)) {printf ("not isinf(oo) ... "); return 1;}
-    if (! isinf(-rrdinf)) {printf ("not isinf(-oo) ... "); return 1;}
-    if (! rrdinf > 0) {printf ("not inf > 0 ... "); return 1;}
-    if (! -rrdinf < 0) {printf ("not -inf < 0 ... "); return 1;}
-    return 0;
- }
+int
+main ()
+{
+return $ac_func ();
+  ;
+  return 0;
+}
 _ACEOF
-rm -f conftest$ac_exeext
+rm -f conftest.$ac_objext conftest$ac_exeext
 if { (ac_try="$ac_link"
 case "(($ac_try" in
   *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
   *) ac_try_echo=$ac_try;;
 esac
 eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_link") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
+  (eval "$ac_link") 2>conftest.er1
   ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  rd_cv_ieee_nofold=yes
+  (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
+  eval "$as_ac_var=yes"
 else
-  echo "$as_me: program exited with status $ac_status" >&5
-echo "$as_me: failed program was:" >&5
+  echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-( exit $ac_status )
-rd_cv_ieee_nofold=no
-fi
-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+       eval "$as_ac_var=no"
 fi
 
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+ac_res=`eval echo '${'$as_ac_var'}'`
+              { echo "$as_me:$LINENO: result: $ac_res" >&5
+echo "${ECHO_T}$ac_res" >&6; }
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
 
 fi
+done
 
-if test x${rd_cv_ieee_nofold} = "xyes"; then
- { echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6; }
+         MSGFMT_OPTS=
+         { echo "$as_me:$LINENO: checking if msgfmt accepts -c" >&5
+echo $ECHO_N "checking if msgfmt accepts -c... $ECHO_C" >&6; }
+         cat >conftest.foo <<_ACEOF
 
-else
- { echo "$as_me:$LINENO: result: no" >&5
+msgid ""
+msgstr ""
+"Content-Type: text/plain; charset=UTF-8\n"
+"Project-Id-Version: test 1.0\n"
+"PO-Revision-Date: 2007-02-15 12:01+0100\n"
+"Last-Translator: test <foo@bar.xx>\n"
+"Language-Team: C <LL@li.org>\n"
+"MIME-Version: 1.0\n"
+"Content-Transfer-Encoding: 8bit\n"
+
+_ACEOF
+if { (echo "$as_me:$LINENO: msgfmt -c -o /dev/null conftest.foo") >&5
+  (msgfmt -c -o /dev/null conftest.foo) 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; then
+  MSGFMT_OPTS=-c; { echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6; }
+else { echo "$as_me:$LINENO: result: no" >&5
 echo "${ECHO_T}no" >&6; }
- CFLAGS="$_cflags -w -qflttrap=enable:zerodivide"
+echo "$as_me: failed input was:" >&5
+sed 's/^/| /' conftest.foo >&5
+fi
 
-{ echo "$as_me:$LINENO: checking if IEEE math works with the -w -qflttrap=enable:zerodivide" >&5
-echo $ECHO_N "checking if IEEE math works with the -w -qflttrap=enable:zerodivide... $ECHO_C" >&6; }
-if test "${rd_cv_ieee_flttrap+set}" = set; then
+         # Extract the first word of "gmsgfmt", so it can be a program name with args.
+set dummy gmsgfmt; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_path_GMSGFMT+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
-  if test "$cross_compiling" = yes; then
-  :
-else
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-
-
-#if HAVE_MATH_H
-#  include <math.h>
-#endif
-
-#if HAVE_FLOAT_H
-#  include <float.h>
-#endif
-
-#if HAVE_IEEEFP_H
-#  include <ieeefp.h>
-#endif
-
-#if HAVE_FP_CLASS_H
-#  include <fp_class.h>
-#endif
-
-/* Solaris */
-#if (! defined(HAVE_ISINF) && defined(HAVE_FPCLASS))
-#  define HAVE_ISINF 1
-#  define isinf(a) (fpclass(a) == FP_NINF || fpclass(a) == FP_PINF)
-#endif
-
-/* solaris 10 it defines isnan such that only forte can compile it ... bad bad  */
-#if (defined(HAVE_ISNAN) && defined(isnan) && defined(HAVE_FPCLASS))
-#  undef isnan
-#  define isnan(a) (fpclass(a) == FP_SNAN || fpclass(a) == FP_QNAN)
-#endif
+  case $GMSGFMT in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_GMSGFMT="$GMSGFMT" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_path_GMSGFMT="$as_dir/$ac_word$ac_exec_ext"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+IFS=$as_save_IFS
 
-/* Digital UNIX */
-#if (! defined(HAVE_ISINF) && defined(HAVE_FP_CLASS) && defined(HAVE_FP_CLASS_H))
-#  define HAVE_ISINF 1
-#  define isinf(a) (fp_class(a) == FP_NEG_INF || fp_class(a) == FP_POS_INF)
-#endif
+  test -z "$ac_cv_path_GMSGFMT" && ac_cv_path_GMSGFMT="$MSGFMT"
+  ;;
+esac
+fi
+GMSGFMT=$ac_cv_path_GMSGFMT
+if test -n "$GMSGFMT"; then
+  { echo "$as_me:$LINENO: result: $GMSGFMT" >&5
+echo "${ECHO_T}$GMSGFMT" >&6; }
+else
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
 
-/* AIX */
-#if (! defined(HAVE_ISINF) && defined(HAVE_CLASS))
-#  define HAVE_ISINF 1
-#  define isinf(a) (class(a) == FP_MINUS_INF || class(a) == FP_PLUS_INF)
-#endif
 
-#if (! defined(HAVE_ISINF) && defined(HAVE_FPCLASSIFY) && defined(FP_PLUS_INF) && defined(FP_MINUS_INF))
-#  define HAVE_ISINF 1
-#  define isinf(a) (fpclassify(a) == FP_MINUS_INF || fpclassify(a) == FP_PLUS_INF)
-#endif
+         # Extract the first word of "xgettext", so it can be a program name with args.
+set dummy xgettext; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_path_XGETTEXT+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  case "$XGETTEXT" in
+  /*)
+  ac_cv_path_XGETTEXT="$XGETTEXT" # Let the user override the test with a path.
+  ;;
+  *)
+  IFS="${IFS=  }"; ac_save_ifs="$IFS"; IFS="${IFS}:"
+  for ac_dir in $PATH; do
+    test -z "$ac_dir" && ac_dir=.
+    if test -f $ac_dir/$ac_word; then
+      if test -z "`$ac_dir/$ac_word -h 2>&1 | grep '(HELP)'`"; then
+       ac_cv_path_XGETTEXT="$ac_dir/$ac_word"
+       break
+      fi
+    fi
+  done
+  IFS="$ac_save_ifs"
+  test -z "$ac_cv_path_XGETTEXT" && ac_cv_path_XGETTEXT=":"
+  ;;
+esac
+fi
+XGETTEXT="$ac_cv_path_XGETTEXT"
+if test "$XGETTEXT" != ":"; then
+  { echo "$as_me:$LINENO: result: $XGETTEXT" >&5
+echo "${ECHO_T}$XGETTEXT" >&6; }
+else
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
 
-#if (! defined(HAVE_ISINF) && defined(HAVE_FPCLASSIFY) && defined(FP_INFINITE))
-#  define HAVE_ISINF 1
-#  define isinf(a) (fpclassify(a) == FP_INFINITE)
-#endif
+         cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
 
-#include <stdio.h>
-int main(void){
-    double rrdnan,rrdinf,rrdc,rrdzero;
-    ;
-    /* some math to see if we get a floating point exception */
-    rrdzero=sin(0.0); /* don't let the compiler optimize us away */
-    rrdnan=0.0/rrdzero; /* especially here */
-    rrdinf=1.0/rrdzero; /* and here. I want to know if it can do the magic */
-                 /* at run time without sig fpe */
-    rrdc = rrdinf + rrdnan;
-    rrdc = rrdinf / rrdnan;
-    if (! isnan(rrdnan)) {printf ("not isnan(NaN) ... "); return 1;}
-    if (rrdnan == rrdnan) {printf ("nan == nan ... "); return 1;}
-    if (! isinf(rrdinf)) {printf ("not isinf(oo) ... "); return 1;}
-    if (! isinf(-rrdinf)) {printf ("not isinf(-oo) ... "); return 1;}
-    if (! rrdinf > 0) {printf ("not inf > 0 ... "); return 1;}
-    if (! -rrdinf < 0) {printf ("not -inf < 0 ... "); return 1;}
-    return 0;
- }
+int
+main ()
+{
+extern int _nl_msg_cat_cntr;
+                        return _nl_msg_cat_cntr
+  ;
+  return 0;
+}
 _ACEOF
-rm -f conftest$ac_exeext
+rm -f conftest.$ac_objext conftest$ac_exeext
 if { (ac_try="$ac_link"
 case "(($ac_try" in
   *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
   *) ac_try_echo=$ac_try;;
 esac
 eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_link") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
+  (eval "$ac_link") 2>conftest.er1
   ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  rd_cv_ieee_flttrap=yes
+  (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
+  CATOBJEXT=.gmo
+             DATADIRNAME=share
 else
-  echo "$as_me: program exited with status $ac_status" >&5
-echo "$as_me: failed program was:" >&5
+  echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-( exit $ac_status )
-rd_cv_ieee_flttrap=no
-fi
-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
-fi
-
-
-fi
-
-if test x${rd_cv_ieee_flttrap} = "xyes"; then
- { echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6; }
-
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
- CFLAGS="$_cflags -mieee"
-
-{ echo "$as_me:$LINENO: checking if IEEE math works with the -mieee switch" >&5
-echo $ECHO_N "checking if IEEE math works with the -mieee switch... $ECHO_C" >&6; }
-if test "${rd_cv_ieee_mswitch+set}" = set; then
+       case $host in
+           *-*-solaris*)
+                                                               { echo "$as_me:$LINENO: checking for bind_textdomain_codeset" >&5
+echo $ECHO_N "checking for bind_textdomain_codeset... $ECHO_C" >&6; }
+if test "${ac_cv_func_bind_textdomain_codeset+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  if test "$cross_compiling" = yes; then
-  :
 else
   cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
@@ -24005,324 +24054,2814 @@ _ACEOF
 cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
+/* Define bind_textdomain_codeset to an innocuous variant, in case <limits.h> declares bind_textdomain_codeset.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define bind_textdomain_codeset innocuous_bind_textdomain_codeset
 
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char bind_textdomain_codeset (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
 
-#if HAVE_MATH_H
-#  include <math.h>
-#endif
-
-#if HAVE_FLOAT_H
-#  include <float.h>
-#endif
-
-#if HAVE_IEEEFP_H
-#  include <ieeefp.h>
-#endif
-
-#if HAVE_FP_CLASS_H
-#  include <fp_class.h>
-#endif
-
-/* Solaris */
-#if (! defined(HAVE_ISINF) && defined(HAVE_FPCLASS))
-#  define HAVE_ISINF 1
-#  define isinf(a) (fpclass(a) == FP_NINF || fpclass(a) == FP_PINF)
-#endif
-
-/* solaris 10 it defines isnan such that only forte can compile it ... bad bad  */
-#if (defined(HAVE_ISNAN) && defined(isnan) && defined(HAVE_FPCLASS))
-#  undef isnan
-#  define isnan(a) (fpclass(a) == FP_SNAN || fpclass(a) == FP_QNAN)
-#endif
-
-/* Digital UNIX */
-#if (! defined(HAVE_ISINF) && defined(HAVE_FP_CLASS) && defined(HAVE_FP_CLASS_H))
-#  define HAVE_ISINF 1
-#  define isinf(a) (fp_class(a) == FP_NEG_INF || fp_class(a) == FP_POS_INF)
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
 #endif
 
-/* AIX */
-#if (! defined(HAVE_ISINF) && defined(HAVE_CLASS))
-#  define HAVE_ISINF 1
-#  define isinf(a) (class(a) == FP_MINUS_INF || class(a) == FP_PLUS_INF)
-#endif
+#undef bind_textdomain_codeset
 
-#if (! defined(HAVE_ISINF) && defined(HAVE_FPCLASSIFY) && defined(FP_PLUS_INF) && defined(FP_MINUS_INF))
-#  define HAVE_ISINF 1
-#  define isinf(a) (fpclassify(a) == FP_MINUS_INF || fpclassify(a) == FP_PLUS_INF)
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
 #endif
-
-#if (! defined(HAVE_ISINF) && defined(HAVE_FPCLASSIFY) && defined(FP_INFINITE))
-#  define HAVE_ISINF 1
-#  define isinf(a) (fpclassify(a) == FP_INFINITE)
+char bind_textdomain_codeset ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined __stub_bind_textdomain_codeset || defined __stub___bind_textdomain_codeset
+choke me
 #endif
 
-#include <stdio.h>
-int main(void){
-    double rrdnan,rrdinf,rrdc,rrdzero;
-    ;
-    /* some math to see if we get a floating point exception */
-    rrdzero=sin(0.0); /* don't let the compiler optimize us away */
-    rrdnan=0.0/rrdzero; /* especially here */
-    rrdinf=1.0/rrdzero; /* and here. I want to know if it can do the magic */
-                 /* at run time without sig fpe */
-    rrdc = rrdinf + rrdnan;
-    rrdc = rrdinf / rrdnan;
-    if (! isnan(rrdnan)) {printf ("not isnan(NaN) ... "); return 1;}
-    if (rrdnan == rrdnan) {printf ("nan == nan ... "); return 1;}
-    if (! isinf(rrdinf)) {printf ("not isinf(oo) ... "); return 1;}
-    if (! isinf(-rrdinf)) {printf ("not isinf(-oo) ... "); return 1;}
-    if (! rrdinf > 0) {printf ("not inf > 0 ... "); return 1;}
-    if (! -rrdinf < 0) {printf ("not -inf < 0 ... "); return 1;}
-    return 0;
- }
+int
+main ()
+{
+return bind_textdomain_codeset ();
+  ;
+  return 0;
+}
 _ACEOF
-rm -f conftest$ac_exeext
+rm -f conftest.$ac_objext conftest$ac_exeext
 if { (ac_try="$ac_link"
 case "(($ac_try" in
   *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
   *) ac_try_echo=$ac_try;;
 esac
 eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_link") 2>&5
+  (eval "$ac_link") 2>conftest.er1
   ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  rd_cv_ieee_mswitch=yes
+  (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
+  ac_cv_func_bind_textdomain_codeset=yes
 else
-  echo "$as_me: program exited with status $ac_status" >&5
-echo "$as_me: failed program was:" >&5
+  echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-( exit $ac_status )
-rd_cv_ieee_mswitch=no
+       ac_cv_func_bind_textdomain_codeset=no
 fi
-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_func_bind_textdomain_codeset" >&5
+echo "${ECHO_T}$ac_cv_func_bind_textdomain_codeset" >&6; }
+if test $ac_cv_func_bind_textdomain_codeset = yes; then
+  CATOBJEXT=.gmo
+               DATADIRNAME=share
+else
+  CATOBJEXT=.mo
+               DATADIRNAME=lib
+fi
+
+           ;;
+           *)
+           CATOBJEXT=.mo
+            DATADIRNAME=lib
+           ;;
+           esac
 fi
 
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+          LIBS="$glib_save_LIBS"
+         INSTOBJEXT=.mo
+       else
+         gt_cv_have_gettext=no
+       fi
+      fi
 
 fi
 
-if test x${rd_cv_ieee_mswitch} = "xyes"; then
- { echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6; }
 
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
- CFLAGS="$_cflags -q float=rndsngl"
 
-{ echo "$as_me:$LINENO: checking if IEEE math works with the -q float=rndsngl switch" >&5
-echo $ECHO_N "checking if IEEE math works with the -q float=rndsngl switch... $ECHO_C" >&6; }
-if test "${rd_cv_ieee_qswitch+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  if test "$cross_compiling" = yes; then
-  :
-else
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
+    if test "$gt_cv_have_gettext" = "yes" ; then
+
+cat >>confdefs.h <<\_ACEOF
+#define ENABLE_NLS 1
 _ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
 
+    fi
 
-#if HAVE_MATH_H
-#  include <math.h>
-#endif
+        if test "$XGETTEXT" != ":"; then
+                  if $XGETTEXT --omit-header /dev/null 2> /dev/null; then
+        : ;
+      else
+        { echo "$as_me:$LINENO: result: found xgettext program is not GNU xgettext; ignore it" >&5
+echo "${ECHO_T}found xgettext program is not GNU xgettext; ignore it" >&6; }
+        XGETTEXT=":"
+      fi
+    fi
 
-#if HAVE_FLOAT_H
-#  include <float.h>
-#endif
+    # We need to process the po/ directory.
+    POSUB=po
 
-#if HAVE_IEEEFP_H
-#  include <ieeefp.h>
-#endif
+    ac_config_commands="$ac_config_commands default-1"
 
-#if HAVE_FP_CLASS_H
-#  include <fp_class.h>
-#endif
 
-/* Solaris */
-#if (! defined(HAVE_ISINF) && defined(HAVE_FPCLASS))
-#  define HAVE_ISINF 1
-#  define isinf(a) (fpclass(a) == FP_NINF || fpclass(a) == FP_PINF)
-#endif
+                for lang in $ALL_LINGUAS; do
+      GMOFILES="$GMOFILES $lang.gmo"
+      POFILES="$POFILES $lang.po"
+    done
 
-/* solaris 10 it defines isnan such that only forte can compile it ... bad bad  */
-#if (defined(HAVE_ISNAN) && defined(isnan) && defined(HAVE_FPCLASS))
-#  undef isnan
-#  define isnan(a) (fpclass(a) == FP_SNAN || fpclass(a) == FP_QNAN)
-#endif
 
-/* Digital UNIX */
-#if (! defined(HAVE_ISINF) && defined(HAVE_FP_CLASS) && defined(HAVE_FP_CLASS_H))
-#  define HAVE_ISINF 1
-#  define isinf(a) (fp_class(a) == FP_NEG_INF || fp_class(a) == FP_POS_INF)
-#endif
 
-/* AIX */
-#if (! defined(HAVE_ISINF) && defined(HAVE_CLASS))
-#  define HAVE_ISINF 1
-#  define isinf(a) (class(a) == FP_MINUS_INF || class(a) == FP_PLUS_INF)
-#endif
 
-#if (! defined(HAVE_ISINF) && defined(HAVE_FPCLASSIFY) && defined(FP_PLUS_INF) && defined(FP_MINUS_INF))
-#  define HAVE_ISINF 1
-#  define isinf(a) (fpclassify(a) == FP_MINUS_INF || fpclassify(a) == FP_PLUS_INF)
-#endif
 
-#if (! defined(HAVE_ISINF) && defined(HAVE_FPCLASSIFY) && defined(FP_INFINITE))
-#  define HAVE_ISINF 1
-#  define isinf(a) (fpclassify(a) == FP_INFINITE)
-#endif
 
-#include <stdio.h>
-int main(void){
-    double rrdnan,rrdinf,rrdc,rrdzero;
-    ;
-    /* some math to see if we get a floating point exception */
-    rrdzero=sin(0.0); /* don't let the compiler optimize us away */
-    rrdnan=0.0/rrdzero; /* especially here */
-    rrdinf=1.0/rrdzero; /* and here. I want to know if it can do the magic */
-                 /* at run time without sig fpe */
-    rrdc = rrdinf + rrdnan;
-    rrdc = rrdinf / rrdnan;
-    if (! isnan(rrdnan)) {printf ("not isnan(NaN) ... "); return 1;}
-    if (rrdnan == rrdnan) {printf ("nan == nan ... "); return 1;}
-    if (! isinf(rrdinf)) {printf ("not isinf(oo) ... "); return 1;}
-    if (! isinf(-rrdinf)) {printf ("not isinf(-oo) ... "); return 1;}
-    if (! rrdinf > 0) {printf ("not inf > 0 ... "); return 1;}
-    if (! -rrdinf < 0) {printf ("not -inf < 0 ... "); return 1;}
-    return 0;
- }
-_ACEOF
-rm -f conftest$ac_exeext
-if { (ac_try="$ac_link"
-case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_link") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  rd_cv_ieee_qswitch=yes
-else
-  echo "$as_me: program exited with status $ac_status" >&5
-echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
 
-( exit $ac_status )
-rd_cv_ieee_qswitch=no
-fi
-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+
+
+
+
+
+
+   if test "$gt_cv_have_gettext" = "yes"; then
+     if test "x$ALL_LINGUAS" = "x"; then
+       LINGUAS=
+     else
+       { echo "$as_me:$LINENO: checking for catalogs to be installed" >&5
+echo $ECHO_N "checking for catalogs to be installed... $ECHO_C" >&6; }
+       NEW_LINGUAS=
+       for presentlang in $ALL_LINGUAS; do
+         useit=no
+         if test "%UNSET%" != "${LINGUAS-%UNSET%}"; then
+           desiredlanguages="$LINGUAS"
+         else
+           desiredlanguages="$ALL_LINGUAS"
+         fi
+         for desiredlang in $desiredlanguages; do
+          # Use the presentlang catalog if desiredlang is
+           #   a. equal to presentlang, or
+           #   b. a variant of presentlang (because in this case,
+           #      presentlang can be used as a fallback for messages
+           #      which are not translated in the desiredlang catalog).
+           case "$desiredlang" in
+             "$presentlang"*) useit=yes;;
+           esac
+         done
+         if test $useit = yes; then
+           NEW_LINGUAS="$NEW_LINGUAS $presentlang"
+         fi
+       done
+       LINGUAS=$NEW_LINGUAS
+       { echo "$as_me:$LINENO: result: $LINGUAS" >&5
+echo "${ECHO_T}$LINGUAS" >&6; }
+     fi
+
+          if test -n "$LINGUAS"; then
+       for lang in $LINGUAS; do CATALOGS="$CATALOGS $lang$CATOBJEXT"; done
+     fi
+   fi
+
+            MKINSTALLDIRS=
+   if test -n "$ac_aux_dir"; then
+     MKINSTALLDIRS="$ac_aux_dir/mkinstalldirs"
+   fi
+   if test -z "$MKINSTALLDIRS"; then
+     MKINSTALLDIRS="\$(top_srcdir)/mkinstalldirs"
+   fi
+
+
+         test -d po || mkdir po
+   if test "x$srcdir" != "x."; then
+     if test "x`echo $srcdir | sed 's@/.*@@'`" = "x"; then
+       posrcprefix="$srcdir/"
+     else
+       posrcprefix="../$srcdir/"
+     fi
+   else
+     posrcprefix="../"
+   fi
+   rm -f po/POTFILES
+   sed -e "/^#/d" -e "/^\$/d" -e "s,.*,        $posrcprefix& \\\\," -e "\$s/\(.*\) \\\\/\1/" \
+       < $srcdir/po/POTFILES.in > po/POTFILES
+
+
+# Check whether --enable-libintl was given.
+if test "${enable_libintl+set}" = set; then
+  enableval=$enable_libintl;
+else
+  enable_libintl=yes
 fi
 
 
+if test x$enable_libintl = xyes; then
+
+case "$am__api_version" in
+    1.01234)
+       { { echo "$as_me:$LINENO: error: Automake 1.5 or newer is required to use intltool" >&5
+echo "$as_me: error: Automake 1.5 or newer is required to use intltool" >&2;}
+   { (exit 1); exit 1; }; }
+    ;;
+    *)
+    ;;
+esac
+
+if test -n "0.35.0"; then
+    { echo "$as_me:$LINENO: checking for intltool >= 0.35.0" >&5
+echo $ECHO_N "checking for intltool >= 0.35.0... $ECHO_C" >&6; }
+
+    INTLTOOL_REQUIRED_VERSION_AS_INT=`echo 0.35.0 | awk -F. '{ print $ 1 * 1000 + $ 2 * 100 + $ 3; }'`
+    INTLTOOL_APPLIED_VERSION=`awk -F\" '/\\$VERSION / { print $ 2; }' ${ac_aux_dir}/intltool-update.in`
+    INTLTOOL_APPLIED_VERSION_AS_INT=`awk -F\" '/\\$VERSION / { split($ 2, VERSION, "."); print VERSION[1] * 1000 + VERSION[2] * 100 + VERSION[3];}' ${ac_aux_dir}/intltool-update.in`
+
+    { echo "$as_me:$LINENO: result: $INTLTOOL_APPLIED_VERSION found" >&5
+echo "${ECHO_T}$INTLTOOL_APPLIED_VERSION found" >&6; }
+    test "$INTLTOOL_APPLIED_VERSION_AS_INT" -ge "$INTLTOOL_REQUIRED_VERSION_AS_INT" ||
+       { { echo "$as_me:$LINENO: error: Your intltool is too old.  You need intltool 0.35.0 or later." >&5
+echo "$as_me: error: Your intltool is too old.  You need intltool 0.35.0 or later." >&2;}
+   { (exit 1); exit 1; }; }
 fi
 
-if test x${rd_cv_ieee_qswitch} = "xyes"; then
- { echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6; }
+  INTLTOOL_DESKTOP_RULE='%.desktop:   %.desktop.in   $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@'
+INTLTOOL_DIRECTORY_RULE='%.directory: %.directory.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@'
+     INTLTOOL_KEYS_RULE='%.keys:      %.keys.in      $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -k -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@'
+     INTLTOOL_PROP_RULE='%.prop:      %.prop.in      $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@'
+      INTLTOOL_OAF_RULE='%.oaf:       %.oaf.in       $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -o -p $(top_srcdir)/po $< $@'
+     INTLTOOL_PONG_RULE='%.pong:      %.pong.in      $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -x -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@'
+   INTLTOOL_SERVER_RULE='%.server:    %.server.in    $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -o -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@'
+    INTLTOOL_SHEET_RULE='%.sheet:     %.sheet.in     $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -x -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@'
+INTLTOOL_SOUNDLIST_RULE='%.soundlist: %.soundlist.in $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@'
+       INTLTOOL_UI_RULE='%.ui:        %.ui.in        $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -x -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@'
+      INTLTOOL_XML_RULE='%.xml:       %.xml.in       $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -x -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@'
+      INTLTOOL_XML_NOMERGE_RULE='%.xml:       %.xml.in       $(INTLTOOL_MERGE) ; LC_ALL=C $(INTLTOOL_MERGE) -x -u /tmp $< $@'
+      INTLTOOL_XAM_RULE='%.xam:       %.xml.in       $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -x -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@'
+      INTLTOOL_KBD_RULE='%.kbd:       %.kbd.in       $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -x -u -m -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@'
+    INTLTOOL_CAVES_RULE='%.caves:     %.caves.in     $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@'
+  INTLTOOL_SCHEMAS_RULE='%.schemas:   %.schemas.in   $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -s -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@'
+    INTLTOOL_THEME_RULE='%.theme:     %.theme.in     $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@'
+    INTLTOOL_SERVICE_RULE='%.service: %.service.in   $(INTLTOOL_MERGE) $(wildcard $(top_srcdir)/po/*.po) ; LC_ALL=C $(INTLTOOL_MERGE) -d -u -c $(top_builddir)/po/.intltool-merge-cache $(top_srcdir)/po $< $@'
 
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
- CFLAGS="$_cflags -OPT:IEEE_NaN_inf=ON"
 
-{ echo "$as_me:$LINENO: checking if IEEE math works with the -OPT:IEEE_NaN_inf=ON switch" >&5
-echo $ECHO_N "checking if IEEE math works with the -OPT:IEEE_NaN_inf=ON switch... $ECHO_C" >&6; }
-if test "${rd_cv_ieee_ieeenaninfswitch+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  if test "$cross_compiling" = yes; then
-  :
-else
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
 
 
-#if HAVE_MATH_H
-#  include <math.h>
-#endif
 
-#if HAVE_FLOAT_H
-#  include <float.h>
-#endif
 
-#if HAVE_IEEEFP_H
-#  include <ieeefp.h>
-#endif
 
-#if HAVE_FP_CLASS_H
-#  include <fp_class.h>
-#endif
 
-/* Solaris */
-#if (! defined(HAVE_ISINF) && defined(HAVE_FPCLASS))
-#  define HAVE_ISINF 1
-#  define isinf(a) (fpclass(a) == FP_NINF || fpclass(a) == FP_PINF)
-#endif
 
-/* solaris 10 it defines isnan such that only forte can compile it ... bad bad  */
-#if (defined(HAVE_ISNAN) && defined(isnan) && defined(HAVE_FPCLASS))
-#  undef isnan
-#  define isnan(a) (fpclass(a) == FP_SNAN || fpclass(a) == FP_QNAN)
-#endif
 
-/* Digital UNIX */
-#if (! defined(HAVE_ISINF) && defined(HAVE_FP_CLASS) && defined(HAVE_FP_CLASS_H))
-#  define HAVE_ISINF 1
-#  define isinf(a) (fp_class(a) == FP_NEG_INF || fp_class(a) == FP_POS_INF)
-#endif
 
-/* AIX */
-#if (! defined(HAVE_ISINF) && defined(HAVE_CLASS))
-#  define HAVE_ISINF 1
-#  define isinf(a) (class(a) == FP_MINUS_INF || class(a) == FP_PLUS_INF)
-#endif
 
-#if (! defined(HAVE_ISINF) && defined(HAVE_FPCLASSIFY) && defined(FP_PLUS_INF) && defined(FP_MINUS_INF))
-#  define HAVE_ISINF 1
-#  define isinf(a) (fpclassify(a) == FP_MINUS_INF || fpclassify(a) == FP_PLUS_INF)
-#endif
 
-#if (! defined(HAVE_ISINF) && defined(HAVE_FPCLASSIFY) && defined(FP_INFINITE))
-#  define HAVE_ISINF 1
-#  define isinf(a) (fpclassify(a) == FP_INFINITE)
-#endif
 
-#include <stdio.h>
-int main(void){
-    double rrdnan,rrdinf,rrdc,rrdzero;
-    ;
-    /* some math to see if we get a floating point exception */
-    rrdzero=sin(0.0); /* don't let the compiler optimize us away */
+
+
+
+
+
+
+# Use the tools built into the package, not the ones that are installed.
+INTLTOOL_EXTRACT='$(top_builddir)/intltool-extract'
+
+INTLTOOL_MERGE='$(top_builddir)/intltool-merge'
+
+INTLTOOL_UPDATE='$(top_builddir)/intltool-update'
+
+
+# Extract the first word of "perl", so it can be a program name with args.
+set dummy perl; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_path_INTLTOOL_PERL+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  case $INTLTOOL_PERL in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_INTLTOOL_PERL="$INTLTOOL_PERL" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_path_INTLTOOL_PERL="$as_dir/$ac_word$ac_exec_ext"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+IFS=$as_save_IFS
+
+  ;;
+esac
+fi
+INTLTOOL_PERL=$ac_cv_path_INTLTOOL_PERL
+if test -n "$INTLTOOL_PERL"; then
+  { echo "$as_me:$LINENO: result: $INTLTOOL_PERL" >&5
+echo "${ECHO_T}$INTLTOOL_PERL" >&6; }
+else
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+
+if test -z "$INTLTOOL_PERL"; then
+   { { echo "$as_me:$LINENO: error: perl not found; required for intltool" >&5
+echo "$as_me: error: perl not found; required for intltool" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+if test -z "`$INTLTOOL_PERL -v | fgrep '5.' 2> /dev/null`"; then
+   { { echo "$as_me:$LINENO: error: perl 5.x required for intltool" >&5
+echo "$as_me: error: perl 5.x required for intltool" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+if test "xno-xml" != "xno-xml"; then
+   { echo "$as_me:$LINENO: checking for XML::Parser" >&5
+echo $ECHO_N "checking for XML::Parser... $ECHO_C" >&6; }
+   if `$INTLTOOL_PERL -e "require XML::Parser" 2>/dev/null`; then
+       { echo "$as_me:$LINENO: result: ok" >&5
+echo "${ECHO_T}ok" >&6; }
+   else
+       { { echo "$as_me:$LINENO: error: XML::Parser perl module is required for intltool" >&5
+echo "$as_me: error: XML::Parser perl module is required for intltool" >&2;}
+   { (exit 1); exit 1; }; }
+   fi
+fi
+
+# Extract the first word of "iconv", so it can be a program name with args.
+set dummy iconv; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_path_INTLTOOL_ICONV+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  case $INTLTOOL_ICONV in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_INTLTOOL_ICONV="$INTLTOOL_ICONV" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_path_INTLTOOL_ICONV="$as_dir/$ac_word$ac_exec_ext"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+IFS=$as_save_IFS
+
+  test -z "$ac_cv_path_INTLTOOL_ICONV" && ac_cv_path_INTLTOOL_ICONV="iconv"
+  ;;
+esac
+fi
+INTLTOOL_ICONV=$ac_cv_path_INTLTOOL_ICONV
+if test -n "$INTLTOOL_ICONV"; then
+  { echo "$as_me:$LINENO: result: $INTLTOOL_ICONV" >&5
+echo "${ECHO_T}$INTLTOOL_ICONV" >&6; }
+else
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+
+# Extract the first word of "msgfmt", so it can be a program name with args.
+set dummy msgfmt; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_path_INTLTOOL_MSGFMT+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  case $INTLTOOL_MSGFMT in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_INTLTOOL_MSGFMT="$INTLTOOL_MSGFMT" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_path_INTLTOOL_MSGFMT="$as_dir/$ac_word$ac_exec_ext"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+IFS=$as_save_IFS
+
+  test -z "$ac_cv_path_INTLTOOL_MSGFMT" && ac_cv_path_INTLTOOL_MSGFMT="msgfmt"
+  ;;
+esac
+fi
+INTLTOOL_MSGFMT=$ac_cv_path_INTLTOOL_MSGFMT
+if test -n "$INTLTOOL_MSGFMT"; then
+  { echo "$as_me:$LINENO: result: $INTLTOOL_MSGFMT" >&5
+echo "${ECHO_T}$INTLTOOL_MSGFMT" >&6; }
+else
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+
+# Extract the first word of "msgmerge", so it can be a program name with args.
+set dummy msgmerge; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_path_INTLTOOL_MSGMERGE+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  case $INTLTOOL_MSGMERGE in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_INTLTOOL_MSGMERGE="$INTLTOOL_MSGMERGE" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_path_INTLTOOL_MSGMERGE="$as_dir/$ac_word$ac_exec_ext"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+IFS=$as_save_IFS
+
+  test -z "$ac_cv_path_INTLTOOL_MSGMERGE" && ac_cv_path_INTLTOOL_MSGMERGE="msgmerge"
+  ;;
+esac
+fi
+INTLTOOL_MSGMERGE=$ac_cv_path_INTLTOOL_MSGMERGE
+if test -n "$INTLTOOL_MSGMERGE"; then
+  { echo "$as_me:$LINENO: result: $INTLTOOL_MSGMERGE" >&5
+echo "${ECHO_T}$INTLTOOL_MSGMERGE" >&6; }
+else
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+
+# Extract the first word of "xgettext", so it can be a program name with args.
+set dummy xgettext; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_path_INTLTOOL_XGETTEXT+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  case $INTLTOOL_XGETTEXT in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_INTLTOOL_XGETTEXT="$INTLTOOL_XGETTEXT" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_path_INTLTOOL_XGETTEXT="$as_dir/$ac_word$ac_exec_ext"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+IFS=$as_save_IFS
+
+  test -z "$ac_cv_path_INTLTOOL_XGETTEXT" && ac_cv_path_INTLTOOL_XGETTEXT="xgettext"
+  ;;
+esac
+fi
+INTLTOOL_XGETTEXT=$ac_cv_path_INTLTOOL_XGETTEXT
+if test -n "$INTLTOOL_XGETTEXT"; then
+  { echo "$as_me:$LINENO: result: $INTLTOOL_XGETTEXT" >&5
+echo "${ECHO_T}$INTLTOOL_XGETTEXT" >&6; }
+else
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+
+
+# Substitute ALL_LINGUAS so we can use it in po/Makefile
+
+
+# Set DATADIRNAME correctly if it is not set yet
+# (copied from glib-gettext.m4)
+if test -z "$DATADIRNAME"; then
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+int
+main ()
+{
+extern int _nl_msg_cat_cntr;
+                 return _nl_msg_cat_cntr
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
+  DATADIRNAME=share
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       case $host in
+    *-*-solaris*)
+                        { echo "$as_me:$LINENO: checking for bind_textdomain_codeset" >&5
+echo $ECHO_N "checking for bind_textdomain_codeset... $ECHO_C" >&6; }
+if test "${ac_cv_func_bind_textdomain_codeset+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define bind_textdomain_codeset to an innocuous variant, in case <limits.h> declares bind_textdomain_codeset.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define bind_textdomain_codeset innocuous_bind_textdomain_codeset
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char bind_textdomain_codeset (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef bind_textdomain_codeset
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char bind_textdomain_codeset ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined __stub_bind_textdomain_codeset || defined __stub___bind_textdomain_codeset
+choke me
+#endif
+
+int
+main ()
+{
+return bind_textdomain_codeset ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
+  ac_cv_func_bind_textdomain_codeset=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       ac_cv_func_bind_textdomain_codeset=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_func_bind_textdomain_codeset" >&5
+echo "${ECHO_T}$ac_cv_func_bind_textdomain_codeset" >&6; }
+if test $ac_cv_func_bind_textdomain_codeset = yes; then
+  DATADIRNAME=share
+else
+  DATADIRNAME=lib
+fi
+
+    ;;
+    *)
+    DATADIRNAME=lib
+    ;;
+    esac
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+
+
+
+
+
+ac_config_commands="$ac_config_commands intltool"
+
+
+
+fi
+
+if test x$enable_libintl = xyes -a x$MSGFMT = xno; then
+  { echo "$as_me:$LINENO: WARNING: I could not find msgfmt. Diabeling libintl build." >&5
+echo "$as_me: WARNING: I could not find msgfmt. Diabeling libintl build." >&2;}
+  enable_libintl=no
+fi
+
+if test x$enable_libintl = xyes; then
+
+for ac_header in libintl.h
+do
+as_ac_Header=`echo "ac_cv_header_$ac_header" | $as_tr_sh`
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+  { echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+ac_res=`eval echo '${'$as_ac_Header'}'`
+              { echo "$as_me:$LINENO: result: $ac_res" >&5
+echo "${ECHO_T}$ac_res" >&6; }
+else
+  # Is the header compilable?
+{ echo "$as_me:$LINENO: checking $ac_header usability" >&5
+echo $ECHO_N "checking $ac_header usability... $ECHO_C" >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <$ac_header>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       ac_header_compiler=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ echo "$as_me:$LINENO: checking $ac_header presence" >&5
+echo $ECHO_N "checking $ac_header presence... $ECHO_C" >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <$ac_header>
+_ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null && {
+        test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       }; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+
+rm -f conftest.err conftest.$ac_ext
+{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6; }
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: $ac_header: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: $ac_header: present but cannot be compiled" >&5
+echo "$as_me: WARNING: $ac_header: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: $ac_header:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: $ac_header: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: $ac_header:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: $ac_header: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: $ac_header: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: $ac_header: in the future, the compiler will take precedence" >&2;}
+
+    ;;
+esac
+{ echo "$as_me:$LINENO: checking for $ac_header" >&5
+echo $ECHO_N "checking for $ac_header... $ECHO_C" >&6; }
+if { as_var=$as_ac_Header; eval "test \"\${$as_var+set}\" = set"; }; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  eval "$as_ac_Header=\$ac_header_preproc"
+fi
+ac_res=`eval echo '${'$as_ac_Header'}'`
+              { echo "$as_me:$LINENO: result: $ac_res" >&5
+echo "${ECHO_T}$ac_res" >&6; }
+
+fi
+if test `eval echo '${'$as_ac_Header'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_header" | $as_tr_cpp` 1
+_ACEOF
+
+else
+  { echo "$as_me:$LINENO: result: disabeling libintl build" >&5
+echo "${ECHO_T}disabeling libintl build" >&6; }; enable_libintl=no
+fi
+
+done
+
+fi
+
+if test x$enable_libintl = xyes ; then
+      { echo "$as_me:$LINENO: checking for libintl_gettext in -lintl" >&5
+echo $ECHO_N "checking for libintl_gettext in -lintl... $ECHO_C" >&6; }
+if test "${ac_cv_lib_intl_libintl_gettext+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lintl  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char libintl_gettext ();
+int
+main ()
+{
+return libintl_gettext ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
+  ac_cv_lib_intl_libintl_gettext=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       ac_cv_lib_intl_libintl_gettext=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_lib_intl_libintl_gettext" >&5
+echo "${ECHO_T}$ac_cv_lib_intl_libintl_gettext" >&6; }
+if test $ac_cv_lib_intl_libintl_gettext = yes; then
+  LIB_LIBINTL="-lintl"
+fi
+
+fi
+
+
+
+
+
+if test x$enable_libintl = xyes; then
+  BUILD_LIBINTL_TRUE=
+  BUILD_LIBINTL_FALSE='#'
+else
+  BUILD_LIBINTL_TRUE='#'
+  BUILD_LIBINTL_FALSE=
+fi
+
+
+if test x$enable_libintl = xyes; then
+
+cat >>confdefs.h <<\_ACEOF
+#define BUILD_LIBINTL
+_ACEOF
+
+fi
+
+
+case $TERM in
+       #   for the most important terminal types we directly know the sequences
+       xterm|xterm*|vt220|vt220*)
+               T_MD=`awk 'BEGIN { printf("%c%c%c%c", 27, 91, 49, 109); }' </dev/null 2>/dev/null`
+               T_ME=`awk 'BEGIN { printf("%c%c%c", 27, 91, 109); }' </dev/null 2>/dev/null`
+       ;;
+       vt100|vt100*|cygwin)
+               T_MD=`awk 'BEGIN { printf("%c%c%c%c%c%c", 27, 91, 49, 109, 0, 0); }' </dev/null 2>/dev/null`
+               T_ME=`awk 'BEGIN { printf("%c%c%c%c%c", 27, 91, 109, 0, 0); }' </dev/null 2>/dev/null`
+       ;;
+       *)
+               T_MD=''
+               T_ME=''
+       ;;
+esac
+  { echo "$as_me:$LINENO: result: " >&5
+echo "${ECHO_T}" >&6; }
+  { echo "$as_me:$LINENO: result: ${T_MD}IEEE Math Checks${T_ME}" >&5
+echo "${ECHO_T}${T_MD}IEEE Math Checks${T_ME}" >&6; }
+
+
+
+
+for ac_func in fpclassify
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+{ echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; }
+if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined __stub_$ac_func || defined __stub___$ac_func
+choke me
+#endif
+
+int
+main ()
+{
+return $ac_func ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       eval "$as_ac_var=no"
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+ac_res=`eval echo '${'$as_ac_var'}'`
+              { echo "$as_me:$LINENO: result: $ac_res" >&5
+echo "${ECHO_T}$ac_res" >&6; }
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+else
+  { echo "$as_me:$LINENO: checking for fpclassify with <math.h>" >&5
+echo $ECHO_N "checking for fpclassify with <math.h>... $ECHO_C" >&6; }
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <math.h>
+volatile int x;volatile float f;
+int
+main ()
+{
+x = fpclassify(f)
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
+  { echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6; }
+      cat >>confdefs.h <<\_ACEOF
+#define HAVE_FPCLASSIFY 1
+_ACEOF
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+done
+
+
+
+for ac_func in isinf
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+{ echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; }
+if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined __stub_$ac_func || defined __stub___$ac_func
+choke me
+#endif
+
+int
+main ()
+{
+return $ac_func ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       eval "$as_ac_var=no"
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+ac_res=`eval echo '${'$as_ac_var'}'`
+              { echo "$as_me:$LINENO: result: $ac_res" >&5
+echo "${ECHO_T}$ac_res" >&6; }
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+else
+  { echo "$as_me:$LINENO: checking for isinf with <math.h>" >&5
+echo $ECHO_N "checking for isinf with <math.h>... $ECHO_C" >&6; }
+    cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <math.h>
+volatile int x;volatile float f;
+int
+main ()
+{
+x = isinf(f)
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
+  { echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6; }
+      cat >>confdefs.h <<\_ACEOF
+#define HAVE_ISINF 1
+_ACEOF
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+done
+
+
+{ echo "$as_me:$LINENO: checking whether isfinite is broken" >&5
+echo $ECHO_N "checking whether isfinite is broken... $ECHO_C" >&6; }
+if test "${have_broken_isfinite+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+
+if test "$cross_compiling" = yes; then
+
+case "${target}" in
+  hppa*-*-hpux*) have_broken_isfinite=yes ;;
+  *) have_broken_isfinite=no ;;
+esac
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+#ifdef HAVE_MATH_H
+#include <math.h>
+#endif
+#ifdef HAVE_FLOAT_H
+#include <float.h>
+#endif
+int main ()
+{
+#ifdef isfinite
+#ifdef LDBL_MAX
+  if (!isfinite(LDBL_MAX)) return 1;
+#endif
+#ifdef DBL_MAX
+  if (!isfinite(DBL_MAX)) return 1;
+#endif
+#endif
+return 0;
+}
+_ACEOF
+rm -f conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+
+have_broken_isfinite=no
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+have_broken_isfinite=yes
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+
+
+
+fi
+{ echo "$as_me:$LINENO: result: $have_broken_isfinite" >&5
+echo "${ECHO_T}$have_broken_isfinite" >&6; }
+if test "x$have_broken_isfinite" = "xno"; then
+  cat >>confdefs.h <<\_ACEOF
+#define HAVE_ISFINITE 1
+_ACEOF
+
+else
+
+for ac_func in finite
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+{ echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; }
+if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined __stub_$ac_func || defined __stub___$ac_func
+choke me
+#endif
+
+int
+main ()
+{
+return $ac_func ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       eval "$as_ac_var=no"
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+ac_res=`eval echo '${'$as_ac_var'}'`
+              { echo "$as_me:$LINENO: result: $ac_res" >&5
+echo "${ECHO_T}$ac_res" >&6; }
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+else
+
+for ac_func in isfinite
+do
+as_ac_var=`echo "ac_cv_func_$ac_func" | $as_tr_sh`
+{ echo "$as_me:$LINENO: checking for $ac_func" >&5
+echo $ECHO_N "checking for $ac_func... $ECHO_C" >&6; }
+if { as_var=$as_ac_var; eval "test \"\${$as_var+set}\" = set"; }; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+/* Define $ac_func to an innocuous variant, in case <limits.h> declares $ac_func.
+   For example, HP-UX 11i <limits.h> declares gettimeofday.  */
+#define $ac_func innocuous_$ac_func
+
+/* System header to define __stub macros and hopefully few prototypes,
+    which can conflict with char $ac_func (); below.
+    Prefer <limits.h> to <assert.h> if __STDC__ is defined, since
+    <limits.h> exists even on freestanding compilers.  */
+
+#ifdef __STDC__
+# include <limits.h>
+#else
+# include <assert.h>
+#endif
+
+#undef $ac_func
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char $ac_func ();
+/* The GNU C library defines this for functions which it implements
+    to always fail with ENOSYS.  Some functions are actually named
+    something starting with __ and the normal name is an alias.  */
+#if defined __stub_$ac_func || defined __stub___$ac_func
+choke me
+#endif
+
+int
+main ()
+{
+return $ac_func ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
+  eval "$as_ac_var=yes"
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       eval "$as_ac_var=no"
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+ac_res=`eval echo '${'$as_ac_var'}'`
+              { echo "$as_me:$LINENO: result: $ac_res" >&5
+echo "${ECHO_T}$ac_res" >&6; }
+if test `eval echo '${'$as_ac_var'}'` = yes; then
+  cat >>confdefs.h <<_ACEOF
+#define `echo "HAVE_$ac_func" | $as_tr_cpp` 1
+_ACEOF
+
+else
+  { echo "$as_me:$LINENO: checking for isfinite with <math.h>" >&5
+echo $ECHO_N "checking for isfinite with <math.h>... $ECHO_C" >&6; }
+       cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <math.h>
+volatile int x;volatile float f;
+int
+main ()
+{
+x = isfinite(f)
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
+  { echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6; }
+               cat >>confdefs.h <<\_ACEOF
+#define HAVE_ISFINITE 1
+_ACEOF
+
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+fi
+done
+
+fi
+done
+
+fi
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+_cflags=${CFLAGS}
+
+{ echo "$as_me:$LINENO: checking if IEEE math works out of the box" >&5
+echo $ECHO_N "checking if IEEE math works out of the box... $ECHO_C" >&6; }
+if test "${rd_cv_ieee_works+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test "$cross_compiling" = yes; then
+  :
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+
+#if HAVE_MATH_H
+#  include <math.h>
+#endif
+
+#if HAVE_FLOAT_H
+#  include <float.h>
+#endif
+
+#if HAVE_IEEEFP_H
+#  include <ieeefp.h>
+#endif
+
+#if HAVE_FP_CLASS_H
+#  include <fp_class.h>
+#endif
+
+/* Solaris */
+#if (! defined(HAVE_ISINF) && defined(HAVE_FPCLASS))
+#  define HAVE_ISINF 1
+#  define isinf(a) (fpclass(a) == FP_NINF || fpclass(a) == FP_PINF)
+#endif
+
+/* solaris 10 it defines isnan such that only forte can compile it ... bad bad  */
+#if (defined(HAVE_ISNAN) && defined(isnan) && defined(HAVE_FPCLASS))
+#  undef isnan
+#  define isnan(a) (fpclass(a) == FP_SNAN || fpclass(a) == FP_QNAN)
+#endif
+
+/* Digital UNIX */
+#if (! defined(HAVE_ISINF) && defined(HAVE_FP_CLASS) && defined(HAVE_FP_CLASS_H))
+#  define HAVE_ISINF 1
+#  define isinf(a) (fp_class(a) == FP_NEG_INF || fp_class(a) == FP_POS_INF)
+#endif
+
+/* AIX */
+#if (! defined(HAVE_ISINF) && defined(HAVE_CLASS))
+#  define HAVE_ISINF 1
+#  define isinf(a) (class(a) == FP_MINUS_INF || class(a) == FP_PLUS_INF)
+#endif
+
+#if (! defined(HAVE_ISINF) && defined(HAVE_FPCLASSIFY) && defined(FP_PLUS_INF) && defined(FP_MINUS_INF))
+#  define HAVE_ISINF 1
+#  define isinf(a) (fpclassify(a) == FP_MINUS_INF || fpclassify(a) == FP_PLUS_INF)
+#endif
+
+#if (! defined(HAVE_ISINF) && defined(HAVE_FPCLASSIFY) && defined(FP_INFINITE))
+#  define HAVE_ISINF 1
+#  define isinf(a) (fpclassify(a) == FP_INFINITE)
+#endif
+
+#include <stdio.h>
+int main(void){
+    double rrdnan,rrdinf,rrdc,rrdzero;
+    ;
+    /* some math to see if we get a floating point exception */
+    rrdzero=sin(0.0); /* don't let the compiler optimize us away */
+    rrdnan=0.0/rrdzero; /* especially here */
+    rrdinf=1.0/rrdzero; /* and here. I want to know if it can do the magic */
+                 /* at run time without sig fpe */
+    rrdc = rrdinf + rrdnan;
+    rrdc = rrdinf / rrdnan;
+    if (! isnan(rrdnan)) {printf ("not isnan(NaN) ... "); return 1;}
+    if (rrdnan == rrdnan) {printf ("nan == nan ... "); return 1;}
+    if (! isinf(rrdinf)) {printf ("not isinf(oo) ... "); return 1;}
+    if (! isinf(-rrdinf)) {printf ("not isinf(-oo) ... "); return 1;}
+    if (! rrdinf > 0) {printf ("not inf > 0 ... "); return 1;}
+    if (! -rrdinf < 0) {printf ("not -inf < 0 ... "); return 1;}
+    return 0;
+ }
+_ACEOF
+rm -f conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  rd_cv_ieee_works=yes
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+rd_cv_ieee_works=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+
+
+fi
+
+if test x${rd_cv_ieee_works} = "xyes"; then
+ { echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6; }
+
+else
+ { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+ CFLAGS="$_cflags -ieee"
+
+{ echo "$as_me:$LINENO: checking if IEEE math works with the -ieee switch" >&5
+echo $ECHO_N "checking if IEEE math works with the -ieee switch... $ECHO_C" >&6; }
+if test "${rd_cv_ieee_switch+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test "$cross_compiling" = yes; then
+  :
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+
+#if HAVE_MATH_H
+#  include <math.h>
+#endif
+
+#if HAVE_FLOAT_H
+#  include <float.h>
+#endif
+
+#if HAVE_IEEEFP_H
+#  include <ieeefp.h>
+#endif
+
+#if HAVE_FP_CLASS_H
+#  include <fp_class.h>
+#endif
+
+/* Solaris */
+#if (! defined(HAVE_ISINF) && defined(HAVE_FPCLASS))
+#  define HAVE_ISINF 1
+#  define isinf(a) (fpclass(a) == FP_NINF || fpclass(a) == FP_PINF)
+#endif
+
+/* solaris 10 it defines isnan such that only forte can compile it ... bad bad  */
+#if (defined(HAVE_ISNAN) && defined(isnan) && defined(HAVE_FPCLASS))
+#  undef isnan
+#  define isnan(a) (fpclass(a) == FP_SNAN || fpclass(a) == FP_QNAN)
+#endif
+
+/* Digital UNIX */
+#if (! defined(HAVE_ISINF) && defined(HAVE_FP_CLASS) && defined(HAVE_FP_CLASS_H))
+#  define HAVE_ISINF 1
+#  define isinf(a) (fp_class(a) == FP_NEG_INF || fp_class(a) == FP_POS_INF)
+#endif
+
+/* AIX */
+#if (! defined(HAVE_ISINF) && defined(HAVE_CLASS))
+#  define HAVE_ISINF 1
+#  define isinf(a) (class(a) == FP_MINUS_INF || class(a) == FP_PLUS_INF)
+#endif
+
+#if (! defined(HAVE_ISINF) && defined(HAVE_FPCLASSIFY) && defined(FP_PLUS_INF) && defined(FP_MINUS_INF))
+#  define HAVE_ISINF 1
+#  define isinf(a) (fpclassify(a) == FP_MINUS_INF || fpclassify(a) == FP_PLUS_INF)
+#endif
+
+#if (! defined(HAVE_ISINF) && defined(HAVE_FPCLASSIFY) && defined(FP_INFINITE))
+#  define HAVE_ISINF 1
+#  define isinf(a) (fpclassify(a) == FP_INFINITE)
+#endif
+
+#include <stdio.h>
+int main(void){
+    double rrdnan,rrdinf,rrdc,rrdzero;
+    ;
+    /* some math to see if we get a floating point exception */
+    rrdzero=sin(0.0); /* don't let the compiler optimize us away */
+    rrdnan=0.0/rrdzero; /* especially here */
+    rrdinf=1.0/rrdzero; /* and here. I want to know if it can do the magic */
+                 /* at run time without sig fpe */
+    rrdc = rrdinf + rrdnan;
+    rrdc = rrdinf / rrdnan;
+    if (! isnan(rrdnan)) {printf ("not isnan(NaN) ... "); return 1;}
+    if (rrdnan == rrdnan) {printf ("nan == nan ... "); return 1;}
+    if (! isinf(rrdinf)) {printf ("not isinf(oo) ... "); return 1;}
+    if (! isinf(-rrdinf)) {printf ("not isinf(-oo) ... "); return 1;}
+    if (! rrdinf > 0) {printf ("not inf > 0 ... "); return 1;}
+    if (! -rrdinf < 0) {printf ("not -inf < 0 ... "); return 1;}
+    return 0;
+ }
+_ACEOF
+rm -f conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  rd_cv_ieee_switch=yes
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+rd_cv_ieee_switch=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+
+
+fi
+
+if test x${rd_cv_ieee_switch} = "xyes"; then
+ { echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6; }
+
+else
+ { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+ CFLAGS="$_cflags -qfloat=nofold"
+
+{ echo "$as_me:$LINENO: checking if IEEE math works with the -qfloat=nofold switch" >&5
+echo $ECHO_N "checking if IEEE math works with the -qfloat=nofold switch... $ECHO_C" >&6; }
+if test "${rd_cv_ieee_nofold+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test "$cross_compiling" = yes; then
+  :
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+
+#if HAVE_MATH_H
+#  include <math.h>
+#endif
+
+#if HAVE_FLOAT_H
+#  include <float.h>
+#endif
+
+#if HAVE_IEEEFP_H
+#  include <ieeefp.h>
+#endif
+
+#if HAVE_FP_CLASS_H
+#  include <fp_class.h>
+#endif
+
+/* Solaris */
+#if (! defined(HAVE_ISINF) && defined(HAVE_FPCLASS))
+#  define HAVE_ISINF 1
+#  define isinf(a) (fpclass(a) == FP_NINF || fpclass(a) == FP_PINF)
+#endif
+
+/* solaris 10 it defines isnan such that only forte can compile it ... bad bad  */
+#if (defined(HAVE_ISNAN) && defined(isnan) && defined(HAVE_FPCLASS))
+#  undef isnan
+#  define isnan(a) (fpclass(a) == FP_SNAN || fpclass(a) == FP_QNAN)
+#endif
+
+/* Digital UNIX */
+#if (! defined(HAVE_ISINF) && defined(HAVE_FP_CLASS) && defined(HAVE_FP_CLASS_H))
+#  define HAVE_ISINF 1
+#  define isinf(a) (fp_class(a) == FP_NEG_INF || fp_class(a) == FP_POS_INF)
+#endif
+
+/* AIX */
+#if (! defined(HAVE_ISINF) && defined(HAVE_CLASS))
+#  define HAVE_ISINF 1
+#  define isinf(a) (class(a) == FP_MINUS_INF || class(a) == FP_PLUS_INF)
+#endif
+
+#if (! defined(HAVE_ISINF) && defined(HAVE_FPCLASSIFY) && defined(FP_PLUS_INF) && defined(FP_MINUS_INF))
+#  define HAVE_ISINF 1
+#  define isinf(a) (fpclassify(a) == FP_MINUS_INF || fpclassify(a) == FP_PLUS_INF)
+#endif
+
+#if (! defined(HAVE_ISINF) && defined(HAVE_FPCLASSIFY) && defined(FP_INFINITE))
+#  define HAVE_ISINF 1
+#  define isinf(a) (fpclassify(a) == FP_INFINITE)
+#endif
+
+#include <stdio.h>
+int main(void){
+    double rrdnan,rrdinf,rrdc,rrdzero;
+    ;
+    /* some math to see if we get a floating point exception */
+    rrdzero=sin(0.0); /* don't let the compiler optimize us away */
+    rrdnan=0.0/rrdzero; /* especially here */
+    rrdinf=1.0/rrdzero; /* and here. I want to know if it can do the magic */
+                 /* at run time without sig fpe */
+    rrdc = rrdinf + rrdnan;
+    rrdc = rrdinf / rrdnan;
+    if (! isnan(rrdnan)) {printf ("not isnan(NaN) ... "); return 1;}
+    if (rrdnan == rrdnan) {printf ("nan == nan ... "); return 1;}
+    if (! isinf(rrdinf)) {printf ("not isinf(oo) ... "); return 1;}
+    if (! isinf(-rrdinf)) {printf ("not isinf(-oo) ... "); return 1;}
+    if (! rrdinf > 0) {printf ("not inf > 0 ... "); return 1;}
+    if (! -rrdinf < 0) {printf ("not -inf < 0 ... "); return 1;}
+    return 0;
+ }
+_ACEOF
+rm -f conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  rd_cv_ieee_nofold=yes
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+rd_cv_ieee_nofold=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+
+
+fi
+
+if test x${rd_cv_ieee_nofold} = "xyes"; then
+ { echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6; }
+
+else
+ { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+ CFLAGS="$_cflags -w -qflttrap=enable:zerodivide"
+
+{ echo "$as_me:$LINENO: checking if IEEE math works with the -w -qflttrap=enable:zerodivide" >&5
+echo $ECHO_N "checking if IEEE math works with the -w -qflttrap=enable:zerodivide... $ECHO_C" >&6; }
+if test "${rd_cv_ieee_flttrap+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test "$cross_compiling" = yes; then
+  :
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+
+#if HAVE_MATH_H
+#  include <math.h>
+#endif
+
+#if HAVE_FLOAT_H
+#  include <float.h>
+#endif
+
+#if HAVE_IEEEFP_H
+#  include <ieeefp.h>
+#endif
+
+#if HAVE_FP_CLASS_H
+#  include <fp_class.h>
+#endif
+
+/* Solaris */
+#if (! defined(HAVE_ISINF) && defined(HAVE_FPCLASS))
+#  define HAVE_ISINF 1
+#  define isinf(a) (fpclass(a) == FP_NINF || fpclass(a) == FP_PINF)
+#endif
+
+/* solaris 10 it defines isnan such that only forte can compile it ... bad bad  */
+#if (defined(HAVE_ISNAN) && defined(isnan) && defined(HAVE_FPCLASS))
+#  undef isnan
+#  define isnan(a) (fpclass(a) == FP_SNAN || fpclass(a) == FP_QNAN)
+#endif
+
+/* Digital UNIX */
+#if (! defined(HAVE_ISINF) && defined(HAVE_FP_CLASS) && defined(HAVE_FP_CLASS_H))
+#  define HAVE_ISINF 1
+#  define isinf(a) (fp_class(a) == FP_NEG_INF || fp_class(a) == FP_POS_INF)
+#endif
+
+/* AIX */
+#if (! defined(HAVE_ISINF) && defined(HAVE_CLASS))
+#  define HAVE_ISINF 1
+#  define isinf(a) (class(a) == FP_MINUS_INF || class(a) == FP_PLUS_INF)
+#endif
+
+#if (! defined(HAVE_ISINF) && defined(HAVE_FPCLASSIFY) && defined(FP_PLUS_INF) && defined(FP_MINUS_INF))
+#  define HAVE_ISINF 1
+#  define isinf(a) (fpclassify(a) == FP_MINUS_INF || fpclassify(a) == FP_PLUS_INF)
+#endif
+
+#if (! defined(HAVE_ISINF) && defined(HAVE_FPCLASSIFY) && defined(FP_INFINITE))
+#  define HAVE_ISINF 1
+#  define isinf(a) (fpclassify(a) == FP_INFINITE)
+#endif
+
+#include <stdio.h>
+int main(void){
+    double rrdnan,rrdinf,rrdc,rrdzero;
+    ;
+    /* some math to see if we get a floating point exception */
+    rrdzero=sin(0.0); /* don't let the compiler optimize us away */
+    rrdnan=0.0/rrdzero; /* especially here */
+    rrdinf=1.0/rrdzero; /* and here. I want to know if it can do the magic */
+                 /* at run time without sig fpe */
+    rrdc = rrdinf + rrdnan;
+    rrdc = rrdinf / rrdnan;
+    if (! isnan(rrdnan)) {printf ("not isnan(NaN) ... "); return 1;}
+    if (rrdnan == rrdnan) {printf ("nan == nan ... "); return 1;}
+    if (! isinf(rrdinf)) {printf ("not isinf(oo) ... "); return 1;}
+    if (! isinf(-rrdinf)) {printf ("not isinf(-oo) ... "); return 1;}
+    if (! rrdinf > 0) {printf ("not inf > 0 ... "); return 1;}
+    if (! -rrdinf < 0) {printf ("not -inf < 0 ... "); return 1;}
+    return 0;
+ }
+_ACEOF
+rm -f conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  rd_cv_ieee_flttrap=yes
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+rd_cv_ieee_flttrap=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+
+
+fi
+
+if test x${rd_cv_ieee_flttrap} = "xyes"; then
+ { echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6; }
+
+else
+ { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+ CFLAGS="$_cflags -mieee"
+
+{ echo "$as_me:$LINENO: checking if IEEE math works with the -mieee switch" >&5
+echo $ECHO_N "checking if IEEE math works with the -mieee switch... $ECHO_C" >&6; }
+if test "${rd_cv_ieee_mswitch+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test "$cross_compiling" = yes; then
+  :
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+
+#if HAVE_MATH_H
+#  include <math.h>
+#endif
+
+#if HAVE_FLOAT_H
+#  include <float.h>
+#endif
+
+#if HAVE_IEEEFP_H
+#  include <ieeefp.h>
+#endif
+
+#if HAVE_FP_CLASS_H
+#  include <fp_class.h>
+#endif
+
+/* Solaris */
+#if (! defined(HAVE_ISINF) && defined(HAVE_FPCLASS))
+#  define HAVE_ISINF 1
+#  define isinf(a) (fpclass(a) == FP_NINF || fpclass(a) == FP_PINF)
+#endif
+
+/* solaris 10 it defines isnan such that only forte can compile it ... bad bad  */
+#if (defined(HAVE_ISNAN) && defined(isnan) && defined(HAVE_FPCLASS))
+#  undef isnan
+#  define isnan(a) (fpclass(a) == FP_SNAN || fpclass(a) == FP_QNAN)
+#endif
+
+/* Digital UNIX */
+#if (! defined(HAVE_ISINF) && defined(HAVE_FP_CLASS) && defined(HAVE_FP_CLASS_H))
+#  define HAVE_ISINF 1
+#  define isinf(a) (fp_class(a) == FP_NEG_INF || fp_class(a) == FP_POS_INF)
+#endif
+
+/* AIX */
+#if (! defined(HAVE_ISINF) && defined(HAVE_CLASS))
+#  define HAVE_ISINF 1
+#  define isinf(a) (class(a) == FP_MINUS_INF || class(a) == FP_PLUS_INF)
+#endif
+
+#if (! defined(HAVE_ISINF) && defined(HAVE_FPCLASSIFY) && defined(FP_PLUS_INF) && defined(FP_MINUS_INF))
+#  define HAVE_ISINF 1
+#  define isinf(a) (fpclassify(a) == FP_MINUS_INF || fpclassify(a) == FP_PLUS_INF)
+#endif
+
+#if (! defined(HAVE_ISINF) && defined(HAVE_FPCLASSIFY) && defined(FP_INFINITE))
+#  define HAVE_ISINF 1
+#  define isinf(a) (fpclassify(a) == FP_INFINITE)
+#endif
+
+#include <stdio.h>
+int main(void){
+    double rrdnan,rrdinf,rrdc,rrdzero;
+    ;
+    /* some math to see if we get a floating point exception */
+    rrdzero=sin(0.0); /* don't let the compiler optimize us away */
+    rrdnan=0.0/rrdzero; /* especially here */
+    rrdinf=1.0/rrdzero; /* and here. I want to know if it can do the magic */
+                 /* at run time without sig fpe */
+    rrdc = rrdinf + rrdnan;
+    rrdc = rrdinf / rrdnan;
+    if (! isnan(rrdnan)) {printf ("not isnan(NaN) ... "); return 1;}
+    if (rrdnan == rrdnan) {printf ("nan == nan ... "); return 1;}
+    if (! isinf(rrdinf)) {printf ("not isinf(oo) ... "); return 1;}
+    if (! isinf(-rrdinf)) {printf ("not isinf(-oo) ... "); return 1;}
+    if (! rrdinf > 0) {printf ("not inf > 0 ... "); return 1;}
+    if (! -rrdinf < 0) {printf ("not -inf < 0 ... "); return 1;}
+    return 0;
+ }
+_ACEOF
+rm -f conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  rd_cv_ieee_mswitch=yes
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+rd_cv_ieee_mswitch=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+
+
+fi
+
+if test x${rd_cv_ieee_mswitch} = "xyes"; then
+ { echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6; }
+
+else
+ { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+ CFLAGS="$_cflags -q float=rndsngl"
+
+{ echo "$as_me:$LINENO: checking if IEEE math works with the -q float=rndsngl switch" >&5
+echo $ECHO_N "checking if IEEE math works with the -q float=rndsngl switch... $ECHO_C" >&6; }
+if test "${rd_cv_ieee_qswitch+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test "$cross_compiling" = yes; then
+  :
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+
+#if HAVE_MATH_H
+#  include <math.h>
+#endif
+
+#if HAVE_FLOAT_H
+#  include <float.h>
+#endif
+
+#if HAVE_IEEEFP_H
+#  include <ieeefp.h>
+#endif
+
+#if HAVE_FP_CLASS_H
+#  include <fp_class.h>
+#endif
+
+/* Solaris */
+#if (! defined(HAVE_ISINF) && defined(HAVE_FPCLASS))
+#  define HAVE_ISINF 1
+#  define isinf(a) (fpclass(a) == FP_NINF || fpclass(a) == FP_PINF)
+#endif
+
+/* solaris 10 it defines isnan such that only forte can compile it ... bad bad  */
+#if (defined(HAVE_ISNAN) && defined(isnan) && defined(HAVE_FPCLASS))
+#  undef isnan
+#  define isnan(a) (fpclass(a) == FP_SNAN || fpclass(a) == FP_QNAN)
+#endif
+
+/* Digital UNIX */
+#if (! defined(HAVE_ISINF) && defined(HAVE_FP_CLASS) && defined(HAVE_FP_CLASS_H))
+#  define HAVE_ISINF 1
+#  define isinf(a) (fp_class(a) == FP_NEG_INF || fp_class(a) == FP_POS_INF)
+#endif
+
+/* AIX */
+#if (! defined(HAVE_ISINF) && defined(HAVE_CLASS))
+#  define HAVE_ISINF 1
+#  define isinf(a) (class(a) == FP_MINUS_INF || class(a) == FP_PLUS_INF)
+#endif
+
+#if (! defined(HAVE_ISINF) && defined(HAVE_FPCLASSIFY) && defined(FP_PLUS_INF) && defined(FP_MINUS_INF))
+#  define HAVE_ISINF 1
+#  define isinf(a) (fpclassify(a) == FP_MINUS_INF || fpclassify(a) == FP_PLUS_INF)
+#endif
+
+#if (! defined(HAVE_ISINF) && defined(HAVE_FPCLASSIFY) && defined(FP_INFINITE))
+#  define HAVE_ISINF 1
+#  define isinf(a) (fpclassify(a) == FP_INFINITE)
+#endif
+
+#include <stdio.h>
+int main(void){
+    double rrdnan,rrdinf,rrdc,rrdzero;
+    ;
+    /* some math to see if we get a floating point exception */
+    rrdzero=sin(0.0); /* don't let the compiler optimize us away */
+    rrdnan=0.0/rrdzero; /* especially here */
+    rrdinf=1.0/rrdzero; /* and here. I want to know if it can do the magic */
+                 /* at run time without sig fpe */
+    rrdc = rrdinf + rrdnan;
+    rrdc = rrdinf / rrdnan;
+    if (! isnan(rrdnan)) {printf ("not isnan(NaN) ... "); return 1;}
+    if (rrdnan == rrdnan) {printf ("nan == nan ... "); return 1;}
+    if (! isinf(rrdinf)) {printf ("not isinf(oo) ... "); return 1;}
+    if (! isinf(-rrdinf)) {printf ("not isinf(-oo) ... "); return 1;}
+    if (! rrdinf > 0) {printf ("not inf > 0 ... "); return 1;}
+    if (! -rrdinf < 0) {printf ("not -inf < 0 ... "); return 1;}
+    return 0;
+ }
+_ACEOF
+rm -f conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  rd_cv_ieee_qswitch=yes
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+rd_cv_ieee_qswitch=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+
+
+fi
+
+if test x${rd_cv_ieee_qswitch} = "xyes"; then
+ { echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6; }
+
+else
+ { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+ CFLAGS="$_cflags -OPT:IEEE_NaN_inf=ON"
+
+{ echo "$as_me:$LINENO: checking if IEEE math works with the -OPT:IEEE_NaN_inf=ON switch" >&5
+echo $ECHO_N "checking if IEEE math works with the -OPT:IEEE_NaN_inf=ON switch... $ECHO_C" >&6; }
+if test "${rd_cv_ieee_ieeenaninfswitch+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test "$cross_compiling" = yes; then
+  :
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+
+#if HAVE_MATH_H
+#  include <math.h>
+#endif
+
+#if HAVE_FLOAT_H
+#  include <float.h>
+#endif
+
+#if HAVE_IEEEFP_H
+#  include <ieeefp.h>
+#endif
+
+#if HAVE_FP_CLASS_H
+#  include <fp_class.h>
+#endif
+
+/* Solaris */
+#if (! defined(HAVE_ISINF) && defined(HAVE_FPCLASS))
+#  define HAVE_ISINF 1
+#  define isinf(a) (fpclass(a) == FP_NINF || fpclass(a) == FP_PINF)
+#endif
+
+/* solaris 10 it defines isnan such that only forte can compile it ... bad bad  */
+#if (defined(HAVE_ISNAN) && defined(isnan) && defined(HAVE_FPCLASS))
+#  undef isnan
+#  define isnan(a) (fpclass(a) == FP_SNAN || fpclass(a) == FP_QNAN)
+#endif
+
+/* Digital UNIX */
+#if (! defined(HAVE_ISINF) && defined(HAVE_FP_CLASS) && defined(HAVE_FP_CLASS_H))
+#  define HAVE_ISINF 1
+#  define isinf(a) (fp_class(a) == FP_NEG_INF || fp_class(a) == FP_POS_INF)
+#endif
+
+/* AIX */
+#if (! defined(HAVE_ISINF) && defined(HAVE_CLASS))
+#  define HAVE_ISINF 1
+#  define isinf(a) (class(a) == FP_MINUS_INF || class(a) == FP_PLUS_INF)
+#endif
+
+#if (! defined(HAVE_ISINF) && defined(HAVE_FPCLASSIFY) && defined(FP_PLUS_INF) && defined(FP_MINUS_INF))
+#  define HAVE_ISINF 1
+#  define isinf(a) (fpclassify(a) == FP_MINUS_INF || fpclassify(a) == FP_PLUS_INF)
+#endif
+
+#if (! defined(HAVE_ISINF) && defined(HAVE_FPCLASSIFY) && defined(FP_INFINITE))
+#  define HAVE_ISINF 1
+#  define isinf(a) (fpclassify(a) == FP_INFINITE)
+#endif
+
+#include <stdio.h>
+int main(void){
+    double rrdnan,rrdinf,rrdc,rrdzero;
+    ;
+    /* some math to see if we get a floating point exception */
+    rrdzero=sin(0.0); /* don't let the compiler optimize us away */
+    rrdnan=0.0/rrdzero; /* especially here */
+    rrdinf=1.0/rrdzero; /* and here. I want to know if it can do the magic */
+                 /* at run time without sig fpe */
+    rrdc = rrdinf + rrdnan;
+    rrdc = rrdinf / rrdnan;
+    if (! isnan(rrdnan)) {printf ("not isnan(NaN) ... "); return 1;}
+    if (rrdnan == rrdnan) {printf ("nan == nan ... "); return 1;}
+    if (! isinf(rrdinf)) {printf ("not isinf(oo) ... "); return 1;}
+    if (! isinf(-rrdinf)) {printf ("not isinf(-oo) ... "); return 1;}
+    if (! rrdinf > 0) {printf ("not inf > 0 ... "); return 1;}
+    if (! -rrdinf < 0) {printf ("not -inf < 0 ... "); return 1;}
+    return 0;
+ }
+_ACEOF
+rm -f conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  rd_cv_ieee_ieeenaninfswitch=yes
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+rd_cv_ieee_ieeenaninfswitch=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+
+
+fi
+
+if test x${rd_cv_ieee_ieeenaninfswitch} = "xyes"; then
+ { echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6; }
+
+else
+ { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+ CFLAGS="$_cflags -OPT:IEEE_comparisons=ON"
+
+{ echo "$as_me:$LINENO: checking if IEEE math works with the -OPT:IEEE_comparisons=ON switch" >&5
+echo $ECHO_N "checking if IEEE math works with the -OPT:IEEE_comparisons=ON switch... $ECHO_C" >&6; }
+if test "${rd_cv_ieee_ieeecmpswitch+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test "$cross_compiling" = yes; then
+  :
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+
+#if HAVE_MATH_H
+#  include <math.h>
+#endif
+
+#if HAVE_FLOAT_H
+#  include <float.h>
+#endif
+
+#if HAVE_IEEEFP_H
+#  include <ieeefp.h>
+#endif
+
+#if HAVE_FP_CLASS_H
+#  include <fp_class.h>
+#endif
+
+/* Solaris */
+#if (! defined(HAVE_ISINF) && defined(HAVE_FPCLASS))
+#  define HAVE_ISINF 1
+#  define isinf(a) (fpclass(a) == FP_NINF || fpclass(a) == FP_PINF)
+#endif
+
+/* solaris 10 it defines isnan such that only forte can compile it ... bad bad  */
+#if (defined(HAVE_ISNAN) && defined(isnan) && defined(HAVE_FPCLASS))
+#  undef isnan
+#  define isnan(a) (fpclass(a) == FP_SNAN || fpclass(a) == FP_QNAN)
+#endif
+
+/* Digital UNIX */
+#if (! defined(HAVE_ISINF) && defined(HAVE_FP_CLASS) && defined(HAVE_FP_CLASS_H))
+#  define HAVE_ISINF 1
+#  define isinf(a) (fp_class(a) == FP_NEG_INF || fp_class(a) == FP_POS_INF)
+#endif
+
+/* AIX */
+#if (! defined(HAVE_ISINF) && defined(HAVE_CLASS))
+#  define HAVE_ISINF 1
+#  define isinf(a) (class(a) == FP_MINUS_INF || class(a) == FP_PLUS_INF)
+#endif
+
+#if (! defined(HAVE_ISINF) && defined(HAVE_FPCLASSIFY) && defined(FP_PLUS_INF) && defined(FP_MINUS_INF))
+#  define HAVE_ISINF 1
+#  define isinf(a) (fpclassify(a) == FP_MINUS_INF || fpclassify(a) == FP_PLUS_INF)
+#endif
+
+#if (! defined(HAVE_ISINF) && defined(HAVE_FPCLASSIFY) && defined(FP_INFINITE))
+#  define HAVE_ISINF 1
+#  define isinf(a) (fpclassify(a) == FP_INFINITE)
+#endif
+
+#include <stdio.h>
+int main(void){
+    double rrdnan,rrdinf,rrdc,rrdzero;
+    ;
+    /* some math to see if we get a floating point exception */
+    rrdzero=sin(0.0); /* don't let the compiler optimize us away */
+    rrdnan=0.0/rrdzero; /* especially here */
+    rrdinf=1.0/rrdzero; /* and here. I want to know if it can do the magic */
+                 /* at run time without sig fpe */
+    rrdc = rrdinf + rrdnan;
+    rrdc = rrdinf / rrdnan;
+    if (! isnan(rrdnan)) {printf ("not isnan(NaN) ... "); return 1;}
+    if (rrdnan == rrdnan) {printf ("nan == nan ... "); return 1;}
+    if (! isinf(rrdinf)) {printf ("not isinf(oo) ... "); return 1;}
+    if (! isinf(-rrdinf)) {printf ("not isinf(-oo) ... "); return 1;}
+    if (! rrdinf > 0) {printf ("not inf > 0 ... "); return 1;}
+    if (! -rrdinf < 0) {printf ("not -inf < 0 ... "); return 1;}
+    return 0;
+ }
+_ACEOF
+rm -f conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  rd_cv_ieee_ieeecmpswitch=yes
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+rd_cv_ieee_ieeecmpswitch=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+
+
+fi
+
+if test x${rd_cv_ieee_ieeecmpswitch} = "xyes"; then
+ { echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6; }
+
+else
+ { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+ CFLAGS=$_cflags
+
+{ echo "$as_me:$LINENO: checking if IEEE math works with fpsetmask(0)" >&5
+echo $ECHO_N "checking if IEEE math works with fpsetmask(0)... $ECHO_C" >&6; }
+if test "${rd_cv_ieee_mask+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test "$cross_compiling" = yes; then
+  :
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <floatingpoint.h>
+
+#if HAVE_MATH_H
+#  include <math.h>
+#endif
+
+#if HAVE_FLOAT_H
+#  include <float.h>
+#endif
+
+#if HAVE_IEEEFP_H
+#  include <ieeefp.h>
+#endif
+
+#if HAVE_FP_CLASS_H
+#  include <fp_class.h>
+#endif
+
+/* Solaris */
+#if (! defined(HAVE_ISINF) && defined(HAVE_FPCLASS))
+#  define HAVE_ISINF 1
+#  define isinf(a) (fpclass(a) == FP_NINF || fpclass(a) == FP_PINF)
+#endif
+
+/* solaris 10 it defines isnan such that only forte can compile it ... bad bad  */
+#if (defined(HAVE_ISNAN) && defined(isnan) && defined(HAVE_FPCLASS))
+#  undef isnan
+#  define isnan(a) (fpclass(a) == FP_SNAN || fpclass(a) == FP_QNAN)
+#endif
+
+/* Digital UNIX */
+#if (! defined(HAVE_ISINF) && defined(HAVE_FP_CLASS) && defined(HAVE_FP_CLASS_H))
+#  define HAVE_ISINF 1
+#  define isinf(a) (fp_class(a) == FP_NEG_INF || fp_class(a) == FP_POS_INF)
+#endif
+
+/* AIX */
+#if (! defined(HAVE_ISINF) && defined(HAVE_CLASS))
+#  define HAVE_ISINF 1
+#  define isinf(a) (class(a) == FP_MINUS_INF || class(a) == FP_PLUS_INF)
+#endif
+
+#if (! defined(HAVE_ISINF) && defined(HAVE_FPCLASSIFY) && defined(FP_PLUS_INF) && defined(FP_MINUS_INF))
+#  define HAVE_ISINF 1
+#  define isinf(a) (fpclassify(a) == FP_MINUS_INF || fpclassify(a) == FP_PLUS_INF)
+#endif
+
+#if (! defined(HAVE_ISINF) && defined(HAVE_FPCLASSIFY) && defined(FP_INFINITE))
+#  define HAVE_ISINF 1
+#  define isinf(a) (fpclassify(a) == FP_INFINITE)
+#endif
+
+#include <stdio.h>
+int main(void){
+    double rrdnan,rrdinf,rrdc,rrdzero;
+    fpsetmask(0);
+    /* some math to see if we get a floating point exception */
+    rrdzero=sin(0.0); /* don't let the compiler optimize us away */
+    rrdnan=0.0/rrdzero; /* especially here */
+    rrdinf=1.0/rrdzero; /* and here. I want to know if it can do the magic */
+                 /* at run time without sig fpe */
+    rrdc = rrdinf + rrdnan;
+    rrdc = rrdinf / rrdnan;
+    if (! isnan(rrdnan)) {printf ("not isnan(NaN) ... "); return 1;}
+    if (rrdnan == rrdnan) {printf ("nan == nan ... "); return 1;}
+    if (! isinf(rrdinf)) {printf ("not isinf(oo) ... "); return 1;}
+    if (! isinf(-rrdinf)) {printf ("not isinf(-oo) ... "); return 1;}
+    if (! rrdinf > 0) {printf ("not inf > 0 ... "); return 1;}
+    if (! -rrdinf < 0) {printf ("not -inf < 0 ... "); return 1;}
+    return 0;
+ }
+_ACEOF
+rm -f conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  rd_cv_ieee_mask=yes
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+rd_cv_ieee_mask=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+
+
+fi
+
+if test x${rd_cv_ieee_mask} = "xyes"; then
+ { echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6; }
+ cat >>confdefs.h <<\_ACEOF
+#define MUST_DISABLE_FPMASK 1
+_ACEOF
+
+                PERLFLAGS="CCFLAGS=-DMUST_DISABLE_FPMASK"
+else
+ { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+
+{ echo "$as_me:$LINENO: checking if IEEE math works with signal(SIGFPE,SIG_IGN)" >&5
+echo $ECHO_N "checking if IEEE math works with signal(SIGFPE,SIG_IGN)... $ECHO_C" >&6; }
+if test "${rd_cv_ieee_sigfpe+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test "$cross_compiling" = yes; then
+  :
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <signal.h>
+
+#if HAVE_MATH_H
+#  include <math.h>
+#endif
+
+#if HAVE_FLOAT_H
+#  include <float.h>
+#endif
+
+#if HAVE_IEEEFP_H
+#  include <ieeefp.h>
+#endif
+
+#if HAVE_FP_CLASS_H
+#  include <fp_class.h>
+#endif
+
+/* Solaris */
+#if (! defined(HAVE_ISINF) && defined(HAVE_FPCLASS))
+#  define HAVE_ISINF 1
+#  define isinf(a) (fpclass(a) == FP_NINF || fpclass(a) == FP_PINF)
+#endif
+
+/* solaris 10 it defines isnan such that only forte can compile it ... bad bad  */
+#if (defined(HAVE_ISNAN) && defined(isnan) && defined(HAVE_FPCLASS))
+#  undef isnan
+#  define isnan(a) (fpclass(a) == FP_SNAN || fpclass(a) == FP_QNAN)
+#endif
+
+/* Digital UNIX */
+#if (! defined(HAVE_ISINF) && defined(HAVE_FP_CLASS) && defined(HAVE_FP_CLASS_H))
+#  define HAVE_ISINF 1
+#  define isinf(a) (fp_class(a) == FP_NEG_INF || fp_class(a) == FP_POS_INF)
+#endif
+
+/* AIX */
+#if (! defined(HAVE_ISINF) && defined(HAVE_CLASS))
+#  define HAVE_ISINF 1
+#  define isinf(a) (class(a) == FP_MINUS_INF || class(a) == FP_PLUS_INF)
+#endif
+
+#if (! defined(HAVE_ISINF) && defined(HAVE_FPCLASSIFY) && defined(FP_PLUS_INF) && defined(FP_MINUS_INF))
+#  define HAVE_ISINF 1
+#  define isinf(a) (fpclassify(a) == FP_MINUS_INF || fpclassify(a) == FP_PLUS_INF)
+#endif
+
+#if (! defined(HAVE_ISINF) && defined(HAVE_FPCLASSIFY) && defined(FP_INFINITE))
+#  define HAVE_ISINF 1
+#  define isinf(a) (fpclassify(a) == FP_INFINITE)
+#endif
+
+#include <stdio.h>
+int main(void){
+    double rrdnan,rrdinf,rrdc,rrdzero;
+    signal(SIGFPE,SIG_IGN);
+    /* some math to see if we get a floating point exception */
+    rrdzero=sin(0.0); /* don't let the compiler optimize us away */
     rrdnan=0.0/rrdzero; /* especially here */
     rrdinf=1.0/rrdzero; /* and here. I want to know if it can do the magic */
                  /* at run time without sig fpe */
@@ -24337,487 +26876,902 @@ int main(void){
     return 0;
  }
 _ACEOF
-rm -f conftest$ac_exeext
+rm -f conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  rd_cv_ieee_sigfpe=yes
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+rd_cv_ieee_sigfpe=no
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+
+
+fi
+
+if test x${rd_cv_ieee_sigfpe} = "xyes"; then
+ { echo "$as_me:$LINENO: result: yes" >&5
+echo "${ECHO_T}yes" >&6; }
+ cat >>confdefs.h <<\_ACEOF
+#define MUST_DISABLE_SIGFPE 1
+_ACEOF
+
+                   PERLFLAGS="CCFLAGS=-DMUST_DISABLE_SIGFPE"
+else
+ { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+ { { echo "$as_me:$LINENO: error:
+Your Compiler does not do propper IEEE math ... Please find out how to
+make IEEE math work with your compiler and let me know (tobi@oetiker.ch).
+Check config.log to see what went wrong ...
+" >&5
+echo "$as_me: error:
+Your Compiler does not do propper IEEE math ... Please find out how to
+make IEEE math work with your compiler and let me know (tobi@oetiker.ch).
+Check config.log to see what went wrong ...
+" >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+fi
+
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+
+
+
+
+case $TERM in
+       #   for the most important terminal types we directly know the sequences
+       xterm|xterm*|vt220|vt220*)
+               T_MD=`awk 'BEGIN { printf("%c%c%c%c", 27, 91, 49, 109); }' </dev/null 2>/dev/null`
+               T_ME=`awk 'BEGIN { printf("%c%c%c", 27, 91, 109); }' </dev/null 2>/dev/null`
+       ;;
+       vt100|vt100*|cygwin)
+               T_MD=`awk 'BEGIN { printf("%c%c%c%c%c%c", 27, 91, 49, 109, 0, 0); }' </dev/null 2>/dev/null`
+               T_ME=`awk 'BEGIN { printf("%c%c%c%c%c", 27, 91, 109, 0, 0); }' </dev/null 2>/dev/null`
+       ;;
+       *)
+               T_MD=''
+               T_ME=''
+       ;;
+esac
+  { echo "$as_me:$LINENO: result: " >&5
+echo "${ECHO_T}" >&6; }
+  { echo "$as_me:$LINENO: result: ${T_MD}Resolve Portability Issues${T_ME}" >&5
+echo "${ECHO_T}${T_MD}Resolve Portability Issues${T_ME}" >&6; }
+
+
+
+{ echo "$as_me:$LINENO: checking if realloc can deal with NULL" >&5
+echo $ECHO_N "checking if realloc can deal with NULL... $ECHO_C" >&6; }
+if test "${rd_cv_null_realloc+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test "$cross_compiling" = yes; then
+  :
+else
+  cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdlib.h>
+             int main(void){
+              char *x = NULL;
+             x = realloc (x,10);
+             if (x==NULL) return 1;
+             return 0;
+             }
+_ACEOF
+rm -f conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
+  { (case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_try") 2>&5
+  ac_status=$?
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); }; }; then
+  rd_cv_null_realloc=yes
+else
+  echo "$as_me: program exited with status $ac_status" >&5
+echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+( exit $ac_status )
+rd_cv_null_realloc=nope
+fi
+rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+fi
+
+
+fi
+{ echo "$as_me:$LINENO: result: $rd_cv_null_realloc" >&5
+echo "${ECHO_T}$rd_cv_null_realloc" >&6; }
+
+if test x"$rd_cv_null_realloc" = xnope; then
+cat >>confdefs.h <<\_ACEOF
+#define NO_NULL_REALLOC 1
+_ACEOF
+
+fi
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+{ echo "$as_me:$LINENO: checking if ctime_r need special care to act posixly correct" >&5
+echo $ECHO_N "checking if ctime_r need special care to act posixly correct... $ECHO_C" >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <time.h>
+int
+main ()
+{
+ctime_r(NULL,NULL,0)
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
 if { (ac_try="$ac_link"
 case "(($ac_try" in
   *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
   *) ac_try_echo=$ac_try;;
 esac
 eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_link") 2>&5
+  (eval "$ac_link") 2>conftest.er1
   ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
-  { (case "(($ac_try" in
+  (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
+   CPPFLAGS="$CPPFLAGS -D_POSIX_PTHREAD_SEMANTICS"
+      cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <time.h>
+int
+main ()
+{
+ctime_r(NULL,NULL)
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
   *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
   *) ac_try_echo=$ac_try;;
 esac
 eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
+  (eval "$ac_link") 2>conftest.er1
   ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  rd_cv_ieee_ieeenaninfswitch=yes
+  (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
+  { echo "$as_me:$LINENO: result: yes, this seems to be solaris style" >&5
+echo "${ECHO_T}yes, this seems to be solaris style" >&6; }
 else
-  echo "$as_me: program exited with status $ac_status" >&5
-echo "$as_me: failed program was:" >&5
+  echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-( exit $ac_status )
-rd_cv_ieee_ieeenaninfswitch=no
-fi
-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
-fi
-
+       { { echo "$as_me:$LINENO: error: Can't figure how to compile ctime_r" >&5
+echo "$as_me: error: Can't figure how to compile ctime_r" >&2;}
+   { (exit 1); exit 1; }; }
 
 fi
 
-if test x${rd_cv_ieee_ieeenaninfswitch} = "xyes"; then
- { echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6; }
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
 
 else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
- CFLAGS="$_cflags -OPT:IEEE_comparisons=ON"
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
 
-{ echo "$as_me:$LINENO: checking if IEEE math works with the -OPT:IEEE_comparisons=ON switch" >&5
-echo $ECHO_N "checking if IEEE math works with the -OPT:IEEE_comparisons=ON switch... $ECHO_C" >&6; }
-if test "${rd_cv_ieee_ieeecmpswitch+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  if test "$cross_compiling" = yes; then
-  :
-else
-  cat >conftest.$ac_ext <<_ACEOF
+        cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
 cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
+#include <time.h>
+int
+main ()
+{
+ctime_r(NULL,NULL)
 
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
 
-#if HAVE_MATH_H
-#  include <math.h>
-#endif
+       { { echo "$as_me:$LINENO: error: Can't figure how to compile ctime_r" >&5
+echo "$as_me: error: Can't figure how to compile ctime_r" >&2;}
+   { (exit 1); exit 1; }; }
 
-#if HAVE_FLOAT_H
-#  include <float.h>
-#endif
+fi
 
-#if HAVE_IEEEFP_H
-#  include <ieeefp.h>
-#endif
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
 
-#if HAVE_FP_CLASS_H
-#  include <fp_class.h>
-#endif
 
-/* Solaris */
-#if (! defined(HAVE_ISINF) && defined(HAVE_FPCLASS))
-#  define HAVE_ISINF 1
-#  define isinf(a) (fpclass(a) == FP_NINF || fpclass(a) == FP_PINF)
-#endif
+fi
 
-/* solaris 10 it defines isnan such that only forte can compile it ... bad bad  */
-#if (defined(HAVE_ISNAN) && defined(isnan) && defined(HAVE_FPCLASS))
-#  undef isnan
-#  define isnan(a) (fpclass(a) == FP_SNAN || fpclass(a) == FP_QNAN)
-#endif
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
-/* Digital UNIX */
-#if (! defined(HAVE_ISINF) && defined(HAVE_FP_CLASS) && defined(HAVE_FP_CLASS_H))
-#  define HAVE_ISINF 1
-#  define isinf(a) (fp_class(a) == FP_NEG_INF || fp_class(a) == FP_POS_INF)
-#endif
 
-/* AIX */
-#if (! defined(HAVE_ISINF) && defined(HAVE_CLASS))
-#  define HAVE_ISINF 1
-#  define isinf(a) (class(a) == FP_MINUS_INF || class(a) == FP_PLUS_INF)
-#endif
 
-#if (! defined(HAVE_ISINF) && defined(HAVE_FPCLASSIFY) && defined(FP_PLUS_INF) && defined(FP_MINUS_INF))
-#  define HAVE_ISINF 1
-#  define isinf(a) (fpclassify(a) == FP_MINUS_INF || fpclassify(a) == FP_PLUS_INF)
-#endif
 
-#if (! defined(HAVE_ISINF) && defined(HAVE_FPCLASSIFY) && defined(FP_INFINITE))
-#  define HAVE_ISINF 1
-#  define isinf(a) (fpclassify(a) == FP_INFINITE)
-#endif
 
-#include <stdio.h>
-int main(void){
-    double rrdnan,rrdinf,rrdc,rrdzero;
-    ;
-    /* some math to see if we get a floating point exception */
-    rrdzero=sin(0.0); /* don't let the compiler optimize us away */
-    rrdnan=0.0/rrdzero; /* especially here */
-    rrdinf=1.0/rrdzero; /* and here. I want to know if it can do the magic */
-                 /* at run time without sig fpe */
-    rrdc = rrdinf + rrdnan;
-    rrdc = rrdinf / rrdnan;
-    if (! isnan(rrdnan)) {printf ("not isnan(NaN) ... "); return 1;}
-    if (rrdnan == rrdnan) {printf ("nan == nan ... "); return 1;}
-    if (! isinf(rrdinf)) {printf ("not isinf(oo) ... "); return 1;}
-    if (! isinf(-rrdinf)) {printf ("not isinf(-oo) ... "); return 1;}
-    if (! rrdinf > 0) {printf ("not inf > 0 ... "); return 1;}
-    if (! -rrdinf < 0) {printf ("not -inf < 0 ... "); return 1;}
-    return 0;
- }
+
+if test $enable_pthread != no; then
+
+
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+acx_pthread_ok=no
+
+# We used to check for pthread.h first, but this fails if pthread.h
+# requires special compiler flags (e.g. on True64 or Sequent).
+# It gets checked for in the link test anyway.
+
+# First of all, check if the user has set any of the PTHREAD_LIBS,
+# etcetera environment variables, and if threads linking works using
+# them:
+if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then
+        save_CFLAGS="$CFLAGS"
+        CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+        save_LIBS="$LIBS"
+        LIBS="$PTHREAD_LIBS $LIBS"
+        { echo "$as_me:$LINENO: checking for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS" >&5
+echo $ECHO_N "checking for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS... $ECHO_C" >&6; }
+        cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
 _ACEOF
-rm -f conftest$ac_exeext
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char pthread_join ();
+int
+main ()
+{
+return pthread_join ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
 if { (ac_try="$ac_link"
 case "(($ac_try" in
   *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
   *) ac_try_echo=$ac_try;;
 esac
 eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_link") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
+  (eval "$ac_link") 2>conftest.er1
   ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  rd_cv_ieee_ieeecmpswitch=yes
+  (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
+  acx_pthread_ok=yes
 else
-  echo "$as_me: program exited with status $ac_status" >&5
-echo "$as_me: failed program was:" >&5
+  echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-( exit $ac_status )
-rd_cv_ieee_ieeecmpswitch=no
+
 fi
-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+        { echo "$as_me:$LINENO: result: $acx_pthread_ok" >&5
+echo "${ECHO_T}$acx_pthread_ok" >&6; }
+        if test x"$acx_pthread_ok" = xno; then
+                PTHREAD_LIBS=""
+                PTHREAD_CFLAGS=""
+        fi
+        LIBS="$save_LIBS"
+        CFLAGS="$save_CFLAGS"
 fi
 
+# We must check for the threads library under a number of different
+# names; the ordering is very important because some systems
+# (e.g. DEC) have both -lpthread and -lpthreads, where one of the
+# libraries is broken (non-POSIX).
 
-fi
+# Create a list of thread flags to try.  Items starting with a "-" are
+# C compiler flags, and other items are library names, except for "none"
+# which indicates that we try without any flags at all, and "pthread-config"
+# which is a program returning the flags for the Pth emulation library.
 
-if test x${rd_cv_ieee_ieeecmpswitch} = "xyes"; then
- { echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6; }
+acx_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config"
 
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
- CFLAGS=$_cflags
+# The ordering *is* (sometimes) important.  Some notes on the
+# individual items follow:
 
-{ echo "$as_me:$LINENO: checking if IEEE math works with fpsetmask(0)" >&5
-echo $ECHO_N "checking if IEEE math works with fpsetmask(0)... $ECHO_C" >&6; }
-if test "${rd_cv_ieee_mask+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  if test "$cross_compiling" = yes; then
-  :
-else
-  cat >conftest.$ac_ext <<_ACEOF
-/* confdefs.h.  */
-_ACEOF
-cat confdefs.h >>conftest.$ac_ext
-cat >>conftest.$ac_ext <<_ACEOF
-/* end confdefs.h.  */
-#include <floatingpoint.h>
+# pthreads: AIX (must check this before -lpthread)
+# none: in case threads are in libc; should be tried before -Kthread and
+#       other compiler flags to prevent continual compiler warnings
+# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h)
+# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able)
+# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread)
+# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads)
+# -pthreads: Solaris/gcc
+# -mthreads: Mingw32/gcc, Lynx/gcc
+# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it
+#      doesn't hurt to check since this sometimes defines pthreads too;
+#      also defines -D_REENTRANT)
+# pthread: Linux, etcetera
+# --thread-safe: KAI C++
+# pthread-config: use pthread-config program (for GNU Pth library)
 
-#if HAVE_MATH_H
-#  include <math.h>
-#endif
+case "${host_cpu}-${host_os}" in
+        *solaris*)
 
-#if HAVE_FLOAT_H
-#  include <float.h>
-#endif
+        # On Solaris (at least, for some versions), libc contains stubbed
+        # (non-functional) versions of the pthreads routines, so link-based
+        # tests will erroneously succeed.  (We need to link with -pthread or
+        # -lpthread.)  (The stubs are missing pthread_cleanup_push, or rather
+        # a function called by this macro, so we could check for that, but
+        # who knows whether they'll stub that too in a future libc.)  So,
+        # we'll just look for -pthreads and -lpthread first:
 
-#if HAVE_IEEEFP_H
-#  include <ieeefp.h>
-#endif
+        acx_pthread_flags="-pthread -pthreads pthread -mt $acx_pthread_flags"
+        ;;
+esac
 
-#if HAVE_FP_CLASS_H
-#  include <fp_class.h>
-#endif
+if test x"$acx_pthread_ok" = xno; then
+for flag in $acx_pthread_flags; do
 
-/* Solaris */
-#if (! defined(HAVE_ISINF) && defined(HAVE_FPCLASS))
-#  define HAVE_ISINF 1
-#  define isinf(a) (fpclass(a) == FP_NINF || fpclass(a) == FP_PINF)
-#endif
+        case $flag in
+                none)
+                { echo "$as_me:$LINENO: checking whether pthreads work without any flags" >&5
+echo $ECHO_N "checking whether pthreads work without any flags... $ECHO_C" >&6; }
+                ;;
 
-/* solaris 10 it defines isnan such that only forte can compile it ... bad bad  */
-#if (defined(HAVE_ISNAN) && defined(isnan) && defined(HAVE_FPCLASS))
-#  undef isnan
-#  define isnan(a) (fpclass(a) == FP_SNAN || fpclass(a) == FP_QNAN)
-#endif
+                -*)
+                { echo "$as_me:$LINENO: checking whether pthreads work with $flag" >&5
+echo $ECHO_N "checking whether pthreads work with $flag... $ECHO_C" >&6; }
+                PTHREAD_CFLAGS="$flag"
+                ;;
 
-/* Digital UNIX */
-#if (! defined(HAVE_ISINF) && defined(HAVE_FP_CLASS) && defined(HAVE_FP_CLASS_H))
-#  define HAVE_ISINF 1
-#  define isinf(a) (fp_class(a) == FP_NEG_INF || fp_class(a) == FP_POS_INF)
-#endif
+               pthread-config)
+               # Extract the first word of "pthread-config", so it can be a program name with args.
+set dummy pthread-config; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_prog_acx_pthread_config+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$acx_pthread_config"; then
+  ac_cv_prog_acx_pthread_config="$acx_pthread_config" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_acx_pthread_config="yes"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+IFS=$as_save_IFS
 
-/* AIX */
-#if (! defined(HAVE_ISINF) && defined(HAVE_CLASS))
-#  define HAVE_ISINF 1
-#  define isinf(a) (class(a) == FP_MINUS_INF || class(a) == FP_PLUS_INF)
-#endif
+  test -z "$ac_cv_prog_acx_pthread_config" && ac_cv_prog_acx_pthread_config="no"
+fi
+fi
+acx_pthread_config=$ac_cv_prog_acx_pthread_config
+if test -n "$acx_pthread_config"; then
+  { echo "$as_me:$LINENO: result: $acx_pthread_config" >&5
+echo "${ECHO_T}$acx_pthread_config" >&6; }
+else
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
 
-#if (! defined(HAVE_ISINF) && defined(HAVE_FPCLASSIFY) && defined(FP_PLUS_INF) && defined(FP_MINUS_INF))
-#  define HAVE_ISINF 1
-#  define isinf(a) (fpclassify(a) == FP_MINUS_INF || fpclassify(a) == FP_PLUS_INF)
-#endif
 
-#if (! defined(HAVE_ISINF) && defined(HAVE_FPCLASSIFY) && defined(FP_INFINITE))
-#  define HAVE_ISINF 1
-#  define isinf(a) (fpclassify(a) == FP_INFINITE)
-#endif
+               if test x"$acx_pthread_config" = xno; then continue; fi
+               PTHREAD_CFLAGS="`pthread-config --cflags`"
+               PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`"
+               ;;
 
-#include <stdio.h>
-int main(void){
-    double rrdnan,rrdinf,rrdc,rrdzero;
-    fpsetmask(0);
-    /* some math to see if we get a floating point exception */
-    rrdzero=sin(0.0); /* don't let the compiler optimize us away */
-    rrdnan=0.0/rrdzero; /* especially here */
-    rrdinf=1.0/rrdzero; /* and here. I want to know if it can do the magic */
-                 /* at run time without sig fpe */
-    rrdc = rrdinf + rrdnan;
-    rrdc = rrdinf / rrdnan;
-    if (! isnan(rrdnan)) {printf ("not isnan(NaN) ... "); return 1;}
-    if (rrdnan == rrdnan) {printf ("nan == nan ... "); return 1;}
-    if (! isinf(rrdinf)) {printf ("not isinf(oo) ... "); return 1;}
-    if (! isinf(-rrdinf)) {printf ("not isinf(-oo) ... "); return 1;}
-    if (! rrdinf > 0) {printf ("not inf > 0 ... "); return 1;}
-    if (! -rrdinf < 0) {printf ("not -inf < 0 ... "); return 1;}
-    return 0;
- }
+                *)
+                { echo "$as_me:$LINENO: checking for the pthreads library -l$flag" >&5
+echo $ECHO_N "checking for the pthreads library -l$flag... $ECHO_C" >&6; }
+                PTHREAD_LIBS="-l$flag"
+                ;;
+        esac
+
+        save_LIBS="$LIBS"
+        save_CFLAGS="$CFLAGS"
+        LIBS="$PTHREAD_LIBS $LIBS"
+        CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+
+        # Check for various functions.  We must include pthread.h,
+        # since some functions may be macros.  (On the Sequent, we
+        # need a special flag -Kthread to make this header compile.)
+        # We check for pthread_join because it is in -lpthread on IRIX
+        # while pthread_create is in libc.  We check for pthread_attr_init
+        # due to DEC craziness with -lpthreads.  We check for
+        # pthread_cleanup_push because it is one of the few pthread
+        # functions on Solaris that doesn't have a non-functional libc stub.
+        # We try pthread_create on general principles.
+        cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
 _ACEOF
-rm -f conftest$ac_exeext
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <pthread.h>
+int
+main ()
+{
+pthread_t th; pthread_join(th, 0);
+                     pthread_attr_init(0); pthread_cleanup_push(0, 0);
+                     pthread_create(0,0,0,0); pthread_cleanup_pop(0);
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
 if { (ac_try="$ac_link"
 case "(($ac_try" in
   *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
   *) ac_try_echo=$ac_try;;
 esac
 eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_link") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
+  (eval "$ac_link") 2>conftest.er1
   ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  rd_cv_ieee_mask=yes
+  (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
+  acx_pthread_ok=yes
 else
-  echo "$as_me: program exited with status $ac_status" >&5
-echo "$as_me: failed program was:" >&5
+  echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-( exit $ac_status )
-rd_cv_ieee_mask=no
-fi
-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+
 fi
 
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
 
-fi
+        LIBS="$save_LIBS"
+        CFLAGS="$save_CFLAGS"
 
-if test x${rd_cv_ieee_mask} = "xyes"; then
- { echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6; }
- cat >>confdefs.h <<\_ACEOF
-#define MUST_DISABLE_FPMASK 1
-_ACEOF
+        { echo "$as_me:$LINENO: result: $acx_pthread_ok" >&5
+echo "${ECHO_T}$acx_pthread_ok" >&6; }
+        if test "x$acx_pthread_ok" = xyes; then
+                break;
+        fi
 
-                PERLFLAGS="CCFLAGS=-DMUST_DISABLE_FPMASK"
-else
- { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
+        PTHREAD_LIBS=""
+        PTHREAD_CFLAGS=""
+done
+fi
 
-{ echo "$as_me:$LINENO: checking if IEEE math works with signal(SIGFPE,SIG_IGN)" >&5
-echo $ECHO_N "checking if IEEE math works with signal(SIGFPE,SIG_IGN)... $ECHO_C" >&6; }
-if test "${rd_cv_ieee_sigfpe+set}" = set; then
-  echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  if test "$cross_compiling" = yes; then
-  :
-else
-  cat >conftest.$ac_ext <<_ACEOF
+# Various other checks:
+if test "x$acx_pthread_ok" = xyes; then
+        save_LIBS="$LIBS"
+        LIBS="$PTHREAD_LIBS $LIBS"
+        save_CFLAGS="$CFLAGS"
+        CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+
+        # Detect AIX lossage: JOINABLE attribute is called UNDETACHED.
+       { echo "$as_me:$LINENO: checking for joinable pthread attribute" >&5
+echo $ECHO_N "checking for joinable pthread attribute... $ECHO_C" >&6; }
+       attr_name=unknown
+       for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do
+           cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
 cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
-#include <signal.h>
-
-#if HAVE_MATH_H
-#  include <math.h>
-#endif
-
-#if HAVE_FLOAT_H
-#  include <float.h>
-#endif
-
-#if HAVE_IEEEFP_H
-#  include <ieeefp.h>
-#endif
-
-#if HAVE_FP_CLASS_H
-#  include <fp_class.h>
-#endif
-
-/* Solaris */
-#if (! defined(HAVE_ISINF) && defined(HAVE_FPCLASS))
-#  define HAVE_ISINF 1
-#  define isinf(a) (fpclass(a) == FP_NINF || fpclass(a) == FP_PINF)
-#endif
-
-/* solaris 10 it defines isnan such that only forte can compile it ... bad bad  */
-#if (defined(HAVE_ISNAN) && defined(isnan) && defined(HAVE_FPCLASS))
-#  undef isnan
-#  define isnan(a) (fpclass(a) == FP_SNAN || fpclass(a) == FP_QNAN)
-#endif
-
-/* Digital UNIX */
-#if (! defined(HAVE_ISINF) && defined(HAVE_FP_CLASS) && defined(HAVE_FP_CLASS_H))
-#  define HAVE_ISINF 1
-#  define isinf(a) (fp_class(a) == FP_NEG_INF || fp_class(a) == FP_POS_INF)
-#endif
-
-/* AIX */
-#if (! defined(HAVE_ISINF) && defined(HAVE_CLASS))
-#  define HAVE_ISINF 1
-#  define isinf(a) (class(a) == FP_MINUS_INF || class(a) == FP_PLUS_INF)
-#endif
-
-#if (! defined(HAVE_ISINF) && defined(HAVE_FPCLASSIFY) && defined(FP_PLUS_INF) && defined(FP_MINUS_INF))
-#  define HAVE_ISINF 1
-#  define isinf(a) (fpclassify(a) == FP_MINUS_INF || fpclassify(a) == FP_PLUS_INF)
-#endif
-
-#if (! defined(HAVE_ISINF) && defined(HAVE_FPCLASSIFY) && defined(FP_INFINITE))
-#  define HAVE_ISINF 1
-#  define isinf(a) (fpclassify(a) == FP_INFINITE)
-#endif
-
-#include <stdio.h>
-int main(void){
-    double rrdnan,rrdinf,rrdc,rrdzero;
-    signal(SIGFPE,SIG_IGN);
-    /* some math to see if we get a floating point exception */
-    rrdzero=sin(0.0); /* don't let the compiler optimize us away */
-    rrdnan=0.0/rrdzero; /* especially here */
-    rrdinf=1.0/rrdzero; /* and here. I want to know if it can do the magic */
-                 /* at run time without sig fpe */
-    rrdc = rrdinf + rrdnan;
-    rrdc = rrdinf / rrdnan;
-    if (! isnan(rrdnan)) {printf ("not isnan(NaN) ... "); return 1;}
-    if (rrdnan == rrdnan) {printf ("nan == nan ... "); return 1;}
-    if (! isinf(rrdinf)) {printf ("not isinf(oo) ... "); return 1;}
-    if (! isinf(-rrdinf)) {printf ("not isinf(-oo) ... "); return 1;}
-    if (! rrdinf > 0) {printf ("not inf > 0 ... "); return 1;}
-    if (! -rrdinf < 0) {printf ("not -inf < 0 ... "); return 1;}
-    return 0;
- }
+#include <pthread.h>
+int
+main ()
+{
+int attr=$attr;
+  ;
+  return 0;
+}
 _ACEOF
-rm -f conftest$ac_exeext
+rm -f conftest.$ac_objext conftest$ac_exeext
 if { (ac_try="$ac_link"
 case "(($ac_try" in
   *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
   *) ac_try_echo=$ac_try;;
 esac
 eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_link") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
+  (eval "$ac_link") 2>conftest.er1
   ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  rd_cv_ieee_sigfpe=yes
+  (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
+  attr_name=$attr; break
 else
-  echo "$as_me: program exited with status $ac_status" >&5
-echo "$as_me: failed program was:" >&5
+  echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-( exit $ac_status )
-rd_cv_ieee_sigfpe=no
-fi
-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
-fi
-
 
 fi
 
-if test x${rd_cv_ieee_sigfpe} = "xyes"; then
- { echo "$as_me:$LINENO: result: yes" >&5
-echo "${ECHO_T}yes" >&6; }
- cat >>confdefs.h <<\_ACEOF
-#define MUST_DISABLE_SIGFPE 1
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+       done
+        { echo "$as_me:$LINENO: result: $attr_name" >&5
+echo "${ECHO_T}$attr_name" >&6; }
+        if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then
+
+cat >>confdefs.h <<_ACEOF
+#define PTHREAD_CREATE_JOINABLE $attr_name
 _ACEOF
 
-                   PERLFLAGS="CCFLAGS=-DMUST_DISABLE_SIGFPE"
+        fi
+
+        { echo "$as_me:$LINENO: checking if more special flags are required for pthreads" >&5
+echo $ECHO_N "checking if more special flags are required for pthreads... $ECHO_C" >&6; }
+        x_rflag=no
+        case "${host_cpu}-${host_os}" in
+            *-aix* | *-freebsd* | *-darwin*) x_rflag="-D_THREAD_SAFE";;
+            *solaris* | *-osf* | *-hpux*) x_rflag="-D_REENTRANT";;
+            *-linux*)
+            if test x"$PTHREAD_CFLAGS" = "x-pthread"; then
+                # For Linux/gcc "-pthread" implies "-lpthread". We need, however, to make this explicit
+                # in PTHREAD_LIBS such that a shared library to be built properly depends on libpthread.
+                PTHREAD_LIBS="-lpthread $PTHREAD_LIBS"
+            fi;;
+        esac
+        { echo "$as_me:$LINENO: result: ${x_rflag}" >&5
+echo "${ECHO_T}${x_rflag}" >&6; }
+        if test "x$x_rflag" != xno; then
+            PTHREAD_CFLAGS="$x_rflag $PTHREAD_CFLAGS"
+        fi
+
+        LIBS="$save_LIBS"
+        CFLAGS="$save_CFLAGS"
+
+        # More AIX lossage: must compile with cc_r
+        # Extract the first word of "cc_r", so it can be a program name with args.
+set dummy cc_r; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_prog_PTHREAD_CC+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
 else
- { echo "$as_me:$LINENO: result: no" >&5
+  if test -n "$PTHREAD_CC"; then
+  ac_cv_prog_PTHREAD_CC="$PTHREAD_CC" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_PTHREAD_CC="cc_r"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+IFS=$as_save_IFS
+
+  test -z "$ac_cv_prog_PTHREAD_CC" && ac_cv_prog_PTHREAD_CC="${CC}"
+fi
+fi
+PTHREAD_CC=$ac_cv_prog_PTHREAD_CC
+if test -n "$PTHREAD_CC"; then
+  { echo "$as_me:$LINENO: result: $PTHREAD_CC" >&5
+echo "${ECHO_T}$PTHREAD_CC" >&6; }
+else
+  { echo "$as_me:$LINENO: result: no" >&5
 echo "${ECHO_T}no" >&6; }
- { { echo "$as_me:$LINENO: error:
-Your Compiler does not do propper IEEE math ... Please find out how to
-make IEEE math work with your compiler and let me know (tobi@oetiker.ch).
-Check config.log to see what went wrong ...
-" >&5
-echo "$as_me: error:
-Your Compiler does not do propper IEEE math ... Please find out how to
-make IEEE math work with your compiler and let me know (tobi@oetiker.ch).
-Check config.log to see what went wrong ...
-" >&2;}
-   { (exit 1); exit 1; }; }
 fi
 
 
-fi
+else
+        PTHREAD_CC="$CC"
+fi
+
+
 
 
-fi
 
+# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:
+if test x"$acx_pthread_ok" = xyes; then
 
-fi
+    MULTITHREAD_CFLAGS=$PTHREAD_CFLAGS
+    MULTITHREAD_LDFLAGS=$PTHREAD_LIBS
 
+        :
+else
+        acx_pthread_ok=no
 
 fi
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
 
 fi
 
 
+if test  "x$x_rflag" != "xno"; then
+   CPPFLAGS="$CPPFLAGS $x_rflag"
 fi
 
 
+
+if test $enable_pthread != no; then
+  BUILD_MULTITHREAD_TRUE=
+  BUILD_MULTITHREAD_FALSE='#'
+else
+  BUILD_MULTITHREAD_TRUE='#'
+  BUILD_MULTITHREAD_FALSE=
 fi
 
 
-fi
+ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+{ echo "$as_me:$LINENO: checking do we need malloc/malloc.h" >&5
+echo $ECHO_N "checking do we need malloc/malloc.h... $ECHO_C" >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdlib.h>
+int
+main ()
+{
+malloc(1)
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
+   { echo "$as_me:$LINENO: result: nope, works out of the box" >&5
+echo "${ECHO_T}nope, works out of the box" >&6; }
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+        cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <stdlib.h>
+                  #include <malloc/malloc.h>
+int
+main ()
+{
+malloc(1)
+
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
+  cat >>confdefs.h <<\_ACEOF
+#define NEED_MALLOC_MALLOC_H 1
+_ACEOF
 
+           { echo "$as_me:$LINENO: result: yes we do" >&5
+echo "${ECHO_T}yes we do" >&6; }
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       { { echo "$as_me:$LINENO: error: Can not figure how to compile malloc" >&5
+echo "$as_me: error: Can not figure how to compile malloc" >&2;}
+   { (exit 1); exit 1; }; }
 
 fi
 
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+
 
+fi
 
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
 ac_ext=c
 ac_cpp='$CPP $CPPFLAGS'
 ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
@@ -24826,8 +27780,6 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
 
 
-
-
 case $TERM in
        #   for the most important terminal types we directly know the sequences
        xterm|xterm*|vt220|vt220*)
@@ -24845,97 +27797,310 @@ case $TERM in
 esac
   { echo "$as_me:$LINENO: result: " >&5
 echo "${ECHO_T}" >&6; }
-  { echo "$as_me:$LINENO: result: ${T_MD}Resolve Portability Issues${T_ME}" >&5
-echo "${ECHO_T}${T_MD}Resolve Portability Issues${T_ME}" >&6; }
+  { echo "$as_me:$LINENO: result: ${T_MD}Find 3rd-Party Libraries${T_ME}" >&5
+echo "${ECHO_T}${T_MD}Find 3rd-Party Libraries${T_ME}" >&6; }
 
 
 
-{ echo "$as_me:$LINENO: checking if realloc can deal with NULL" >&5
-echo $ECHO_N "checking if realloc can deal with NULL... $ECHO_C" >&6; }
-if test "${rd_cv_null_realloc+set}" = set; then
+
+
+if test $enable_rrdcgi != no; then
+  BUILD_RRDCGI_TRUE=
+  BUILD_RRDCGI_FALSE='#'
+else
+  BUILD_RRDCGI_TRUE='#'
+  BUILD_RRDCGI_FALSE=
+fi
+
+
+
+CORE_LIBS="$LIBS"
+
+
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+ EX_CHECK_STATE=NO
+ ex_check_save_LIBS=${LIBS}
+ ex_check_save_CPPFLAGS=${CPPFLAGS}
+ ex_check_save_LDFLAGS=${LDFLAGS}
+ if test "x""" != "x"; then
+   CPPFLAGS="$CPPFLAGS -I"""
+ fi
+  { echo "$as_me:$LINENO: checking for cairo_font_options_create in -lcairo" >&5
+echo $ECHO_N "checking for cairo_font_options_create in -lcairo... $ECHO_C" >&6; }
+if test "${ac_cv_lib_cairo_cairo_font_options_create+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
-  if test "$cross_compiling" = yes; then
-  :
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lcairo  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char cairo_font_options_create ();
+int
+main ()
+{
+return cairo_font_options_create ();
+  ;
+  return 0;
+}
+_ACEOF
+rm -f conftest.$ac_objext conftest$ac_exeext
+if { (ac_try="$ac_link"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_link") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest$ac_exeext &&
+       $as_test_x conftest$ac_exeext; then
+  ac_cv_lib_cairo_cairo_font_options_create=yes
 else
-  cat >conftest.$ac_ext <<_ACEOF
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       ac_cv_lib_cairo_cairo_font_options_create=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_lib_cairo_cairo_font_options_create" >&5
+echo "${ECHO_T}$ac_cv_lib_cairo_cairo_font_options_create" >&6; }
+if test $ac_cv_lib_cairo_cairo_font_options_create = yes; then
+
+    if test "${ac_cv_header_cairo_h+set}" = set; then
+  { echo "$as_me:$LINENO: checking for cairo.h" >&5
+echo $ECHO_N "checking for cairo.h... $ECHO_C" >&6; }
+if test "${ac_cv_header_cairo_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_header_cairo_h" >&5
+echo "${ECHO_T}$ac_cv_header_cairo_h" >&6; }
+else
+  # Is the header compilable?
+{ echo "$as_me:$LINENO: checking cairo.h usability" >&5
+echo $ECHO_N "checking cairo.h usability... $ECHO_C" >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+$ac_includes_default
+#include <cairo.h>
+_ACEOF
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_compile") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } && {
+        test -z "$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       } && test -s conftest.$ac_objext; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       ac_header_compiler=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ echo "$as_me:$LINENO: checking cairo.h presence" >&5
+echo $ECHO_N "checking cairo.h presence... $ECHO_C" >&6; }
+cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
 cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
-#include <stdlib.h>
-             int main(void){
-              char *x = NULL;
-             x = realloc (x,10);
-             if (x==NULL) return 1;
-             return 0;
-             }
+#include <cairo.h>
 _ACEOF
-rm -f conftest$ac_exeext
-if { (ac_try="$ac_link"
+if { (ac_try="$ac_cpp conftest.$ac_ext"
 case "(($ac_try" in
   *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
   *) ac_try_echo=$ac_try;;
 esac
 eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_link") 2>&5
-  ac_status=$?
-  echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && { ac_try='./conftest$ac_exeext'
-  { (case "(($ac_try" in
-  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
-  *) ac_try_echo=$ac_try;;
-esac
-eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_try") 2>&5
+  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
   ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); }; }; then
-  rd_cv_null_realloc=yes
+  (exit $ac_status); } >/dev/null && {
+        test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       }; then
+  ac_header_preproc=yes
 else
-  echo "$as_me: program exited with status $ac_status" >&5
-echo "$as_me: failed program was:" >&5
+  echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-( exit $ac_status )
-rd_cv_null_realloc=nope
+  ac_header_preproc=no
 fi
-rm -f core *.core core.conftest.* gmon.out bb.out conftest$ac_exeext conftest.$ac_objext conftest.$ac_ext
+
+rm -f conftest.err conftest.$ac_ext
+{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6; }
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: cairo.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: cairo.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: cairo.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: cairo.h: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: cairo.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: cairo.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: cairo.h:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: cairo.h:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: cairo.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: cairo.h: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: cairo.h:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: cairo.h:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: cairo.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: cairo.h: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: cairo.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: cairo.h: in the future, the compiler will take precedence" >&2;}
+
+    ;;
+esac
+{ echo "$as_me:$LINENO: checking for cairo.h" >&5
+echo $ECHO_N "checking for cairo.h... $ECHO_C" >&6; }
+if test "${ac_cv_header_cairo_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_cairo_h=$ac_header_preproc
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_header_cairo_h" >&5
+echo "${ECHO_T}$ac_cv_header_cairo_h" >&6; }
+
+fi
+if test $ac_cv_header_cairo_h = yes; then
+  LIBS="-lcairo ${LIBS}";EX_CHECK_STATE=YES
 fi
 
 
 fi
-{ echo "$as_me:$LINENO: result: $rd_cv_null_realloc" >&5
-echo "${ECHO_T}$rd_cv_null_realloc" >&6; }
 
-if test x"$rd_cv_null_realloc" = xnope; then
-cat >>confdefs.h <<\_ACEOF
-#define NO_NULL_REALLOC 1
-_ACEOF
+ if test $EX_CHECK_STATE = NO; then
+        for ac_prog in pkg-config
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_prog_PKGCONFIG+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  if test -n "$PKGCONFIG"; then
+  ac_cv_prog_PKGCONFIG="$PKGCONFIG" # Let the user override the test.
+else
+as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_prog_PKGCONFIG="$ac_prog"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+IFS=$as_save_IFS
 
+fi
+fi
+PKGCONFIG=$ac_cv_prog_PKGCONFIG
+if test -n "$PKGCONFIG"; then
+  { echo "$as_me:$LINENO: result: $PKGCONFIG" >&5
+echo "${ECHO_T}$PKGCONFIG" >&6; }
+else
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
 fi
 
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
-{ echo "$as_me:$LINENO: checking if ctime_r need special care to act posixly correct" >&5
-echo $ECHO_N "checking if ctime_r need special care to act posixly correct... $ECHO_C" >&6; }
+  test -n "$PKGCONFIG" && break
+done
+test -n "$PKGCONFIG" || PKGCONFIG="no"
+
+    if test "$PKGCONFIG" != "no"; then
+          if $PKGCONFIG --exists cairo-png; then
+             CPPFLAGS=${CPPFLAGS}" "`$PKGCONFIG --cflags cairo-png`
+             LDFLAGS=${LDFLAGS}" "`$PKGCONFIG --libs-only-L cairo-png`
+             LDFLAGS=${LDFLAGS}" "`$PKGCONFIG --libs-only-other cairo-png`
+             LIBS=${LIBS}" "`$PKGCONFIG --libs-only-l cairo-png`
+                            unset ac_cv_lib_`echo cairo | sed 's/[^_a-zA-Z0-9]/_/g;s/^[0-9]/_/'`_cairo_font_options_create
+             { echo "$as_me:$LINENO: checking for cairo_font_options_create in -lcairo" >&5
+echo $ECHO_N "checking for cairo_font_options_create in -lcairo... $ECHO_C" >&6; }
+if test "${ac_cv_lib_cairo_cairo_font_options_create+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lcairo  $LIBS"
 cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
 cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
-#include <time.h>
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char cairo_font_options_create ();
 int
 main ()
 {
-ctime_r(NULL,NULL,0)
-
+return cairo_font_options_create ();
   ;
   return 0;
 }
@@ -24958,31 +28123,52 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
         test ! -s conftest.err
        } && test -s conftest$ac_exeext &&
        $as_test_x conftest$ac_exeext; then
-   CPPFLAGS="$CPPFLAGS -D_POSIX_PTHREAD_SEMANTICS"
-      cat >conftest.$ac_ext <<_ACEOF
+  ac_cv_lib_cairo_cairo_font_options_create=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       ac_cv_lib_cairo_cairo_font_options_create=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_lib_cairo_cairo_font_options_create" >&5
+echo "${ECHO_T}$ac_cv_lib_cairo_cairo_font_options_create" >&6; }
+if test $ac_cv_lib_cairo_cairo_font_options_create = yes; then
+
+                unset ac_cv_header_`echo cairo.h | sed 's/[^_a-zA-Z0-9]/_/g;s/^[0-9]/_/'`
+                if test "${ac_cv_header_cairo_h+set}" = set; then
+  { echo "$as_me:$LINENO: checking for cairo.h" >&5
+echo $ECHO_N "checking for cairo.h... $ECHO_C" >&6; }
+if test "${ac_cv_header_cairo_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_header_cairo_h" >&5
+echo "${ECHO_T}$ac_cv_header_cairo_h" >&6; }
+else
+  # Is the header compilable?
+{ echo "$as_me:$LINENO: checking cairo.h usability" >&5
+echo $ECHO_N "checking cairo.h usability... $ECHO_C" >&6; }
+cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
 cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
-#include <time.h>
-int
-main ()
-{
-ctime_r(NULL,NULL)
-
-  ;
-  return 0;
-}
+$ac_includes_default
+#include <cairo.h>
 _ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
 case "(($ac_try" in
   *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
   *) ac_try_echo=$ac_try;;
 esac
 eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_link") 2>conftest.er1
+  (eval "$ac_compile") 2>conftest.er1
   ac_status=$?
   grep -v '^ *+' conftest.er1 >conftest.err
   rm -f conftest.er1
@@ -24991,118 +28177,199 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
   (exit $ac_status); } && {
         test -z "$ac_c_werror_flag" ||
         test ! -s conftest.err
-       } && test -s conftest$ac_exeext &&
-       $as_test_x conftest$ac_exeext; then
-  { echo "$as_me:$LINENO: result: yes, this seems to be solaris style" >&5
-echo "${ECHO_T}yes, this seems to be solaris style" >&6; }
+       } && test -s conftest.$ac_objext; then
+  ac_header_compiler=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-       { { echo "$as_me:$LINENO: error: Can't figure how to compile ctime_r" >&5
-echo "$as_me: error: Can't figure how to compile ctime_r" >&2;}
-   { (exit 1); exit 1; }; }
-
+       ac_header_compiler=no
 fi
 
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
-      conftest$ac_exeext conftest.$ac_ext
-
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6; }
 
-        cat >conftest.$ac_ext <<_ACEOF
+# Is the header present?
+{ echo "$as_me:$LINENO: checking cairo.h presence" >&5
+echo $ECHO_N "checking cairo.h presence... $ECHO_C" >&6; }
+cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
 cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
-#include <time.h>
-int
-main ()
-{
-ctime_r(NULL,NULL)
-
-  ;
-  return 0;
-}
+#include <cairo.h>
 _ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
+if { (ac_try="$ac_cpp conftest.$ac_ext"
 case "(($ac_try" in
   *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
   *) ac_try_echo=$ac_try;;
 esac
 eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_link") 2>conftest.er1
+  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
   ac_status=$?
   grep -v '^ *+' conftest.er1 >conftest.err
   rm -f conftest.er1
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && {
-        test -z "$ac_c_werror_flag" ||
+  (exit $ac_status); } >/dev/null && {
+        test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
         test ! -s conftest.err
-       } && test -s conftest$ac_exeext &&
-       $as_test_x conftest$ac_exeext; then
-  { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
+       }; then
+  ac_header_preproc=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-       { { echo "$as_me:$LINENO: error: Can't figure how to compile ctime_r" >&5
-echo "$as_me: error: Can't figure how to compile ctime_r" >&2;}
-   { (exit 1); exit 1; }; }
+  ac_header_preproc=no
+fi
+
+rm -f conftest.err conftest.$ac_ext
+{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6; }
+
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: cairo.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: cairo.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: cairo.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: cairo.h: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: cairo.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: cairo.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: cairo.h:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: cairo.h:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: cairo.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: cairo.h: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: cairo.h:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: cairo.h:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: cairo.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: cairo.h: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: cairo.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: cairo.h: in the future, the compiler will take precedence" >&2;}
 
+    ;;
+esac
+{ echo "$as_me:$LINENO: checking for cairo.h" >&5
+echo $ECHO_N "checking for cairo.h... $ECHO_C" >&6; }
+if test "${ac_cv_header_cairo_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_cairo_h=$ac_header_preproc
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_header_cairo_h" >&5
+echo "${ECHO_T}$ac_cv_header_cairo_h" >&6; }
+
+fi
+if test $ac_cv_header_cairo_h = yes; then
+  EX_CHECK_STATE=YES
 fi
 
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
-      conftest$ac_exeext conftest.$ac_ext
 
 
-fi
+fi
+
+          else
+             { echo "$as_me:$LINENO: WARNING:
+----------------------------------------------------------------------------
+* I found a copy of pkgconfig, but there is no cairo-png.pc file around.
+  You may want to set the PKG_CONFIG_PATH variable to point to its
+  location.
+----------------------------------------------------------------------------
+                       " >&5
+echo "$as_me: WARNING:
+----------------------------------------------------------------------------
+* I found a copy of pkgconfig, but there is no cairo-png.pc file around.
+  You may want to set the PKG_CONFIG_PATH variable to point to its
+  location.
+----------------------------------------------------------------------------
+                       " >&2;}
+           fi
+     fi
+  fi
+
+  if test ${EX_CHECK_STATE} = NO; then
+     { echo "$as_me:$LINENO: WARNING:
+----------------------------------------------------------------------------
+* I could not find a working copy of cairo-png. Check config.log for hints on why
+  this is the case. Maybe you need to set LDFLAGS and CPPFLAGS appropriately
+  so that compiler and the linker can find libcairo and its header files. If
+  you have not installed cairo-png, you can get it either from its original home on
+
+     http://cairographics.org/releases/
+
+  You can find also find an archive copy on
+
+     http://oss.oetiker.ch/rrdtool/pub/libs
 
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
-      conftest$ac_exeext conftest.$ac_ext
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
+  The last tested version of cairo-png is 1.4.6.
 
+       LIBS=$LIBS
+   LDFLAGS=$LDFLAGS
+  CPPFLAGS=$CPPFLAGS
 
+----------------------------------------------------------------------------
+                " >&5
+echo "$as_me: WARNING:
+----------------------------------------------------------------------------
+* I could not find a working copy of cairo-png. Check config.log for hints on why
+  this is the case. Maybe you need to set LDFLAGS and CPPFLAGS appropriately
+  so that compiler and the linker can find libcairo and its header files. If
+  you have not installed cairo-png, you can get it either from its original home on
 
+     http://cairographics.org/releases/
 
+  You can find also find an archive copy on
 
+     http://oss.oetiker.ch/rrdtool/pub/libs
 
-if test $enable_pthread != no; then
+  The last tested version of cairo-png is 1.4.6.
 
+       LIBS=$LIBS
+   LDFLAGS=$LDFLAGS
+  CPPFLAGS=$CPPFLAGS
 
-ac_ext=c
+----------------------------------------------------------------------------
+                " >&2;}
+       EX_CHECK_ALL_ERR=YES
+       LIBS="${ex_check_save_LIBS}"
+       CPPFLAGS="${ex_check_save_CPPFLAGS}"
+       LDFLAGS="${ex_check_save_LDFLAGS}"
+    fi
+    ac_ext=c
 ac_cpp='$CPP $CPPFLAGS'
 ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
 ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
 ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
-acx_pthread_ok=no
 
-# We used to check for pthread.h first, but this fails if pthread.h
-# requires special compiler flags (e.g. on True64 or Sequent).
-# It gets checked for in the link test anyway.
 
-# First of all, check if the user has set any of the PTHREAD_LIBS,
-# etcetera environment variables, and if threads linking works using
-# them:
-if test x"$PTHREAD_LIBS$PTHREAD_CFLAGS" != x; then
-        save_CFLAGS="$CFLAGS"
-        CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
-        save_LIBS="$LIBS"
-        LIBS="$PTHREAD_LIBS $LIBS"
-        { echo "$as_me:$LINENO: checking for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS" >&5
-echo $ECHO_N "checking for pthread_join in LIBS=$PTHREAD_LIBS with CFLAGS=$PTHREAD_CFLAGS... $ECHO_C" >&6; }
-        cat >conftest.$ac_ext <<_ACEOF
+
+ ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
+
+ EX_CHECK_STATE=NO
+ ex_check_save_LIBS=${LIBS}
+ ex_check_save_CPPFLAGS=${CPPFLAGS}
+ ex_check_save_LDFLAGS=${LDFLAGS}
+ if test "x""" != "x"; then
+   CPPFLAGS="$CPPFLAGS -I"""
+ fi
+  { echo "$as_me:$LINENO: checking for cairo_svg_surface_create in -lcairo" >&5
+echo $ECHO_N "checking for cairo_svg_surface_create in -lcairo... $ECHO_C" >&6; }
+if test "${ac_cv_lib_cairo_cairo_svg_surface_create+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lcairo  $LIBS"
+cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
 cat confdefs.h >>conftest.$ac_ext
@@ -25115,11 +28382,11 @@ cat >>conftest.$ac_ext <<_ACEOF
 #ifdef __cplusplus
 extern "C"
 #endif
-char pthread_join ();
+char cairo_svg_surface_create ();
 int
 main ()
 {
-return pthread_join ();
+return cairo_svg_surface_create ();
   ;
   return 0;
 }
@@ -25142,177 +28409,51 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
         test ! -s conftest.err
        } && test -s conftest$ac_exeext &&
        $as_test_x conftest$ac_exeext; then
-  acx_pthread_ok=yes
+  ac_cv_lib_cairo_cairo_svg_surface_create=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-
+       ac_cv_lib_cairo_cairo_svg_surface_create=no
 fi
 
 rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
       conftest$ac_exeext conftest.$ac_ext
-        { echo "$as_me:$LINENO: result: $acx_pthread_ok" >&5
-echo "${ECHO_T}$acx_pthread_ok" >&6; }
-        if test x"$acx_pthread_ok" = xno; then
-                PTHREAD_LIBS=""
-                PTHREAD_CFLAGS=""
-        fi
-        LIBS="$save_LIBS"
-        CFLAGS="$save_CFLAGS"
+LIBS=$ac_check_lib_save_LIBS
 fi
+{ echo "$as_me:$LINENO: result: $ac_cv_lib_cairo_cairo_svg_surface_create" >&5
+echo "${ECHO_T}$ac_cv_lib_cairo_cairo_svg_surface_create" >&6; }
+if test $ac_cv_lib_cairo_cairo_svg_surface_create = yes; then
 
-# We must check for the threads library under a number of different
-# names; the ordering is very important because some systems
-# (e.g. DEC) have both -lpthread and -lpthreads, where one of the
-# libraries is broken (non-POSIX).
-
-# Create a list of thread flags to try.  Items starting with a "-" are
-# C compiler flags, and other items are library names, except for "none"
-# which indicates that we try without any flags at all, and "pthread-config"
-# which is a program returning the flags for the Pth emulation library.
-
-acx_pthread_flags="pthreads none -Kthread -kthread lthread -pthread -pthreads -mthreads pthread --thread-safe -mt pthread-config"
-
-# The ordering *is* (sometimes) important.  Some notes on the
-# individual items follow:
-
-# pthreads: AIX (must check this before -lpthread)
-# none: in case threads are in libc; should be tried before -Kthread and
-#       other compiler flags to prevent continual compiler warnings
-# -Kthread: Sequent (threads in libc, but -Kthread needed for pthread.h)
-# -kthread: FreeBSD kernel threads (preferred to -pthread since SMP-able)
-# lthread: LinuxThreads port on FreeBSD (also preferred to -pthread)
-# -pthread: Linux/gcc (kernel threads), BSD/gcc (userland threads)
-# -pthreads: Solaris/gcc
-# -mthreads: Mingw32/gcc, Lynx/gcc
-# -mt: Sun Workshop C (may only link SunOS threads [-lthread], but it
-#      doesn't hurt to check since this sometimes defines pthreads too;
-#      also defines -D_REENTRANT)
-# pthread: Linux, etcetera
-# --thread-safe: KAI C++
-# pthread-config: use pthread-config program (for GNU Pth library)
-
-case "${host_cpu}-${host_os}" in
-        *solaris*)
-
-        # On Solaris (at least, for some versions), libc contains stubbed
-        # (non-functional) versions of the pthreads routines, so link-based
-        # tests will erroneously succeed.  (We need to link with -pthread or
-        # -lpthread.)  (The stubs are missing pthread_cleanup_push, or rather
-        # a function called by this macro, so we could check for that, but
-        # who knows whether they'll stub that too in a future libc.)  So,
-        # we'll just look for -pthreads and -lpthread first:
-
-        acx_pthread_flags="-pthread -pthreads pthread -mt $acx_pthread_flags"
-        ;;
-esac
-
-if test x"$acx_pthread_ok" = xno; then
-for flag in $acx_pthread_flags; do
-
-        case $flag in
-                none)
-                { echo "$as_me:$LINENO: checking whether pthreads work without any flags" >&5
-echo $ECHO_N "checking whether pthreads work without any flags... $ECHO_C" >&6; }
-                ;;
-
-                -*)
-                { echo "$as_me:$LINENO: checking whether pthreads work with $flag" >&5
-echo $ECHO_N "checking whether pthreads work with $flag... $ECHO_C" >&6; }
-                PTHREAD_CFLAGS="$flag"
-                ;;
-
-               pthread-config)
-               # Extract the first word of "pthread-config", so it can be a program name with args.
-set dummy pthread-config; ac_word=$2
-{ echo "$as_me:$LINENO: checking for $ac_word" >&5
-echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_prog_acx_pthread_config+set}" = set; then
+    if test "${ac_cv_header_cairo_svg_h+set}" = set; then
+  { echo "$as_me:$LINENO: checking for cairo-svg.h" >&5
+echo $ECHO_N "checking for cairo-svg.h... $ECHO_C" >&6; }
+if test "${ac_cv_header_cairo_svg_h+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
-else
-  if test -n "$acx_pthread_config"; then
-  ac_cv_prog_acx_pthread_config="$acx_pthread_config" # Let the user override the test.
-else
-as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
-for as_dir in $PATH
-do
-  IFS=$as_save_IFS
-  test -z "$as_dir" && as_dir=.
-  for ac_exec_ext in '' $ac_executable_extensions; do
-  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
-    ac_cv_prog_acx_pthread_config="yes"
-    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
-    break 2
-  fi
-done
-done
-IFS=$as_save_IFS
-
-  test -z "$ac_cv_prog_acx_pthread_config" && ac_cv_prog_acx_pthread_config="no"
 fi
-fi
-acx_pthread_config=$ac_cv_prog_acx_pthread_config
-if test -n "$acx_pthread_config"; then
-  { echo "$as_me:$LINENO: result: $acx_pthread_config" >&5
-echo "${ECHO_T}$acx_pthread_config" >&6; }
+{ echo "$as_me:$LINENO: result: $ac_cv_header_cairo_svg_h" >&5
+echo "${ECHO_T}$ac_cv_header_cairo_svg_h" >&6; }
 else
-  { echo "$as_me:$LINENO: result: no" >&5
-echo "${ECHO_T}no" >&6; }
-fi
-
-
-               if test x"$acx_pthread_config" = xno; then continue; fi
-               PTHREAD_CFLAGS="`pthread-config --cflags`"
-               PTHREAD_LIBS="`pthread-config --ldflags` `pthread-config --libs`"
-               ;;
-
-                *)
-                { echo "$as_me:$LINENO: checking for the pthreads library -l$flag" >&5
-echo $ECHO_N "checking for the pthreads library -l$flag... $ECHO_C" >&6; }
-                PTHREAD_LIBS="-l$flag"
-                ;;
-        esac
-
-        save_LIBS="$LIBS"
-        save_CFLAGS="$CFLAGS"
-        LIBS="$PTHREAD_LIBS $LIBS"
-        CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
-
-        # Check for various functions.  We must include pthread.h,
-        # since some functions may be macros.  (On the Sequent, we
-        # need a special flag -Kthread to make this header compile.)
-        # We check for pthread_join because it is in -lpthread on IRIX
-        # while pthread_create is in libc.  We check for pthread_attr_init
-        # due to DEC craziness with -lpthreads.  We check for
-        # pthread_cleanup_push because it is one of the few pthread
-        # functions on Solaris that doesn't have a non-functional libc stub.
-        # We try pthread_create on general principles.
-        cat >conftest.$ac_ext <<_ACEOF
+  # Is the header compilable?
+{ echo "$as_me:$LINENO: checking cairo-svg.h usability" >&5
+echo $ECHO_N "checking cairo-svg.h usability... $ECHO_C" >&6; }
+cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
 cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
-#include <pthread.h>
-int
-main ()
-{
-pthread_t th; pthread_join(th, 0);
-                     pthread_attr_init(0); pthread_cleanup_push(0, 0);
-                     pthread_create(0,0,0,0); pthread_cleanup_pop(0);
-  ;
-  return 0;
-}
+$ac_includes_default
+#include <cairo-svg.h>
 _ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
 case "(($ac_try" in
   *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
   *) ac_try_echo=$ac_try;;
 esac
 eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_link") 2>conftest.er1
+  (eval "$ac_compile") 2>conftest.er1
   ac_status=$?
   grep -v '^ *+' conftest.er1 >conftest.err
   rm -f conftest.er1
@@ -25321,131 +28462,113 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
   (exit $ac_status); } && {
         test -z "$ac_c_werror_flag" ||
         test ! -s conftest.err
-       } && test -s conftest$ac_exeext &&
-       $as_test_x conftest$ac_exeext; then
-  acx_pthread_ok=yes
+       } && test -s conftest.$ac_objext; then
+  ac_header_compiler=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-
-fi
-
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
-      conftest$ac_exeext conftest.$ac_ext
-
-        LIBS="$save_LIBS"
-        CFLAGS="$save_CFLAGS"
-
-        { echo "$as_me:$LINENO: result: $acx_pthread_ok" >&5
-echo "${ECHO_T}$acx_pthread_ok" >&6; }
-        if test "x$acx_pthread_ok" = xyes; then
-                break;
-        fi
-
-        PTHREAD_LIBS=""
-        PTHREAD_CFLAGS=""
-done
+       ac_header_compiler=no
 fi
 
-# Various other checks:
-if test "x$acx_pthread_ok" = xyes; then
-        save_LIBS="$LIBS"
-        LIBS="$PTHREAD_LIBS $LIBS"
-        save_CFLAGS="$CFLAGS"
-        CFLAGS="$CFLAGS $PTHREAD_CFLAGS"
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6; }
 
-        # Detect AIX lossage: JOINABLE attribute is called UNDETACHED.
-       { echo "$as_me:$LINENO: checking for joinable pthread attribute" >&5
-echo $ECHO_N "checking for joinable pthread attribute... $ECHO_C" >&6; }
-       attr_name=unknown
-       for attr in PTHREAD_CREATE_JOINABLE PTHREAD_CREATE_UNDETACHED; do
-           cat >conftest.$ac_ext <<_ACEOF
+# Is the header present?
+{ echo "$as_me:$LINENO: checking cairo-svg.h presence" >&5
+echo $ECHO_N "checking cairo-svg.h presence... $ECHO_C" >&6; }
+cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
 cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
-#include <pthread.h>
-int
-main ()
-{
-int attr=$attr;
-  ;
-  return 0;
-}
+#include <cairo-svg.h>
 _ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
+if { (ac_try="$ac_cpp conftest.$ac_ext"
 case "(($ac_try" in
   *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
   *) ac_try_echo=$ac_try;;
 esac
 eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_link") 2>conftest.er1
+  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
   ac_status=$?
   grep -v '^ *+' conftest.er1 >conftest.err
   rm -f conftest.er1
   cat conftest.err >&5
   echo "$as_me:$LINENO: \$? = $ac_status" >&5
-  (exit $ac_status); } && {
-        test -z "$ac_c_werror_flag" ||
+  (exit $ac_status); } >/dev/null && {
+        test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
         test ! -s conftest.err
-       } && test -s conftest$ac_exeext &&
-       $as_test_x conftest$ac_exeext; then
-  attr_name=$attr; break
+       }; then
+  ac_header_preproc=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-
+  ac_header_preproc=no
 fi
 
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
-      conftest$ac_exeext conftest.$ac_ext
-       done
-        { echo "$as_me:$LINENO: result: $attr_name" >&5
-echo "${ECHO_T}$attr_name" >&6; }
-        if test "$attr_name" != PTHREAD_CREATE_JOINABLE; then
+rm -f conftest.err conftest.$ac_ext
+{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6; }
 
-cat >>confdefs.h <<_ACEOF
-#define PTHREAD_CREATE_JOINABLE $attr_name
-_ACEOF
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: cairo-svg.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: cairo-svg.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: cairo-svg.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: cairo-svg.h: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: cairo-svg.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: cairo-svg.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: cairo-svg.h:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: cairo-svg.h:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: cairo-svg.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: cairo-svg.h: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: cairo-svg.h:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: cairo-svg.h:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: cairo-svg.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: cairo-svg.h: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: cairo-svg.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: cairo-svg.h: in the future, the compiler will take precedence" >&2;}
 
-        fi
+    ;;
+esac
+{ echo "$as_me:$LINENO: checking for cairo-svg.h" >&5
+echo $ECHO_N "checking for cairo-svg.h... $ECHO_C" >&6; }
+if test "${ac_cv_header_cairo_svg_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_cairo_svg_h=$ac_header_preproc
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_header_cairo_svg_h" >&5
+echo "${ECHO_T}$ac_cv_header_cairo_svg_h" >&6; }
 
-        { echo "$as_me:$LINENO: checking if more special flags are required for pthreads" >&5
-echo $ECHO_N "checking if more special flags are required for pthreads... $ECHO_C" >&6; }
-        x_rflag=no
-        case "${host_cpu}-${host_os}" in
-            *-aix* | *-freebsd* | *-darwin*) x_rflag="-D_THREAD_SAFE";;
-            *solaris* | *-osf* | *-hpux*) x_rflag="-D_REENTRANT";;
-            *-linux*)
-            if test x"$PTHREAD_CFLAGS" = "x-pthread"; then
-                # For Linux/gcc "-pthread" implies "-lpthread". We need, however, to make this explicit
-                # in PTHREAD_LIBS such that a shared library to be built properly depends on libpthread.
-                PTHREAD_LIBS="-lpthread $PTHREAD_LIBS"
-            fi;;
-        esac
-        { echo "$as_me:$LINENO: result: ${x_rflag}" >&5
-echo "${ECHO_T}${x_rflag}" >&6; }
-        if test "x$x_rflag" != xno; then
-            PTHREAD_CFLAGS="$x_rflag $PTHREAD_CFLAGS"
-        fi
+fi
+if test $ac_cv_header_cairo_svg_h = yes; then
+  LIBS="-lcairo ${LIBS}";EX_CHECK_STATE=YES
+fi
 
-        LIBS="$save_LIBS"
-        CFLAGS="$save_CFLAGS"
 
-        # More AIX lossage: must compile with cc_r
-        # Extract the first word of "cc_r", so it can be a program name with args.
-set dummy cc_r; ac_word=$2
+fi
+
+ if test $EX_CHECK_STATE = NO; then
+        for ac_prog in pkg-config
+do
+  # Extract the first word of "$ac_prog", so it can be a program name with args.
+set dummy $ac_prog; ac_word=$2
 { echo "$as_me:$LINENO: checking for $ac_word" >&5
 echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
-if test "${ac_cv_prog_PTHREAD_CC+set}" = set; then
+if test "${ac_cv_prog_PKGCONFIG+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
-  if test -n "$PTHREAD_CC"; then
-  ac_cv_prog_PTHREAD_CC="$PTHREAD_CC" # Let the user override the test.
+  if test -n "$PKGCONFIG"; then
+  ac_cv_prog_PKGCONFIG="$PKGCONFIG" # Let the user override the test.
 else
 as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
 for as_dir in $PATH
@@ -25454,7 +28577,7 @@ do
   test -z "$as_dir" && as_dir=.
   for ac_exec_ext in '' $ac_executable_extensions; do
   if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
-    ac_cv_prog_PTHREAD_CC="cc_r"
+    ac_cv_prog_PKGCONFIG="$ac_prog"
     echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
     break 2
   fi
@@ -25462,83 +28585,54 @@ done
 done
 IFS=$as_save_IFS
 
-  test -z "$ac_cv_prog_PTHREAD_CC" && ac_cv_prog_PTHREAD_CC="${CC}"
 fi
 fi
-PTHREAD_CC=$ac_cv_prog_PTHREAD_CC
-if test -n "$PTHREAD_CC"; then
-  { echo "$as_me:$LINENO: result: $PTHREAD_CC" >&5
-echo "${ECHO_T}$PTHREAD_CC" >&6; }
+PKGCONFIG=$ac_cv_prog_PKGCONFIG
+if test -n "$PKGCONFIG"; then
+  { echo "$as_me:$LINENO: result: $PKGCONFIG" >&5
+echo "${ECHO_T}$PKGCONFIG" >&6; }
 else
   { echo "$as_me:$LINENO: result: no" >&5
 echo "${ECHO_T}no" >&6; }
 fi
 
 
-else
-        PTHREAD_CC="$CC"
-fi
-
-
-
-
-
-# Finally, execute ACTION-IF-FOUND/ACTION-IF-NOT-FOUND:
-if test x"$acx_pthread_ok" = xyes; then
-
-    MULTITHREAD_CFLAGS=$PTHREAD_CFLAGS
-    MULTITHREAD_LDFLAGS=$PTHREAD_LIBS
-
-        :
-else
-        acx_pthread_ok=no
-
-fi
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-
-fi
-
-
-if test  "x$x_rflag" != "xno"; then
-   CPPFLAGS="$CPPFLAGS $x_rflag"
-fi
-
-
+  test -n "$PKGCONFIG" && break
+done
+test -n "$PKGCONFIG" || PKGCONFIG="no"
 
-if test $enable_pthread != no; then
-  BUILD_MULTITHREAD_TRUE=
-  BUILD_MULTITHREAD_FALSE='#'
+    if test "$PKGCONFIG" != "no"; then
+          if $PKGCONFIG --exists cairo-svg; then
+             CPPFLAGS=${CPPFLAGS}" "`$PKGCONFIG --cflags cairo-svg`
+             LDFLAGS=${LDFLAGS}" "`$PKGCONFIG --libs-only-L cairo-svg`
+             LDFLAGS=${LDFLAGS}" "`$PKGCONFIG --libs-only-other cairo-svg`
+             LIBS=${LIBS}" "`$PKGCONFIG --libs-only-l cairo-svg`
+                            unset ac_cv_lib_`echo cairo | sed 's/[^_a-zA-Z0-9]/_/g;s/^[0-9]/_/'`_cairo_svg_surface_create
+             { echo "$as_me:$LINENO: checking for cairo_svg_surface_create in -lcairo" >&5
+echo $ECHO_N "checking for cairo_svg_surface_create in -lcairo... $ECHO_C" >&6; }
+if test "${ac_cv_lib_cairo_cairo_svg_surface_create+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
 else
-  BUILD_MULTITHREAD_TRUE='#'
-  BUILD_MULTITHREAD_FALSE=
-fi
-
-
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
-
-{ echo "$as_me:$LINENO: checking do we need malloc/malloc.h" >&5
-echo $ECHO_N "checking do we need malloc/malloc.h... $ECHO_C" >&6; }
+  ac_check_lib_save_LIBS=$LIBS
+LIBS="-lcairo  $LIBS"
 cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
 cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
-#include <stdlib.h>
+
+/* Override any GCC internal prototype to avoid an error.
+   Use char because int might match the return type of a GCC
+   builtin and then its argument prototype would still apply.  */
+#ifdef __cplusplus
+extern "C"
+#endif
+char cairo_svg_surface_create ();
 int
 main ()
 {
-malloc(1)
-
+return cairo_svg_surface_create ();
   ;
   return 0;
 }
@@ -25561,37 +28655,52 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
         test ! -s conftest.err
        } && test -s conftest$ac_exeext &&
        $as_test_x conftest$ac_exeext; then
-   { echo "$as_me:$LINENO: result: nope, works out of the box" >&5
-echo "${ECHO_T}nope, works out of the box" >&6; }
+  ac_cv_lib_cairo_cairo_svg_surface_create=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-        cat >conftest.$ac_ext <<_ACEOF
+       ac_cv_lib_cairo_cairo_svg_surface_create=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
+      conftest$ac_exeext conftest.$ac_ext
+LIBS=$ac_check_lib_save_LIBS
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_lib_cairo_cairo_svg_surface_create" >&5
+echo "${ECHO_T}$ac_cv_lib_cairo_cairo_svg_surface_create" >&6; }
+if test $ac_cv_lib_cairo_cairo_svg_surface_create = yes; then
+
+                unset ac_cv_header_`echo cairo-svg.h | sed 's/[^_a-zA-Z0-9]/_/g;s/^[0-9]/_/'`
+                if test "${ac_cv_header_cairo_svg_h+set}" = set; then
+  { echo "$as_me:$LINENO: checking for cairo-svg.h" >&5
+echo $ECHO_N "checking for cairo-svg.h... $ECHO_C" >&6; }
+if test "${ac_cv_header_cairo_svg_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_header_cairo_svg_h" >&5
+echo "${ECHO_T}$ac_cv_header_cairo_svg_h" >&6; }
+else
+  # Is the header compilable?
+{ echo "$as_me:$LINENO: checking cairo-svg.h usability" >&5
+echo $ECHO_N "checking cairo-svg.h usability... $ECHO_C" >&6; }
+cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
 cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
-#include <stdlib.h>
-                  #include <malloc/malloc.h>
-int
-main ()
-{
-malloc(1)
-
-  ;
-  return 0;
-}
+$ac_includes_default
+#include <cairo-svg.h>
 _ACEOF
-rm -f conftest.$ac_objext conftest$ac_exeext
-if { (ac_try="$ac_link"
+rm -f conftest.$ac_objext
+if { (ac_try="$ac_compile"
 case "(($ac_try" in
   *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
   *) ac_try_echo=$ac_try;;
 esac
 eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
-  (eval "$ac_link") 2>conftest.er1
+  (eval "$ac_compile") 2>conftest.er1
   ac_status=$?
   grep -v '^ *+' conftest.er1 >conftest.err
   rm -f conftest.er1
@@ -25600,74 +28709,176 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
   (exit $ac_status); } && {
         test -z "$ac_c_werror_flag" ||
         test ! -s conftest.err
-       } && test -s conftest$ac_exeext &&
-       $as_test_x conftest$ac_exeext; then
-  cat >>confdefs.h <<\_ACEOF
-#define NEED_MALLOC_MALLOC_H 1
+       } && test -s conftest.$ac_objext; then
+  ac_header_compiler=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+       ac_header_compiler=no
+fi
+
+rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
+{ echo "$as_me:$LINENO: result: $ac_header_compiler" >&5
+echo "${ECHO_T}$ac_header_compiler" >&6; }
+
+# Is the header present?
+{ echo "$as_me:$LINENO: checking cairo-svg.h presence" >&5
+echo $ECHO_N "checking cairo-svg.h presence... $ECHO_C" >&6; }
+cat >conftest.$ac_ext <<_ACEOF
+/* confdefs.h.  */
+_ACEOF
+cat confdefs.h >>conftest.$ac_ext
+cat >>conftest.$ac_ext <<_ACEOF
+/* end confdefs.h.  */
+#include <cairo-svg.h>
 _ACEOF
+if { (ac_try="$ac_cpp conftest.$ac_ext"
+case "(($ac_try" in
+  *\"* | *\`* | *\\*) ac_try_echo=\$ac_try;;
+  *) ac_try_echo=$ac_try;;
+esac
+eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
+  (eval "$ac_cpp conftest.$ac_ext") 2>conftest.er1
+  ac_status=$?
+  grep -v '^ *+' conftest.er1 >conftest.err
+  rm -f conftest.er1
+  cat conftest.err >&5
+  echo "$as_me:$LINENO: \$? = $ac_status" >&5
+  (exit $ac_status); } >/dev/null && {
+        test -z "$ac_c_preproc_warn_flag$ac_c_werror_flag" ||
+        test ! -s conftest.err
+       }; then
+  ac_header_preproc=yes
+else
+  echo "$as_me: failed program was:" >&5
+sed 's/^/| /' conftest.$ac_ext >&5
+
+  ac_header_preproc=no
+fi
+
+rm -f conftest.err conftest.$ac_ext
+{ echo "$as_me:$LINENO: result: $ac_header_preproc" >&5
+echo "${ECHO_T}$ac_header_preproc" >&6; }
 
-           { echo "$as_me:$LINENO: result: yes we do" >&5
-echo "${ECHO_T}yes we do" >&6; }
-else
-  echo "$as_me: failed program was:" >&5
-sed 's/^/| /' conftest.$ac_ext >&5
+# So?  What about this header?
+case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
+  yes:no: )
+    { echo "$as_me:$LINENO: WARNING: cairo-svg.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: cairo-svg.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: cairo-svg.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: cairo-svg.h: proceeding with the compiler's result" >&2;}
+    ac_header_preproc=yes
+    ;;
+  no:yes:* )
+    { echo "$as_me:$LINENO: WARNING: cairo-svg.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: cairo-svg.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: cairo-svg.h:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: cairo-svg.h:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: cairo-svg.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: cairo-svg.h: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: cairo-svg.h:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: cairo-svg.h:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: cairo-svg.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: cairo-svg.h: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: cairo-svg.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: cairo-svg.h: in the future, the compiler will take precedence" >&2;}
 
-       { { echo "$as_me:$LINENO: error: Can not figure how to compile malloc" >&5
-echo "$as_me: error: Can not figure how to compile malloc" >&2;}
-   { (exit 1); exit 1; }; }
+    ;;
+esac
+{ echo "$as_me:$LINENO: checking for cairo-svg.h" >&5
+echo $ECHO_N "checking for cairo-svg.h... $ECHO_C" >&6; }
+if test "${ac_cv_header_cairo_svg_h+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  ac_cv_header_cairo_svg_h=$ac_header_preproc
+fi
+{ echo "$as_me:$LINENO: result: $ac_cv_header_cairo_svg_h" >&5
+echo "${ECHO_T}$ac_cv_header_cairo_svg_h" >&6; }
 
 fi
+if test $ac_cv_header_cairo_svg_h = yes; then
+  EX_CHECK_STATE=YES
+fi
 
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
-      conftest$ac_exeext conftest.$ac_ext
 
 
 fi
 
-rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
-      conftest$ac_exeext conftest.$ac_ext
-ac_ext=c
-ac_cpp='$CPP $CPPFLAGS'
-ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
-ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
-ac_compiler_gnu=$ac_cv_c_compiler_gnu
+          else
+             { echo "$as_me:$LINENO: WARNING:
+----------------------------------------------------------------------------
+* I found a copy of pkgconfig, but there is no cairo-svg.pc file around.
+  You may want to set the PKG_CONFIG_PATH variable to point to its
+  location.
+----------------------------------------------------------------------------
+                       " >&5
+echo "$as_me: WARNING:
+----------------------------------------------------------------------------
+* I found a copy of pkgconfig, but there is no cairo-svg.pc file around.
+  You may want to set the PKG_CONFIG_PATH variable to point to its
+  location.
+----------------------------------------------------------------------------
+                       " >&2;}
+           fi
+     fi
+  fi
 
+  if test ${EX_CHECK_STATE} = NO; then
+     { echo "$as_me:$LINENO: WARNING:
+----------------------------------------------------------------------------
+* I could not find a working copy of cairo-svg. Check config.log for hints on why
+  this is the case. Maybe you need to set LDFLAGS and CPPFLAGS appropriately
+  so that compiler and the linker can find libcairo and its header files. If
+  you have not installed cairo-svg, you can get it either from its original home on
 
+     http://cairographics.org/releases/
 
-case $TERM in
-       #   for the most important terminal types we directly know the sequences
-       xterm|xterm*|vt220|vt220*)
-               T_MD=`awk 'BEGIN { printf("%c%c%c%c", 27, 91, 49, 109); }' </dev/null 2>/dev/null`
-               T_ME=`awk 'BEGIN { printf("%c%c%c", 27, 91, 109); }' </dev/null 2>/dev/null`
-       ;;
-       vt100|vt100*|cygwin)
-               T_MD=`awk 'BEGIN { printf("%c%c%c%c%c%c", 27, 91, 49, 109, 0, 0); }' </dev/null 2>/dev/null`
-               T_ME=`awk 'BEGIN { printf("%c%c%c%c%c", 27, 91, 109, 0, 0); }' </dev/null 2>/dev/null`
-       ;;
-       *)
-               T_MD=''
-               T_ME=''
-       ;;
-esac
-  { echo "$as_me:$LINENO: result: " >&5
-echo "${ECHO_T}" >&6; }
-  { echo "$as_me:$LINENO: result: ${T_MD}Find 3rd-Party Libraries${T_ME}" >&5
-echo "${ECHO_T}${T_MD}Find 3rd-Party Libraries${T_ME}" >&6; }
+  You can find also find an archive copy on
+
+     http://oss.oetiker.ch/rrdtool/pub/libs
+
+  The last tested version of cairo-svg is 1.4.6.
+
+       LIBS=$LIBS
+   LDFLAGS=$LDFLAGS
+  CPPFLAGS=$CPPFLAGS
 
+----------------------------------------------------------------------------
+                " >&5
+echo "$as_me: WARNING:
+----------------------------------------------------------------------------
+* I could not find a working copy of cairo-svg. Check config.log for hints on why
+  this is the case. Maybe you need to set LDFLAGS and CPPFLAGS appropriately
+  so that compiler and the linker can find libcairo and its header files. If
+  you have not installed cairo-svg, you can get it either from its original home on
 
+     http://cairographics.org/releases/
 
+  You can find also find an archive copy on
 
+     http://oss.oetiker.ch/rrdtool/pub/libs
 
-if test $enable_rrdcgi != no; then
-  BUILD_RRDCGI_TRUE=
-  BUILD_RRDCGI_FALSE='#'
-else
-  BUILD_RRDCGI_TRUE='#'
-  BUILD_RRDCGI_FALSE=
-fi
+  The last tested version of cairo-svg is 1.4.6.
+
+       LIBS=$LIBS
+   LDFLAGS=$LDFLAGS
+  CPPFLAGS=$CPPFLAGS
+
+----------------------------------------------------------------------------
+                " >&2;}
+       EX_CHECK_ALL_ERR=YES
+       LIBS="${ex_check_save_LIBS}"
+       CPPFLAGS="${ex_check_save_CPPFLAGS}"
+       LDFLAGS="${ex_check_save_LDFLAGS}"
+    fi
+    ac_ext=c
+ac_cpp='$CPP $CPPFLAGS'
+ac_compile='$CC -c $CFLAGS $CPPFLAGS conftest.$ac_ext >&5'
+ac_link='$CC -o conftest$ac_exeext $CFLAGS $CPPFLAGS $LDFLAGS conftest.$ac_ext $LIBS >&5'
+ac_compiler_gnu=$ac_cv_c_compiler_gnu
 
 
-CORE_LIBS="$LIBS"
 
 
  ac_ext=c
@@ -25680,16 +28891,16 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
  ex_check_save_LIBS=${LIBS}
  ex_check_save_CPPFLAGS=${CPPFLAGS}
  ex_check_save_LDFLAGS=${LDFLAGS}
- if test "x/usr/include/libart-2.0" != "x"; then
-   CPPFLAGS="$CPPFLAGS -I/usr/include/libart-2.0"
+ if test "x""" != "x"; then
+   CPPFLAGS="$CPPFLAGS -I"""
  fi
-  { echo "$as_me:$LINENO: checking for art_vpath_add_point in -lart_lgpl_2" >&5
-echo $ECHO_N "checking for art_vpath_add_point in -lart_lgpl_2... $ECHO_C" >&6; }
-if test "${ac_cv_lib_art_lgpl_2_art_vpath_add_point+set}" = set; then
+  { echo "$as_me:$LINENO: checking for cairo_pdf_surface_create in -lcairo" >&5
+echo $ECHO_N "checking for cairo_pdf_surface_create in -lcairo... $ECHO_C" >&6; }
+if test "${ac_cv_lib_cairo_cairo_pdf_surface_create+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
   ac_check_lib_save_LIBS=$LIBS
-LIBS="-lart_lgpl_2  $LIBS"
+LIBS="-lcairo  $LIBS"
 cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
@@ -25703,11 +28914,11 @@ cat >>conftest.$ac_ext <<_ACEOF
 #ifdef __cplusplus
 extern "C"
 #endif
-char art_vpath_add_point ();
+char cairo_pdf_surface_create ();
 int
 main ()
 {
-return art_vpath_add_point ();
+return cairo_pdf_surface_create ();
   ;
   return 0;
 }
@@ -25730,34 +28941,34 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
         test ! -s conftest.err
        } && test -s conftest$ac_exeext &&
        $as_test_x conftest$ac_exeext; then
-  ac_cv_lib_art_lgpl_2_art_vpath_add_point=yes
+  ac_cv_lib_cairo_cairo_pdf_surface_create=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-       ac_cv_lib_art_lgpl_2_art_vpath_add_point=no
+       ac_cv_lib_cairo_cairo_pdf_surface_create=no
 fi
 
 rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
       conftest$ac_exeext conftest.$ac_ext
 LIBS=$ac_check_lib_save_LIBS
 fi
-{ echo "$as_me:$LINENO: result: $ac_cv_lib_art_lgpl_2_art_vpath_add_point" >&5
-echo "${ECHO_T}$ac_cv_lib_art_lgpl_2_art_vpath_add_point" >&6; }
-if test $ac_cv_lib_art_lgpl_2_art_vpath_add_point = yes; then
+{ echo "$as_me:$LINENO: result: $ac_cv_lib_cairo_cairo_pdf_surface_create" >&5
+echo "${ECHO_T}$ac_cv_lib_cairo_cairo_pdf_surface_create" >&6; }
+if test $ac_cv_lib_cairo_cairo_pdf_surface_create = yes; then
 
-    if test "${ac_cv_header_libart_lgpl_libart_h+set}" = set; then
-  { echo "$as_me:$LINENO: checking for libart_lgpl/libart.h" >&5
-echo $ECHO_N "checking for libart_lgpl/libart.h... $ECHO_C" >&6; }
-if test "${ac_cv_header_libart_lgpl_libart_h+set}" = set; then
+    if test "${ac_cv_header_cairo_pdf_h+set}" = set; then
+  { echo "$as_me:$LINENO: checking for cairo-pdf.h" >&5
+echo $ECHO_N "checking for cairo-pdf.h... $ECHO_C" >&6; }
+if test "${ac_cv_header_cairo_pdf_h+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_libart_lgpl_libart_h" >&5
-echo "${ECHO_T}$ac_cv_header_libart_lgpl_libart_h" >&6; }
+{ echo "$as_me:$LINENO: result: $ac_cv_header_cairo_pdf_h" >&5
+echo "${ECHO_T}$ac_cv_header_cairo_pdf_h" >&6; }
 else
   # Is the header compilable?
-{ echo "$as_me:$LINENO: checking libart_lgpl/libart.h usability" >&5
-echo $ECHO_N "checking libart_lgpl/libart.h usability... $ECHO_C" >&6; }
+{ echo "$as_me:$LINENO: checking cairo-pdf.h usability" >&5
+echo $ECHO_N "checking cairo-pdf.h usability... $ECHO_C" >&6; }
 cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
@@ -25765,7 +28976,7 @@ cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
 $ac_includes_default
-#include <libart_lgpl/libart.h>
+#include <cairo-pdf.h>
 _ACEOF
 rm -f conftest.$ac_objext
 if { (ac_try="$ac_compile"
@@ -25797,15 +29008,15 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
 echo "${ECHO_T}$ac_header_compiler" >&6; }
 
 # Is the header present?
-{ echo "$as_me:$LINENO: checking libart_lgpl/libart.h presence" >&5
-echo $ECHO_N "checking libart_lgpl/libart.h presence... $ECHO_C" >&6; }
+{ echo "$as_me:$LINENO: checking cairo-pdf.h presence" >&5
+echo $ECHO_N "checking cairo-pdf.h presence... $ECHO_C" >&6; }
 cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
 cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
-#include <libart_lgpl/libart.h>
+#include <cairo-pdf.h>
 _ACEOF
 if { (ac_try="$ac_cpp conftest.$ac_ext"
 case "(($ac_try" in
@@ -25838,41 +29049,41 @@ echo "${ECHO_T}$ac_header_preproc" >&6; }
 # So?  What about this header?
 case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
   yes:no: )
-    { echo "$as_me:$LINENO: WARNING: libart_lgpl/libart.h: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: libart_lgpl/libart.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
-    { echo "$as_me:$LINENO: WARNING: libart_lgpl/libart.h: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: libart_lgpl/libart.h: proceeding with the compiler's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: cairo-pdf.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: cairo-pdf.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: cairo-pdf.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: cairo-pdf.h: proceeding with the compiler's result" >&2;}
     ac_header_preproc=yes
     ;;
   no:yes:* )
-    { echo "$as_me:$LINENO: WARNING: libart_lgpl/libart.h: present but cannot be compiled" >&5
-echo "$as_me: WARNING: libart_lgpl/libart.h: present but cannot be compiled" >&2;}
-    { echo "$as_me:$LINENO: WARNING: libart_lgpl/libart.h:     check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: libart_lgpl/libart.h:     check for missing prerequisite headers?" >&2;}
-    { echo "$as_me:$LINENO: WARNING: libart_lgpl/libart.h: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: libart_lgpl/libart.h: see the Autoconf documentation" >&2;}
-    { echo "$as_me:$LINENO: WARNING: libart_lgpl/libart.h:     section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: libart_lgpl/libart.h:     section \"Present But Cannot Be Compiled\"" >&2;}
-    { echo "$as_me:$LINENO: WARNING: libart_lgpl/libart.h: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: libart_lgpl/libart.h: proceeding with the preprocessor's result" >&2;}
-    { echo "$as_me:$LINENO: WARNING: libart_lgpl/libart.h: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: libart_lgpl/libart.h: in the future, the compiler will take precedence" >&2;}
+    { echo "$as_me:$LINENO: WARNING: cairo-pdf.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: cairo-pdf.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: cairo-pdf.h:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: cairo-pdf.h:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: cairo-pdf.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: cairo-pdf.h: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: cairo-pdf.h:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: cairo-pdf.h:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: cairo-pdf.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: cairo-pdf.h: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: cairo-pdf.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: cairo-pdf.h: in the future, the compiler will take precedence" >&2;}
 
     ;;
 esac
-{ echo "$as_me:$LINENO: checking for libart_lgpl/libart.h" >&5
-echo $ECHO_N "checking for libart_lgpl/libart.h... $ECHO_C" >&6; }
-if test "${ac_cv_header_libart_lgpl_libart_h+set}" = set; then
+{ echo "$as_me:$LINENO: checking for cairo-pdf.h" >&5
+echo $ECHO_N "checking for cairo-pdf.h... $ECHO_C" >&6; }
+if test "${ac_cv_header_cairo_pdf_h+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
-  ac_cv_header_libart_lgpl_libart_h=$ac_header_preproc
+  ac_cv_header_cairo_pdf_h=$ac_header_preproc
 fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_libart_lgpl_libart_h" >&5
-echo "${ECHO_T}$ac_cv_header_libart_lgpl_libart_h" >&6; }
+{ echo "$as_me:$LINENO: result: $ac_cv_header_cairo_pdf_h" >&5
+echo "${ECHO_T}$ac_cv_header_cairo_pdf_h" >&6; }
 
 fi
-if test $ac_cv_header_libart_lgpl_libart_h = yes; then
-  LIBS="-lart_lgpl_2 ${LIBS}";EX_CHECK_STATE=YES
+if test $ac_cv_header_cairo_pdf_h = yes; then
+  LIBS="-lcairo ${LIBS}";EX_CHECK_STATE=YES
 fi
 
 
@@ -25923,19 +29134,19 @@ done
 test -n "$PKGCONFIG" || PKGCONFIG="no"
 
     if test "$PKGCONFIG" != "no"; then
-          if $PKGCONFIG --exists libart-2.0; then
-             CPPFLAGS=${CPPFLAGS}" "`$PKGCONFIG --cflags libart-2.0`
-             LDFLAGS=${LDFLAGS}" "`$PKGCONFIG --libs-only-L libart-2.0`
-             LDFLAGS=${LDFLAGS}" "`$PKGCONFIG --libs-only-other libart-2.0`
-             LIBS=${LIBS}" "`$PKGCONFIG --libs-only-l libart-2.0`
-                    unset ac_cv_lib_art_lgpl_2_art_vpath_add_point
-             { echo "$as_me:$LINENO: checking for art_vpath_add_point in -lart_lgpl_2" >&5
-echo $ECHO_N "checking for art_vpath_add_point in -lart_lgpl_2... $ECHO_C" >&6; }
-if test "${ac_cv_lib_art_lgpl_2_art_vpath_add_point+set}" = set; then
+          if $PKGCONFIG --exists cairo-pdf; then
+             CPPFLAGS=${CPPFLAGS}" "`$PKGCONFIG --cflags cairo-pdf`
+             LDFLAGS=${LDFLAGS}" "`$PKGCONFIG --libs-only-L cairo-pdf`
+             LDFLAGS=${LDFLAGS}" "`$PKGCONFIG --libs-only-other cairo-pdf`
+             LIBS=${LIBS}" "`$PKGCONFIG --libs-only-l cairo-pdf`
+                            unset ac_cv_lib_`echo cairo | sed 's/[^_a-zA-Z0-9]/_/g;s/^[0-9]/_/'`_cairo_pdf_surface_create
+             { echo "$as_me:$LINENO: checking for cairo_pdf_surface_create in -lcairo" >&5
+echo $ECHO_N "checking for cairo_pdf_surface_create in -lcairo... $ECHO_C" >&6; }
+if test "${ac_cv_lib_cairo_cairo_pdf_surface_create+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
   ac_check_lib_save_LIBS=$LIBS
-LIBS="-lart_lgpl_2  $LIBS"
+LIBS="-lcairo  $LIBS"
 cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
@@ -25949,11 +29160,11 @@ cat >>conftest.$ac_ext <<_ACEOF
 #ifdef __cplusplus
 extern "C"
 #endif
-char art_vpath_add_point ();
+char cairo_pdf_surface_create ();
 int
 main ()
 {
-return art_vpath_add_point ();
+return cairo_pdf_surface_create ();
   ;
   return 0;
 }
@@ -25976,35 +29187,35 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
         test ! -s conftest.err
        } && test -s conftest$ac_exeext &&
        $as_test_x conftest$ac_exeext; then
-  ac_cv_lib_art_lgpl_2_art_vpath_add_point=yes
+  ac_cv_lib_cairo_cairo_pdf_surface_create=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-       ac_cv_lib_art_lgpl_2_art_vpath_add_point=no
+       ac_cv_lib_cairo_cairo_pdf_surface_create=no
 fi
 
 rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
       conftest$ac_exeext conftest.$ac_ext
 LIBS=$ac_check_lib_save_LIBS
 fi
-{ echo "$as_me:$LINENO: result: $ac_cv_lib_art_lgpl_2_art_vpath_add_point" >&5
-echo "${ECHO_T}$ac_cv_lib_art_lgpl_2_art_vpath_add_point" >&6; }
-if test $ac_cv_lib_art_lgpl_2_art_vpath_add_point = yes; then
+{ echo "$as_me:$LINENO: result: $ac_cv_lib_cairo_cairo_pdf_surface_create" >&5
+echo "${ECHO_T}$ac_cv_lib_cairo_cairo_pdf_surface_create" >&6; }
+if test $ac_cv_lib_cairo_cairo_pdf_surface_create = yes; then
 
-                unset ac_cv_header_`echo libart_lgpl/libart.h | sed 's/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/'`
-                if test "${ac_cv_header_libart_lgpl_libart_h+set}" = set; then
-  { echo "$as_me:$LINENO: checking for libart_lgpl/libart.h" >&5
-echo $ECHO_N "checking for libart_lgpl/libart.h... $ECHO_C" >&6; }
-if test "${ac_cv_header_libart_lgpl_libart_h+set}" = set; then
+                unset ac_cv_header_`echo cairo-pdf.h | sed 's/[^_a-zA-Z0-9]/_/g;s/^[0-9]/_/'`
+                if test "${ac_cv_header_cairo_pdf_h+set}" = set; then
+  { echo "$as_me:$LINENO: checking for cairo-pdf.h" >&5
+echo $ECHO_N "checking for cairo-pdf.h... $ECHO_C" >&6; }
+if test "${ac_cv_header_cairo_pdf_h+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_libart_lgpl_libart_h" >&5
-echo "${ECHO_T}$ac_cv_header_libart_lgpl_libart_h" >&6; }
+{ echo "$as_me:$LINENO: result: $ac_cv_header_cairo_pdf_h" >&5
+echo "${ECHO_T}$ac_cv_header_cairo_pdf_h" >&6; }
 else
   # Is the header compilable?
-{ echo "$as_me:$LINENO: checking libart_lgpl/libart.h usability" >&5
-echo $ECHO_N "checking libart_lgpl/libart.h usability... $ECHO_C" >&6; }
+{ echo "$as_me:$LINENO: checking cairo-pdf.h usability" >&5
+echo $ECHO_N "checking cairo-pdf.h usability... $ECHO_C" >&6; }
 cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
@@ -26012,7 +29223,7 @@ cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
 $ac_includes_default
-#include <libart_lgpl/libart.h>
+#include <cairo-pdf.h>
 _ACEOF
 rm -f conftest.$ac_objext
 if { (ac_try="$ac_compile"
@@ -26044,15 +29255,15 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
 echo "${ECHO_T}$ac_header_compiler" >&6; }
 
 # Is the header present?
-{ echo "$as_me:$LINENO: checking libart_lgpl/libart.h presence" >&5
-echo $ECHO_N "checking libart_lgpl/libart.h presence... $ECHO_C" >&6; }
+{ echo "$as_me:$LINENO: checking cairo-pdf.h presence" >&5
+echo $ECHO_N "checking cairo-pdf.h presence... $ECHO_C" >&6; }
 cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
 cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
-#include <libart_lgpl/libart.h>
+#include <cairo-pdf.h>
 _ACEOF
 if { (ac_try="$ac_cpp conftest.$ac_ext"
 case "(($ac_try" in
@@ -26085,40 +29296,40 @@ echo "${ECHO_T}$ac_header_preproc" >&6; }
 # So?  What about this header?
 case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
   yes:no: )
-    { echo "$as_me:$LINENO: WARNING: libart_lgpl/libart.h: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: libart_lgpl/libart.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
-    { echo "$as_me:$LINENO: WARNING: libart_lgpl/libart.h: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: libart_lgpl/libart.h: proceeding with the compiler's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: cairo-pdf.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: cairo-pdf.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: cairo-pdf.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: cairo-pdf.h: proceeding with the compiler's result" >&2;}
     ac_header_preproc=yes
     ;;
   no:yes:* )
-    { echo "$as_me:$LINENO: WARNING: libart_lgpl/libart.h: present but cannot be compiled" >&5
-echo "$as_me: WARNING: libart_lgpl/libart.h: present but cannot be compiled" >&2;}
-    { echo "$as_me:$LINENO: WARNING: libart_lgpl/libart.h:     check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: libart_lgpl/libart.h:     check for missing prerequisite headers?" >&2;}
-    { echo "$as_me:$LINENO: WARNING: libart_lgpl/libart.h: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: libart_lgpl/libart.h: see the Autoconf documentation" >&2;}
-    { echo "$as_me:$LINENO: WARNING: libart_lgpl/libart.h:     section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: libart_lgpl/libart.h:     section \"Present But Cannot Be Compiled\"" >&2;}
-    { echo "$as_me:$LINENO: WARNING: libart_lgpl/libart.h: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: libart_lgpl/libart.h: proceeding with the preprocessor's result" >&2;}
-    { echo "$as_me:$LINENO: WARNING: libart_lgpl/libart.h: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: libart_lgpl/libart.h: in the future, the compiler will take precedence" >&2;}
+    { echo "$as_me:$LINENO: WARNING: cairo-pdf.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: cairo-pdf.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: cairo-pdf.h:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: cairo-pdf.h:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: cairo-pdf.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: cairo-pdf.h: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: cairo-pdf.h:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: cairo-pdf.h:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: cairo-pdf.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: cairo-pdf.h: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: cairo-pdf.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: cairo-pdf.h: in the future, the compiler will take precedence" >&2;}
 
     ;;
 esac
-{ echo "$as_me:$LINENO: checking for libart_lgpl/libart.h" >&5
-echo $ECHO_N "checking for libart_lgpl/libart.h... $ECHO_C" >&6; }
-if test "${ac_cv_header_libart_lgpl_libart_h+set}" = set; then
+{ echo "$as_me:$LINENO: checking for cairo-pdf.h" >&5
+echo $ECHO_N "checking for cairo-pdf.h... $ECHO_C" >&6; }
+if test "${ac_cv_header_cairo_pdf_h+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
-  ac_cv_header_libart_lgpl_libart_h=$ac_header_preproc
+  ac_cv_header_cairo_pdf_h=$ac_header_preproc
 fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_libart_lgpl_libart_h" >&5
-echo "${ECHO_T}$ac_cv_header_libart_lgpl_libart_h" >&6; }
+{ echo "$as_me:$LINENO: result: $ac_cv_header_cairo_pdf_h" >&5
+echo "${ECHO_T}$ac_cv_header_cairo_pdf_h" >&6; }
 
 fi
-if test $ac_cv_header_libart_lgpl_libart_h = yes; then
+if test $ac_cv_header_cairo_pdf_h = yes; then
   EX_CHECK_STATE=YES
 fi
 
           else
              { echo "$as_me:$LINENO: WARNING:
 ----------------------------------------------------------------------------
-* I found a copy of pkgconfig, but there is no libart-2.0.pc file around.
+* I found a copy of pkgconfig, but there is no cairo-pdf.pc file around.
   You may want to set the PKG_CONFIG_PATH variable to point to its
   location.
 ----------------------------------------------------------------------------
                        " >&5
 echo "$as_me: WARNING:
 ----------------------------------------------------------------------------
-* I found a copy of pkgconfig, but there is no libart-2.0.pc file around.
+* I found a copy of pkgconfig, but there is no cairo-pdf.pc file around.
   You may want to set the PKG_CONFIG_PATH variable to point to its
   location.
 ----------------------------------------------------------------------------
@@ -26148,18 +29359,18 @@ echo "$as_me: WARNING:
   if test ${EX_CHECK_STATE} = NO; then
      { echo "$as_me:$LINENO: WARNING:
 ----------------------------------------------------------------------------
-* I could not find a working copy of libart-2.0. Check config.log for hints on why
+* I could not find a working copy of cairo-pdf. Check config.log for hints on why
   this is the case. Maybe you need to set LDFLAGS and CPPFLAGS appropriately
-  so that compiler and the linker can find libart_lgpl_2 and its header files. If
-  you have not installed libart-2.0, you can get it either from its original home on
+  so that compiler and the linker can find libcairo and its header files. If
+  you have not installed cairo-pdf, you can get it either from its original home on
 
-     ftp://ftp.gnome.org/pub/GNOME/sources/libart_lgpl/2.3/
+     http://cairographics.org/releases/
 
   You can find also find an archive copy on
 
      http://oss.oetiker.ch/rrdtool/pub/libs
 
-  The last tested version of libart-2.0 is 2.3.17.
+  The last tested version of cairo-pdf is 1.4.6.
 
        LIBS=$LIBS
    LDFLAGS=$LDFLAGS
@@ -26169,18 +29380,18 @@ echo "$as_me: WARNING:
                 " >&5
 echo "$as_me: WARNING:
 ----------------------------------------------------------------------------
-* I could not find a working copy of libart-2.0. Check config.log for hints on why
+* I could not find a working copy of cairo-pdf. Check config.log for hints on why
   this is the case. Maybe you need to set LDFLAGS and CPPFLAGS appropriately
-  so that compiler and the linker can find libart_lgpl_2 and its header files. If
-  you have not installed libart-2.0, you can get it either from its original home on
+  so that compiler and the linker can find libcairo and its header files. If
+  you have not installed cairo-pdf, you can get it either from its original home on
 
-     ftp://ftp.gnome.org/pub/GNOME/sources/libart_lgpl/2.3/
+     http://cairographics.org/releases/
 
   You can find also find an archive copy on
 
      http://oss.oetiker.ch/rrdtool/pub/libs
 
-  The last tested version of libart-2.0 is 2.3.17.
+  The last tested version of cairo-pdf is 1.4.6.
 
        LIBS=$LIBS
    LDFLAGS=$LDFLAGS
@@ -26215,13 +29426,13 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
  if test "x""" != "x"; then
    CPPFLAGS="$CPPFLAGS -I"""
  fi
-  { echo "$as_me:$LINENO: checking for zlibVersion in -lz" >&5
-echo $ECHO_N "checking for zlibVersion in -lz... $ECHO_C" >&6; }
-if test "${ac_cv_lib_z_zlibVersion+set}" = set; then
+  { echo "$as_me:$LINENO: checking for cairo_ps_surface_create in -lcairo" >&5
+echo $ECHO_N "checking for cairo_ps_surface_create in -lcairo... $ECHO_C" >&6; }
+if test "${ac_cv_lib_cairo_cairo_ps_surface_create+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
   ac_check_lib_save_LIBS=$LIBS
-LIBS="-lz  $LIBS"
+LIBS="-lcairo  $LIBS"
 cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
@@ -26235,11 +29446,11 @@ cat >>conftest.$ac_ext <<_ACEOF
 #ifdef __cplusplus
 extern "C"
 #endif
-char zlibVersion ();
+char cairo_ps_surface_create ();
 int
 main ()
 {
-return zlibVersion ();
+return cairo_ps_surface_create ();
   ;
   return 0;
 }
@@ -26262,34 +29473,34 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
         test ! -s conftest.err
        } && test -s conftest$ac_exeext &&
        $as_test_x conftest$ac_exeext; then
-  ac_cv_lib_z_zlibVersion=yes
+  ac_cv_lib_cairo_cairo_ps_surface_create=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-       ac_cv_lib_z_zlibVersion=no
+       ac_cv_lib_cairo_cairo_ps_surface_create=no
 fi
 
 rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
       conftest$ac_exeext conftest.$ac_ext
 LIBS=$ac_check_lib_save_LIBS
 fi
-{ echo "$as_me:$LINENO: result: $ac_cv_lib_z_zlibVersion" >&5
-echo "${ECHO_T}$ac_cv_lib_z_zlibVersion" >&6; }
-if test $ac_cv_lib_z_zlibVersion = yes; then
+{ echo "$as_me:$LINENO: result: $ac_cv_lib_cairo_cairo_ps_surface_create" >&5
+echo "${ECHO_T}$ac_cv_lib_cairo_cairo_ps_surface_create" >&6; }
+if test $ac_cv_lib_cairo_cairo_ps_surface_create = yes; then
 
-    if test "${ac_cv_header_zlib_h+set}" = set; then
-  { echo "$as_me:$LINENO: checking for zlib.h" >&5
-echo $ECHO_N "checking for zlib.h... $ECHO_C" >&6; }
-if test "${ac_cv_header_zlib_h+set}" = set; then
+    if test "${ac_cv_header_cairo_ps_h+set}" = set; then
+  { echo "$as_me:$LINENO: checking for cairo-ps.h" >&5
+echo $ECHO_N "checking for cairo-ps.h... $ECHO_C" >&6; }
+if test "${ac_cv_header_cairo_ps_h+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_zlib_h" >&5
-echo "${ECHO_T}$ac_cv_header_zlib_h" >&6; }
+{ echo "$as_me:$LINENO: result: $ac_cv_header_cairo_ps_h" >&5
+echo "${ECHO_T}$ac_cv_header_cairo_ps_h" >&6; }
 else
   # Is the header compilable?
-{ echo "$as_me:$LINENO: checking zlib.h usability" >&5
-echo $ECHO_N "checking zlib.h usability... $ECHO_C" >&6; }
+{ echo "$as_me:$LINENO: checking cairo-ps.h usability" >&5
+echo $ECHO_N "checking cairo-ps.h usability... $ECHO_C" >&6; }
 cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
@@ -26297,7 +29508,7 @@ cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
 $ac_includes_default
-#include <zlib.h>
+#include <cairo-ps.h>
 _ACEOF
 rm -f conftest.$ac_objext
 if { (ac_try="$ac_compile"
@@ -26329,15 +29540,15 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
 echo "${ECHO_T}$ac_header_compiler" >&6; }
 
 # Is the header present?
-{ echo "$as_me:$LINENO: checking zlib.h presence" >&5
-echo $ECHO_N "checking zlib.h presence... $ECHO_C" >&6; }
+{ echo "$as_me:$LINENO: checking cairo-ps.h presence" >&5
+echo $ECHO_N "checking cairo-ps.h presence... $ECHO_C" >&6; }
 cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
 cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
-#include <zlib.h>
+#include <cairo-ps.h>
 _ACEOF
 if { (ac_try="$ac_cpp conftest.$ac_ext"
 case "(($ac_try" in
@@ -26370,41 +29581,41 @@ echo "${ECHO_T}$ac_header_preproc" >&6; }
 # So?  What about this header?
 case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
   yes:no: )
-    { echo "$as_me:$LINENO: WARNING: zlib.h: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: zlib.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
-    { echo "$as_me:$LINENO: WARNING: zlib.h: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: zlib.h: proceeding with the compiler's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: cairo-ps.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: cairo-ps.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: cairo-ps.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: cairo-ps.h: proceeding with the compiler's result" >&2;}
     ac_header_preproc=yes
     ;;
   no:yes:* )
-    { echo "$as_me:$LINENO: WARNING: zlib.h: present but cannot be compiled" >&5
-echo "$as_me: WARNING: zlib.h: present but cannot be compiled" >&2;}
-    { echo "$as_me:$LINENO: WARNING: zlib.h:     check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: zlib.h:     check for missing prerequisite headers?" >&2;}
-    { echo "$as_me:$LINENO: WARNING: zlib.h: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: zlib.h: see the Autoconf documentation" >&2;}
-    { echo "$as_me:$LINENO: WARNING: zlib.h:     section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: zlib.h:     section \"Present But Cannot Be Compiled\"" >&2;}
-    { echo "$as_me:$LINENO: WARNING: zlib.h: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: zlib.h: proceeding with the preprocessor's result" >&2;}
-    { echo "$as_me:$LINENO: WARNING: zlib.h: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: zlib.h: in the future, the compiler will take precedence" >&2;}
+    { echo "$as_me:$LINENO: WARNING: cairo-ps.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: cairo-ps.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: cairo-ps.h:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: cairo-ps.h:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: cairo-ps.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: cairo-ps.h: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: cairo-ps.h:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: cairo-ps.h:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: cairo-ps.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: cairo-ps.h: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: cairo-ps.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: cairo-ps.h: in the future, the compiler will take precedence" >&2;}
 
     ;;
 esac
-{ echo "$as_me:$LINENO: checking for zlib.h" >&5
-echo $ECHO_N "checking for zlib.h... $ECHO_C" >&6; }
-if test "${ac_cv_header_zlib_h+set}" = set; then
+{ echo "$as_me:$LINENO: checking for cairo-ps.h" >&5
+echo $ECHO_N "checking for cairo-ps.h... $ECHO_C" >&6; }
+if test "${ac_cv_header_cairo_ps_h+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
-  ac_cv_header_zlib_h=$ac_header_preproc
+  ac_cv_header_cairo_ps_h=$ac_header_preproc
 fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_zlib_h" >&5
-echo "${ECHO_T}$ac_cv_header_zlib_h" >&6; }
+{ echo "$as_me:$LINENO: result: $ac_cv_header_cairo_ps_h" >&5
+echo "${ECHO_T}$ac_cv_header_cairo_ps_h" >&6; }
 
 fi
-if test $ac_cv_header_zlib_h = yes; then
-  LIBS="-lz ${LIBS}";EX_CHECK_STATE=YES
+if test $ac_cv_header_cairo_ps_h = yes; then
+  LIBS="-lcairo ${LIBS}";EX_CHECK_STATE=YES
 fi
 
 
@@ -26455,19 +29666,19 @@ done
 test -n "$PKGCONFIG" || PKGCONFIG="no"
 
     if test "$PKGCONFIG" != "no"; then
-          if $PKGCONFIG --exists zlib; then
-             CPPFLAGS=${CPPFLAGS}" "`$PKGCONFIG --cflags zlib`
-             LDFLAGS=${LDFLAGS}" "`$PKGCONFIG --libs-only-L zlib`
-             LDFLAGS=${LDFLAGS}" "`$PKGCONFIG --libs-only-other zlib`
-             LIBS=${LIBS}" "`$PKGCONFIG --libs-only-l zlib`
-                    unset ac_cv_lib_z_zlibVersion
-             { echo "$as_me:$LINENO: checking for zlibVersion in -lz" >&5
-echo $ECHO_N "checking for zlibVersion in -lz... $ECHO_C" >&6; }
-if test "${ac_cv_lib_z_zlibVersion+set}" = set; then
+          if $PKGCONFIG --exists cairo-ps; then
+             CPPFLAGS=${CPPFLAGS}" "`$PKGCONFIG --cflags cairo-ps`
+             LDFLAGS=${LDFLAGS}" "`$PKGCONFIG --libs-only-L cairo-ps`
+             LDFLAGS=${LDFLAGS}" "`$PKGCONFIG --libs-only-other cairo-ps`
+             LIBS=${LIBS}" "`$PKGCONFIG --libs-only-l cairo-ps`
+                            unset ac_cv_lib_`echo cairo | sed 's/[^_a-zA-Z0-9]/_/g;s/^[0-9]/_/'`_cairo_ps_surface_create
+             { echo "$as_me:$LINENO: checking for cairo_ps_surface_create in -lcairo" >&5
+echo $ECHO_N "checking for cairo_ps_surface_create in -lcairo... $ECHO_C" >&6; }
+if test "${ac_cv_lib_cairo_cairo_ps_surface_create+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
   ac_check_lib_save_LIBS=$LIBS
-LIBS="-lz  $LIBS"
+LIBS="-lcairo  $LIBS"
 cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
@@ -26481,11 +29692,11 @@ cat >>conftest.$ac_ext <<_ACEOF
 #ifdef __cplusplus
 extern "C"
 #endif
-char zlibVersion ();
+char cairo_ps_surface_create ();
 int
 main ()
 {
-return zlibVersion ();
+return cairo_ps_surface_create ();
   ;
   return 0;
 }
@@ -26508,35 +29719,35 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
         test ! -s conftest.err
        } && test -s conftest$ac_exeext &&
        $as_test_x conftest$ac_exeext; then
-  ac_cv_lib_z_zlibVersion=yes
+  ac_cv_lib_cairo_cairo_ps_surface_create=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-       ac_cv_lib_z_zlibVersion=no
+       ac_cv_lib_cairo_cairo_ps_surface_create=no
 fi
 
 rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
       conftest$ac_exeext conftest.$ac_ext
 LIBS=$ac_check_lib_save_LIBS
 fi
-{ echo "$as_me:$LINENO: result: $ac_cv_lib_z_zlibVersion" >&5
-echo "${ECHO_T}$ac_cv_lib_z_zlibVersion" >&6; }
-if test $ac_cv_lib_z_zlibVersion = yes; then
+{ echo "$as_me:$LINENO: result: $ac_cv_lib_cairo_cairo_ps_surface_create" >&5
+echo "${ECHO_T}$ac_cv_lib_cairo_cairo_ps_surface_create" >&6; }
+if test $ac_cv_lib_cairo_cairo_ps_surface_create = yes; then
 
-                unset ac_cv_header_`echo zlib.h | sed 's/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/'`
-                if test "${ac_cv_header_zlib_h+set}" = set; then
-  { echo "$as_me:$LINENO: checking for zlib.h" >&5
-echo $ECHO_N "checking for zlib.h... $ECHO_C" >&6; }
-if test "${ac_cv_header_zlib_h+set}" = set; then
+                unset ac_cv_header_`echo cairo-ps.h | sed 's/[^_a-zA-Z0-9]/_/g;s/^[0-9]/_/'`
+                if test "${ac_cv_header_cairo_ps_h+set}" = set; then
+  { echo "$as_me:$LINENO: checking for cairo-ps.h" >&5
+echo $ECHO_N "checking for cairo-ps.h... $ECHO_C" >&6; }
+if test "${ac_cv_header_cairo_ps_h+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_zlib_h" >&5
-echo "${ECHO_T}$ac_cv_header_zlib_h" >&6; }
+{ echo "$as_me:$LINENO: result: $ac_cv_header_cairo_ps_h" >&5
+echo "${ECHO_T}$ac_cv_header_cairo_ps_h" >&6; }
 else
   # Is the header compilable?
-{ echo "$as_me:$LINENO: checking zlib.h usability" >&5
-echo $ECHO_N "checking zlib.h usability... $ECHO_C" >&6; }
+{ echo "$as_me:$LINENO: checking cairo-ps.h usability" >&5
+echo $ECHO_N "checking cairo-ps.h usability... $ECHO_C" >&6; }
 cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
@@ -26544,7 +29755,7 @@ cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
 $ac_includes_default
-#include <zlib.h>
+#include <cairo-ps.h>
 _ACEOF
 rm -f conftest.$ac_objext
 if { (ac_try="$ac_compile"
@@ -26576,15 +29787,15 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
 echo "${ECHO_T}$ac_header_compiler" >&6; }
 
 # Is the header present?
-{ echo "$as_me:$LINENO: checking zlib.h presence" >&5
-echo $ECHO_N "checking zlib.h presence... $ECHO_C" >&6; }
+{ echo "$as_me:$LINENO: checking cairo-ps.h presence" >&5
+echo $ECHO_N "checking cairo-ps.h presence... $ECHO_C" >&6; }
 cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
 cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
-#include <zlib.h>
+#include <cairo-ps.h>
 _ACEOF
 if { (ac_try="$ac_cpp conftest.$ac_ext"
 case "(($ac_try" in
@@ -26617,40 +29828,40 @@ echo "${ECHO_T}$ac_header_preproc" >&6; }
 # So?  What about this header?
 case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
   yes:no: )
-    { echo "$as_me:$LINENO: WARNING: zlib.h: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: zlib.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
-    { echo "$as_me:$LINENO: WARNING: zlib.h: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: zlib.h: proceeding with the compiler's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: cairo-ps.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: cairo-ps.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: cairo-ps.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: cairo-ps.h: proceeding with the compiler's result" >&2;}
     ac_header_preproc=yes
     ;;
   no:yes:* )
-    { echo "$as_me:$LINENO: WARNING: zlib.h: present but cannot be compiled" >&5
-echo "$as_me: WARNING: zlib.h: present but cannot be compiled" >&2;}
-    { echo "$as_me:$LINENO: WARNING: zlib.h:     check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: zlib.h:     check for missing prerequisite headers?" >&2;}
-    { echo "$as_me:$LINENO: WARNING: zlib.h: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: zlib.h: see the Autoconf documentation" >&2;}
-    { echo "$as_me:$LINENO: WARNING: zlib.h:     section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: zlib.h:     section \"Present But Cannot Be Compiled\"" >&2;}
-    { echo "$as_me:$LINENO: WARNING: zlib.h: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: zlib.h: proceeding with the preprocessor's result" >&2;}
-    { echo "$as_me:$LINENO: WARNING: zlib.h: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: zlib.h: in the future, the compiler will take precedence" >&2;}
+    { echo "$as_me:$LINENO: WARNING: cairo-ps.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: cairo-ps.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: cairo-ps.h:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: cairo-ps.h:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: cairo-ps.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: cairo-ps.h: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: cairo-ps.h:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: cairo-ps.h:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: cairo-ps.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: cairo-ps.h: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: cairo-ps.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: cairo-ps.h: in the future, the compiler will take precedence" >&2;}
 
     ;;
 esac
-{ echo "$as_me:$LINENO: checking for zlib.h" >&5
-echo $ECHO_N "checking for zlib.h... $ECHO_C" >&6; }
-if test "${ac_cv_header_zlib_h+set}" = set; then
+{ echo "$as_me:$LINENO: checking for cairo-ps.h" >&5
+echo $ECHO_N "checking for cairo-ps.h... $ECHO_C" >&6; }
+if test "${ac_cv_header_cairo_ps_h+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
-  ac_cv_header_zlib_h=$ac_header_preproc
+  ac_cv_header_cairo_ps_h=$ac_header_preproc
 fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_zlib_h" >&5
-echo "${ECHO_T}$ac_cv_header_zlib_h" >&6; }
+{ echo "$as_me:$LINENO: result: $ac_cv_header_cairo_ps_h" >&5
+echo "${ECHO_T}$ac_cv_header_cairo_ps_h" >&6; }
 
 fi
-if test $ac_cv_header_zlib_h = yes; then
+if test $ac_cv_header_cairo_ps_h = yes; then
   EX_CHECK_STATE=YES
 fi
 
           else
              { echo "$as_me:$LINENO: WARNING:
 ----------------------------------------------------------------------------
-* I found a copy of pkgconfig, but there is no zlib.pc file around.
+* I found a copy of pkgconfig, but there is no cairo-ps.pc file around.
   You may want to set the PKG_CONFIG_PATH variable to point to its
   location.
 ----------------------------------------------------------------------------
                        " >&5
 echo "$as_me: WARNING:
 ----------------------------------------------------------------------------
-* I found a copy of pkgconfig, but there is no zlib.pc file around.
+* I found a copy of pkgconfig, but there is no cairo-ps.pc file around.
   You may want to set the PKG_CONFIG_PATH variable to point to its
   location.
 ----------------------------------------------------------------------------
@@ -26680,18 +29891,18 @@ echo "$as_me: WARNING:
   if test ${EX_CHECK_STATE} = NO; then
      { echo "$as_me:$LINENO: WARNING:
 ----------------------------------------------------------------------------
-* I could not find a working copy of zlib. Check config.log for hints on why
+* I could not find a working copy of cairo-ps. Check config.log for hints on why
   this is the case. Maybe you need to set LDFLAGS and CPPFLAGS appropriately
-  so that compiler and the linker can find libz and its header files. If
-  you have not installed zlib, you can get it either from its original home on
+  so that compiler and the linker can find libcairo and its header files. If
+  you have not installed cairo-ps, you can get it either from its original home on
 
-     http://www.gzip.org/zlib/
+     http://cairographics.org/releases/
 
   You can find also find an archive copy on
 
      http://oss.oetiker.ch/rrdtool/pub/libs
 
-  The last tested version of zlib is 1.2.3.
+  The last tested version of cairo-ps is 1.4.6.
 
        LIBS=$LIBS
    LDFLAGS=$LDFLAGS
@@ -26701,18 +29912,18 @@ echo "$as_me: WARNING:
                 " >&5
 echo "$as_me: WARNING:
 ----------------------------------------------------------------------------
-* I could not find a working copy of zlib. Check config.log for hints on why
+* I could not find a working copy of cairo-ps. Check config.log for hints on why
   this is the case. Maybe you need to set LDFLAGS and CPPFLAGS appropriately
-  so that compiler and the linker can find libz and its header files. If
-  you have not installed zlib, you can get it either from its original home on
+  so that compiler and the linker can find libcairo and its header files. If
+  you have not installed cairo-ps, you can get it either from its original home on
 
-     http://www.gzip.org/zlib/
+     http://cairographics.org/releases/
 
   You can find also find an archive copy on
 
      http://oss.oetiker.ch/rrdtool/pub/libs
 
-  The last tested version of zlib is 1.2.3.
+  The last tested version of cairo-ps is 1.4.6.
 
        LIBS=$LIBS
    LDFLAGS=$LDFLAGS
@@ -26747,13 +29958,13 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
  if test "x""" != "x"; then
    CPPFLAGS="$CPPFLAGS -I"""
  fi
-  { echo "$as_me:$LINENO: checking for png_access_version_number in -lpng" >&5
-echo $ECHO_N "checking for png_access_version_number in -lpng... $ECHO_C" >&6; }
-if test "${ac_cv_lib_png_png_access_version_number+set}" = set; then
+  { echo "$as_me:$LINENO: checking for pango_cairo_context_set_font_options in -lpango-1.0" >&5
+echo $ECHO_N "checking for pango_cairo_context_set_font_options in -lpango-1.0... $ECHO_C" >&6; }
+if test "${ac_cv_lib_pango_1_0_pango_cairo_context_set_font_options+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
   ac_check_lib_save_LIBS=$LIBS
-LIBS="-lpng  $LIBS"
+LIBS="-lpango-1.0  $LIBS"
 cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
@@ -26767,11 +29978,11 @@ cat >>conftest.$ac_ext <<_ACEOF
 #ifdef __cplusplus
 extern "C"
 #endif
-char png_access_version_number ();
+char pango_cairo_context_set_font_options ();
 int
 main ()
 {
-return png_access_version_number ();
+return pango_cairo_context_set_font_options ();
   ;
   return 0;
 }
@@ -26794,34 +30005,34 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
         test ! -s conftest.err
        } && test -s conftest$ac_exeext &&
        $as_test_x conftest$ac_exeext; then
-  ac_cv_lib_png_png_access_version_number=yes
+  ac_cv_lib_pango_1_0_pango_cairo_context_set_font_options=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-       ac_cv_lib_png_png_access_version_number=no
+       ac_cv_lib_pango_1_0_pango_cairo_context_set_font_options=no
 fi
 
 rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
       conftest$ac_exeext conftest.$ac_ext
 LIBS=$ac_check_lib_save_LIBS
 fi
-{ echo "$as_me:$LINENO: result: $ac_cv_lib_png_png_access_version_number" >&5
-echo "${ECHO_T}$ac_cv_lib_png_png_access_version_number" >&6; }
-if test $ac_cv_lib_png_png_access_version_number = yes; then
+{ echo "$as_me:$LINENO: result: $ac_cv_lib_pango_1_0_pango_cairo_context_set_font_options" >&5
+echo "${ECHO_T}$ac_cv_lib_pango_1_0_pango_cairo_context_set_font_options" >&6; }
+if test $ac_cv_lib_pango_1_0_pango_cairo_context_set_font_options = yes; then
 
-    if test "${ac_cv_header_png_h+set}" = set; then
-  { echo "$as_me:$LINENO: checking for png.h" >&5
-echo $ECHO_N "checking for png.h... $ECHO_C" >&6; }
-if test "${ac_cv_header_png_h+set}" = set; then
+    if test "${ac_cv_header_pango_pango_h+set}" = set; then
+  { echo "$as_me:$LINENO: checking for pango/pango.h" >&5
+echo $ECHO_N "checking for pango/pango.h... $ECHO_C" >&6; }
+if test "${ac_cv_header_pango_pango_h+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_png_h" >&5
-echo "${ECHO_T}$ac_cv_header_png_h" >&6; }
+{ echo "$as_me:$LINENO: result: $ac_cv_header_pango_pango_h" >&5
+echo "${ECHO_T}$ac_cv_header_pango_pango_h" >&6; }
 else
   # Is the header compilable?
-{ echo "$as_me:$LINENO: checking png.h usability" >&5
-echo $ECHO_N "checking png.h usability... $ECHO_C" >&6; }
+{ echo "$as_me:$LINENO: checking pango/pango.h usability" >&5
+echo $ECHO_N "checking pango/pango.h usability... $ECHO_C" >&6; }
 cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
@@ -26829,7 +30040,7 @@ cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
 $ac_includes_default
-#include <png.h>
+#include <pango/pango.h>
 _ACEOF
 rm -f conftest.$ac_objext
 if { (ac_try="$ac_compile"
@@ -26861,15 +30072,15 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
 echo "${ECHO_T}$ac_header_compiler" >&6; }
 
 # Is the header present?
-{ echo "$as_me:$LINENO: checking png.h presence" >&5
-echo $ECHO_N "checking png.h presence... $ECHO_C" >&6; }
+{ echo "$as_me:$LINENO: checking pango/pango.h presence" >&5
+echo $ECHO_N "checking pango/pango.h presence... $ECHO_C" >&6; }
 cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
 cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
-#include <png.h>
+#include <pango/pango.h>
 _ACEOF
 if { (ac_try="$ac_cpp conftest.$ac_ext"
 case "(($ac_try" in
@@ -26902,41 +30113,41 @@ echo "${ECHO_T}$ac_header_preproc" >&6; }
 # So?  What about this header?
 case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
   yes:no: )
-    { echo "$as_me:$LINENO: WARNING: png.h: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: png.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
-    { echo "$as_me:$LINENO: WARNING: png.h: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: png.h: proceeding with the compiler's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: pango/pango.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: pango/pango.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: pango/pango.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: pango/pango.h: proceeding with the compiler's result" >&2;}
     ac_header_preproc=yes
     ;;
   no:yes:* )
-    { echo "$as_me:$LINENO: WARNING: png.h: present but cannot be compiled" >&5
-echo "$as_me: WARNING: png.h: present but cannot be compiled" >&2;}
-    { echo "$as_me:$LINENO: WARNING: png.h:     check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: png.h:     check for missing prerequisite headers?" >&2;}
-    { echo "$as_me:$LINENO: WARNING: png.h: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: png.h: see the Autoconf documentation" >&2;}
-    { echo "$as_me:$LINENO: WARNING: png.h:     section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: png.h:     section \"Present But Cannot Be Compiled\"" >&2;}
-    { echo "$as_me:$LINENO: WARNING: png.h: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: png.h: proceeding with the preprocessor's result" >&2;}
-    { echo "$as_me:$LINENO: WARNING: png.h: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: png.h: in the future, the compiler will take precedence" >&2;}
+    { echo "$as_me:$LINENO: WARNING: pango/pango.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: pango/pango.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: pango/pango.h:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: pango/pango.h:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: pango/pango.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: pango/pango.h: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: pango/pango.h:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: pango/pango.h:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: pango/pango.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: pango/pango.h: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: pango/pango.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: pango/pango.h: in the future, the compiler will take precedence" >&2;}
 
     ;;
 esac
-{ echo "$as_me:$LINENO: checking for png.h" >&5
-echo $ECHO_N "checking for png.h... $ECHO_C" >&6; }
-if test "${ac_cv_header_png_h+set}" = set; then
+{ echo "$as_me:$LINENO: checking for pango/pango.h" >&5
+echo $ECHO_N "checking for pango/pango.h... $ECHO_C" >&6; }
+if test "${ac_cv_header_pango_pango_h+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
-  ac_cv_header_png_h=$ac_header_preproc
+  ac_cv_header_pango_pango_h=$ac_header_preproc
 fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_png_h" >&5
-echo "${ECHO_T}$ac_cv_header_png_h" >&6; }
+{ echo "$as_me:$LINENO: result: $ac_cv_header_pango_pango_h" >&5
+echo "${ECHO_T}$ac_cv_header_pango_pango_h" >&6; }
 
 fi
-if test $ac_cv_header_png_h = yes; then
-  LIBS="-lpng ${LIBS}";EX_CHECK_STATE=YES
+if test $ac_cv_header_pango_pango_h = yes; then
+  LIBS="-lpango-1.0 ${LIBS}";EX_CHECK_STATE=YES
 fi
 
 
@@ -26987,19 +30198,19 @@ done
 test -n "$PKGCONFIG" || PKGCONFIG="no"
 
     if test "$PKGCONFIG" != "no"; then
-          if $PKGCONFIG --exists libpng; then
-             CPPFLAGS=${CPPFLAGS}" "`$PKGCONFIG --cflags libpng`
-             LDFLAGS=${LDFLAGS}" "`$PKGCONFIG --libs-only-L libpng`
-             LDFLAGS=${LDFLAGS}" "`$PKGCONFIG --libs-only-other libpng`
-             LIBS=${LIBS}" "`$PKGCONFIG --libs-only-l libpng`
-                    unset ac_cv_lib_png_png_access_version_number
-             { echo "$as_me:$LINENO: checking for png_access_version_number in -lpng" >&5
-echo $ECHO_N "checking for png_access_version_number in -lpng... $ECHO_C" >&6; }
-if test "${ac_cv_lib_png_png_access_version_number+set}" = set; then
+          if $PKGCONFIG --exists pangocairo; then
+             CPPFLAGS=${CPPFLAGS}" "`$PKGCONFIG --cflags pangocairo`
+             LDFLAGS=${LDFLAGS}" "`$PKGCONFIG --libs-only-L pangocairo`
+             LDFLAGS=${LDFLAGS}" "`$PKGCONFIG --libs-only-other pangocairo`
+             LIBS=${LIBS}" "`$PKGCONFIG --libs-only-l pangocairo`
+                            unset ac_cv_lib_`echo pango-1.0 | sed 's/[^_a-zA-Z0-9]/_/g;s/^[0-9]/_/'`_pango_cairo_context_set_font_options
+             { echo "$as_me:$LINENO: checking for pango_cairo_context_set_font_options in -lpango-1.0" >&5
+echo $ECHO_N "checking for pango_cairo_context_set_font_options in -lpango-1.0... $ECHO_C" >&6; }
+if test "${ac_cv_lib_pango_1_0_pango_cairo_context_set_font_options+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
   ac_check_lib_save_LIBS=$LIBS
-LIBS="-lpng  $LIBS"
+LIBS="-lpango-1.0  $LIBS"
 cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
@@ -27013,11 +30224,11 @@ cat >>conftest.$ac_ext <<_ACEOF
 #ifdef __cplusplus
 extern "C"
 #endif
-char png_access_version_number ();
+char pango_cairo_context_set_font_options ();
 int
 main ()
 {
-return png_access_version_number ();
+return pango_cairo_context_set_font_options ();
   ;
   return 0;
 }
@@ -27040,35 +30251,35 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
         test ! -s conftest.err
        } && test -s conftest$ac_exeext &&
        $as_test_x conftest$ac_exeext; then
-  ac_cv_lib_png_png_access_version_number=yes
+  ac_cv_lib_pango_1_0_pango_cairo_context_set_font_options=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-       ac_cv_lib_png_png_access_version_number=no
+       ac_cv_lib_pango_1_0_pango_cairo_context_set_font_options=no
 fi
 
 rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
       conftest$ac_exeext conftest.$ac_ext
 LIBS=$ac_check_lib_save_LIBS
 fi
-{ echo "$as_me:$LINENO: result: $ac_cv_lib_png_png_access_version_number" >&5
-echo "${ECHO_T}$ac_cv_lib_png_png_access_version_number" >&6; }
-if test $ac_cv_lib_png_png_access_version_number = yes; then
+{ echo "$as_me:$LINENO: result: $ac_cv_lib_pango_1_0_pango_cairo_context_set_font_options" >&5
+echo "${ECHO_T}$ac_cv_lib_pango_1_0_pango_cairo_context_set_font_options" >&6; }
+if test $ac_cv_lib_pango_1_0_pango_cairo_context_set_font_options = yes; then
 
-                unset ac_cv_header_`echo png.h | sed 's/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/'`
-                if test "${ac_cv_header_png_h+set}" = set; then
-  { echo "$as_me:$LINENO: checking for png.h" >&5
-echo $ECHO_N "checking for png.h... $ECHO_C" >&6; }
-if test "${ac_cv_header_png_h+set}" = set; then
+                unset ac_cv_header_`echo pango/pango.h | sed 's/[^_a-zA-Z0-9]/_/g;s/^[0-9]/_/'`
+                if test "${ac_cv_header_pango_pango_h+set}" = set; then
+  { echo "$as_me:$LINENO: checking for pango/pango.h" >&5
+echo $ECHO_N "checking for pango/pango.h... $ECHO_C" >&6; }
+if test "${ac_cv_header_pango_pango_h+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_png_h" >&5
-echo "${ECHO_T}$ac_cv_header_png_h" >&6; }
+{ echo "$as_me:$LINENO: result: $ac_cv_header_pango_pango_h" >&5
+echo "${ECHO_T}$ac_cv_header_pango_pango_h" >&6; }
 else
   # Is the header compilable?
-{ echo "$as_me:$LINENO: checking png.h usability" >&5
-echo $ECHO_N "checking png.h usability... $ECHO_C" >&6; }
+{ echo "$as_me:$LINENO: checking pango/pango.h usability" >&5
+echo $ECHO_N "checking pango/pango.h usability... $ECHO_C" >&6; }
 cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
@@ -27076,7 +30287,7 @@ cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
 $ac_includes_default
-#include <png.h>
+#include <pango/pango.h>
 _ACEOF
 rm -f conftest.$ac_objext
 if { (ac_try="$ac_compile"
@@ -27108,15 +30319,15 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
 echo "${ECHO_T}$ac_header_compiler" >&6; }
 
 # Is the header present?
-{ echo "$as_me:$LINENO: checking png.h presence" >&5
-echo $ECHO_N "checking png.h presence... $ECHO_C" >&6; }
+{ echo "$as_me:$LINENO: checking pango/pango.h presence" >&5
+echo $ECHO_N "checking pango/pango.h presence... $ECHO_C" >&6; }
 cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
 cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
-#include <png.h>
+#include <pango/pango.h>
 _ACEOF
 if { (ac_try="$ac_cpp conftest.$ac_ext"
 case "(($ac_try" in
@@ -27149,40 +30360,40 @@ echo "${ECHO_T}$ac_header_preproc" >&6; }
 # So?  What about this header?
 case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
   yes:no: )
-    { echo "$as_me:$LINENO: WARNING: png.h: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: png.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
-    { echo "$as_me:$LINENO: WARNING: png.h: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: png.h: proceeding with the compiler's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: pango/pango.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: pango/pango.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: pango/pango.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: pango/pango.h: proceeding with the compiler's result" >&2;}
     ac_header_preproc=yes
     ;;
   no:yes:* )
-    { echo "$as_me:$LINENO: WARNING: png.h: present but cannot be compiled" >&5
-echo "$as_me: WARNING: png.h: present but cannot be compiled" >&2;}
-    { echo "$as_me:$LINENO: WARNING: png.h:     check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: png.h:     check for missing prerequisite headers?" >&2;}
-    { echo "$as_me:$LINENO: WARNING: png.h: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: png.h: see the Autoconf documentation" >&2;}
-    { echo "$as_me:$LINENO: WARNING: png.h:     section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: png.h:     section \"Present But Cannot Be Compiled\"" >&2;}
-    { echo "$as_me:$LINENO: WARNING: png.h: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: png.h: proceeding with the preprocessor's result" >&2;}
-    { echo "$as_me:$LINENO: WARNING: png.h: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: png.h: in the future, the compiler will take precedence" >&2;}
+    { echo "$as_me:$LINENO: WARNING: pango/pango.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: pango/pango.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: pango/pango.h:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: pango/pango.h:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: pango/pango.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: pango/pango.h: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: pango/pango.h:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: pango/pango.h:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: pango/pango.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: pango/pango.h: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: pango/pango.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: pango/pango.h: in the future, the compiler will take precedence" >&2;}
 
     ;;
 esac
-{ echo "$as_me:$LINENO: checking for png.h" >&5
-echo $ECHO_N "checking for png.h... $ECHO_C" >&6; }
-if test "${ac_cv_header_png_h+set}" = set; then
+{ echo "$as_me:$LINENO: checking for pango/pango.h" >&5
+echo $ECHO_N "checking for pango/pango.h... $ECHO_C" >&6; }
+if test "${ac_cv_header_pango_pango_h+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
-  ac_cv_header_png_h=$ac_header_preproc
+  ac_cv_header_pango_pango_h=$ac_header_preproc
 fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_png_h" >&5
-echo "${ECHO_T}$ac_cv_header_png_h" >&6; }
+{ echo "$as_me:$LINENO: result: $ac_cv_header_pango_pango_h" >&5
+echo "${ECHO_T}$ac_cv_header_pango_pango_h" >&6; }
 
 fi
-if test $ac_cv_header_png_h = yes; then
+if test $ac_cv_header_pango_pango_h = yes; then
   EX_CHECK_STATE=YES
 fi
 
           else
              { echo "$as_me:$LINENO: WARNING:
 ----------------------------------------------------------------------------
-* I found a copy of pkgconfig, but there is no libpng.pc file around.
+* I found a copy of pkgconfig, but there is no pangocairo.pc file around.
   You may want to set the PKG_CONFIG_PATH variable to point to its
   location.
 ----------------------------------------------------------------------------
                        " >&5
 echo "$as_me: WARNING:
 ----------------------------------------------------------------------------
-* I found a copy of pkgconfig, but there is no libpng.pc file around.
+* I found a copy of pkgconfig, but there is no pangocairo.pc file around.
   You may want to set the PKG_CONFIG_PATH variable to point to its
   location.
 ----------------------------------------------------------------------------
@@ -27212,18 +30423,18 @@ echo "$as_me: WARNING:
   if test ${EX_CHECK_STATE} = NO; then
      { echo "$as_me:$LINENO: WARNING:
 ----------------------------------------------------------------------------
-* I could not find a working copy of libpng. Check config.log for hints on why
+* I could not find a working copy of pangocairo. Check config.log for hints on why
   this is the case. Maybe you need to set LDFLAGS and CPPFLAGS appropriately
-  so that compiler and the linker can find libpng and its header files. If
-  you have not installed libpng, you can get it either from its original home on
+  so that compiler and the linker can find libpango-1.0 and its header files. If
+  you have not installed pangocairo, you can get it either from its original home on
 
-     http://prdownloads.sourceforge.net/libpng/
+     http://ftp.gnome.org/pub/GNOME/sources/pango/1.17
 
   You can find also find an archive copy on
 
      http://oss.oetiker.ch/rrdtool/pub/libs
 
-  The last tested version of libpng is 1.2.10.
+  The last tested version of pangocairo is 1.17.
 
        LIBS=$LIBS
    LDFLAGS=$LDFLAGS
@@ -27233,18 +30444,18 @@ echo "$as_me: WARNING:
                 " >&5
 echo "$as_me: WARNING:
 ----------------------------------------------------------------------------
-* I could not find a working copy of libpng. Check config.log for hints on why
+* I could not find a working copy of pangocairo. Check config.log for hints on why
   this is the case. Maybe you need to set LDFLAGS and CPPFLAGS appropriately
-  so that compiler and the linker can find libpng and its header files. If
-  you have not installed libpng, you can get it either from its original home on
+  so that compiler and the linker can find libpango-1.0 and its header files. If
+  you have not installed pangocairo, you can get it either from its original home on
 
-     http://prdownloads.sourceforge.net/libpng/
+     http://ftp.gnome.org/pub/GNOME/sources/pango/1.17
 
   You can find also find an archive copy on
 
      http://oss.oetiker.ch/rrdtool/pub/libs
 
-  The last tested version of libpng is 1.2.10.
+  The last tested version of pangocairo is 1.17.
 
        LIBS=$LIBS
    LDFLAGS=$LDFLAGS
@@ -27276,16 +30487,16 @@ ac_compiler_gnu=$ac_cv_c_compiler_gnu
  ex_check_save_LIBS=${LIBS}
  ex_check_save_CPPFLAGS=${CPPFLAGS}
  ex_check_save_LDFLAGS=${LDFLAGS}
- if test "x/usr/include/freetype2" != "x"; then
-   CPPFLAGS="$CPPFLAGS -I/usr/include/freetype2"
+ if test "x/usr/include/libxml2" != "x"; then
+   CPPFLAGS="$CPPFLAGS -I/usr/include/libxml2"
  fi
-  { echo "$as_me:$LINENO: checking for FT_Init_FreeType in -lfreetype" >&5
-echo $ECHO_N "checking for FT_Init_FreeType in -lfreetype... $ECHO_C" >&6; }
-if test "${ac_cv_lib_freetype_FT_Init_FreeType+set}" = set; then
+  { echo "$as_me:$LINENO: checking for xmlParseFile in -lxml2" >&5
+echo $ECHO_N "checking for xmlParseFile in -lxml2... $ECHO_C" >&6; }
+if test "${ac_cv_lib_xml2_xmlParseFile+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
   ac_check_lib_save_LIBS=$LIBS
-LIBS="-lfreetype  $LIBS"
+LIBS="-lxml2  $LIBS"
 cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
@@ -27299,11 +30510,11 @@ cat >>conftest.$ac_ext <<_ACEOF
 #ifdef __cplusplus
 extern "C"
 #endif
-char FT_Init_FreeType ();
+char xmlParseFile ();
 int
 main ()
 {
-return FT_Init_FreeType ();
+return xmlParseFile ();
   ;
   return 0;
 }
@@ -27326,34 +30537,34 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
         test ! -s conftest.err
        } && test -s conftest$ac_exeext &&
        $as_test_x conftest$ac_exeext; then
-  ac_cv_lib_freetype_FT_Init_FreeType=yes
+  ac_cv_lib_xml2_xmlParseFile=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-       ac_cv_lib_freetype_FT_Init_FreeType=no
+       ac_cv_lib_xml2_xmlParseFile=no
 fi
 
 rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
       conftest$ac_exeext conftest.$ac_ext
 LIBS=$ac_check_lib_save_LIBS
 fi
-{ echo "$as_me:$LINENO: result: $ac_cv_lib_freetype_FT_Init_FreeType" >&5
-echo "${ECHO_T}$ac_cv_lib_freetype_FT_Init_FreeType" >&6; }
-if test $ac_cv_lib_freetype_FT_Init_FreeType = yes; then
+{ echo "$as_me:$LINENO: result: $ac_cv_lib_xml2_xmlParseFile" >&5
+echo "${ECHO_T}$ac_cv_lib_xml2_xmlParseFile" >&6; }
+if test $ac_cv_lib_xml2_xmlParseFile = yes; then
 
-    if test "${ac_cv_header_ft2build_h+set}" = set; then
-  { echo "$as_me:$LINENO: checking for ft2build.h" >&5
-echo $ECHO_N "checking for ft2build.h... $ECHO_C" >&6; }
-if test "${ac_cv_header_ft2build_h+set}" = set; then
+    if test "${ac_cv_header_libxml_parser_h+set}" = set; then
+  { echo "$as_me:$LINENO: checking for libxml/parser.h" >&5
+echo $ECHO_N "checking for libxml/parser.h... $ECHO_C" >&6; }
+if test "${ac_cv_header_libxml_parser_h+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_ft2build_h" >&5
-echo "${ECHO_T}$ac_cv_header_ft2build_h" >&6; }
+{ echo "$as_me:$LINENO: result: $ac_cv_header_libxml_parser_h" >&5
+echo "${ECHO_T}$ac_cv_header_libxml_parser_h" >&6; }
 else
   # Is the header compilable?
-{ echo "$as_me:$LINENO: checking ft2build.h usability" >&5
-echo $ECHO_N "checking ft2build.h usability... $ECHO_C" >&6; }
+{ echo "$as_me:$LINENO: checking libxml/parser.h usability" >&5
+echo $ECHO_N "checking libxml/parser.h usability... $ECHO_C" >&6; }
 cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
@@ -27361,7 +30572,7 @@ cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
 $ac_includes_default
-#include <ft2build.h>
+#include <libxml/parser.h>
 _ACEOF
 rm -f conftest.$ac_objext
 if { (ac_try="$ac_compile"
@@ -27393,15 +30604,15 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
 echo "${ECHO_T}$ac_header_compiler" >&6; }
 
 # Is the header present?
-{ echo "$as_me:$LINENO: checking ft2build.h presence" >&5
-echo $ECHO_N "checking ft2build.h presence... $ECHO_C" >&6; }
+{ echo "$as_me:$LINENO: checking libxml/parser.h presence" >&5
+echo $ECHO_N "checking libxml/parser.h presence... $ECHO_C" >&6; }
 cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
 cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
-#include <ft2build.h>
+#include <libxml/parser.h>
 _ACEOF
 if { (ac_try="$ac_cpp conftest.$ac_ext"
 case "(($ac_try" in
@@ -27434,41 +30645,41 @@ echo "${ECHO_T}$ac_header_preproc" >&6; }
 # So?  What about this header?
 case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
   yes:no: )
-    { echo "$as_me:$LINENO: WARNING: ft2build.h: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: ft2build.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
-    { echo "$as_me:$LINENO: WARNING: ft2build.h: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: ft2build.h: proceeding with the compiler's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: libxml/parser.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: libxml/parser.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: libxml/parser.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: libxml/parser.h: proceeding with the compiler's result" >&2;}
     ac_header_preproc=yes
     ;;
   no:yes:* )
-    { echo "$as_me:$LINENO: WARNING: ft2build.h: present but cannot be compiled" >&5
-echo "$as_me: WARNING: ft2build.h: present but cannot be compiled" >&2;}
-    { echo "$as_me:$LINENO: WARNING: ft2build.h:     check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: ft2build.h:     check for missing prerequisite headers?" >&2;}
-    { echo "$as_me:$LINENO: WARNING: ft2build.h: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: ft2build.h: see the Autoconf documentation" >&2;}
-    { echo "$as_me:$LINENO: WARNING: ft2build.h:     section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: ft2build.h:     section \"Present But Cannot Be Compiled\"" >&2;}
-    { echo "$as_me:$LINENO: WARNING: ft2build.h: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: ft2build.h: proceeding with the preprocessor's result" >&2;}
-    { echo "$as_me:$LINENO: WARNING: ft2build.h: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: ft2build.h: in the future, the compiler will take precedence" >&2;}
+    { echo "$as_me:$LINENO: WARNING: libxml/parser.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: libxml/parser.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: libxml/parser.h:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: libxml/parser.h:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: libxml/parser.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: libxml/parser.h: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: libxml/parser.h:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: libxml/parser.h:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: libxml/parser.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: libxml/parser.h: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: libxml/parser.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: libxml/parser.h: in the future, the compiler will take precedence" >&2;}
 
     ;;
 esac
-{ echo "$as_me:$LINENO: checking for ft2build.h" >&5
-echo $ECHO_N "checking for ft2build.h... $ECHO_C" >&6; }
-if test "${ac_cv_header_ft2build_h+set}" = set; then
+{ echo "$as_me:$LINENO: checking for libxml/parser.h" >&5
+echo $ECHO_N "checking for libxml/parser.h... $ECHO_C" >&6; }
+if test "${ac_cv_header_libxml_parser_h+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
-  ac_cv_header_ft2build_h=$ac_header_preproc
+  ac_cv_header_libxml_parser_h=$ac_header_preproc
 fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_ft2build_h" >&5
-echo "${ECHO_T}$ac_cv_header_ft2build_h" >&6; }
+{ echo "$as_me:$LINENO: result: $ac_cv_header_libxml_parser_h" >&5
+echo "${ECHO_T}$ac_cv_header_libxml_parser_h" >&6; }
 
 fi
-if test $ac_cv_header_ft2build_h = yes; then
-  LIBS="-lfreetype ${LIBS}";EX_CHECK_STATE=YES
+if test $ac_cv_header_libxml_parser_h = yes; then
+  LIBS="-lxml2 ${LIBS}";EX_CHECK_STATE=YES
 fi
 
 
@@ -27519,19 +30730,19 @@ done
 test -n "$PKGCONFIG" || PKGCONFIG="no"
 
     if test "$PKGCONFIG" != "no"; then
-          if $PKGCONFIG --exists freetype2; then
-             CPPFLAGS=${CPPFLAGS}" "`$PKGCONFIG --cflags freetype2`
-             LDFLAGS=${LDFLAGS}" "`$PKGCONFIG --libs-only-L freetype2`
-             LDFLAGS=${LDFLAGS}" "`$PKGCONFIG --libs-only-other freetype2`
-             LIBS=${LIBS}" "`$PKGCONFIG --libs-only-l freetype2`
-                    unset ac_cv_lib_freetype_FT_Init_FreeType
-             { echo "$as_me:$LINENO: checking for FT_Init_FreeType in -lfreetype" >&5
-echo $ECHO_N "checking for FT_Init_FreeType in -lfreetype... $ECHO_C" >&6; }
-if test "${ac_cv_lib_freetype_FT_Init_FreeType+set}" = set; then
+          if $PKGCONFIG --exists libxml-2.0; then
+             CPPFLAGS=${CPPFLAGS}" "`$PKGCONFIG --cflags libxml-2.0`
+             LDFLAGS=${LDFLAGS}" "`$PKGCONFIG --libs-only-L libxml-2.0`
+             LDFLAGS=${LDFLAGS}" "`$PKGCONFIG --libs-only-other libxml-2.0`
+             LIBS=${LIBS}" "`$PKGCONFIG --libs-only-l libxml-2.0`
+                            unset ac_cv_lib_`echo xml2 | sed 's/[^_a-zA-Z0-9]/_/g;s/^[0-9]/_/'`_xmlParseFile
+             { echo "$as_me:$LINENO: checking for xmlParseFile in -lxml2" >&5
+echo $ECHO_N "checking for xmlParseFile in -lxml2... $ECHO_C" >&6; }
+if test "${ac_cv_lib_xml2_xmlParseFile+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
   ac_check_lib_save_LIBS=$LIBS
-LIBS="-lfreetype  $LIBS"
+LIBS="-lxml2  $LIBS"
 cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
@@ -27545,11 +30756,11 @@ cat >>conftest.$ac_ext <<_ACEOF
 #ifdef __cplusplus
 extern "C"
 #endif
-char FT_Init_FreeType ();
+char xmlParseFile ();
 int
 main ()
 {
-return FT_Init_FreeType ();
+return xmlParseFile ();
   ;
   return 0;
 }
@@ -27572,35 +30783,35 @@ eval "echo \"\$as_me:$LINENO: $ac_try_echo\"") >&5
         test ! -s conftest.err
        } && test -s conftest$ac_exeext &&
        $as_test_x conftest$ac_exeext; then
-  ac_cv_lib_freetype_FT_Init_FreeType=yes
+  ac_cv_lib_xml2_xmlParseFile=yes
 else
   echo "$as_me: failed program was:" >&5
 sed 's/^/| /' conftest.$ac_ext >&5
 
-       ac_cv_lib_freetype_FT_Init_FreeType=no
+       ac_cv_lib_xml2_xmlParseFile=no
 fi
 
 rm -f core conftest.err conftest.$ac_objext conftest_ipa8_conftest.oo \
       conftest$ac_exeext conftest.$ac_ext
 LIBS=$ac_check_lib_save_LIBS
 fi
-{ echo "$as_me:$LINENO: result: $ac_cv_lib_freetype_FT_Init_FreeType" >&5
-echo "${ECHO_T}$ac_cv_lib_freetype_FT_Init_FreeType" >&6; }
-if test $ac_cv_lib_freetype_FT_Init_FreeType = yes; then
+{ echo "$as_me:$LINENO: result: $ac_cv_lib_xml2_xmlParseFile" >&5
+echo "${ECHO_T}$ac_cv_lib_xml2_xmlParseFile" >&6; }
+if test $ac_cv_lib_xml2_xmlParseFile = yes; then
 
-                unset ac_cv_header_`echo ft2build.h | sed 's/[^a-zA-Z0-9_]/_/g;s/^[0-9]/_/'`
-                if test "${ac_cv_header_ft2build_h+set}" = set; then
-  { echo "$as_me:$LINENO: checking for ft2build.h" >&5
-echo $ECHO_N "checking for ft2build.h... $ECHO_C" >&6; }
-if test "${ac_cv_header_ft2build_h+set}" = set; then
+                unset ac_cv_header_`echo libxml/parser.h | sed 's/[^_a-zA-Z0-9]/_/g;s/^[0-9]/_/'`
+                if test "${ac_cv_header_libxml_parser_h+set}" = set; then
+  { echo "$as_me:$LINENO: checking for libxml/parser.h" >&5
+echo $ECHO_N "checking for libxml/parser.h... $ECHO_C" >&6; }
+if test "${ac_cv_header_libxml_parser_h+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_ft2build_h" >&5
-echo "${ECHO_T}$ac_cv_header_ft2build_h" >&6; }
+{ echo "$as_me:$LINENO: result: $ac_cv_header_libxml_parser_h" >&5
+echo "${ECHO_T}$ac_cv_header_libxml_parser_h" >&6; }
 else
   # Is the header compilable?
-{ echo "$as_me:$LINENO: checking ft2build.h usability" >&5
-echo $ECHO_N "checking ft2build.h usability... $ECHO_C" >&6; }
+{ echo "$as_me:$LINENO: checking libxml/parser.h usability" >&5
+echo $ECHO_N "checking libxml/parser.h usability... $ECHO_C" >&6; }
 cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
@@ -27608,7 +30819,7 @@ cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
 $ac_includes_default
-#include <ft2build.h>
+#include <libxml/parser.h>
 _ACEOF
 rm -f conftest.$ac_objext
 if { (ac_try="$ac_compile"
@@ -27640,15 +30851,15 @@ rm -f core conftest.err conftest.$ac_objext conftest.$ac_ext
 echo "${ECHO_T}$ac_header_compiler" >&6; }
 
 # Is the header present?
-{ echo "$as_me:$LINENO: checking ft2build.h presence" >&5
-echo $ECHO_N "checking ft2build.h presence... $ECHO_C" >&6; }
+{ echo "$as_me:$LINENO: checking libxml/parser.h presence" >&5
+echo $ECHO_N "checking libxml/parser.h presence... $ECHO_C" >&6; }
 cat >conftest.$ac_ext <<_ACEOF
 /* confdefs.h.  */
 _ACEOF
 cat confdefs.h >>conftest.$ac_ext
 cat >>conftest.$ac_ext <<_ACEOF
 /* end confdefs.h.  */
-#include <ft2build.h>
+#include <libxml/parser.h>
 _ACEOF
 if { (ac_try="$ac_cpp conftest.$ac_ext"
 case "(($ac_try" in
@@ -27681,40 +30892,40 @@ echo "${ECHO_T}$ac_header_preproc" >&6; }
 # So?  What about this header?
 case $ac_header_compiler:$ac_header_preproc:$ac_c_preproc_warn_flag in
   yes:no: )
-    { echo "$as_me:$LINENO: WARNING: ft2build.h: accepted by the compiler, rejected by the preprocessor!" >&5
-echo "$as_me: WARNING: ft2build.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
-    { echo "$as_me:$LINENO: WARNING: ft2build.h: proceeding with the compiler's result" >&5
-echo "$as_me: WARNING: ft2build.h: proceeding with the compiler's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: libxml/parser.h: accepted by the compiler, rejected by the preprocessor!" >&5
+echo "$as_me: WARNING: libxml/parser.h: accepted by the compiler, rejected by the preprocessor!" >&2;}
+    { echo "$as_me:$LINENO: WARNING: libxml/parser.h: proceeding with the compiler's result" >&5
+echo "$as_me: WARNING: libxml/parser.h: proceeding with the compiler's result" >&2;}
     ac_header_preproc=yes
     ;;
   no:yes:* )
-    { echo "$as_me:$LINENO: WARNING: ft2build.h: present but cannot be compiled" >&5
-echo "$as_me: WARNING: ft2build.h: present but cannot be compiled" >&2;}
-    { echo "$as_me:$LINENO: WARNING: ft2build.h:     check for missing prerequisite headers?" >&5
-echo "$as_me: WARNING: ft2build.h:     check for missing prerequisite headers?" >&2;}
-    { echo "$as_me:$LINENO: WARNING: ft2build.h: see the Autoconf documentation" >&5
-echo "$as_me: WARNING: ft2build.h: see the Autoconf documentation" >&2;}
-    { echo "$as_me:$LINENO: WARNING: ft2build.h:     section \"Present But Cannot Be Compiled\"" >&5
-echo "$as_me: WARNING: ft2build.h:     section \"Present But Cannot Be Compiled\"" >&2;}
-    { echo "$as_me:$LINENO: WARNING: ft2build.h: proceeding with the preprocessor's result" >&5
-echo "$as_me: WARNING: ft2build.h: proceeding with the preprocessor's result" >&2;}
-    { echo "$as_me:$LINENO: WARNING: ft2build.h: in the future, the compiler will take precedence" >&5
-echo "$as_me: WARNING: ft2build.h: in the future, the compiler will take precedence" >&2;}
+    { echo "$as_me:$LINENO: WARNING: libxml/parser.h: present but cannot be compiled" >&5
+echo "$as_me: WARNING: libxml/parser.h: present but cannot be compiled" >&2;}
+    { echo "$as_me:$LINENO: WARNING: libxml/parser.h:     check for missing prerequisite headers?" >&5
+echo "$as_me: WARNING: libxml/parser.h:     check for missing prerequisite headers?" >&2;}
+    { echo "$as_me:$LINENO: WARNING: libxml/parser.h: see the Autoconf documentation" >&5
+echo "$as_me: WARNING: libxml/parser.h: see the Autoconf documentation" >&2;}
+    { echo "$as_me:$LINENO: WARNING: libxml/parser.h:     section \"Present But Cannot Be Compiled\"" >&5
+echo "$as_me: WARNING: libxml/parser.h:     section \"Present But Cannot Be Compiled\"" >&2;}
+    { echo "$as_me:$LINENO: WARNING: libxml/parser.h: proceeding with the preprocessor's result" >&5
+echo "$as_me: WARNING: libxml/parser.h: proceeding with the preprocessor's result" >&2;}
+    { echo "$as_me:$LINENO: WARNING: libxml/parser.h: in the future, the compiler will take precedence" >&5
+echo "$as_me: WARNING: libxml/parser.h: in the future, the compiler will take precedence" >&2;}
 
     ;;
 esac
-{ echo "$as_me:$LINENO: checking for ft2build.h" >&5
-echo $ECHO_N "checking for ft2build.h... $ECHO_C" >&6; }
-if test "${ac_cv_header_ft2build_h+set}" = set; then
+{ echo "$as_me:$LINENO: checking for libxml/parser.h" >&5
+echo $ECHO_N "checking for libxml/parser.h... $ECHO_C" >&6; }
+if test "${ac_cv_header_libxml_parser_h+set}" = set; then
   echo $ECHO_N "(cached) $ECHO_C" >&6
 else
-  ac_cv_header_ft2build_h=$ac_header_preproc
+  ac_cv_header_libxml_parser_h=$ac_header_preproc
 fi
-{ echo "$as_me:$LINENO: result: $ac_cv_header_ft2build_h" >&5
-echo "${ECHO_T}$ac_cv_header_ft2build_h" >&6; }
+{ echo "$as_me:$LINENO: result: $ac_cv_header_libxml_parser_h" >&5
+echo "${ECHO_T}$ac_cv_header_libxml_parser_h" >&6; }
 
 fi
-if test $ac_cv_header_ft2build_h = yes; then
+if test $ac_cv_header_libxml_parser_h = yes; then
   EX_CHECK_STATE=YES
 fi
 
           else
              { echo "$as_me:$LINENO: WARNING:
 ----------------------------------------------------------------------------
-* I found a copy of pkgconfig, but there is no freetype2.pc file around.
+* I found a copy of pkgconfig, but there is no libxml-2.0.pc file around.
   You may want to set the PKG_CONFIG_PATH variable to point to its
   location.
 ----------------------------------------------------------------------------
                        " >&5
 echo "$as_me: WARNING:
 ----------------------------------------------------------------------------
-* I found a copy of pkgconfig, but there is no freetype2.pc file around.
+* I found a copy of pkgconfig, but there is no libxml-2.0.pc file around.
   You may want to set the PKG_CONFIG_PATH variable to point to its
   location.
 ----------------------------------------------------------------------------
@@ -27744,18 +30955,18 @@ echo "$as_me: WARNING:
   if test ${EX_CHECK_STATE} = NO; then
      { echo "$as_me:$LINENO: WARNING:
 ----------------------------------------------------------------------------
-* I could not find a working copy of freetype2. Check config.log for hints on why
+* I could not find a working copy of libxml-2.0. Check config.log for hints on why
   this is the case. Maybe you need to set LDFLAGS and CPPFLAGS appropriately
-  so that compiler and the linker can find libfreetype and its header files. If
-  you have not installed freetype2, you can get it either from its original home on
+  so that compiler and the linker can find libxml2 and its header files. If
+  you have not installed libxml-2.0, you can get it either from its original home on
 
-     http://prdownloads.sourceforge.net/freetype/
+     http://xmlsoft.org/downloads.html
 
   You can find also find an archive copy on
 
      http://oss.oetiker.ch/rrdtool/pub/libs
 
-  The last tested version of freetype2 is 2.1.10.
+  The last tested version of libxml-2.0 is 2.6.31.
 
        LIBS=$LIBS
    LDFLAGS=$LDFLAGS
@@ -27765,18 +30976,18 @@ echo "$as_me: WARNING:
                 " >&5
 echo "$as_me: WARNING:
 ----------------------------------------------------------------------------
-* I could not find a working copy of freetype2. Check config.log for hints on why
+* I could not find a working copy of libxml-2.0. Check config.log for hints on why
   this is the case. Maybe you need to set LDFLAGS and CPPFLAGS appropriately
-  so that compiler and the linker can find libfreetype and its header files. If
-  you have not installed freetype2, you can get it either from its original home on
+  so that compiler and the linker can find libxml2 and its header files. If
+  you have not installed libxml-2.0, you can get it either from its original home on
 
-     http://prdownloads.sourceforge.net/freetype/
+     http://xmlsoft.org/downloads.html
 
   You can find also find an archive copy on
 
      http://oss.oetiker.ch/rrdtool/pub/libs
 
-  The last tested version of freetype2 is 2.1.10.
+  The last tested version of libxml-2.0 is 2.6.31.
 
        LIBS=$LIBS
    LDFLAGS=$LDFLAGS
@@ -27832,6 +31043,8 @@ echo "${ECHO_T}" >&6; }
 echo "${ECHO_T}${T_MD}Prep for Building Language Bindings${T_ME}" >&6; }
 
 
+PATH=$PATH:/usr/perl5/bin
+export PATH
 # Extract the first word of "perl", so it can be a program name with args.
 set dummy perl; ac_word=$2
 { echo "$as_me:$LINENO: checking for $ac_word" >&5
@@ -27873,6 +31086,89 @@ echo "${ECHO_T}no" >&6; }
 fi
 
 
+# Extract the first word of "pod2man", so it can be a program name with args.
+set dummy pod2man; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_path_POD2MAN+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  case $POD2MAN in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_POD2MAN="$POD2MAN" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_path_POD2MAN="$as_dir/$ac_word$ac_exec_ext"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+IFS=$as_save_IFS
+
+  test -z "$ac_cv_path_POD2MAN" && ac_cv_path_POD2MAN="no"
+  ;;
+esac
+fi
+POD2MAN=$ac_cv_path_POD2MAN
+if test -n "$POD2MAN"; then
+  { echo "$as_me:$LINENO: result: $POD2MAN" >&5
+echo "${ECHO_T}$POD2MAN" >&6; }
+else
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+
+# Extract the first word of "pod2html", so it can be a program name with args.
+set dummy pod2html; ac_word=$2
+{ echo "$as_me:$LINENO: checking for $ac_word" >&5
+echo $ECHO_N "checking for $ac_word... $ECHO_C" >&6; }
+if test "${ac_cv_path_POD2HTML+set}" = set; then
+  echo $ECHO_N "(cached) $ECHO_C" >&6
+else
+  case $POD2HTML in
+  [\\/]* | ?:[\\/]*)
+  ac_cv_path_POD2HTML="$POD2HTML" # Let the user override the test with a path.
+  ;;
+  *)
+  as_save_IFS=$IFS; IFS=$PATH_SEPARATOR
+for as_dir in $PATH
+do
+  IFS=$as_save_IFS
+  test -z "$as_dir" && as_dir=.
+  for ac_exec_ext in '' $ac_executable_extensions; do
+  if { test -f "$as_dir/$ac_word$ac_exec_ext" && $as_test_x "$as_dir/$ac_word$ac_exec_ext"; }; then
+    ac_cv_path_POD2HTML="$as_dir/$ac_word$ac_exec_ext"
+    echo "$as_me:$LINENO: found $as_dir/$ac_word$ac_exec_ext" >&5
+    break 2
+  fi
+done
+done
+IFS=$as_save_IFS
+
+  test -z "$ac_cv_path_POD2HTML" && ac_cv_path_POD2HTML="no"
+  ;;
+esac
+fi
+POD2HTML=$ac_cv_path_POD2HTML
+if test -n "$POD2HTML"; then
+  { echo "$as_me:$LINENO: result: $POD2HTML" >&5
+echo "${ECHO_T}$POD2HTML" >&6; }
+else
+  { echo "$as_me:$LINENO: result: no" >&5
+echo "${ECHO_T}no" >&6; }
+fi
+
+
+
 
 # Check whether --enable-perl was given.
 if test "${enable_perl+set}" = set; then
@@ -28088,7 +31384,7 @@ fi
 if test "${enable_ruby_site_install+set}" = set; then
   enableval=$enable_ruby_site_install; RUBY_MAKE_OPTIONS=
 else
-  RUBY_MAKE_OPTIONS="sitedir=$prefix/lib/ruby"
+  RUBY_MAKE_OPTIONS="sitedir="'$(DESTDIR)'"$prefix/lib/ruby"
 fi
 
 
@@ -28124,7 +31420,7 @@ if test "${with_tcllib+set}" = set; then
 fi
 
   enable_tcl=no
-  for dir in $withval /usr/lib /usr/local/lib; do
+  for dir in $withval /usr/lib /usr/local/lib /usr/lib/tcl8.4 /usr/lib/tcl8.3 ; do
     { echo "$as_me:$LINENO: checking for tclConfig.sh in $dir" >&5
 echo $ECHO_N "checking for tclConfig.sh in $dir... $ECHO_C" >&6; }
     if test -f "$dir/tclConfig.sh" ; then
@@ -28140,8 +31436,8 @@ echo "${ECHO_T}no" >&6; }
   done
 
   if test "$enable_tcl" = "no"; then
-        { echo "$as_me:$LINENO: WARNING: tclConfig.sh not found - Tcl interface won't be built" >&5
-echo "$as_me: WARNING: tclConfig.sh not found - Tcl interface won't be built" >&2;}
+        { echo "$as_me:$LINENO: WARNING: tclConfig.sh not found - Tcl interface will not be built" >&5
+echo "$as_me: WARNING: tclConfig.sh not found - Tcl interface will not be built" >&2;}
   else
        . $tcl_config
        TCL_PACKAGE_DIR="$TCL_PACKAGE_PATH/tclrrd$VERSION"
@@ -28187,6 +31483,8 @@ fi
 
 
 
+
+
 # Check whether --enable-python was given.
 if test "${enable_python+set}" = set; then
   enableval=$enable_python;
@@ -28578,6 +31876,8 @@ ac_config_files="$ac_config_files examples/Makefile"
 
 ac_config_files="$ac_config_files doc/Makefile"
 
+ac_config_files="$ac_config_files po/Makefile.in"
+
 ac_config_files="$ac_config_files src/Makefile"
 
 ac_config_files="$ac_config_files bindings/Makefile"
@@ -28687,6 +31987,20 @@ LIBOBJS=$ac_libobjs
 LTLIBOBJS=$ac_ltlibobjs
 
 
+if test -z "${MAINTAINER_MODE_TRUE}" && test -z "${MAINTAINER_MODE_FALSE}"; then
+  { { echo "$as_me:$LINENO: error: conditional \"MAINTAINER_MODE\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+echo "$as_me: error: conditional \"MAINTAINER_MODE\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+if test -z "${STATIC_PROGRAMS_TRUE}" && test -z "${STATIC_PROGRAMS_FALSE}"; then
+  { { echo "$as_me:$LINENO: error: conditional \"STATIC_PROGRAMS\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+echo "$as_me: error: conditional \"STATIC_PROGRAMS\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+   { (exit 1); exit 1; }; }
+fi
 if test -z "${AMDEP_TRUE}" && test -z "${AMDEP_FALSE}"; then
   { { echo "$as_me:$LINENO: error: conditional \"AMDEP\" was never defined.
 Usually this means the macro was only invoked conditionally." >&5
@@ -28705,6 +32019,17 @@ if test -z "${am__fastdepCXX_TRUE}" && test -z "${am__fastdepCXX_FALSE}"; then
   { { echo "$as_me:$LINENO: error: conditional \"am__fastdepCXX\" was never defined.
 Usually this means the macro was only invoked conditionally." >&5
 echo "$as_me: error: conditional \"am__fastdepCXX\" was never defined.
+Usually this means the macro was only invoked conditionally." >&2;}
+   { (exit 1); exit 1; }; }
+fi
+
+  ac_config_commands="$ac_config_commands po/stamp-it"
+
+
+if test -z "${BUILD_LIBINTL_TRUE}" && test -z "${BUILD_LIBINTL_FALSE}"; then
+  { { echo "$as_me:$LINENO: error: conditional \"BUILD_LIBINTL\" was never defined.
+Usually this means the macro was only invoked conditionally." >&5
+echo "$as_me: error: conditional \"BUILD_LIBINTL\" was never defined.
 Usually this means the macro was only invoked conditionally." >&2;}
    { (exit 1); exit 1; }; }
 fi
@@ -29036,7 +32361,7 @@ exec 6>&1
 # report actual input values of CONFIG_FILES etc. instead of their
 # values after options handling.
 ac_log="
-This file was extended by rrdtool $as_me 1.2.27, which was
+This file was extended by rrdtool $as_me 1.3rc4, which was
 generated by GNU Autoconf 2.61.  Invocation command line was
 
   CONFIG_FILES    = $CONFIG_FILES
@@ -29089,7 +32414,7 @@ Report bugs to <bug-autoconf@gnu.org>."
 _ACEOF
 cat >>$CONFIG_STATUS <<_ACEOF
 ac_cs_version="\\
-rrdtool config.status 1.2.27
+rrdtool config.status 1.3rc4
 configured by $0, generated by GNU Autoconf 2.61,
   with options \\"`echo "$ac_configure_args" | sed 's/^ //; s/[\\""\`\$]/\\\\&/g'`\\"
 
@@ -29194,6 +32519,12 @@ cat >>$CONFIG_STATUS <<_ACEOF
 #
 AMDEP_TRUE="$AMDEP_TRUE" ac_aux_dir="$ac_aux_dir"
 
+INTLTOOL_PERL='${INTLTOOL_PERL}' ac_aux_dir='${ac_aux_dir}'
+prefix="$prefix" exec_prefix="$exec_prefix" INTLTOOL_LIBDIR="$libdir"
+INTLTOOL_EXTRACT='${INTLTOOL_EXTRACT}' INTLTOOL_ICONV='${INTLTOOL_ICONV}'
+INTLTOOL_MSGFMT='${INTLTOOL_MSGFMT}' INTLTOOL_MSGMERGE='${INTLTOOL_MSGMERGE}'
+INTLTOOL_XGETTEXT='${INTLTOOL_XGETTEXT}'
+
 
 _ACEOF
 
@@ -29205,6 +32536,8 @@ do
   case $ac_config_target in
     "rrd_config.h") CONFIG_HEADERS="$CONFIG_HEADERS rrd_config.h" ;;
     "depfiles") CONFIG_COMMANDS="$CONFIG_COMMANDS depfiles" ;;
+    "default-1") CONFIG_COMMANDS="$CONFIG_COMMANDS default-1" ;;
+    "intltool") CONFIG_COMMANDS="$CONFIG_COMMANDS intltool" ;;
     "examples/shared-demo.pl") CONFIG_FILES="$CONFIG_FILES examples/shared-demo.pl" ;;
     "examples/piped-demo.pl") CONFIG_FILES="$CONFIG_FILES examples/piped-demo.pl" ;;
     "examples/stripes.pl") CONFIG_FILES="$CONFIG_FILES examples/stripes.pl" ;;
     "examples/perftest.pl") CONFIG_FILES="$CONFIG_FILES examples/perftest.pl" ;;
     "examples/Makefile") CONFIG_FILES="$CONFIG_FILES examples/Makefile" ;;
     "doc/Makefile") CONFIG_FILES="$CONFIG_FILES doc/Makefile" ;;
+    "po/Makefile.in") CONFIG_FILES="$CONFIG_FILES po/Makefile.in" ;;
     "src/Makefile") CONFIG_FILES="$CONFIG_FILES src/Makefile" ;;
     "bindings/Makefile") CONFIG_FILES="$CONFIG_FILES bindings/Makefile" ;;
     "bindings/tcl/Makefile") CONFIG_FILES="$CONFIG_FILES bindings/tcl/Makefile" ;;
     "bindings/tcl/ifOctets.tcl") CONFIG_FILES="$CONFIG_FILES bindings/tcl/ifOctets.tcl" ;;
     "Makefile") CONFIG_FILES="$CONFIG_FILES Makefile" ;;
     "default") CONFIG_COMMANDS="$CONFIG_COMMANDS default" ;;
+    "po/stamp-it") CONFIG_COMMANDS="$CONFIG_COMMANDS po/stamp-it" ;;
 
   *) { { echo "$as_me:$LINENO: error: invalid argument: $ac_config_target" >&5
 echo "$as_me: error: invalid argument: $ac_config_target" >&2;}
@@ -29321,6 +32656,7 @@ build_alias!$build_alias$ac_delim
 host_alias!$host_alias$ac_delim
 target_alias!$target_alias$ac_delim
 NUMVERS!$NUMVERS$ac_delim
+LIBVERS!$LIBVERS$ac_delim
 build!$build$ac_delim
 build_cpu!$build_cpu$ac_delim
 build_vendor!$build_vendor$ac_delim
@@ -29354,7 +32690,12 @@ am__leading_dot!$am__leading_dot$ac_delim
 AMTAR!$AMTAR$ac_delim
 am__tar!$am__tar$ac_delim
 am__untar!$am__untar$ac_delim
+MAINTAINER_MODE_TRUE!$MAINTAINER_MODE_TRUE$ac_delim
+MAINTAINER_MODE_FALSE!$MAINTAINER_MODE_FALSE$ac_delim
+MAINT!$MAINT$ac_delim
 RRDGRAPH_YLEGEND_ANGLE!$RRDGRAPH_YLEGEND_ANGLE$ac_delim
+STATIC_PROGRAMS_TRUE!$STATIC_PROGRAMS_TRUE$ac_delim
+STATIC_PROGRAMS_FALSE!$STATIC_PROGRAMS_FALSE$ac_delim
 CC!$CC$ac_delim
 CFLAGS!$CFLAGS$ac_delim
 LDFLAGS!$LDFLAGS$ac_delim
@@ -29373,12 +32714,6 @@ am__fastdepCC_TRUE!$am__fastdepCC_TRUE$ac_delim
 am__fastdepCC_FALSE!$am__fastdepCC_FALSE$ac_delim
 CPP!$CPP$ac_delim
 GREP!$GREP$ac_delim
-EGREP!$EGREP$ac_delim
-LN_S!$LN_S$ac_delim
-ECHO!$ECHO$ac_delim
-AR!$AR$ac_delim
-RANLIB!$RANLIB$ac_delim
-CXX!$CXX$ac_delim
 _ACEOF
 
   if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 97; then
@@ -29420,6 +32755,12 @@ _ACEOF
 ac_delim='%!_!# '
 for ac_last_try in false false false false false :; do
   cat >conf$$subs.sed <<_ACEOF
+EGREP!$EGREP$ac_delim
+LN_S!$LN_S$ac_delim
+ECHO!$ECHO$ac_delim
+AR!$AR$ac_delim
+RANLIB!$RANLIB$ac_delim
+CXX!$CXX$ac_delim
 CXXFLAGS!$CXXFLAGS$ac_delim
 ac_ct_CXX!$ac_ct_CXX$ac_delim
 CXXDEPMODE!$CXXDEPMODE$ac_delim
@@ -29431,6 +32772,53 @@ FFLAGS!$FFLAGS$ac_delim
 ac_ct_F77!$ac_ct_F77$ac_delim
 LIBTOOL!$LIBTOOL$ac_delim
 RRD_DEFAULT_FONT!$RRD_DEFAULT_FONT$ac_delim
+GETTEXT_PACKAGE!$GETTEXT_PACKAGE$ac_delim
+USE_NLS!$USE_NLS$ac_delim
+MSGFMT!$MSGFMT$ac_delim
+MSGFMT_OPTS!$MSGFMT_OPTS$ac_delim
+GMSGFMT!$GMSGFMT$ac_delim
+XGETTEXT!$XGETTEXT$ac_delim
+CATALOGS!$CATALOGS$ac_delim
+CATOBJEXT!$CATOBJEXT$ac_delim
+DATADIRNAME!$DATADIRNAME$ac_delim
+GMOFILES!$GMOFILES$ac_delim
+INSTOBJEXT!$INSTOBJEXT$ac_delim
+INTLLIBS!$INTLLIBS$ac_delim
+PO_IN_DATADIR_TRUE!$PO_IN_DATADIR_TRUE$ac_delim
+PO_IN_DATADIR_FALSE!$PO_IN_DATADIR_FALSE$ac_delim
+POFILES!$POFILES$ac_delim
+POSUB!$POSUB$ac_delim
+MKINSTALLDIRS!$MKINSTALLDIRS$ac_delim
+INTLTOOL_DESKTOP_RULE!$INTLTOOL_DESKTOP_RULE$ac_delim
+INTLTOOL_DIRECTORY_RULE!$INTLTOOL_DIRECTORY_RULE$ac_delim
+INTLTOOL_KEYS_RULE!$INTLTOOL_KEYS_RULE$ac_delim
+INTLTOOL_PROP_RULE!$INTLTOOL_PROP_RULE$ac_delim
+INTLTOOL_OAF_RULE!$INTLTOOL_OAF_RULE$ac_delim
+INTLTOOL_PONG_RULE!$INTLTOOL_PONG_RULE$ac_delim
+INTLTOOL_SERVER_RULE!$INTLTOOL_SERVER_RULE$ac_delim
+INTLTOOL_SHEET_RULE!$INTLTOOL_SHEET_RULE$ac_delim
+INTLTOOL_SOUNDLIST_RULE!$INTLTOOL_SOUNDLIST_RULE$ac_delim
+INTLTOOL_UI_RULE!$INTLTOOL_UI_RULE$ac_delim
+INTLTOOL_XAM_RULE!$INTLTOOL_XAM_RULE$ac_delim
+INTLTOOL_KBD_RULE!$INTLTOOL_KBD_RULE$ac_delim
+INTLTOOL_XML_RULE!$INTLTOOL_XML_RULE$ac_delim
+INTLTOOL_XML_NOMERGE_RULE!$INTLTOOL_XML_NOMERGE_RULE$ac_delim
+INTLTOOL_CAVES_RULE!$INTLTOOL_CAVES_RULE$ac_delim
+INTLTOOL_SCHEMAS_RULE!$INTLTOOL_SCHEMAS_RULE$ac_delim
+INTLTOOL_THEME_RULE!$INTLTOOL_THEME_RULE$ac_delim
+INTLTOOL_SERVICE_RULE!$INTLTOOL_SERVICE_RULE$ac_delim
+INTLTOOL_EXTRACT!$INTLTOOL_EXTRACT$ac_delim
+INTLTOOL_MERGE!$INTLTOOL_MERGE$ac_delim
+INTLTOOL_UPDATE!$INTLTOOL_UPDATE$ac_delim
+INTLTOOL_PERL!$INTLTOOL_PERL$ac_delim
+INTLTOOL_ICONV!$INTLTOOL_ICONV$ac_delim
+INTLTOOL_MSGFMT!$INTLTOOL_MSGFMT$ac_delim
+INTLTOOL_MSGMERGE!$INTLTOOL_MSGMERGE$ac_delim
+INTLTOOL_XGETTEXT!$INTLTOOL_XGETTEXT$ac_delim
+ALL_LINGUAS!$ALL_LINGUAS$ac_delim
+LIB_LIBINTL!$LIB_LIBINTL$ac_delim
+BUILD_LIBINTL_TRUE!$BUILD_LIBINTL_TRUE$ac_delim
+BUILD_LIBINTL_FALSE!$BUILD_LIBINTL_FALSE$ac_delim
 MULTITHREAD_CFLAGS!$MULTITHREAD_CFLAGS$ac_delim
 MULTITHREAD_LDFLAGS!$MULTITHREAD_LDFLAGS$ac_delim
 acx_pthread_config!$acx_pthread_config$ac_delim
@@ -29445,6 +32833,8 @@ PKGCONFIG!$PKGCONFIG$ac_delim
 CORE_LIBS!$CORE_LIBS$ac_delim
 ALL_LIBS!$ALL_LIBS$ac_delim
 PERL!$PERL$ac_delim
+POD2MAN!$POD2MAN$ac_delim
+POD2HTML!$POD2HTML$ac_delim
 PERLCC!$PERLCC$ac_delim
 PERLCCFLAGS!$PERLCCFLAGS$ac_delim
 PERLLD!$PERLLD$ac_delim
@@ -29462,6 +32852,47 @@ BUILD_TCL_SITE_TRUE!$BUILD_TCL_SITE_TRUE$ac_delim
 BUILD_TCL_SITE_FALSE!$BUILD_TCL_SITE_FALSE$ac_delim
 TCL_PREFIX!$TCL_PREFIX$ac_delim
 TCL_SHLIB_CFLAGS!$TCL_SHLIB_CFLAGS$ac_delim
+_ACEOF
+
+  if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 97; then
+    break
+  elif $ac_last_try; then
+    { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
+echo "$as_me: error: could not make $CONFIG_STATUS" >&2;}
+   { (exit 1); exit 1; }; }
+  else
+    ac_delim="$ac_delim!$ac_delim _$ac_delim!! "
+  fi
+done
+
+ac_eof=`sed -n '/^CEOF[0-9]*$/s/CEOF/0/p' conf$$subs.sed`
+if test -n "$ac_eof"; then
+  ac_eof=`echo "$ac_eof" | sort -nru | sed 1q`
+  ac_eof=`expr $ac_eof + 1`
+fi
+
+cat >>$CONFIG_STATUS <<_ACEOF
+cat >"\$tmp/subs-2.sed" <<\CEOF$ac_eof
+/@[a-zA-Z_][a-zA-Z_0-9]*@/!b
+_ACEOF
+sed '
+s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g
+s/^/s,@/; s/!/@,|#_!!_#|/
+:n
+t n
+s/'"$ac_delim"'$/,g/; t
+s/$/\\/; p
+N; s/^.*\n//; s/[,\\&]/\\&/g; s/@/@|#_!!_#|/g; b n
+' >>$CONFIG_STATUS <conf$$subs.sed
+rm -f conf$$subs.sed
+cat >>$CONFIG_STATUS <<_ACEOF
+CEOF$ac_eof
+_ACEOF
+
+
+ac_delim='%!_!# '
+for ac_last_try in false false false false false :; do
+  cat >conf$$subs.sed <<_ACEOF
 TCL_SHLIB_LD!$TCL_SHLIB_LD$ac_delim
 TCL_SHLIB_SUFFIX!$TCL_SHLIB_SUFFIX$ac_delim
 TCL_PACKAGE_PATH!$TCL_PACKAGE_PATH$ac_delim
@@ -29469,6 +32900,7 @@ TCL_LD_SEARCH_FLAGS!$TCL_LD_SEARCH_FLAGS$ac_delim
 TCL_STUB_LIB_SPEC!$TCL_STUB_LIB_SPEC$ac_delim
 TCL_VERSION!$TCL_VERSION$ac_delim
 TCL_PACKAGE_DIR!$TCL_PACKAGE_DIR$ac_delim
+TCL_INC_DIR!$TCL_INC_DIR$ac_delim
 PYTHON!$PYTHON$ac_delim
 PYTHON_VERSION!$PYTHON_VERSION$ac_delim
 PYTHON_PREFIX!$PYTHON_PREFIX$ac_delim
@@ -29487,7 +32919,7 @@ LIBOBJS!$LIBOBJS$ac_delim
 LTLIBOBJS!$LTLIBOBJS$ac_delim
 _ACEOF
 
-  if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 65; then
+  if test `sed -n "s/.*$ac_delim\$/X/p" conf$$subs.sed | grep -c X` = 24; then
     break
   elif $ac_last_try; then
     { { echo "$as_me:$LINENO: error: could not make $CONFIG_STATUS" >&5
@@ -29505,7 +32937,7 @@ if test -n "$ac_eof"; then
 fi
 
 cat >>$CONFIG_STATUS <<_ACEOF
-cat >"\$tmp/subs-2.sed" <<\CEOF$ac_eof
+cat >"\$tmp/subs-3.sed" <<\CEOF$ac_eof
 /@[a-zA-Z_][a-zA-Z_0-9]*@/!b end
 _ACEOF
 sed '
@@ -29768,7 +33200,7 @@ s&@abs_builddir@&$ac_abs_builddir&;t t
 s&@abs_top_builddir@&$ac_abs_top_builddir&;t t
 s&@INSTALL@&$ac_INSTALL&;t t
 $ac_datarootdir_hack
-" $ac_file_inputs | sed -f "$tmp/subs-1.sed" | sed -f "$tmp/subs-2.sed" >$tmp/out
+" $ac_file_inputs | sed -f "$tmp/subs-1.sed" | sed -f "$tmp/subs-2.sed" | sed -f "$tmp/subs-3.sed" >$tmp/out
 
 test -z "$ac_datarootdir_hack$ac_datarootdir_seen" &&
   { ac_out=`sed -n '/\${datarootdir}/p' "$tmp/out"`; test -n "$ac_out"; } &&
@@ -30045,8 +33477,55 @@ echo "$as_me: error: cannot create directory $as_dir" >&2;}
     echo '# dummy' > "$dirpart/$file"
   done
 done
+ ;;
+    "default-1":C) case "$CONFIG_FILES" in *po/Makefile.in*)
+        sed -e "/POTFILES =/r po/POTFILES" po/Makefile.in > po/Makefile
+      esac ;;
+    "intltool":C)
+
+for file in intltool-extract intltool-merge intltool-update; do
+  sed -e "s|@INTLTOOL_EXTRACT@|`pwd`/intltool-extract|g" \
+      -e "s|@INTLTOOL_LIBDIR@|${INTLTOOL_LIBDIR}|g" \
+      -e "s|@INTLTOOL_ICONV@|${INTLTOOL_ICONV}|g" \
+      -e "s|@INTLTOOL_MSGFMT@|${INTLTOOL_MSGFMT}|g" \
+      -e "s|@INTLTOOL_MSGMERGE@|${INTLTOOL_MSGMERGE}|g" \
+      -e "s|@INTLTOOL_XGETTEXT@|${INTLTOOL_XGETTEXT}|g" \
+      -e "s|@INTLTOOL_PERL@|${INTLTOOL_PERL}|g" \
+       < ${ac_aux_dir}/${file}.in > ${file}.out
+  if cmp -s ${file} ${file}.out 2>/dev/null; then
+    rm -f ${file}.out
+  else
+    mv -f ${file}.out ${file}
+  fi
+  chmod ugo+x ${file}
+  chmod u+w ${file}
+done
+
  ;;
     "default":C)  chmod +x examples/*.pl ;;
+    "po/stamp-it":C)
+    rm -f "po/stamp-it" "po/stamp-it.tmp" "po/POTFILES" "po/Makefile.tmp"
+    >"po/stamp-it.tmp"
+    sed '/^#/d
+        s/^[[].*] *//
+        /^[    ]*$/d
+       '"s|^|  $ac_top_srcdir/|" \
+      "$srcdir/po/POTFILES.in" | sed '$!s/$/ \\/' >"po/POTFILES"
+
+    if test ! -f "po/Makefile"; then
+      { { echo "$as_me:$LINENO: error: po/Makefile is not ready." >&5
+echo "$as_me: error: po/Makefile is not ready." >&2;}
+   { (exit 1); exit 1; }; }
+    fi
+    mv "po/Makefile" "po/Makefile.tmp"
+    sed '/^POTFILES =/,/[^\\]$/ {
+               /^POTFILES =/!d
+               r po/POTFILES
+         }
+        ' "po/Makefile.tmp" >"po/Makefile"
+    rm -f "po/Makefile.tmp"
+    mv "po/stamp-it.tmp" "po/stamp-it"
+   ;;
 
   esac
 done # for ac_tag
@@ -30101,7 +33580,8 @@ echo
 echo "----------------------------------------------------------------"
 echo "Config is DONE!"
 echo
-echo "          With MMAP IO: $ac_cv_func_mmap_fixed_mapped"
+echo "          With MMAP IO: $enable_mmap"
+echo "       Static programs: $staticprogs"
 echo "          Perl Modules: $COMP_PERL"
 echo "           Perl Binary: $PERL"
 echo "          Perl Version: $PERL_VERSION"
@@ -30113,7 +33593,9 @@ echo "    Build Tcl Bindings: $enable_tcl"
 echo " Build Python Bindings: $enable_python"
 echo "          Build rrdcgi: $enable_rrdcgi"
 echo "       Build librrd MT: $enable_pthread"
+echo "     Link with libintl: $enable_libintl"
 echo
+echo "             Libraries: $ALL_LIBS"
 echo
 echo "Type 'make' to compile the software and use 'make install' to "
 echo "install everything to: $prefix."
index f2384275e8eb2b9cfbb699f86dd1f83f65a58e62..5a73316f234a0032dcb60281d5c9c793569967a9 100644 (file)
@@ -6,18 +6,35 @@ dnl
 dnl Inspiration from http://autoconf-archive.cryp.to
  
 dnl tell automake the this script is for rrdtool
+
 dnl the official version number is
 dnl a.b.c
-AC_INIT([rrdtool],[1.2.27])
+AC_INIT([rrdtool],[1.3rc4])
+
 dnl for testing a numberical version number comes handy
 dnl the released version are
 dnl a.bccc
-dnl the devl versions will be something like
+dnl the devel versions will be something like
 dnl a.b999yymmddhh 
-NUMVERS=1.2027
+NUMVERS=1.299908051800
 AC_SUBST(NUMVERS)
+
+dnl for the linker to understand which version the library is compatible with
+dnl we must keep a separate library version cout of the format c:r:a if any
+dnl functionality is changed do c++ prior to release
+dnl if only implementation changed but all interfaces are kept, do r++
+dnl when only functionality was added, do a++ if any functionality was
+dnl removed do a=0.
+dnl
+dnl see http://sourceware.org/autobook/autobook/autobook_91.html
+dnl 
+LIBVERS=3:2:1
+AC_SUBST(LIBVERS)
+
 AC_CANONICAL_TARGET
 AM_INIT_AUTOMAKE
+AM_MAINTAINER_MODE
+
 AC_CONFIG_HEADERS([rrd_config.h])
 
 dnl all our local stuff like install scripts and include files
@@ -49,7 +66,7 @@ AH_TOP([
 /* realloc does not support NULL as argument */
 #undef NO_NULL_REALLOC
 
-/* lets enable madvise defines in NetBSD */
+/* lets enable madvise defines in NetBSD */ 
 #if defined(__NetBSD__)
 # if !defined(_NETBSD_SOURCE)
 #  define _NETBSD_SOURCE
@@ -59,19 +76,18 @@ AH_TOP([
  ])
 
 AH_BOTTOM([
+/* make sure that we pickup the correct stuff from all headers */
 #ifdef HAVE_FEATURES_H
+#undef _XOPEN_SOURCE /* keep unmodified */
+#undef _BSD_SOURCE /* keep unmodified */
 #define _XOPEN_SOURCE 600
-#undef _BSD_SOURCE /* comment to prevent configure from modifying this line */   
 #define _BSD_SOURCE 1
 # include <features.h>
 #endif
 
-#ifdef HAVE_ERRNO_H
-# include <errno.h>
-#endif
-
-#if defined(HAVE_SYS_MMAN_H)
-#include <sys/mman.h>
+/* FreeBSD 4.8 wants this included BEFORE sys/types.h */
+#ifdef HAVE_SYS_MMAN_H
+# include <sys/mman.h>
 #endif
 
 #ifdef HAVE_SYS_TYPES_H
@@ -93,6 +109,10 @@ AH_BOTTOM([
 # endif
 #endif
 
+#ifdef HAVE_ERRNO_H
+# include <errno.h>
+#endif
+
 #if !defined HAVE_MADVISE && defined HAVE_POSIX_MADVISE
 /* use posix_madvise family */
 # define madvise posix_madvise
@@ -102,13 +122,6 @@ AH_BOTTOM([
 # define MADV_WILLNEED POSIX_MADV_WILLNEED
 # define MADV_DONTNEED POSIX_MADV_DONTNEED
 #endif
-
-#if defined POSIX_MADV_RANDOM && !defined MADV_RANDOM
-#define MADV_RANDOM POSIX_MADV_RANDOM
-#endif
-
-
-
 #if defined HAVE_MADVISE || defined HAVE_POSIX_MADVISE
 # define USE_MADVISE 1
 #endif
@@ -143,12 +156,13 @@ AH_BOTTOM([
 #ifdef HAVE_SYS_RESOURCE_H
 # include <sys/resource.h>
 #if (defined(__svr4__) && defined(__sun__))
-/* Solaris headers (pre 2.6) don't have a getrusage prototype.
+/* Solaris headers (pre 2.6) do not have a getrusage prototype. 
    Use this instead. */
 extern int getrusage(int, struct rusage *);
 #endif /* __svr4__ && __sun__ */
 #endif
 
+
 /* define strrchr, strchr and memcpy, memmove in terms of bsd funcs
    make sure you are NOT using bcopy, index or rindex in the code */
       
@@ -176,20 +190,58 @@ char *strchr (), *strrchr ();
 #  include <malloc/malloc.h>
 #endif
 
+#ifdef HAVE_STDIO_H
+# include <stdio.h>
+#endif
+
+#ifdef HAVE_STDLIB_H
+# include <stdlib.h>
+#endif
+
+#ifdef HAVE_CTYPE_H
+# include <ctype.h>
+#endif
+
+#ifdef HAVE_DIRENT_H
+# include <dirent.h>
+# define NAMLEN(dirent) strlen((dirent)->d_name)
+#else
+# define dirent direct
+# define NAMLEN(dirent) (dirent)->d_namlen
+# ifdef HAVE_SYS_NDIR_H
+#  include <sys/ndir.h>
+# endif
+# ifdef HAVE_SYS_DIR_H
+#  include <sys/dir.h>
+# endif
+# ifdef HAVE_NDIR_H
+#  include <ndir.h>
+# endif
+#endif
+
+#ifdef MUST_DISABLE_SIGFPE
+# include <signal.h>
+#endif
+
+#ifdef MUST_DISABLE_FPMASK
+# include <floatingpoint.h>
+#endif
+
+
 #ifdef HAVE_MATH_H
-#  include <math.h>
+# include <math.h>
 #endif
 
 #ifdef HAVE_FLOAT_H
-#  include <float.h>
+# include <float.h>
 #endif
 
 #ifdef HAVE_IEEEFP_H
-#  include <ieeefp.h>
+# include <ieeefp.h>
 #endif
 
 #ifdef HAVE_FP_CLASS_H
-#  include <fp_class.h>
+# include <fp_class.h>
 #endif
 
 /* for Solaris */
@@ -203,7 +255,7 @@ char *strchr (), *strrchr ();
 
 /* solaris 10 it defines isnan such that only forte can compile it ... bad bad  */
 #if (defined(HAVE_ISNAN) && defined(isnan) && defined(HAVE_FPCLASS))
-#  undef isnan  /* confuse autoconf to NOT remove this */
+#  undef isnan /* confuse autoconf to NOT remove this */
 #  define isnan(a) (fpclass(a) == FP_SNAN || fpclass(a) == FP_QNAN)
 #endif
 
@@ -247,6 +299,14 @@ char *strchr (), *strrchr ();
 #error "Can't compile without isinf function"
 #endif
 
+#if (! defined(HAVE_FDATASYNC) && defined(HAVE_FSYNC))
+#define fdatasync fsync
+#endif
+
+#if (!defined(HAVE_FDATASYNC) && !defined(HAVE_FSYNC))
+#error "Can't compile with without fsync and fdatasync"
+#endif
+
 #endif /* RRD_CONFIG_H */
 ])
 
@@ -255,9 +315,9 @@ dnl -----------------------------------
 
 dnl How the vertical axis label is printed
 AC_ARG_VAR(RRDGRAPH_YLEGEND_ANGLE, 
- [Vertical label angle: 90.0 (default) or 270.0])
+ [Vertical label angle: -90.0 (default) or 90.0])
 AC_DEFINE_UNQUOTED(RRDGRAPH_YLEGEND_ANGLE,${RRDGRAPH_YLEGEND_ANGLE:-90.0},
- [Vertical label angle: 90.0 (default) or 270.0])
+ [Vertical label angle: -90.0 (default) or 90.0])
 
 AC_ARG_ENABLE(rrdcgi,[  --disable-rrdcgi        disable building of rrdcgi],
 [],[enable_rrdcgi=yes])
@@ -269,7 +329,7 @@ AC_ARG_WITH(rrd-default-font,
   if test -d ${WINDIR:-nodir}/cour.ttf ; then
        RRD_DEFAULT_FONT=`cd $WINDIR;pwd`/cour.ttf
   else
-       RRD_DEFAULT_FONT='$(fontsdir)/$(fonts_DATA)'
+       RRD_DEFAULT_FONT='"DejaVu Sans Mono,Bitstream Vera Sans Mono,monospace,Courier"'
   fi
 ])
 
@@ -279,10 +339,17 @@ AC_ARG_ENABLE([mmap],
 [],
 [enable_mmap=yes])
 
-
- AC_ARG_ENABLE(pthread,[  --disable-pthread       disable multithread support],
+AC_ARG_ENABLE(pthread,[  --disable-pthread       disable multithread support],
 [],[enable_pthread=yes])
 
+AC_ARG_ENABLE(static-programs,
+     [  --enable-static-programs  Build static programs],
+     [case "${enableval}" in
+       yes) staticprogs=yes ;;
+       no)  staticprogs=no ;;
+       *) AC_MSG_ERROR(bad value ${enableval} for --enable-static-programs) ;;
+     esac],[staticprogs=no])
+AM_CONDITIONAL(STATIC_PROGRAMS,[test "x$staticprogs" = "xyes"])
 
 
 CONFIGURE_PART(Audit Compilation Environment)
@@ -293,16 +360,19 @@ AC_PROG_CC
 AC_PROG_CPP
 AC_PROG_LIBTOOL
 
-dnl which flags does the compile support?
-if test "$GCC" = "yes"; then
-  for flag in -fno-strict-aliasing -Wall -std=gnu99 -pedantic -Wshadow -Wpointer-arith -Wcast-align -Wmissing-prototypes -Wmissing-declarations -Wnested-externs -Winline -W; do
-    oCFLAGS=$CFLAGS
+dnl Try to detect/use GNU features
+CFLAGS="$CFLAGS -D_GNU_SOURCE"
+
+dnl which flags does the compiler support?
+if test "x$GCC" = "xyes"; then
+  for flag in -fno-strict-aliasing -Wall -std=c99 -pedantic -Wundef -Wshadow -Wpointer-arith -Wcast-align -Wmissing-prototypes -Wmissing-declarations -Wnested-externs -Winline -Wold-style-definition -W; do
+    oCFLAGS="$CFLAGS"
     CFLAGS="$CFLAGS $flag"
     cachename=rd_cv_gcc_flag_`echo $flag|sed 's/[[^A-Za-z]]/_/g'`
     AC_CACHE_CHECK([if gcc likes the $flag flag], $cachename,
        [AC_COMPILE_IFELSE([AC_LANG_PROGRAM([[]], [[return 0 ]])],[eval $cachename=yes],[eval $cachename=no])])
     if eval test \$$cachename = no; then
-         CFLAGS=$oCFLAGS
+         CFLAGS="$oCFLAGS"
     fi
   done
 fi
@@ -316,21 +386,24 @@ CONFIGURE_PART(Checking for Header Files)
 dnl Checks for header files.
 AC_HEADER_STDC
 AC_HEADER_DIRENT
-AC_CHECK_HEADERS( features.h sys/stat.h sys/types.h fcntl.h locale.h fp_class.h malloc.h unistd.h ieeefp.h math.h sys/times.h sys/param.h sys/resource.h float.h strings.h)
+AC_CHECK_HEADERS(features.h sys/stat.h sys/types.h fcntl.h locale.h fp_class.h malloc.h unistd.h ieeefp.h math.h sys/times.h sys/param.h sys/resource.h signal.h float.h stdio.h stdlib.h errno.h string.h ctype.h)
 
 dnl Checks for typedefs, structures, and compiler characteristics.
 AC_C_CONST
 AC_HEADER_TIME
 AC_STRUCT_TM
 
+CONFIGURE_PART(Test Library Functions)
+
 dnl Checks for libraries.
 AC_CHECK_FUNC(acos, , AC_CHECK_LIB(m, acos))
 
+
+
 dnl add pic flag in any case this makes sure all our code is relocatable
 eval `./libtool --config | grep pic_flag`
 CFLAGS="$CFLAGS $pic_flag"
 
-CONFIGURE_PART(Test Library Functions)
 
 dnl Checks for library functions.
 AC_FUNC_STRFTIME
@@ -341,9 +414,19 @@ AC_C_BIGENDIAN
 dnl for each function found we get a definition in config.h 
 dnl of the form HAVE_FUNCTION
 
-AC_CHECK_FUNCS(tzset mbstowcs opendir readdir chdir chroot getuid setlocale strerror strerror_r snprintf vsnprintf fpclass class fp_class isnan memmove strchr mktime getrusage gettimeofday posix_fadvise madvise)
+AC_CHECK_FUNCS(tzset fsync mbstowcs opendir readdir chdir chroot getuid setlocale strerror strerror_r snprintf vsnprintf fpclass class fp_class isnan memmove strchr mktime getrusage gettimeofday)
+
+CONFIGURE_PART(Map/Fadvis/Madvise checking)
+
+dnl Could use these to know if we need to provide a prototype
+dnl AC_CHECK_DECLS(fdatasync, [], [], [#include <unistd.h>])
+
+dnl check for fdatasync. Solaris has fdatasync in the librt
+
+AC_CHECK_FUNCS(fdatasync, [],  AC_CHECK_LIB(rt, fdatasync, [LIBS="${LIBS} -lrt"; AC_DEFINE(HAVE_FDATASYNC)],[]))
+dnl if there is no fdatasync we may get lucky with fsync
+AC_CHECK_FUNCS(fsync)
 
-AC_CHECK_DECLS(fdatasync, [], [], [#include <unistd.h>])
 
 dnl XXX: dunno about windows.. add AC_CHECK_FUNCS(munmap) there too?
 if test "x$enable_mmap" = "xyes"; then
@@ -360,8 +443,8 @@ if test "x$enable_mmap" = "xyes"; then
     AC_FUNC_MMAP
     AC_CHECK_FUNCS(mmap munmap msync)
     AC_CHECK_DECLS(madvise, [], [], [#ifdef HAVE_SYS_MMAN_H
-                                     # include <sys/mman.h>
-                                     #endif])
+                                    # include <sys/mman.h>
+                                    #endif])
     if test "x$ac_cv_have_decl_madvise" = "xyes";
     then
       AC_CHECK_FUNCS(madvise)
@@ -383,45 +466,104 @@ fi
 dnl can we use posix_fadvise
 AC_CHECK_DECLS(posix_fadvise, [], [], [#define _XOPEN_SOURCE 600
 #include <fcntl.h>])
-AC_CHECK_FUNCS(posix_fadvise)   
+AC_CHECK_FUNCS(posix_fadvise)
 
-if test "x$enable_mmap" = xyes; then
-  case "$host" in
-    *cygwin*)
-       # the normal mmap test does not work in cygwin
-       AC_CHECK_FUNCS(mmap)
-       if [ "x${ac_cv_func_mmap}" = xyes ]; then
-         ac_cv_func_mmap_fixed_mapped=yes
-       fi
-    ;;
-    *)
-       AC_FUNC_MMAP
-    ;;
-  esac
+CONFIGURE_PART(Libintl Processing)
+
+
+dnl gettext
+GETTEXT_PACKAGE=rrdtool
+AC_SUBST(GETTEXT_PACKAGE)
+AC_DEFINE_UNQUOTED(GETTEXT_PACKAGE,"$GETTEXT_PACKAGE",[Gettext package])
+
+AM_GLIB_GNU_GETTEXT()
+
+AC_ARG_ENABLE(libintl,[  --disable-libintl        i18n support (libintl)],
+[],[enable_libintl=yes])
+
+if test x$enable_libintl = xyes; then
+  IT_PROG_INTLTOOL([0.35.0],[no-xml])
+fi
+
+if test x$enable_libintl = xyes -a x$MSGFMT = xno; then
+  AC_MSG_WARN(I could not find msgfmt. Diabeling libintl build.)
+  enable_libintl=no
+fi
+
+if test x$enable_libintl = xyes; then
+  AC_CHECK_HEADERS(libintl.h,[],[AC_MSG_RESULT(disabeling libintl build); enable_libintl=no])
+fi
+
+if test x$enable_libintl = xyes ; then
+  dnl it seems bsd synstems need to link against libintl
+  dnl when compiling rrdupdate. lets check        
+  AC_CHECK_LIB(intl, libintl_gettext,[LIB_LIBINTL="-lintl"])
 fi
 
+dnl use for linking rrdupdate
+AC_SUBST(LIB_LIBINTL)
+
+dnl do not touch the po stuff if we are not going to build intl
+AM_CONDITIONAL(BUILD_LIBINTL,[test x$enable_libintl = xyes])
+
+if test x$enable_libintl = xyes; then
+   AC_DEFINE([BUILD_LIBINTL], [], [Use this in code sections to mark them for libintl build])
+fi
 
 CONFIGURE_PART(IEEE Math Checks)
  
-dnl HP-UX 11.00 does not have finite but does have isfinite as a macro so we need
+
 dnl actual code to check if this works
 AC_CHECK_FUNCS(fpclassify, ,
   [AC_MSG_CHECKING(for fpclassify with <math.h>)
     AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <math.h>
 volatile int x;volatile float f; ]], [[x = fpclassify(f)]])],[AC_MSG_RESULT(yes)
       AC_DEFINE(HAVE_FPCLASSIFY)],[AC_MSG_RESULT(no)])])
-AC_CHECK_FUNCS(finite, ,
-  [AC_CHECK_FUNCS(isfinite, ,
-    [AC_MSG_CHECKING(for isfinite with <math.h>)
-    AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <math.h>
-volatile int x;volatile float f;  ]], [[x = isfinite(f)]])],[AC_MSG_RESULT(yes)
-      AC_DEFINE(HAVE_ISFINITE)],[AC_MSG_RESULT(no)])])])
+
 AC_CHECK_FUNCS(isinf, ,
   [AC_MSG_CHECKING(for isinf with <math.h>)
     AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <math.h>
 volatile int x;volatile float f;  ]], [[x = isinf(f)]])],[AC_MSG_RESULT(yes)
       AC_DEFINE(HAVE_ISINF)],[AC_MSG_RESULT(no)])])
 
+dnl finite is BSD, isfinite is C99, so prefer the latter
+AC_CACHE_CHECK([whether isfinite is broken],[have_broken_isfinite],[
+AC_TRY_RUN([
+#ifdef HAVE_MATH_H
+#include <math.h>
+#endif
+#ifdef HAVE_FLOAT_H
+#include <float.h>
+#endif
+int main ()
+{
+#ifdef isfinite
+#ifdef LDBL_MAX
+  if (!isfinite(LDBL_MAX)) return 1;
+#endif
+#ifdef DBL_MAX
+  if (!isfinite(DBL_MAX)) return 1;
+#endif
+#endif
+return 0;
+}],[
+have_broken_isfinite=no],have_broken_isfinite=yes,[
+case "${target}" in
+  hppa*-*-hpux*) have_broken_isfinite=yes ;;
+  *) have_broken_isfinite=no ;;
+esac])
+])
+if test "x$have_broken_isfinite" = "xno"; then
+  AC_DEFINE(HAVE_ISFINITE)
+else
+AC_CHECK_FUNCS(finite,[],
+  [AC_CHECK_FUNCS(isfinite,[],
+      [AC_MSG_CHECKING(for isfinite with <math.h>)
+       AC_LINK_IFELSE([AC_LANG_PROGRAM([[#include <math.h>
+volatile int x;volatile float f;  ]],[[x = isfinite(f)]])],[AC_MSG_RESULT(yes)
+               AC_DEFINE(HAVE_ISFINITE)],[AC_MSG_RESULT(no)])])])
+fi
+
 AC_FULL_IEEE
 
 CONFIGURE_PART(Resolve Portability Issues)
@@ -522,12 +664,20 @@ CONFIGURE_PART(Find 3rd-Party Libraries)
 
 AM_CONDITIONAL(BUILD_RRDCGI,[test $enable_rrdcgi != no])
 
+
 CORE_LIBS="$LIBS"
 
-EX_CHECK_ALL(art_lgpl_2, art_vpath_add_point,       libart_lgpl/libart.h,   libart-2.0,  2.3.17, ftp://ftp.gnome.org/pub/GNOME/sources/libart_lgpl/2.3/, /usr/include/libart-2.0)
-EX_CHECK_ALL(z,          zlibVersion,               zlib.h,                 zlib,        1.2.3,  http://www.gzip.org/zlib/, "")
-EX_CHECK_ALL(png,        png_access_version_number, png.h,                  libpng,      1.2.10,  http://prdownloads.sourceforge.net/libpng/, "")
-EX_CHECK_ALL(freetype,   FT_Init_FreeType,          ft2build.h,                    freetype2,   2.1.10,  http://prdownloads.sourceforge.net/freetype/, /usr/include/freetype2)
+dnl EX_CHECK_ALL(z,          zlibVersion,               zlib.h,                 zlib,        1.2.3,  http://www.gzip.org/zlib/, "")
+dnl EX_CHECK_ALL(png,        png_access_version_number, png.h,                  libpng,      1.2.10,  http://prdownloads.sourceforge.net/libpng/, "")
+dnl EX_CHECK_ALL(freetype,   FT_Init_FreeType,          ft2build.h,            freetype2,   2.1.10,  http://prdownloads.sourceforge.net/freetype/, /usr/include/freetype2)
+dnl EX_CHECK_ALL(fontconfig, FcInit,                    fontconfig.h,          fontconfig,  2.3.1,  http://fontconfig.org/release/, /usr/include)
+EX_CHECK_ALL(cairo,      cairo_font_options_create,     cairo.h,                cairo-png,   1.4.6,  http://cairographics.org/releases/, "")
+EX_CHECK_ALL(cairo,      cairo_svg_surface_create,      cairo-svg.h,            cairo-svg,   1.4.6,  http://cairographics.org/releases/, "")
+EX_CHECK_ALL(cairo,      cairo_pdf_surface_create,      cairo-pdf.h,            cairo-pdf,   1.4.6,  http://cairographics.org/releases/, "")
+EX_CHECK_ALL(cairo,      cairo_ps_surface_create,       cairo-ps.h,             cairo-ps,    1.4.6,  http://cairographics.org/releases/, "")
+dnl EX_CHECK_ALL(glib-2.0,   glib_check_version,        glib.h,                 glib-2.0,    2.12.12, ftp://ftp.gtk.org/pub/glib/2.12/, "")
+EX_CHECK_ALL(pango-1.0,  pango_cairo_context_set_font_options,  pango/pango.h,  pangocairo,  1.17,    http://ftp.gnome.org/pub/GNOME/sources/pango/1.17, "")
+EX_CHECK_ALL(xml2,       xmlParseFile,                  libxml/parser.h,        libxml-2.0,        2.6.31,  http://xmlsoft.org/downloads.html, /usr/include/libxml2)
 
 if test "$EX_CHECK_ALL_ERR" = "YES"; then
   AC_MSG_ERROR([Please fix the library issues listed above and try again.])
@@ -541,8 +691,13 @@ AC_SUBST(ALL_LIBS)
 
 CONFIGURE_PART(Prep for Building Language Bindings)
   
-dnl Check for Perl.
+dnl Check for Perl and friends
+PATH=$PATH:/usr/perl5/bin
+export PATH
 AC_PATH_PROG(PERL, perl, no)
+AC_PATH_PROG(POD2MAN, pod2man, no)
+AC_PATH_PROG(POD2HTML, pod2html, no)
+
 
 AC_ARG_ENABLE(perl,[  --disable-perl          do not build the perl modules],
 [],[enable_perl=yes])
@@ -657,7 +812,7 @@ AC_ARG_ENABLE(ruby-site-install,
                          together with rrdtool in $prefix/lib/ruby. You have to
                           add $prefix/lib/ruby/$ruby_version/$sitearch to you $: variable
                           for ruby to find the RRD.so file.],
-[RUBY_MAKE_OPTIONS=],[RUBY_MAKE_OPTIONS="sitedir=$prefix/lib/ruby"])
+[RUBY_MAKE_OPTIONS=],[RUBY_MAKE_OPTIONS="sitedir="'$(DESTDIR)'"$prefix/lib/ruby"])
 
     
 AC_ARG_WITH(ruby-options,
@@ -682,7 +837,7 @@ if test  "$enable_tcl" = "yes"; then
   withval=""
   AC_ARG_WITH(tcllib,[  --with-tcllib=DIR       location of the tclConfig.sh])
   enable_tcl=no
-  for dir in $withval /usr/lib /usr/local/lib; do
+  for dir in $withval /usr/lib /usr/local/lib /usr/lib/tcl8.4 /usr/lib/tcl8.3 ; do
     AC_MSG_CHECKING(for tclConfig.sh in $dir)
     if test -f "$dir/tclConfig.sh" ; then
        tcl_config=$dir/tclConfig.sh
@@ -695,7 +850,7 @@ if test  "$enable_tcl" = "yes"; then
   done
 
   if test "$enable_tcl" = "no"; then
-        AC_MSG_WARN([tclConfig.sh not found - Tcl interface won't be built])
+        AC_MSG_WARN([tclConfig.sh not found - Tcl interface will not be built])
   else
        . $tcl_config
        TCL_PACKAGE_DIR="$TCL_PACKAGE_PATH/tclrrd$VERSION"
@@ -708,6 +863,7 @@ fi
 AM_CONDITIONAL(BUILD_TCL, test "$enable_tcl" = "yes" )
 AM_CONDITIONAL(BUILD_TCL_SITE, test "$enable_tcl_site" = "yes" )
 
+
 AC_SUBST(TCL_PREFIX)
 AC_SUBST(TCL_SHLIB_CFLAGS)
 AC_SUBST(TCL_SHLIB_LD)
@@ -717,6 +873,7 @@ AC_SUBST(TCL_LD_SEARCH_FLAGS)
 AC_SUBST(TCL_STUB_LIB_SPEC)
 AC_SUBST(TCL_VERSION)
 AC_SUBST(TCL_PACKAGE_DIR)
+AC_SUBST(TCL_INC_DIR)
 
 AC_ARG_ENABLE(python,[  --disable-python        do not build the python modules],
 [],[enable_python=yes])
@@ -755,6 +912,7 @@ AC_CONFIG_FILES([examples/4charts.pl])
 AC_CONFIG_FILES([examples/perftest.pl])
 AC_CONFIG_FILES([examples/Makefile])
 AC_CONFIG_FILES([doc/Makefile])
+AC_CONFIG_FILES([po/Makefile.in])
 AC_CONFIG_FILES([src/Makefile])
 AC_CONFIG_FILES([bindings/Makefile])
 AC_CONFIG_FILES([bindings/tcl/Makefile])
@@ -782,7 +940,8 @@ echo
 echo "----------------------------------------------------------------"
 echo "Config is DONE!"
 echo
-echo "          With MMAP IO: $ac_cv_func_mmap_fixed_mapped"
+echo "          With MMAP IO: $enable_mmap"
+echo "       Static programs: $staticprogs"
 echo "          Perl Modules: $COMP_PERL"
 echo "           Perl Binary: $PERL"
 echo "          Perl Version: $PERL_VERSION"
@@ -794,7 +953,9 @@ echo "    Build Tcl Bindings: $enable_tcl"
 echo " Build Python Bindings: $enable_python"
 echo "          Build rrdcgi: $enable_rrdcgi"
 echo "       Build librrd MT: $enable_pthread"
+echo "     Link with libintl: $enable_libintl"
 echo
+echo "             Libraries: $ALL_LIBS"
 echo
 echo "Type 'make' to compile the software and use 'make install' to "
 echo "install everything to: $prefix."
index 70f456c2a5a4f82db60c62dc601f06fc2a1e4c6b..16fd61755698fb51666b6a369102d089c144adaf 100644 (file)
@@ -39,7 +39,7 @@ all-local: link txt man html-local
        perl -n -e 'if (/^=include\s+(\S+)/){open F,"$$1.inc" || die $$?;print <F>; close F} else {print}'  $<  > $@
 
 .pod.1 .pm.1 .pl.1:
-       pod2man --release=$(VERSION) --center=rrdtool $<  > $@
+       @POD2MAN@ --release=$(VERSION) --center=rrdtool $<  > $@
 
 .1.txt:
        GROFF_NO_SGR=1 @NROFF@ -man -Tlp $< > $@
@@ -48,7 +48,7 @@ all-local: link txt man html-local
        @TROFF@ -man $< | ps2pdf - $@
 
 .pm.html .pod.html .pl.html:
-       pod2html --infile=$< --outfile=$@ --noindex --htmlroot=. --podpath=. --title=$*
+       @POD2HTML@ --infile=$< --outfile=$@ --noindex --htmlroot=. --podpath=. --title=$*
 
 RRDs.pod:
        $(LN_S) $(top_srcdir)/bindings/perl-shared/RRDs.pm RRDs.pod
index 180d4bc8e4c0fa8307dfad9f5bc3ee79df998d4a..d2dc7f80ed0d1ba3a2f39902d4e4977279d5b157 100644 (file)
@@ -64,6 +64,7 @@ DATA = $(idoc_DATA) $(ihtml_DATA) $(iman_DATA)
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 ACLOCAL = @ACLOCAL@
 ALL_LIBS = @ALL_LIBS@
+ALL_LINGUAS = @ALL_LINGUAS@
 AMDEP_FALSE = @AMDEP_FALSE@
 AMDEP_TRUE = @AMDEP_TRUE@
 AMTAR = @AMTAR@
@@ -72,6 +73,8 @@ AUTOCONF = @AUTOCONF@
 AUTOHEADER = @AUTOHEADER@
 AUTOMAKE = @AUTOMAKE@
 AWK = @AWK@
+BUILD_LIBINTL_FALSE = @BUILD_LIBINTL_FALSE@
+BUILD_LIBINTL_TRUE = @BUILD_LIBINTL_TRUE@
 BUILD_MULTITHREAD_FALSE = @BUILD_MULTITHREAD_FALSE@
 BUILD_MULTITHREAD_TRUE = @BUILD_MULTITHREAD_TRUE@
 BUILD_RRDCGI_FALSE = @BUILD_RRDCGI_FALSE@
@@ -80,6 +83,8 @@ BUILD_TCL_FALSE = @BUILD_TCL_FALSE@
 BUILD_TCL_SITE_FALSE = @BUILD_TCL_SITE_FALSE@
 BUILD_TCL_SITE_TRUE = @BUILD_TCL_SITE_TRUE@
 BUILD_TCL_TRUE = @BUILD_TCL_TRUE@
+CATALOGS = @CATALOGS@
+CATOBJEXT = @CATOBJEXT@
 CC = @CC@
 CCDEPMODE = @CCDEPMODE@
 CFLAGS = @CFLAGS@
@@ -94,6 +99,7 @@ CXXCPP = @CXXCPP@
 CXXDEPMODE = @CXXDEPMODE@
 CXXFLAGS = @CXXFLAGS@
 CYGPATH_W = @CYGPATH_W@
+DATADIRNAME = @DATADIRNAME@
 DEFS = @DEFS@
 DEPDIR = @DEPDIR@
 ECHO = @ECHO@
@@ -104,18 +110,57 @@ EGREP = @EGREP@
 EXEEXT = @EXEEXT@
 F77 = @F77@
 FFLAGS = @FFLAGS@
+GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
+GMOFILES = @GMOFILES@
+GMSGFMT = @GMSGFMT@
 GREP = @GREP@
 INSTALL_DATA = @INSTALL_DATA@
 INSTALL_PROGRAM = @INSTALL_PROGRAM@
 INSTALL_SCRIPT = @INSTALL_SCRIPT@
 INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INSTOBJEXT = @INSTOBJEXT@
+INTLLIBS = @INTLLIBS@
+INTLTOOL_CAVES_RULE = @INTLTOOL_CAVES_RULE@
+INTLTOOL_DESKTOP_RULE = @INTLTOOL_DESKTOP_RULE@
+INTLTOOL_DIRECTORY_RULE = @INTLTOOL_DIRECTORY_RULE@
+INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@
+INTLTOOL_ICONV = @INTLTOOL_ICONV@
+INTLTOOL_KBD_RULE = @INTLTOOL_KBD_RULE@
+INTLTOOL_KEYS_RULE = @INTLTOOL_KEYS_RULE@
+INTLTOOL_MERGE = @INTLTOOL_MERGE@
+INTLTOOL_MSGFMT = @INTLTOOL_MSGFMT@
+INTLTOOL_MSGMERGE = @INTLTOOL_MSGMERGE@
+INTLTOOL_OAF_RULE = @INTLTOOL_OAF_RULE@
+INTLTOOL_PERL = @INTLTOOL_PERL@
+INTLTOOL_PONG_RULE = @INTLTOOL_PONG_RULE@
+INTLTOOL_PROP_RULE = @INTLTOOL_PROP_RULE@
+INTLTOOL_SCHEMAS_RULE = @INTLTOOL_SCHEMAS_RULE@
+INTLTOOL_SERVER_RULE = @INTLTOOL_SERVER_RULE@
+INTLTOOL_SERVICE_RULE = @INTLTOOL_SERVICE_RULE@
+INTLTOOL_SHEET_RULE = @INTLTOOL_SHEET_RULE@
+INTLTOOL_SOUNDLIST_RULE = @INTLTOOL_SOUNDLIST_RULE@
+INTLTOOL_THEME_RULE = @INTLTOOL_THEME_RULE@
+INTLTOOL_UI_RULE = @INTLTOOL_UI_RULE@
+INTLTOOL_UPDATE = @INTLTOOL_UPDATE@
+INTLTOOL_XAM_RULE = @INTLTOOL_XAM_RULE@
+INTLTOOL_XGETTEXT = @INTLTOOL_XGETTEXT@
+INTLTOOL_XML_NOMERGE_RULE = @INTLTOOL_XML_NOMERGE_RULE@
+INTLTOOL_XML_RULE = @INTLTOOL_XML_RULE@
 LDFLAGS = @LDFLAGS@
 LIBOBJS = @LIBOBJS@
 LIBS = @LIBS@
 LIBTOOL = @LIBTOOL@
+LIBVERS = @LIBVERS@
+LIB_LIBINTL = @LIB_LIBINTL@
 LN_S = @LN_S@
 LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@
+MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@
 MAKEINFO = @MAKEINFO@
+MKINSTALLDIRS = @MKINSTALLDIRS@
+MSGFMT = @MSGFMT@
+MSGFMT_OPTS = @MSGFMT_OPTS@
 MULTITHREAD_CFLAGS = @MULTITHREAD_CFLAGS@
 MULTITHREAD_LDFLAGS = @MULTITHREAD_LDFLAGS@
 NROFF = @NROFF@
@@ -138,6 +183,12 @@ PERL_CC = @PERL_CC@
 PERL_MAKE_OPTIONS = @PERL_MAKE_OPTIONS@
 PERL_VERSION = @PERL_VERSION@
 PKGCONFIG = @PKGCONFIG@
+POD2HTML = @POD2HTML@
+POD2MAN = @POD2MAN@
+POFILES = @POFILES@
+POSUB = @POSUB@
+PO_IN_DATADIR_FALSE = @PO_IN_DATADIR_FALSE@
+PO_IN_DATADIR_TRUE = @PO_IN_DATADIR_TRUE@
 PTHREAD_CC = @PTHREAD_CC@
 PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
 PTHREAD_LIBS = @PTHREAD_LIBS@
@@ -155,7 +206,10 @@ RUBY = @RUBY@
 RUBY_MAKE_OPTIONS = @RUBY_MAKE_OPTIONS@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
+STATIC_PROGRAMS_FALSE = @STATIC_PROGRAMS_FALSE@
+STATIC_PROGRAMS_TRUE = @STATIC_PROGRAMS_TRUE@
 STRIP = @STRIP@
+TCL_INC_DIR = @TCL_INC_DIR@
 TCL_LD_SEARCH_FLAGS = @TCL_LD_SEARCH_FLAGS@
 TCL_PACKAGE_DIR = @TCL_PACKAGE_DIR@
 TCL_PACKAGE_PATH = @TCL_PACKAGE_PATH@
@@ -166,7 +220,9 @@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@
 TCL_STUB_LIB_SPEC = @TCL_STUB_LIB_SPEC@
 TCL_VERSION = @TCL_VERSION@
 TROFF = @TROFF@
+USE_NLS = @USE_NLS@
 VERSION = @VERSION@
+XGETTEXT = @XGETTEXT@
 ac_ct_CC = @ac_ct_CC@
 ac_ct_CXX = @ac_ct_CXX@
 ac_ct_F77 = @ac_ct_F77@
@@ -254,7 +310,7 @@ all: all-am
 
 .SUFFIXES:
 .SUFFIXES: .pod .1 .man .html .txt .pm .pdf .inc .pl .src
-$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
        @for dep in $?; do \
          case '$(am__configure_deps)' in \
            *$$dep*) \
@@ -279,9 +335,9 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
 $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
        cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
 
-$(top_srcdir)/configure:  $(am__configure_deps)
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
        cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
        cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
 
 mostlyclean-libtool:
@@ -481,7 +537,7 @@ all-local: link txt man html-local
        perl -n -e 'if (/^=include\s+(\S+)/){open F,"$$1.inc" || die $$?;print <F>; close F} else {print}'  $<  > $@
 
 .pod.1 .pm.1 .pl.1:
-       pod2man --release=$(VERSION) --center=rrdtool $<  > $@
+       @POD2MAN@ --release=$(VERSION) --center=rrdtool $<  > $@
 
 .1.txt:
        GROFF_NO_SGR=1 @NROFF@ -man -Tlp $< > $@
@@ -490,7 +546,7 @@ all-local: link txt man html-local
        @TROFF@ -man $< | ps2pdf - $@
 
 .pm.html .pod.html .pl.html:
-       pod2html --infile=$< --outfile=$@ --noindex --htmlroot=. --podpath=. --title=$*
+       @POD2HTML@ --infile=$< --outfile=$@ --noindex --htmlroot=. --podpath=. --title=$*
 
 RRDs.pod:
        $(LN_S) $(top_srcdir)/bindings/perl-shared/RRDs.pm RRDs.pod
index d7876b5a2b2aeb8de34721231d260247e0df13a0..f5f4c1e1ca5391084e6a53d6d83b5169e4f88c63 100644 (file)
@@ -111,6 +111,11 @@ the values of the properties.</p>
  foreach my $key (keys %$hash){
    print &quot;$key = $$hash{$key}\n&quot;;
  }</pre>
+<p><strong>RRDs::graphv</strong> takes the same paramters as <strong>RRDs::graph</strong> but it returns a
+pointer to hash. The hash returned contains meta information about the
+graph. Like its size as well as the position of the graph area on the image.
+When calling with and empty filename than the contents of the graph will be
+returned in the hash as well (key 'image').</p>
 <p><strong>RRDs::updatev</strong> also returns a pointer to hash. The keys of the hash
 are concatenated strings of a timestamp, RRA index, and data source name for
 each consolidated data point (CDP) written to disk as a result of the
index f09d6e220cc0d83ee4600a5fabf1efe4856ff297..a9b770ce52dbfcf56af14d76b7eb22e404c6477f 100644 (file)
 .\" ========================================================================
 .\"
 .IX Title "BIN_DEC_HEX 1"
-.TH BIN_DEC_HEX 1 "2008-02-17" "1.2.27" "rrdtool"
+.TH BIN_DEC_HEX 1 "2008-03-15" "1.3rc4" "rrdtool"
 .SH "NAME"
 bin_dec_hex \- How to use binary, decimal, and hexadecimal notation.
 .SH "DESCRIPTION"
index 8b86f197373fd135e3e638a153c462a575aa4868..d6c85193d759e86a1c2abc80222506758149b0d5 100644 (file)
@@ -371,4 +371,4 @@ A\bAU\bUT\bTH\bHO\bOR\bR
 
 
 
-1.2.27                            2008-02-17                    BIN_DEC_HEX(1)
+1.3rc4                            2008-03-15                    BIN_DEC_HEX(1)
index 26cd3e925e68d5721597bce1339c37a1dc293285..90599b94814c778b11e9ed9eb0b0b0750a36b11e 100644 (file)
 .\" ========================================================================
 .\"
 .IX Title "CDEFTUTORIAL 1"
-.TH CDEFTUTORIAL 1 "2008-02-17" "1.2.27" "rrdtool"
+.TH CDEFTUTORIAL 1 "2008-03-15" "1.3rc4" "rrdtool"
 .SH "NAME"
 cdeftutorial \- Alex van den Bogaerdt's CDEF tutorial
 .SH "DESCRIPTION"
index 647b758c284b77b8a0c685990b4a87d835ed4d39..2a572d916e5b113536b69a037ffa71120f4def12 100644 (file)
@@ -799,4 +799,4 @@ A\bAU\bUT\bTH\bHO\bOR\bR
 
 
 
-1.2.27                            2008-02-17                   CDEFTUTORIAL(1)
+1.3rc4                            2008-03-15                   CDEFTUTORIAL(1)
index 83734a82176c5b82f03fb4951f82aa7ac0da36dd..ab56b0a741efb04d6bde5cd4e3e4f728b9ad364c 100644 (file)
 .\" ========================================================================
 .\"
 .IX Title "RPNTUTORIAL 1"
-.TH RPNTUTORIAL 1 "2008-02-17" "1.2.27" "rrdtool"
+.TH RPNTUTORIAL 1 "2008-03-15" "1.3rc4" "rrdtool"
 .SH "NAME"
 rpntutorial \- Reading RRDtool RPN Expressions by Steve Rader
 .SH "DESCRIPTION"
index f936d2ddc5a7c7de9b6514878ecf666aab3094df..75f39cd5043aa32c0ebbd73e5675696912d680ad 100644 (file)
@@ -187,4 +187,4 @@ A\bAU\bUT\bTH\bHO\bOR\bR
 
 
 
-1.2.27                            2008-02-17                    RPNTUTORIAL(1)
+1.3rc4                            2008-03-15                    RPNTUTORIAL(1)
index 5c67f83fdd3528832cee2528d27e02b432749ca6..d554a2aa97d229f6e33faa6bdb1f7994570f1628 100644 (file)
 .\" ========================================================================
 .\"
 .IX Title "RRD-BEGINNERS 1"
-.TH RRD-BEGINNERS 1 "2008-02-17" "1.2.27" "rrdtool"
+.TH RRD-BEGINNERS 1 "2008-03-15" "1.3rc4" "rrdtool"
 .SH "NAME"
 rrd\-beginners \- RRDtool Beginners' Guide
 .SH "SYNOPSIS"
index 8c60eeb875876c61ca1e0a962164580978459e76..39f76fcb10cd2ab825f50ee664201eccf04ba044 100644 (file)
@@ -318,4 +318,4 @@ A\bAU\bUT\bTH\bHO\bOR\bR
 
 
 
-1.2.27                            2008-02-17                  RRD-BEGINNERS(1)
+1.3rc4                            2008-03-15                  RRD-BEGINNERS(1)
index 52b88b9cd49aaea5bca8d539383efde1771530a5..25457ae5e9520f465b4d8370d507949a3f363696 100644 (file)
 .\" ========================================================================
 .\"
 .IX Title "RRDBUILD 1"
-.TH RRDBUILD 1 "2008-02-17" "1.2.27" "rrdtool"
+.TH RRDBUILD 1 "2008-05-18" "1.3rc4" "rrdtool"
 .SH "NAME"
 rrdbuild \- Instructions for building RRDtool
-.SH "DESCRIPTION"
-.IX Header "DESCRIPTION"
-.Sh "Overview"
-.IX Subsection "Overview"
+.SH "OVERVIEW"
+.IX Header "OVERVIEW"
 If you downloaded the source of rrdtool you have to compile it. This
 document will give some information on how this is done.
 .PP
@@ -144,8 +142,17 @@ may already be installed on your system. You have to compile copies of the other
 ones before you can build RRDtool.
 .PP
 This document will tell you about all the necessary steps to get going.
-.Sh "Building"
-.IX Subsection "Building"
+.PP
+These instructions assume you are using a \fBbash\fR shell. If you use csh/tcsh,
+then you can either type \fIbash\fR to switch to bash for the compilation or if
+you know what you are doing just replace the export bits with
+setenv.
+.PP
+We further assume that your copies of \fBtar\fR and \fBmake\fR are actually \fB\s-1GNU\s0
+tar\fR and \fB\s-1GNU\s0 make\fR respectively. It could be that they are installed as
+\&\fBgtar\fR and \fBgmake\fR on your system.
+.SH "OPTIMISTIC BUILD"
+.IX Header "OPTIMISTIC BUILD"
 Before you start to build RRDtool, you have to decide two things:
 .IP "1." 4
 In which directory you want to build the software.
@@ -153,18 +160,10 @@ In which directory you want to build the software.
 Where you want to install the software.
 .PP
 Once you have decided. Save the two locations into environment variables.
-Depending on the shell you are using, you can do either (bash,zsh):
 .PP
 .Vb 2
 \& BUILD_DIR=/tmp/rrdbuild
-\& INSTALL_DIR=/usr/local/rrdtool\-1.2.27
-.Ve
-.PP
-Or if you run tcsh:
-.PP
-.Vb 2
-\& set BUILD_DIR=/tmp/rrdbuild
-\& set INSTALL_DIR=/usr/local/rrdtool\-1.2.27
+\& INSTALL_DIR=/usr/local/rrdtool\-1.3rc4
 .Ve
 .PP
 If your \fI/tmp\fR is mounted with the option noexec (\s-1RHEL\s0 seems todo that) you have to choose
@@ -178,26 +177,57 @@ Now make sure the \s-1BUILD_DIR\s0 exists and go there:
 .Ve
 .PP
 Lets first assume you already have all the necessary libraries
-pre\-installed. Note that these instructions assume that your copies of
-\&\fBtar\fR and \fBmake\fR are actually \fB\s-1GNU\s0 tar\fR and \fB\s-1GNU\s0 make\fR respectively. It
-could be that they are installed as \fBgtar\fR and \fBgmake\fR on your system.
+pre\-installed. 
 .PP
 .Vb 4
-\& wget http://oss.oetiker.ch/rrdtool/pub/rrdtool\-1.2.27.tar.gz
-\& tar zxf rrdtool\-1.2.27.tar.gz
-\& cd rrdtool\-1.2.27
+\& wget http://oss.oetiker.ch/rrdtool/pub/rrdtool\-1.3rc4.tar.gz
+\& gunzip \-c rrdtool\-1.3rc4.tar.gz | tar xf \-
+\& cd rrdtool\-1.3rc4
 \& ./configure \-\-prefix=$INSTALL_DIR && make && make install
 .Ve
 .PP
 Ok, this was very optimistic. This try will probably have ended with
-\&\fBconfigure\fR complaining about several missing libraries. If you are on a
-Linux or *bsd system you may want to just install the missing bits from your
-software repository. When you do that, make sure you also get the \fB\-dev\fR
-package for each library you install. Once you have the missing bits on
-board, just re-run the last line of the instructions above.
+\&\fBconfigure\fR complaining about several missing libraries.
+.SH "INSTALLING DEPENDENCIES"
+.IX Header "INSTALLING DEPENDENCIES"
+If your \s-1OS\s0 lets you install additional packages from a software repository,
+you may get away with installing the missing packages. When the packages are
+installed, run configure again and try to compile again. Below you find some
+hints on getting your \s-1OS\s0 ready for the rrdtool compilation. Additions to
+this list are welcome.
+.Sh "OpenSolaris 2008.05"
+.IX Subsection "OpenSolaris 2008.05"
+Just add a compiler and the gnome development package:
+.PP
+.Vb 2
+\& pkg install sunstudioexpress
+\& pkg install SUNWgnome\-common\-devel
+.Ve
+.PP
+There is a a problem with \fIcairo.pc\fR on opensolaris. It suggests that
+xrender is required for compilation with cairo. This is not true and also
+bad since opensolaris does not include an \fIxrender.pc\fR file. Use perl to
+fix this:
+.PP
+.Vb 1
+\& perl \-i~ \-p \-e 's/(Requires.*?)\es*xrender.*/$1/' /usr/lib/pkgconfig/cairo.pc
+.Ve
+.Sh "Debian / Ubuntu"
+.IX Subsection "Debian / Ubuntu"
+Use apt-get to make sure you have all that is required. A number
+of packages will get added through dependencies.
 .PP
-But again this may have been too optimistic, and you actually have to
-compile your own copies of the required libraries.
+.Vb 1
+\& apt\-get install libpango1.0\-dev libxml2\-dev
+.Ve
+.SH "BUILDING DEPENDENCIES"
+.IX Header "BUILDING DEPENDENCIES"
+But again this may have been too optimistic still, and you actually have to
+compile your own copies of some of the required libraries. Things like
+libpng and zlib are pretty standard so you will probably have them on your
+system anyway. Freetype, Fontinst, Cairo, Pango may be installed, but it is
+possible that they are pretty old and thus don't live up to the
+expectations, so you may want to compile their latest versions.
 .PP
 \fIBuild Tipps for \s-1AIX\s0\fR
 .IX Subsection "Build Tipps for AIX"
@@ -226,16 +256,71 @@ If you have an other compile you have to use the following settings:
 .Vb 1
 \& CFLAGS="\-xO3 \-kPIC"
 .Ve
+.Sp
+.RS 4
+Some libraries want to know where other libraries are. For this to work,
+set the following environamen variable
+.Sp
+.Vb 2
+\& export PKG_CONFIG_PATH=${INSTALL_DIR}/lib/pkgconfig
+\& export PATH=$INSTALL_DIR/bin:$PATH
+.Ve
+.Sp
+Since we are compiling libraries dynamically, you they must further know
+where to find each other. This is done by setting an appropriate \s-1LDFLAG\s0.
+Unfortunatly the syntax differs from system to system:
+.IP "Solaris" 4
+.IX Item "Solaris"
+.Vb 1
+\& export LDFLAGS=\-R${INSTALL_DIR}/lib
+.Ve
+.IP "Linux" 4
+.IX Item "Linux"
+.Vb 1
+\& export LDFLAGS="\-Wl,\-\-rpath \-Wl,${INSTALL_DIR}/lib"
+.Ve
+.Sp
+If you are on a 64bit platform, but would like to continue to use the rrd files created
+on your old 32bit linux, you may be able 
+.IP "\s-1HPUX\s0" 4
+.IX Item "HPUX"
+.Vb 1
+\& export LDFLAGS="+b${INSTALL_DIR}/lib"
+.Ve
+.IP "\s-1AIX\s0" 4
+.IX Item "AIX"
+.Vb 1
+\& export LDFLAGS="\-Wl,\-blibpath:${INSTALL_DIR}/lib"
+.Ve
+.RE
+.RS 4
+.Sp
+If you have GNUmake installed and it is not called 'make',
+then do
+.Sp
+.Vb 2
+\& export MAKE=gmake
+\& export GNUMAKE=gmake
+.Ve
+.Sp
+otherwhise just do
+.Sp
+.Vb 1
+\& export MAKE=make
+.Ve
+.RE
 .IP "Building zlib" 4
 .IX Item "Building zlib"
+Chances are very high that you already have that on your system ... 
+.Sp
 .Vb 7
 \& cd $BUILD_DIR
 \& wget http://oss.oetiker.ch/rrdtool/pub/libs/zlib\-1.2.3.tar.gz
-\& tar  zxf zlib\-1.2.3.tar.gz
+\& gunzip \-c zlib\-1.2.3.tar.gz | tar xf \-
 \& cd zlib\-1.2.3
-\& env CFLAGS="\-O3 \-fPIC" ./configure \-\-prefix=$BUILD_DIR/lb
-\& make
-\& make install
+\& ./configure \-\-prefix=$INSTALL_DIR CFLAGS="\-O3 \-fPIC" \-\-shared
+\& $MAKE
+\& $MAKE install
 .Ve
 .IP "Building libpng" 4
 .IX Item "Building libpng"
@@ -244,77 +329,113 @@ already have a copy of zlib on your system (which is very likley) you can
 drop the settings of \s-1LDFLAGS\s0 and \s-1CPPFLAGS\s0. Note that the backslash (\e) at
 the end of line 4 means that line 4 and line 5 are on one line.
 .Sp
-.Vb 8
+.Vb 7
 \& cd $BUILD_DIR
-\& wget http://oss.oetiker.ch/rrdtool/pub/libs/libpng\-1.2.10.tar.gz
-\& tar zxvf libpng\-1.2.10.tar.gz
+\& wget http://oss.oetiker.ch/rrdtool/pub/libs/libpng\-1.2.18.tar.gz
+\& gunzip \-c libpng\-1.2.18.tar.gz | tar xf \-
 \& cd libpng\-1.2.10
-\& env CPPFLAGS="\-I$BUILD_DIR/lb/include" LDFLAGS="\-L$BUILD_DIR/lb/lib" CFLAGS="\-O3 \-fPIC" \e
-\&     ./configure \-\-disable\-shared \-\-prefix=$BUILD_DIR/lb
-\& make
-\& make install
+\& env CFLAGS="\-O3 \-fPIC" ./configure \-\-prefix=$INSTALL_DIR
+\& $MAKE
+\& $MAKE install
 .Ve
 .IP "Building freetype" 4
 .IX Item "Building freetype"
-.Vb 8
+.Vb 7
 \& cd $BUILD_DIR
-\& wget http://oss.oetiker.ch/rrdtool/pub/libs/freetype\-2.1.10.tar.bz2
-\& tar jxvf freetype\-2.1.10.tar.bz2
-\& cd freetype\-2.1.10
-\& env CPPFLAGS="\-I$BUILD_DIR/lb/include" LDFLAGS="\-L$BUILD_DIR/lb/lib" CFLAGS="\-O3 \-fPIC" \e
-\&     ./configure \-\-disable\-shared \-\-prefix=$BUILD_DIR/lb
-\& make
-\& make install
+\& wget http://oss.oetiker.ch/rrdtool/pub/libs/freetype\-2.3.5.tar.gz
+\& gunzip \-c freetype\-2.3.5.tar.gz | tar xf \-
+\& cd freetype\-2.3.5
+\& ./configure \-\-prefix=$INSTALL_DIR CFLAGS="\-O3 \-fPIC"
+\& $MAKE
+\& $MAKE install
 .Ve
 .Sp
 If you run into problems building freetype on Solaris, you may want to try to
-add the following at the end of the configure line:
+add the following at the start the configure line:
 .Sp
 .Vb 1
-\& GNUMAKE=gmake EGREP=egrep
+\& env EGREP=egrep
 .Ve
-.IP "Building libart_lgpl" 4
-.IX Item "Building libart_lgpl"
+.IP "Building LibXML2" 4
+.IX Item "Building LibXML2"
 .Vb 7
 \& cd $BUILD_DIR
-\& wget http://oss.oetiker.ch/rrdtool/pub/libs/libart_lgpl\-2.3.17.tar.gz
-\& tar zxvf libart_lgpl\-2.3.17.tar.gz
-\& cd libart_lgpl\-2.3.17
-\& env CFLAGS="\-O3 \-fPIC" ./configure \-\-disable\-shared \-\-prefix=$BUILD_DIR/lb
-\& make
-\& make install
+\& wget http://oss.oetiker.ch/rrdtool/pub/libs/libxml2\-sources\-2.6.31.tar.gz
+\& gunzip \-c libxml2\-sources\-2.6.32.tar.gz | tar xf \-
+\& cd libxml2\-sources\-2.6.32
+\& ./configure \-\-prefix=$INSTALL_DIR CFLAGS="\-O3 \-fPIC"
+\& $MAKE
+\& $MAKE install
 .Ve
-.PP
-Now all the dependent libraries are built and you can try again. Since these
-are static libraries, you may have to use \fIranlib\fR to make them accessible.
-Especially \s-1BSD\s0 systems like Mac \s-1OS\s0 X may require this, Linux and Solaris
-will do just fine without since their \fIar\fR command does ranlibs job as well.
-.PP
-.Vb 1
-\& ranlib $BUILD_DIR/lb/lib/*.a
+.IP "Building fontconfig" 4
+.IX Item "Building fontconfig"
+Note that fontconfig has a runtime configuration file in INSTALL_DIR/etc you
+may want to adjust that so that fontconfig finds the fonts on your system.
+Run the fc-cache program to build the fontconfig cache after changeing the
+config file.
+.Sp
+.Vb 7
+\& cd $BUILD_DIR
+\& wget http://oss.oetiker.ch/rrdtool/pub/libs/fontconfig\-2.4.2.tar.gz
+\& gunzip \-c fontconfig\-2.4.2.tar.gz   | tar xf \-
+\& cd fontconfig\-2.4.2
+\& ./configure \-\-prefix=$INSTALL_DIR CFLAGS="\-O3 \-fPIC"
+\& $MAKE
+\& $MAKE install
 .Ve
-.PP
-This time you tell configure where it should be looking for libraries and
-include files. This is done via environment variables. Depending on the
-shell you are running, the syntax for setting environment variables is
-different. Under csh/tcsh you use:
-.PP
-.Vb 4
-\& set IR=\-I$BUILD_DIR/lb/include
-\& setenv CPPFLAGS "$IR $IR/libart\-2.0 $IR/freetype2 $IR/libpng"
-\& setenv LDFLAGS  \-L$BUILD_DIR/lb/lib
-\& setenv CFLAGS \-O3
+.IP "Building Pixman" 4
+.IX Item "Building Pixman"
+.Vb 7
+\& cd $BUILD_DIR
+\& wget http://oss.oetiker.ch/rrdtool/pub/libs/pixman\-0.10.0.tar.gz
+\& gunzip \-c pixman\-0.10.0.tar.gz  | tar xf \-
+\& cd fontconfig\-2.4.2
+\& ./configure \-\-prefix=$INSTALL_DIR CFLAGS="\-O3 \-fPIC"
+\& $MAKE
+\& $MAKE install
 .Ve
-.PP
-If you are running bash/sh/ash/ksh/zsh use this:
-.PP
-.Vb 5
-\& IR=\-I$BUILD_DIR/lb/include
-\& CPPFLAGS="$IR $IR/libart\-2.0 $IR/freetype2 $IR/libpng"
-\& LDFLAGS="\-L$BUILD_DIR/lb/lib"
-\& CFLAGS=\-O3
-\& export CPPFLAGS LDFLAGS CFLAGS
+.IP "Building Cairo" 4
+.IX Item "Building Cairo"
+.Vb 11
+\& cd $BUILD_DIR
+\& wget http://oss.oetiker.ch/rrdtool/pub/libs/cairo\-1.6.4.tar.gz
+\& gunzip \-c cairo\-1.4.10.tar.gz   | tar xf \-
+\& cd cairo\-1.4.10
+\& ./configure \-\-prefix=$INSTALL_DIR \e
+\&    \-\-enable\-xlib=no \e
+\&    \-\-enable\-xlib\-render=no \e
+\&    \-\-enable\-win32=no \e
+\&    CFLAGS="\-O3 \-fPIC"
+\& $MAKE
+\& $MAKE install
 .Ve
+.IP "Building Glib" 4
+.IX Item "Building Glib"
+.Vb 7
+\& cd $BUILD_DIR
+\& wget http://oss.oetiker.ch/rrdtool/pub/libs/glib\-2.15.4.tar.gz
+\& gunzip \-c glib\-2.12.13.tar.gz  | tar xf \-
+\& cd glib\-2.12.13
+\& ./configure \-\-prefix=$INSTALL_DIR CFLAGS="\-O3 \-fPIC"
+\& $MAKE
+\& $MAKE install
+.Ve
+.IP "Building Pango" 4
+.IX Item "Building Pango"
+.Vb 7
+\& cd $BUILD_DIR
+\& wget http://oss.oetiker.ch/rrdtool/pub/libs/pango\-1.21.1.tar.gz
+\& gunzip \-c pango\-1.21.1.tar.gz  | tar xf \-
+\& cd pango\-1.21.1
+\& ./configure \-\-prefix=$INSTALL_DIR CFLAGS="\-O3 \-fPIC" \-\-without\-x
+\& $MAKE
+\& $MAKE install
+.Ve
+.PP
+Now all the dependent libraries are built and you can try again. This time
+you tell configure where it should be looking for libraries and include
+files. This is done via environment variables. Depending on the shell you
+are running, the syntax for setting environment variables is different.
 .PP
 And finally try building again. We disable the python and tcl bindings
 because it seems that a fair number of people have ill configured python and
@@ -322,20 +443,20 @@ tcl setups that would prevent rrdtool from building if they are included in
 their current state.
 .PP
 .Vb 5
-\& cd $BUILD_DIR/rrdtool\-1.2.27
-\& ./configure \-\-prefix=$INSTALL_DIR \-\-disable\-python \-\-disable\-tcl
-\& make clean
-\& make
-\& make install
+\& cd $BUILD_DIR/rrdtool\-1.3rc4
+\& ./configure \-\-prefix=$INSTALL_DIR \-\-disable\-tcl \-\-disable\-python
+\& $MAKE clean
+\& $MAKE
+\& $MAKE install
 .Ve
 .PP
 \&\s-1SOLARIS\s0 \s-1HINT:\s0 if you want to build  the perl module for the native perl (the
-one shipping with solaris) you will need the sun forte compiler
-installed on your box or you have to hand-tune bindings/perl\-shared/Makefile
-while building!
+one shipping with solaris) you will need the sun forte compiler installed on
+your box or you have to hand-tune bindings/perl\-shared/Makefile while
+building!
 .PP
-Now go to \fI$INSTALL_DIR\fR\fB/share/rrdtool/examples/\fR and run them to see if your
-build has been successful.
+Now go to \fI$INSTALL_DIR\fR\fB/share/rrdtool/examples/\fR and run them to see if
+your build has been successful.
 .SH "AUTHOR"
 .IX Header "AUTHOR"
 Tobias Oetiker <tobi@oetiker.ch>
index 455b85d4403496481d8e1d5c145a74cac197997a..e91a572fb7e3ec344eb599c208f345946f961c96 100644 (file)
 <ul>
 
        <li><a href="#name">NAME</a></li>
-       <li><a href="#description">DESCRIPTION</a></li>
+       <li><a href="#overview">OVERVIEW</a></li>
+       <li><a href="#optimistic_build">OPTIMISTIC BUILD</a></li>
+       <li><a href="#installing_dependencies">INSTALLING DEPENDENCIES</a></li>
+       <ul>
+
+               <li><a href="#opensolaris_2008_05">OpenSolaris 2008.05</a></li>
+               <li><a href="#debian___ubuntu">Debian / Ubuntu</a></li>
+       </ul>
+
+       <li><a href="#building_dependencies">BUILDING DEPENDENCIES</a></li>
        <ul>
 
-               <li><a href="#overview">Overview</a></li>
-               <li><a href="#building">Building</a></li>
                <ul>
 
                        <li><a href="#build_tipps_for_aix">Build Tipps for AIX</a></li>
 <p>
 </p>
 <hr />
-<h1><a name="description">DESCRIPTION</a></h1>
-<p>
-</p>
-<h2><a name="overview">Overview</a></h2>
+<h1><a name="overview">OVERVIEW</a></h1>
 <p>If you downloaded the source of rrdtool you have to compile it. This
 document will give some information on how this is done.</p>
 <p>RRDtool relies on services of thrid part libraries. Some of these libraries
 may already be installed on your system. You have to compile copies of the other
 ones before you can build RRDtool.</p>
 <p>This document will tell you about all the necessary steps to get going.</p>
+<p>These instructions assume you are using a <strong>bash</strong> shell. If you use csh/tcsh,
+then you can either type <em>bash</em> to switch to bash for the compilation or if
+you know what you are doing just replace the export bits with
+setenv.</p>
+<p>We further assume that your copies of <strong>tar</strong> and <strong>make</strong> are actually <strong>GNU
+tar</strong> and <strong>GNU make</strong> respectively. It could be that they are installed as
+<strong>gtar</strong> and <strong>gmake</strong> on your system.</p>
 <p>
 </p>
-<h2><a name="building">Building</a></h2>
+<hr />
+<h1><a name="optimistic_build">OPTIMISTIC BUILD</a></h1>
 <p>Before you start to build RRDtool, you have to decide two things:</p>
 <ol>
 <li>
@@ -63,15 +75,10 @@ ones before you can build RRDtool.</p>
 <p>Where you want to install the software.</p>
 </li>
 </ol>
-<p>Once you have decided. Save the two locations into environment variables.
-Depending on the shell you are using, you can do either (bash,zsh):</p>
+<p>Once you have decided. Save the two locations into environment variables.</p>
 <pre>
  BUILD_DIR=/tmp/rrdbuild
- INSTALL_DIR=/usr/local/rrdtool-1.2.27</pre>
-<p>Or if you run tcsh:</p>
-<pre>
- set BUILD_DIR=/tmp/rrdbuild
- set INSTALL_DIR=/usr/local/rrdtool-1.2.27</pre>
+ INSTALL_DIR=/usr/local/rrdtool-1.3rc4</pre>
 <p>If your <em>/tmp</em> is mounted with the option noexec (RHEL seems todo that) you have to choose
 a different directory!</p>
 <p>Now make sure the BUILD_DIR exists and go there:</p>
@@ -79,22 +86,53 @@ a different directory!</p>
  mkdir -p $BUILD_DIR
  cd $BUILD_DIR</pre>
 <p>Lets first assume you already have all the necessary libraries
-pre-installed. Note that these instructions assume that your copies of
-<strong>tar</strong> and <strong>make</strong> are actually <strong>GNU tar</strong> and <strong>GNU make</strong> respectively. It
-could be that they are installed as <strong>gtar</strong> and <strong>gmake</strong> on your system.</p>
+pre-installed.</p>
 <pre>
- wget <a href="http://oss.oetiker.ch/rrdtool/pub/rrdtool-1.2.27.tar.gz">http://oss.oetiker.ch/rrdtool/pub/rrdtool-1.2.27.tar.gz</a>
- tar zxf rrdtool-1.2.27.tar.gz
- cd rrdtool-1.2.27
+ wget <a href="http://oss.oetiker.ch/rrdtool/pub/rrdtool-1.3rc4.tar.gz">http://oss.oetiker.ch/rrdtool/pub/rrdtool-1.3rc4.tar.gz</a>
+ gunzip -c rrdtool-1.3rc4.tar.gz | tar xf -
+ cd rrdtool-1.3rc4
  ./configure --prefix=$INSTALL_DIR &amp;&amp; make &amp;&amp; make install</pre>
 <p>Ok, this was very optimistic. This try will probably have ended with
-<strong>configure</strong> complaining about several missing libraries. If you are on a
-Linux or *bsd system you may want to just install the missing bits from your
-software repository. When you do that, make sure you also get the <strong>-dev</strong>
-package for each library you install. Once you have the missing bits on
-board, just re-run the last line of the instructions above.</p>
-<p>But again this may have been too optimistic, and you actually have to
-compile your own copies of the required libraries.</p>
+<strong>configure</strong> complaining about several missing libraries.</p>
+<p>
+</p>
+<hr />
+<h1><a name="installing_dependencies">INSTALLING DEPENDENCIES</a></h1>
+<p>If your OS lets you install additional packages from a software repository,
+you may get away with installing the missing packages. When the packages are
+installed, run configure again and try to compile again. Below you find some
+hints on getting your OS ready for the rrdtool compilation. Additions to
+this list are welcome.</p>
+<p>
+</p>
+<h2><a name="opensolaris_2008_05">OpenSolaris 2008.05</a></h2>
+<p>Just add a compiler and the gnome development package:</p>
+<pre>
+ pkg install sunstudioexpress
+ pkg install SUNWgnome-common-devel</pre>
+<p>There is a a problem with <em>cairo.pc</em> on opensolaris. It suggests that
+xrender is required for compilation with cairo. This is not true and also
+bad since opensolaris does not include an <em>xrender.pc</em> file. Use perl to
+fix this:</p>
+<pre>
+ perl -i~ -p -e 's/(Requires.*?)\s*xrender.*/$1/' /usr/lib/pkgconfig/cairo.pc</pre>
+<p>
+</p>
+<h2><a name="debian___ubuntu">Debian / Ubuntu</a></h2>
+<p>Use apt-get to make sure you have all that is required. A number
+of packages will get added through dependencies.</p>
+<pre>
+ apt-get install libpango1.0-dev libxml2-dev</pre>
+<p>
+</p>
+<hr />
+<h1><a name="building_dependencies">BUILDING DEPENDENCIES</a></h1>
+<p>But again this may have been too optimistic still, and you actually have to
+compile your own copies of some of the required libraries. Things like
+libpng and zlib are pretty standard so you will probably have them on your
+system anyway. Freetype, Fontinst, Cairo, Pango may be installed, but it is
+possible that they are pretty old and thus don't live up to the
+expectations, so you may want to compile their latest versions.</p>
 <p>
 </p>
 <h3><a name="build_tipps_for_aix">Build Tipps for AIX</a></h3>
@@ -122,19 +160,69 @@ If you have an other compile you have to use the following settings:</p>
  CFLAGS=&quot;-xO3 -kPIC&quot;</pre>
 </dd>
 </dl>
+<p>Some libraries want to know where other libraries are. For this to work,
+set the following environamen variable</p>
+<pre>
+ export PKG_CONFIG_PATH=${INSTALL_DIR}/lib/pkgconfig
+ export PATH=$INSTALL_DIR/bin:$PATH</pre>
+<p>Since we are compiling libraries dynamically, you they must further know
+where to find each other. This is done by setting an appropriate LDFLAG.
+Unfortunatly the syntax differs from system to system:</p>
+<dl>
+<dt><strong><a name="item_solaris">Solaris</a></strong>
+
+<dd>
+<pre>
+ export LDFLAGS=-R${INSTALL_DIR}/lib</pre>
+</dd>
+<dt><strong><a name="item_linux">Linux</a></strong>
+
+<dd>
+<pre>
+ export LDFLAGS=&quot;-Wl,--rpath -Wl,${INSTALL_DIR}/lib&quot;</pre>
+</dd>
+<dd>
+<p>If you are on a 64bit platform, but would like to continue to use the rrd files created
+on your old 32bit linux, you may be able</p>
+</dd>
+<dt><strong><a name="item_hpux">HPUX</a></strong>
+
+<dd>
+<pre>
+
+ export LDFLAGS=&quot;+b${INSTALL_DIR}/lib&quot;</pre>
+</dd>
+<dt><strong><a name="item_aix">AIX</a></strong>
+
+<dd>
+<pre>
+ export LDFLAGS=&quot;-Wl,-blibpath:${INSTALL_DIR}/lib&quot;</pre>
+</dd>
+<p>If you have GNUmake installed and it is not called 'make',
+then do</p>
+<pre>
+ export MAKE=gmake
+ export GNUMAKE=gmake</pre>
+<p>otherwhise just do</p>
+<pre>
+ export MAKE=make</pre>
 <dl>
 <dt><strong><a name="item_building_zlib">Building zlib</a></strong>
 
+<dd>
+<p>Chances are very high that you already have that on your system ...</p>
+</dd>
 <dd>
 <pre>
  cd $BUILD_DIR
  wget <a href="http://oss.oetiker.ch/rrdtool/pub/libs/zlib-1.2.3.tar.gz">http://oss.oetiker.ch/rrdtool/pub/libs/zlib-1.2.3.tar.gz</a>
- tar  zxf zlib-1.2.3.tar.gz
+ gunzip -c zlib-1.2.3.tar.gz | tar xf -
  cd zlib-1.2.3
- env CFLAGS=&quot;-O3 -fPIC&quot; ./configure --prefix=$BUILD_DIR/lb
- make
make install</pre>
+ ./configure --prefix=$INSTALL_DIR CFLAGS=&quot;-O3 -fPIC&quot; --shared
+ $MAKE
$MAKE install</pre>
 </dd>
+</li>
 <dt><strong><a name="item_building_libpng">Building libpng</a></strong>
 
 <dd>
@@ -146,13 +234,12 @@ the end of line 4 means that line 4 and line 5 are on one line.</p>
 <dd>
 <pre>
  cd $BUILD_DIR
- wget <a href="http://oss.oetiker.ch/rrdtool/pub/libs/libpng-1.2.10.tar.gz">http://oss.oetiker.ch/rrdtool/pub/libs/libpng-1.2.10.tar.gz</a>
- tar zxvf libpng-1.2.10.tar.gz
+ wget <a href="http://oss.oetiker.ch/rrdtool/pub/libs/libpng-1.2.18.tar.gz">http://oss.oetiker.ch/rrdtool/pub/libs/libpng-1.2.18.tar.gz</a>
+ gunzip -c libpng-1.2.18.tar.gz | tar xf -
  cd libpng-1.2.10
- env CPPFLAGS=&quot;-I$BUILD_DIR/lb/include&quot; LDFLAGS=&quot;-L$BUILD_DIR/lb/lib&quot; CFLAGS=&quot;-O3 -fPIC&quot; \
-     ./configure --disable-shared --prefix=$BUILD_DIR/lb
- make
- make install</pre>
+ env CFLAGS=&quot;-O3 -fPIC&quot; ./configure --prefix=$INSTALL_DIR
+ $MAKE
+ $MAKE install</pre>
 </dd>
 </li>
 <dt><strong><a name="item_building_freetype">Building freetype</a></strong>
@@ -160,78 +247,132 @@ the end of line 4 means that line 4 and line 5 are on one line.</p>
 <dd>
 <pre>
  cd $BUILD_DIR
- wget <a href="http://oss.oetiker.ch/rrdtool/pub/libs/freetype-2.1.10.tar.bz2">http://oss.oetiker.ch/rrdtool/pub/libs/freetype-2.1.10.tar.bz2</a>
- tar jxvf freetype-2.1.10.tar.bz2
- cd freetype-2.1.10
- env CPPFLAGS=&quot;-I$BUILD_DIR/lb/include&quot; LDFLAGS=&quot;-L$BUILD_DIR/lb/lib&quot; CFLAGS=&quot;-O3 -fPIC&quot; \
-     ./configure --disable-shared --prefix=$BUILD_DIR/lb
- make
- make install</pre>
+ wget <a href="http://oss.oetiker.ch/rrdtool/pub/libs/freetype-2.3.5.tar.gz">http://oss.oetiker.ch/rrdtool/pub/libs/freetype-2.3.5.tar.gz</a>
+ gunzip -c freetype-2.3.5.tar.gz | tar xf -
+ cd freetype-2.3.5
+ ./configure --prefix=$INSTALL_DIR CFLAGS=&quot;-O3 -fPIC&quot;
+ $MAKE
+ $MAKE install</pre>
 </dd>
 <dd>
 <p>If you run into problems building freetype on Solaris, you may want to try to
-add the following at the end of the configure line:</p>
+add the following at the start the configure line:</p>
+</dd>
+<dd>
+<pre>
+ env EGREP=egrep</pre>
+</dd>
+<dt><strong><a name="item_building_libxml2">Building LibXML2</a></strong>
+
+<dd>
+<pre>
+ cd $BUILD_DIR
+ wget <a href="http://oss.oetiker.ch/rrdtool/pub/libs/libxml2-sources-2.6.31.tar.gz">http://oss.oetiker.ch/rrdtool/pub/libs/libxml2-sources-2.6.31.tar.gz</a>
+ gunzip -c libxml2-sources-2.6.32.tar.gz | tar xf -
+ cd libxml2-sources-2.6.32
+ ./configure --prefix=$INSTALL_DIR CFLAGS=&quot;-O3 -fPIC&quot;
+ $MAKE
+ $MAKE install</pre>
+</dd>
+<dt><strong><a name="item_building_fontconfig">Building fontconfig</a></strong>
+
+<dd>
+<p>Note that fontconfig has a runtime configuration file in INSTALL_DIR/etc you
+may want to adjust that so that fontconfig finds the fonts on your system.
+Run the fc-cache program to build the fontconfig cache after changeing the
+config file.</p>
 </dd>
 <dd>
 <pre>
- GNUMAKE=gmake EGREP=egrep</pre>
+ cd $BUILD_DIR
+ wget <a href="http://oss.oetiker.ch/rrdtool/pub/libs/fontconfig-2.4.2.tar.gz">http://oss.oetiker.ch/rrdtool/pub/libs/fontconfig-2.4.2.tar.gz</a>
+ gunzip -c fontconfig-2.4.2.tar.gz   | tar xf -
+ cd fontconfig-2.4.2
+ ./configure --prefix=$INSTALL_DIR CFLAGS=&quot;-O3 -fPIC&quot;
+ $MAKE
+ $MAKE install</pre>
+</dd>
+</li>
+<dt><strong><a name="item_building_pixman">Building Pixman</a></strong>
+
+<dd>
+<pre>
+ cd $BUILD_DIR
+ wget <a href="http://oss.oetiker.ch/rrdtool/pub/libs/pixman-0.10.0.tar.gz">http://oss.oetiker.ch/rrdtool/pub/libs/pixman-0.10.0.tar.gz</a>
+ gunzip -c pixman-0.10.0.tar.gz  | tar xf -
+ cd fontconfig-2.4.2
+ ./configure --prefix=$INSTALL_DIR CFLAGS=&quot;-O3 -fPIC&quot;
+ $MAKE
+ $MAKE install</pre>
 </dd>
-<dt><strong><a name="item_building_libart_lgpl">Building libart_lgpl</a></strong>
+<dt><strong><a name="item_building_cairo">Building Cairo</a></strong>
 
 <dd>
 <pre>
  cd $BUILD_DIR
- wget <a href="http://oss.oetiker.ch/rrdtool/pub/libs/libart_lgpl-2.3.17.tar.gz">http://oss.oetiker.ch/rrdtool/pub/libs/libart_lgpl-2.3.17.tar.gz</a>
- tar zxvf libart_lgpl-2.3.17.tar.gz
- cd libart_lgpl-2.3.17
- env CFLAGS=&quot;-O3 -fPIC&quot; ./configure --disable-shared --prefix=$BUILD_DIR/lb
- make
- make install</pre>
+ wget <a href="http://oss.oetiker.ch/rrdtool/pub/libs/cairo-1.6.4.tar.gz">http://oss.oetiker.ch/rrdtool/pub/libs/cairo-1.6.4.tar.gz</a>
+ gunzip -c cairo-1.4.10.tar.gz   | tar xf -
+ cd cairo-1.4.10
+ ./configure --prefix=$INSTALL_DIR \
+    --enable-xlib=no \
+    --enable-xlib-render=no \
+    --enable-win32=no \
+    CFLAGS=&quot;-O3 -fPIC&quot;
+ $MAKE
+ $MAKE install</pre>
+</dd>
+<dt><strong><a name="item_building_glib">Building Glib</a></strong>
+
+<dd>
+<pre>
+ cd $BUILD_DIR
+ wget <a href="http://oss.oetiker.ch/rrdtool/pub/libs/glib-2.15.4.tar.gz">http://oss.oetiker.ch/rrdtool/pub/libs/glib-2.15.4.tar.gz</a>
+ gunzip -c glib-2.12.13.tar.gz  | tar xf -
+ cd glib-2.12.13
+ ./configure --prefix=$INSTALL_DIR CFLAGS=&quot;-O3 -fPIC&quot;
+ $MAKE
+ $MAKE install</pre>
+</dd>
+<dt><strong><a name="item_building_pango">Building Pango</a></strong>
+
+<dd>
+<pre>
+ cd $BUILD_DIR
+ wget <a href="http://oss.oetiker.ch/rrdtool/pub/libs/pango-1.21.1.tar.gz">http://oss.oetiker.ch/rrdtool/pub/libs/pango-1.21.1.tar.gz</a>
+ gunzip -c pango-1.21.1.tar.gz  | tar xf -
+ cd pango-1.21.1
+ ./configure --prefix=$INSTALL_DIR CFLAGS=&quot;-O3 -fPIC&quot; --without-x
+ $MAKE
+ $MAKE install</pre>
 </dd>
 </dl>
-<p>Now all the dependent libraries are built and you can try again. Since these
-are static libraries, you may have to use <em>ranlib</em> to make them accessible.
-Especially BSD systems like Mac OS X may require this, Linux and Solaris
-will do just fine without since their <em>ar</em> command does ranlibs job as well.</p>
-<pre>
- ranlib $BUILD_DIR/lb/lib/*.a</pre>
-<p>This time you tell configure where it should be looking for libraries and
-include files. This is done via environment variables. Depending on the
-shell you are running, the syntax for setting environment variables is
-different. Under csh/tcsh you use:</p>
-<pre>
- set IR=-I$BUILD_DIR/lb/include
- setenv CPPFLAGS &quot;$IR $IR/libart-2.0 $IR/freetype2 $IR/libpng&quot;
- setenv LDFLAGS  -L$BUILD_DIR/lb/lib
- setenv CFLAGS -O3</pre>
-<p>If you are running bash/sh/ash/ksh/zsh use this:</p>
-<pre>
- IR=-I$BUILD_DIR/lb/include
- CPPFLAGS=&quot;$IR $IR/libart-2.0 $IR/freetype2 $IR/libpng&quot;
- LDFLAGS=&quot;-L$BUILD_DIR/lb/lib&quot;
- CFLAGS=-O3
- export CPPFLAGS LDFLAGS CFLAGS</pre>
+<p>Now all the dependent libraries are built and you can try again. This time
+you tell configure where it should be looking for libraries and include
+files. This is done via environment variables. Depending on the shell you
+are running, the syntax for setting environment variables is different.</p>
 <p>And finally try building again. We disable the python and tcl bindings
 because it seems that a fair number of people have ill configured python and
 tcl setups that would prevent rrdtool from building if they are included in
 their current state.</p>
 <pre>
- cd $BUILD_DIR/rrdtool-1.2.27
- ./configure --prefix=$INSTALL_DIR --disable-python --disable-tcl
make clean
- make
make install</pre>
+ cd $BUILD_DIR/rrdtool-1.3rc4
+ ./configure --prefix=$INSTALL_DIR --disable-tcl --disable-python
$MAKE clean
+ $MAKE
$MAKE install</pre>
 <p>SOLARIS HINT: if you want to build  the perl module for the native perl (the
-one shipping with solaris) you will need the sun forte compiler
-installed on your box or you have to hand-tune bindings/perl-shared/Makefile
-while building!</p>
-<p>Now go to <em>$INSTALL_DIR</em><strong>/share/rrdtool/examples/</strong> and run them to see if your
-build has been successful.</p>
+one shipping with solaris) you will need the sun forte compiler installed on
+your box or you have to hand-tune bindings/perl-shared/Makefile while
+building!</p>
+<p>Now go to <em>$INSTALL_DIR</em><strong>/share/rrdtool/examples/</strong> and run them to see if
+your build has been successful.</p>
 <p>
 </p>
 <hr />
 <h1><a name="author">AUTHOR</a></h1>
-<p>Tobias Oetiker &lt;<a href="mailto:tobi@oetiker.ch">tobi@oetiker.ch</a>&gt;</p>
+<p>Tobias Oetiker &lt;<a href="mailto:tobi@oetiker.ch">tobi@oetiker.ch</a>&gt;
+
+</p>
 
 </body>
 
index dd3e71e820b589c2b3ef266cb1a3fccac5f57323..e02ac421ac16a8d0d8e14badb3c05d467ff1ba10 100644 (file)
@@ -2,9 +2,7 @@
 
 rrdbuild - Instructions for building RRDtool
 
-=head1 DESCRIPTION
-
-=head2 Overview
+=head1 OVERVIEW
 
 If you downloaded the source of rrdtool you have to compile it. This
 document will give some information on how this is done.
@@ -15,7 +13,16 @@ ones before you can build RRDtool.
 
 This document will tell you about all the necessary steps to get going.
 
-=head2 Building
+These instructions assume you are using a B<bash> shell. If you use csh/tcsh,
+then you can either type F<bash> to switch to bash for the compilation or if
+you know what you are doing just replace the export bits with
+setenv.
+
+We further assume that your copies of B<tar> and B<make> are actually B<GNU
+tar> and B<GNU make> respectively. It could be that they are installed as
+B<gtar> and B<gmake> on your system.
+
+=head1 OPTIMISTIC BUILD
 
 Before you start to build RRDtool, you have to decide two things:
 
@@ -32,15 +39,10 @@ Where you want to install the software.
 =back
 
 Once you have decided. Save the two locations into environment variables.
-Depending on the shell you are using, you can do either (bash,zsh):
 
  BUILD_DIR=/tmp/rrdbuild
- INSTALL_DIR=/usr/local/rrdtool-1.2.27
+ INSTALL_DIR=/usr/local/rrdtool-1.3rc4
 
-Or if you run tcsh:
-
- set BUILD_DIR=/tmp/rrdbuild
- set INSTALL_DIR=/usr/local/rrdtool-1.2.27
 
 If your F</tmp> is mounted with the option noexec (RHEL seems todo that) you have to choose
 a different directory!
@@ -51,24 +53,53 @@ Now make sure the BUILD_DIR exists and go there:
  cd $BUILD_DIR
 
 Lets first assume you already have all the necessary libraries
-pre-installed. Note that these instructions assume that your copies of
-B<tar> and B<make> are actually B<GNU tar> and B<GNU make> respectively. It
-could be that they are installed as B<gtar> and B<gmake> on your system.
+pre-installed. 
 
- wget http://oss.oetiker.ch/rrdtool/pub/rrdtool-1.2.27.tar.gz
- tar zxf rrdtool-1.2.27.tar.gz
- cd rrdtool-1.2.27
+ wget http://oss.oetiker.ch/rrdtool/pub/rrdtool-1.3rc4.tar.gz
+ gunzip -c rrdtool-1.3rc4.tar.gz | tar xf -
+ cd rrdtool-1.3rc4
  ./configure --prefix=$INSTALL_DIR && make && make install
 
 Ok, this was very optimistic. This try will probably have ended with
-B<configure> complaining about several missing libraries. If you are on a
-Linux or *bsd system you may want to just install the missing bits from your
-software repository. When you do that, make sure you also get the B<-dev>
-package for each library you install. Once you have the missing bits on
-board, just re-run the last line of the instructions above.
+B<configure> complaining about several missing libraries.
+
+=head1 INSTALLING DEPENDENCIES
+
+If your OS lets you install additional packages from a software repository,
+you may get away with installing the missing packages. When the packages are
+installed, run configure again and try to compile again. Below you find some
+hints on getting your OS ready for the rrdtool compilation. Additions to
+this list are welcome.
+
+=head2 OpenSolaris 2008.05
+
+Just add a compiler and the gnome development package:
+
+ pkg install sunstudioexpress
+ pkg install SUNWgnome-common-devel
+
+There is a a problem with F<cairo.pc> on opensolaris. It suggests that
+xrender is required for compilation with cairo. This is not true and also
+bad since opensolaris does not include an F<xrender.pc> file. Use perl to
+fix this:
+
+ perl -i~ -p -e 's/(Requires.*?)\s*xrender.*/$1/' /usr/lib/pkgconfig/cairo.pc 
+
+=head2 Debian / Ubuntu
 
-But again this may have been too optimistic, and you actually have to
-compile your own copies of the required libraries.
+Use apt-get to make sure you have all that is required. A number
+of packages will get added through dependencies.
+
+ apt-get install libpango1.0-dev libxml2-dev
+
+=head1 BUILDING DEPENDENCIES
+
+But again this may have been too optimistic still, and you actually have to
+compile your own copies of some of the required libraries. Things like
+libpng and zlib are pretty standard so you will probably have them on your
+system anyway. Freetype, Fontinst, Cairo, Pango may be installed, but it is
+possible that they are pretty old and thus don't live up to the
+expectations, so you may want to compile their latest versions.
 
 =head3 Build Tipps for AIX
 
@@ -101,15 +132,60 @@ If you have an other compile you have to use the following settings:
 
 =over 
 
+Some libraries want to know where other libraries are. For this to work,
+set the following environamen variable
+
+ export PKG_CONFIG_PATH=${INSTALL_DIR}/lib/pkgconfig
+ export PATH=$INSTALL_DIR/bin:$PATH
+
+Since we are compiling libraries dynamically, you they must further know
+where to find each other. This is done by setting an appropriate LDFLAG.
+Unfortunatly the syntax differs from system to system:
+
+=over
+
+=item Solaris
+
+ export LDFLAGS=-R${INSTALL_DIR}/lib 
+
+=item Linux
+
+ export LDFLAGS="-Wl,--rpath -Wl,${INSTALL_DIR}/lib" 
+
+If you are on a 64bit platform, but would like to continue to use the rrd files created
+on your old 32bit linux, you may be able 
+
+=item HPUX
+ export LDFLAGS="+b${INSTALL_DIR}/lib"
+
+=item AIX
+
+ export LDFLAGS="-Wl,-blibpath:${INSTALL_DIR}/lib"
+
+=back 
+
+If you have GNUmake installed and it is not called 'make',
+then do
+
+ export MAKE=gmake
+ export GNUMAKE=gmake
+
+otherwhise just do
+
+ export MAKE=make
+
 =item Building zlib
 
+Chances are very high that you already have that on your system ... 
+
  cd $BUILD_DIR
  wget http://oss.oetiker.ch/rrdtool/pub/libs/zlib-1.2.3.tar.gz
- tar  zxf zlib-1.2.3.tar.gz
+ gunzip -c zlib-1.2.3.tar.gz | tar xf -
  cd zlib-1.2.3
- env CFLAGS="-O3 -fPIC" ./configure --prefix=$BUILD_DIR/lb
- make
make install
+ ./configure --prefix=$INSTALL_DIR CFLAGS="-O3 -fPIC" --shared
+ $MAKE
$MAKE install
 
 =item Building libpng
 
@@ -119,85 +195,122 @@ drop the settings of LDFLAGS and CPPFLAGS. Note that the backslash (\) at
 the end of line 4 means that line 4 and line 5 are on one line.
 
  cd $BUILD_DIR
- wget http://oss.oetiker.ch/rrdtool/pub/libs/libpng-1.2.10.tar.gz
- tar zxvf libpng-1.2.10.tar.gz
+ wget http://oss.oetiker.ch/rrdtool/pub/libs/libpng-1.2.18.tar.gz
+ gunzip -c libpng-1.2.18.tar.gz | tar xf -
  cd libpng-1.2.10
- env CPPFLAGS="-I$BUILD_DIR/lb/include" LDFLAGS="-L$BUILD_DIR/lb/lib" CFLAGS="-O3 -fPIC" \
-     ./configure --disable-shared --prefix=$BUILD_DIR/lb
- make
- make install
+ env CFLAGS="-O3 -fPIC" ./configure --prefix=$INSTALL_DIR
+ $MAKE
+ $MAKE install
 
 =item Building freetype
 
  cd $BUILD_DIR
- wget http://oss.oetiker.ch/rrdtool/pub/libs/freetype-2.1.10.tar.bz2
- tar jxvf freetype-2.1.10.tar.bz2
- cd freetype-2.1.10
- env CPPFLAGS="-I$BUILD_DIR/lb/include" LDFLAGS="-L$BUILD_DIR/lb/lib" CFLAGS="-O3 -fPIC" \
-     ./configure --disable-shared --prefix=$BUILD_DIR/lb
- make
- make install
+ wget http://oss.oetiker.ch/rrdtool/pub/libs/freetype-2.3.5.tar.gz
+ gunzip -c freetype-2.3.5.tar.gz | tar xf -
+ cd freetype-2.3.5
+ ./configure --prefix=$INSTALL_DIR CFLAGS="-O3 -fPIC"
+ $MAKE
+ $MAKE install
 
 If you run into problems building freetype on Solaris, you may want to try to
-add the following at the end of the configure line:
+add the following at the start the configure line:
 
GNUMAKE=gmake EGREP=egrep
env EGREP=egrep
 
-=item Building libart_lgpl
+=item Building LibXML2
 
  cd $BUILD_DIR
- wget http://oss.oetiker.ch/rrdtool/pub/libs/libart_lgpl-2.3.17.tar.gz
- tar zxvf libart_lgpl-2.3.17.tar.gz
- cd libart_lgpl-2.3.17
- env CFLAGS="-O3 -fPIC" ./configure --disable-shared --prefix=$BUILD_DIR/lb
- make
make install
+ wget http://oss.oetiker.ch/rrdtool/pub/libs/libxml2-sources-2.6.31.tar.gz
+ gunzip -c libxml2-sources-2.6.32.tar.gz | tar xf -
+ cd libxml2-sources-2.6.32
+ ./configure --prefix=$INSTALL_DIR CFLAGS="-O3 -fPIC"
+ $MAKE
$MAKE install
 
-=back
+=item Building fontconfig
 
-Now all the dependent libraries are built and you can try again. Since these
-are static libraries, you may have to use F<ranlib> to make them accessible.
-Especially BSD systems like Mac OS X may require this, Linux and Solaris
-will do just fine without since their F<ar> command does ranlibs job as well.
+Note that fontconfig has a runtime configuration file in INSTALL_DIR/etc you
+may want to adjust that so that fontconfig finds the fonts on your system.
+Run the fc-cache program to build the fontconfig cache after changeing the
+config file.
 
- ranlib $BUILD_DIR/lb/lib/*.a
+ cd $BUILD_DIR
+ wget http://oss.oetiker.ch/rrdtool/pub/libs/fontconfig-2.4.2.tar.gz
+ gunzip -c fontconfig-2.4.2.tar.gz   | tar xf -
+ cd fontconfig-2.4.2
+ ./configure --prefix=$INSTALL_DIR CFLAGS="-O3 -fPIC"
+ $MAKE
+ $MAKE install
+
+=item Building Pixman
+
+ cd $BUILD_DIR
+ wget http://oss.oetiker.ch/rrdtool/pub/libs/pixman-0.10.0.tar.gz
+ gunzip -c pixman-0.10.0.tar.gz  | tar xf -
+ cd fontconfig-2.4.2
+ ./configure --prefix=$INSTALL_DIR CFLAGS="-O3 -fPIC"
+ $MAKE
+ $MAKE install
 
-This time you tell configure where it should be looking for libraries and
-include files. This is done via environment variables. Depending on the
-shell you are running, the syntax for setting environment variables is
-different. Under csh/tcsh you use:
+=item Building Cairo
 
- set IR=-I$BUILD_DIR/lb/include
- setenv CPPFLAGS "$IR $IR/libart-2.0 $IR/freetype2 $IR/libpng"
- setenv LDFLAGS  -L$BUILD_DIR/lb/lib
- setenv CFLAGS -O3
+ cd $BUILD_DIR
+ wget http://oss.oetiker.ch/rrdtool/pub/libs/cairo-1.6.4.tar.gz
+ gunzip -c cairo-1.4.10.tar.gz   | tar xf -
+ cd cairo-1.4.10
+ ./configure --prefix=$INSTALL_DIR \
+    --enable-xlib=no \
+    --enable-xlib-render=no \
+    --enable-win32=no \
+    CFLAGS="-O3 -fPIC"
+ $MAKE
+ $MAKE install
+
+=item Building Glib
 
-If you are running bash/sh/ash/ksh/zsh use this:
+ cd $BUILD_DIR
+ wget http://oss.oetiker.ch/rrdtool/pub/libs/glib-2.15.4.tar.gz
+ gunzip -c glib-2.12.13.tar.gz  | tar xf -
+ cd glib-2.12.13
+ ./configure --prefix=$INSTALL_DIR CFLAGS="-O3 -fPIC"
+ $MAKE
+ $MAKE install
+
+=item Building Pango
+
+ cd $BUILD_DIR
+ wget http://oss.oetiker.ch/rrdtool/pub/libs/pango-1.21.1.tar.gz
+ gunzip -c pango-1.21.1.tar.gz  | tar xf -
+ cd pango-1.21.1
+ ./configure --prefix=$INSTALL_DIR CFLAGS="-O3 -fPIC" --without-x
+ $MAKE
+ $MAKE install
+
+=back
 
- IR=-I$BUILD_DIR/lb/include
- CPPFLAGS="$IR $IR/libart-2.0 $IR/freetype2 $IR/libpng"
- LDFLAGS="-L$BUILD_DIR/lb/lib"
- CFLAGS=-O3
- export CPPFLAGS LDFLAGS CFLAGS
+Now all the dependent libraries are built and you can try again. This time
+you tell configure where it should be looking for libraries and include
+files. This is done via environment variables. Depending on the shell you
+are running, the syntax for setting environment variables is different.
 
 And finally try building again. We disable the python and tcl bindings
 because it seems that a fair number of people have ill configured python and
 tcl setups that would prevent rrdtool from building if they are included in
 their current state.
 
- cd $BUILD_DIR/rrdtool-1.2.27
- ./configure --prefix=$INSTALL_DIR --disable-python --disable-tcl
make clean
- make
make install
+ cd $BUILD_DIR/rrdtool-1.3rc4
+ ./configure --prefix=$INSTALL_DIR --disable-tcl --disable-python
$MAKE clean
+ $MAKE
$MAKE install
 
 SOLARIS HINT: if you want to build  the perl module for the native perl (the
-one shipping with solaris) you will need the sun forte compiler
-installed on your box or you have to hand-tune bindings/perl-shared/Makefile
-while building!
+one shipping with solaris) you will need the sun forte compiler installed on
+your box or you have to hand-tune bindings/perl-shared/Makefile while
+building!
 
-Now go to I<$INSTALL_DIR>B</share/rrdtool/examples/> and run them to see if your
-build has been successful.
+Now go to I<$INSTALL_DIR>B</share/rrdtool/examples/> and run them to see if
+your build has been successful.
 
 =head1 AUTHOR
 
index d63f1396ae32288cb117ceb27afbeac8f5fad306..e825521189917fc368ee17841b964ef1139e935e 100644 (file)
@@ -5,9 +5,7 @@ RRDBUILD(1)                         rrdtool                        RRDBUILD(1)
 N\bNA\bAM\bME\bE
        rrdbuild - Instructions for building RRDtool
 
-D\bDE\bES\bSC\bCR\bRI\bIP\bPT\bTI\bIO\bON\bN
-       O\bOv\bve\ber\brv\bvi\bie\bew\bw
-
+O\bOV\bVE\bER\bRV\bVI\bIE\bEW\bW
        If you downloaded the source of rrdtool you have to compile it. This
        document will give some information on how this is done.
 
@@ -17,8 +15,16 @@ D\bDE\bES\bSC\bCR\bRI\bIP\bPT\bTI\bIO\bON\bN
 
        This document will tell you about all the necessary steps to get going.
 
-       B\bBu\bui\bil\bld\bdi\bin\bng\bg
+       These instructions assume you are using a b\bba\bas\bsh\bh shell. If you use
+       csh/tcsh, then you can either type _\bb_\ba_\bs_\bh to switch to bash for the com-
+       pilation or if you know what you are doing just replace the export bits
+       with setenv.
+
+       We further assume that your copies of t\bta\bar\br and m\bma\bak\bke\be are actually G\bGN\bNU\bU t\bta\bar\br
+       and G\bGN\bNU\bU m\bma\bak\bke\be respectively. It could be that they are installed as g\bgt\bta\bar\br
+       and g\bgm\bma\bak\bke\be on your system.
 
+O\bOP\bPT\bTI\bIM\bMI\bIS\bST\bTI\bIC\bC B\bBU\bUI\bIL\bLD\bD
        Before you start to build RRDtool, you have to decide two things:
 
        1.  In which directory you want to build the software.
@@ -26,16 +32,10 @@ D\bDE\bES\bSC\bCR\bRI\bIP\bPT\bTI\bIO\bON\bN
        2.  Where you want to install the software.
 
        Once you have decided. Save the two locations into environment vari-
-       ables.  Depending on the shell you are using, you can do either
-       (bash,zsh):
+       ables.
 
         BUILD_DIR=/tmp/rrdbuild
-        INSTALL_DIR=/usr/local/rrdtool-1.2.27
-
-       Or if you run tcsh:
-
-        set BUILD_DIR=/tmp/rrdbuild
-        set INSTALL_DIR=/usr/local/rrdtool-1.2.27
+        INSTALL_DIR=/usr/local/rrdtool-1.3rc4
 
        If your _\b/_\bt_\bm_\bp is mounted with the option noexec (RHEL seems todo that)
        you have to choose a different directory!
@@ -46,24 +46,52 @@ D\bDE\bES\bSC\bCR\bRI\bIP\bPT\bTI\bIO\bON\bN
         cd $BUILD_DIR
 
        Lets first assume you already have all the necessary libraries
-       pre-installed. Note that these instructions assume that your copies of
-       t\bta\bar\br and m\bma\bak\bke\be are actually G\bGN\bNU\bU t\bta\bar\br and G\bGN\bNU\bU m\bma\bak\bke\be respectively. It could
-       be that they are installed as g\bgt\bta\bar\br and g\bgm\bma\bak\bke\be on your system.
+       pre-installed.
 
-        wget http://oss.oetiker.ch/rrdtool/pub/rrdtool-1.2.27.tar.gz
-        tar zxf rrdtool-1.2.27.tar.gz
-        cd rrdtool-1.2.27
+        wget http://oss.oetiker.ch/rrdtool/pub/rrdtool-1.3rc4.tar.gz
+        gunzip -c rrdtool-1.3rc4.tar.gz | tar xf -
+        cd rrdtool-1.3rc4
         ./configure --prefix=$INSTALL_DIR && make && make install
 
        Ok, this was very optimistic. This try will probably have ended with
-       c\bco\bon\bnf\bfi\big\bgu\bur\bre\be complaining about several missing libraries. If you are on a
-       Linux or *bsd system you may want to just install the missing bits from
-       your software repository. When you do that, make sure you also get the
-       -\b-d\bde\bev\bv package for each library you install. Once you have the missing
-       bits on board, just re-run the last line of the instructions above.
+       c\bco\bon\bnf\bfi\big\bgu\bur\bre\be complaining about several missing libraries.
+
+I\bIN\bNS\bST\bTA\bAL\bLL\bLI\bIN\bNG\bG D\bDE\bEP\bPE\bEN\bND\bDE\bEN\bNC\bCI\bIE\bES\bS
+       If your OS lets you install additional packages from a software reposi-
+       tory, you may get away with installing the missing packages. When the
+       packages are installed, run configure again and try to compile again.
+       Below you find some hints on getting your OS ready for the rrdtool com-
+       pilation. Additions to this list are welcome.
+
+       O\bOp\bpe\ben\bnS\bSo\bol\bla\bar\bri\bis\bs 2\b20\b00\b08\b8.\b.0\b05\b5
+
+       Just add a compiler and the gnome development package:
+
+        pkg install sunstudioexpress
+        pkg install SUNWgnome-common-devel
 
-       But again this may have been too optimistic, and you actually have to
-       compile your own copies of the required libraries.
+       There is a a problem with _\bc_\ba_\bi_\br_\bo_\b._\bp_\bc on opensolaris. It suggests that
+       xrender is required for compilation with cairo. This is not true and
+       also bad since opensolaris does not include an _\bx_\br_\be_\bn_\bd_\be_\br_\b._\bp_\bc file. Use
+       perl to fix this:
+
+        perl -i~ -p -e 's/(Requires.*?)\s*xrender.*/$1/' /usr/lib/pkgconfig/cairo.pc
+
+       D\bDe\beb\bbi\bia\ban\bn /\b/ U\bUb\bbu\bun\bnt\btu\bu
+
+       Use apt-get to make sure you have all that is required. A number of
+       packages will get added through dependencies.
+
+        apt-get install libpango1.0-dev libxml2-dev
+
+B\bBU\bUI\bIL\bLD\bDI\bIN\bNG\bG D\bDE\bEP\bPE\bEN\bND\bDE\bEN\bNC\bCI\bIE\bES\bS
+       But again this may have been too optimistic still, and you actually
+       have to compile your own copies of some of the required libraries.
+       Things like libpng and zlib are pretty standard so you will probably
+       have them on your system anyway. Freetype, Fontinst, Cairo, Pango may
+       be installed, but it is possible that they are pretty old and thus
+       don't live up to the expectations, so you may want to compile their
+       latest versions.
 
        _\bB_\bu_\bi_\bl_\bd _\bT_\bi_\bp_\bp_\bs _\bf_\bo_\br _\bA_\bI_\bX
 
@@ -91,14 +119,51 @@ D\bDE\bES\bSC\bCR\bRI\bIP\bPT\bTI\bIO\bON\bN
        Sun Forte
             CFLAGS="-xO3 -kPIC"
 
+           Some libraries want to know where other libraries are. For this to
+           work, set the following environamen variable
+
+            export PKG_CONFIG_PATH=${INSTALL_DIR}/lib/pkgconfig
+            export PATH=$INSTALL_DIR/bin:$PATH
+
+           Since we are compiling libraries dynamically, you they must further
+           know where to find each other. This is done by setting an appropri-
+           ate LDFLAG.  Unfortunatly the syntax differs from system to system:
+
+           Solaris
+                export LDFLAGS=-R${INSTALL_DIR}/lib
+
+           Linux
+                export LDFLAGS="-Wl,--rpath -Wl,${INSTALL_DIR}/lib"
+
+               If you are on a 64bit platform, but would like to continue to
+               use the rrd files created on your old 32bit linux, you may be
+               able
+
+           HPUX
+                export LDFLAGS="+b${INSTALL_DIR}/lib"
+
+           AIX
+                export LDFLAGS="-Wl,-blibpath:${INSTALL_DIR}/lib"
+
+           If you have GNUmake installed and it is not called 'make', then do
+
+            export MAKE=gmake
+            export GNUMAKE=gmake
+
+           otherwhise just do
+
+            export MAKE=make
+
        Building zlib
+           Chances are very high that you already have that on your system ...
+
             cd $BUILD_DIR
             wget http://oss.oetiker.ch/rrdtool/pub/libs/zlib-1.2.3.tar.gz
-            tar  zxf zlib-1.2.3.tar.gz
+            gunzip -c zlib-1.2.3.tar.gz | tar xf -
             cd zlib-1.2.3
-            env CFLAGS="-O3 -fPIC" ./configure --prefix=$BUILD_DIR/lb
-            make
-            make install
+            ./configure --prefix=$INSTALL_DIR CFLAGS="-O3 -fPIC" --shared
+            $MAKE
+            $MAKE install
 
        Building libpng
            Libpng itself requires zlib to build, so we need to help a bit. If
@@ -108,74 +173,106 @@ D\bDE\bES\bSC\bCR\bRI\bIP\bPT\bTI\bIO\bON\bN
            are on one line.
 
             cd $BUILD_DIR
-            wget http://oss.oetiker.ch/rrdtool/pub/libs/libpng-1.2.10.tar.gz
-            tar zxvf libpng-1.2.10.tar.gz
+            wget http://oss.oetiker.ch/rrdtool/pub/libs/libpng-1.2.18.tar.gz
+            gunzip -c libpng-1.2.18.tar.gz | tar xf -
             cd libpng-1.2.10
-            env CPPFLAGS="-I$BUILD_DIR/lb/include" LDFLAGS="-L$BUILD_DIR/lb/lib" CFLAGS="-O3 -fPIC" \
-                ./configure --disable-shared --prefix=$BUILD_DIR/lb
-            make
-            make install
+            env CFLAGS="-O3 -fPIC" ./configure --prefix=$INSTALL_DIR
+            $MAKE
+            $MAKE install
 
        Building freetype
             cd $BUILD_DIR
-            wget http://oss.oetiker.ch/rrdtool/pub/libs/freetype-2.1.10.tar.bz2
-            tar jxvf freetype-2.1.10.tar.bz2
-            cd freetype-2.1.10
-            env CPPFLAGS="-I$BUILD_DIR/lb/include" LDFLAGS="-L$BUILD_DIR/lb/lib" CFLAGS="-O3 -fPIC" \
-                ./configure --disable-shared --prefix=$BUILD_DIR/lb
-            make
-            make install
+            wget http://oss.oetiker.ch/rrdtool/pub/libs/freetype-2.3.5.tar.gz
+            gunzip -c freetype-2.3.5.tar.gz | tar xf -
+            cd freetype-2.3.5
+            ./configure --prefix=$INSTALL_DIR CFLAGS="-O3 -fPIC"
+            $MAKE
+            $MAKE install
 
            If you run into problems building freetype on Solaris, you may want
-           to try to add the following at the end of the configure line:
+           to try to add the following at the start the configure line:
 
-            GNUMAKE=gmake EGREP=egrep
+            env EGREP=egrep
+
+       Building LibXML2
+            cd $BUILD_DIR
+            wget http://oss.oetiker.ch/rrdtool/pub/libs/libxml2-sources-2.6.31.tar.gz
+            gunzip -c libxml2-sources-2.6.32.tar.gz | tar xf -
+            cd libxml2-sources-2.6.32
+            ./configure --prefix=$INSTALL_DIR CFLAGS="-O3 -fPIC"
+            $MAKE
+            $MAKE install
+
+       Building fontconfig
+           Note that fontconfig has a runtime configuration file in
+           INSTALL_DIR/etc you may want to adjust that so that fontconfig
+           finds the fonts on your system.  Run the fc-cache program to build
+           the fontconfig cache after changeing the config file.
 
-       Building libart_lgpl
             cd $BUILD_DIR
-            wget http://oss.oetiker.ch/rrdtool/pub/libs/libart_lgpl-2.3.17.tar.gz
-            tar zxvf libart_lgpl-2.3.17.tar.gz
-            cd libart_lgpl-2.3.17
-            env CFLAGS="-O3 -fPIC" ./configure --disable-shared --prefix=$BUILD_DIR/lb
-            make
-            make install
-
-       Now all the dependent libraries are built and you can try again. Since
-       these are static libraries, you may have to use _\br_\ba_\bn_\bl_\bi_\bb to make them
-       accessible.  Especially BSD systems like Mac OS X may require this,
-       Linux and Solaris will do just fine without since their _\ba_\br command does
-       ranlibs job as well.
-
-        ranlib $BUILD_DIR/lb/lib/*.a
-
-       This time you tell configure where it should be looking for libraries
-       and include files. This is done via environment variables. Depending on
-       the shell you are running, the syntax for setting environment variables
-       is different. Under csh/tcsh you use:
-
-        set IR=-I$BUILD_DIR/lb/include
-        setenv CPPFLAGS "$IR $IR/libart-2.0 $IR/freetype2 $IR/libpng"
-        setenv LDFLAGS  -L$BUILD_DIR/lb/lib
-        setenv CFLAGS -O3
-
-       If you are running bash/sh/ash/ksh/zsh use this:
-
-        IR=-I$BUILD_DIR/lb/include
-        CPPFLAGS="$IR $IR/libart-2.0 $IR/freetype2 $IR/libpng"
-        LDFLAGS="-L$BUILD_DIR/lb/lib"
-        CFLAGS=-O3
-        export CPPFLAGS LDFLAGS CFLAGS
+            wget http://oss.oetiker.ch/rrdtool/pub/libs/fontconfig-2.4.2.tar.gz
+            gunzip -c fontconfig-2.4.2.tar.gz   | tar xf -
+            cd fontconfig-2.4.2
+            ./configure --prefix=$INSTALL_DIR CFLAGS="-O3 -fPIC"
+            $MAKE
+            $MAKE install
+
+       Building Pixman
+            cd $BUILD_DIR
+            wget http://oss.oetiker.ch/rrdtool/pub/libs/pixman-0.10.0.tar.gz
+            gunzip -c pixman-0.10.0.tar.gz  | tar xf -
+            cd fontconfig-2.4.2
+            ./configure --prefix=$INSTALL_DIR CFLAGS="-O3 -fPIC"
+            $MAKE
+            $MAKE install
+
+       Building Cairo
+            cd $BUILD_DIR
+            wget http://oss.oetiker.ch/rrdtool/pub/libs/cairo-1.6.4.tar.gz
+            gunzip -c cairo-1.4.10.tar.gz   | tar xf -
+            cd cairo-1.4.10
+            ./configure --prefix=$INSTALL_DIR \
+               --enable-xlib=no \
+               --enable-xlib-render=no \
+               --enable-win32=no \
+               CFLAGS="-O3 -fPIC"
+            $MAKE
+            $MAKE install
+
+       Building Glib
+            cd $BUILD_DIR
+            wget http://oss.oetiker.ch/rrdtool/pub/libs/glib-2.15.4.tar.gz
+            gunzip -c glib-2.12.13.tar.gz  | tar xf -
+            cd glib-2.12.13
+            ./configure --prefix=$INSTALL_DIR CFLAGS="-O3 -fPIC"
+            $MAKE
+            $MAKE install
+
+       Building Pango
+            cd $BUILD_DIR
+            wget http://oss.oetiker.ch/rrdtool/pub/libs/pango-1.21.1.tar.gz
+            gunzip -c pango-1.21.1.tar.gz  | tar xf -
+            cd pango-1.21.1
+            ./configure --prefix=$INSTALL_DIR CFLAGS="-O3 -fPIC" --without-x
+            $MAKE
+            $MAKE install
+
+       Now all the dependent libraries are built and you can try again. This
+       time you tell configure where it should be looking for libraries and
+       include files. This is done via environment variables. Depending on the
+       shell you are running, the syntax for setting environment variables is
+       different.
 
        And finally try building again. We disable the python and tcl bindings
        because it seems that a fair number of people have ill configured
        python and tcl setups that would prevent rrdtool from building if they
        are included in their current state.
 
-        cd $BUILD_DIR/rrdtool-1.2.27
-        ./configure --prefix=$INSTALL_DIR --disable-python --disable-tcl
-        make clean
-        make
-        make install
+        cd $BUILD_DIR/rrdtool-1.3rc4
+        ./configure --prefix=$INSTALL_DIR --disable-tcl --disable-python
+        $MAKE clean
+        $MAKE
+        $MAKE install
 
        SOLARIS HINT: if you want to build  the perl module for the native perl
        (the one shipping with solaris) you will need the sun forte compiler
@@ -190,4 +287,4 @@ A\bAU\bUT\bTH\bHO\bOR\bR
 
 
 
-1.2.27                            2008-02-17                       RRDBUILD(1)
+1.3rc4                            2008-05-18                       RRDBUILD(1)
index f4e67fb7970376cfcdf023a0da3ed49e742adc36..45feb621b35afff1a88176ba185be33358937c03 100644 (file)
 .\" ========================================================================
 .\"
 .IX Title "RRDCGI 1"
-.TH RRDCGI 1 "2008-02-17" "1.2.27" "rrdtool"
+.TH RRDCGI 1 "2008-03-15" "1.3rc4" "rrdtool"
 .SH "NAME"
 rrdcgi \- Create web pages containing RRD graphs based on templates
 .SH "SYNOPSIS"
index 604bbcc0a59303266bdb396e90d7b753cbfc0d06..5ffc399fd42d0294cc651d6084732e6704d142f5 100644 (file)
@@ -204,4 +204,4 @@ A\bAU\bUT\bTH\bHO\bOR\bR
 
 
 
-1.2.27                            2008-02-17                         RRDCGI(1)
+1.3rc4                            2008-03-15                         RRDCGI(1)
index f32da3624c6964bae732a7ab398895f2ab4b770c..8ceba9b227dee4ce38b3f938090b527f8fe2c86f 100644 (file)
 .\" ========================================================================
 .\"
 .IX Title "RRDCREATE 1"
-.TH RRDCREATE 1 "2008-02-17" "1.2.27" "rrdtool"
+.TH RRDCREATE 1 "2008-05-12" "1.3rc4" "rrdtool"
 .SH "NAME"
 rrdcreate \- Set up a new Round Robin Database
 .SH "SYNOPSIS"
@@ -144,12 +144,12 @@ rrdcreate \- Set up a new Round Robin Database
 The create function of RRDtool lets you set up new Round Robin
 Database (\fB\s-1RRD\s0\fR) files.  The file is created at its final, full size
 and filled with \fI*UNKNOWN*\fR data.
-.IP "\fIfilename\fR" 4
+.IP "\fIfilename\fR" 8
 .IX Item "filename"
 The name of the \fB\s-1RRD\s0\fR you want to create. \fB\s-1RRD\s0\fR files should end
 with the extension \fI.rrd\fR. However, \fBRRDtool\fR will accept any
 filename.
-.IP "\fB\-\-start\fR|\fB\-b\fR \fIstart time\fR (default: now \- 10s)" 4
+.IP "\fB\-\-start\fR|\fB\-b\fR \fIstart time\fR (default: now \- 10s)" 8
 .IX Item "--start|-b start time (default: now - 10s)"
 Specifies the time in seconds since 1970\-01\-01 \s-1UTC\s0 when the first
 value should be added to the \fB\s-1RRD\s0\fR. \fBRRDtool\fR will not accept
@@ -157,11 +157,11 @@ any data timed before or at the time specified.
 .Sp
 See also AT-STYLE \s-1TIME\s0 \s-1SPECIFICATION\s0 section in the
 \&\fIrrdfetch\fR documentation for other ways to specify time.
-.IP "\fB\-\-step\fR|\fB\-s\fR \fIstep\fR (default: 300 seconds)" 4
+.IP "\fB\-\-step\fR|\fB\-s\fR \fIstep\fR (default: 300 seconds)" 8
 .IX Item "--step|-s step (default: 300 seconds)"
 Specifies the base interval in seconds with which data will be fed
 into the \fB\s-1RRD\s0\fR.
-.IP "\fB\s-1DS:\s0\fR\fIds-name\fR\fB:\fR\fI\s-1DST\s0\fR\fB:\fR\fIdst arguments\fR" 4
+.IP "\fB\s-1DS:\s0\fR\fIds-name\fR\fB:\fR\fI\s-1DST\s0\fR\fB:\fR\fIdst arguments\fR" 8
 .IX Item "DS:ds-name:DST:dst arguments"
 A single \fB\s-1RRD\s0\fR can accept input from several data sources (\fB\s-1DS\s0\fR),
 for example incoming and outgoing traffic on a specific communication
@@ -185,7 +185,7 @@ For \s-1COMPUTE\s0 data sources, the format is:
 In order to decide which data source type to use, review the
 definitions that follow. Also consult the section on \*(L"\s-1HOW\s0 \s-1TO\s0 \s-1MEASURE\s0\*(R"
 for further insight.
-.RS 4
+.RS 8
 .IP "\fB\s-1GAUGE\s0\fR" 4
 .IX Item "GAUGE"
 is for things like temperatures or number of people in a room or the
@@ -207,9 +207,9 @@ example, to measure the rate of people entering or leaving a
 room. Internally, derive works exactly like \s-1COUNTER\s0 but without
 overflow checks. So if your counter does not reset at 32 or 64 bit you
 might want to use \s-1DERIVE\s0 and combine it with a \s-1MIN\s0 value of 0.
-.Sp
-\&\s-1NOTE\s0 on \s-1COUNTER\s0 vs \s-1DERIVE\s0
-.Sp
+.RS 4
+.IP "\s-1NOTE\s0 on \s-1COUNTER\s0 vs \s-1DERIVE\s0" 4
+.IX Item "NOTE on COUNTER vs DERIVE"
 by Don Baarda <don.baarda@baesystems.com>
 .Sp
 If you cannot tolerate ever mistaking the occasional counter reset for a
@@ -226,6 +226,9 @@ for high bandwidth interfaces and a 32bit counter, \s-1DERIVE\s0 with min=0 is
 probably preferable. If you are using a 64bit counter, just about any max
 setting will eliminate the possibility of mistaking a reset for a counter
 wrap.
+.RE
+.RS 4
+.RE
 .IP "\fB\s-1ABSOLUTE\s0\fR" 4
 .IX Item "ABSOLUTE"
 is for counters which get reset upon reading. This is used for fast counters
@@ -244,7 +247,7 @@ of the \s-1COMPUTE\s0 data source (that is the rpn-expression is only applied
 to generate PDPs). In database software, such data sets are referred
 to as \*(L"virtual\*(R" or \*(L"computed\*(R" columns.
 .RE
-.RS 4
+.RS 8
 .Sp
 \&\fIheartbeat\fR defines the maximum number of seconds that may pass
 between two updates of this data source before the value of the
@@ -272,7 +275,7 @@ names of data source listed previously in the create command. This is
 similar to the restriction that \fB\s-1CDEF\s0\fRs must refer only to \fB\s-1DEF\s0\fRs
 and \fB\s-1CDEF\s0\fRs previously defined in the same graph command.
 .RE
-.IP "\fB\s-1RRA:\s0\fR\fI\s-1CF\s0\fR\fB:\fR\fIcf arguments\fR" 4
+.IP "\fB\s-1RRA:\s0\fR\fI\s-1CF\s0\fR\fB:\fR\fIcf arguments\fR" 8
 .IX Item "RRA:CF:cf arguments"
 The purpose of an \fB\s-1RRD\s0\fR is to store data in the round robin archives
 (\fB\s-1RRA\s0\fR). An archive consists of a number of data values or statistics for
@@ -285,7 +288,29 @@ data point\fR.
 The data is also processed with the consolidation function (\fI\s-1CF\s0\fR) of
 the archive. There are several consolidation functions that
 consolidate primary data points via an aggregate function: \fB\s-1AVERAGE\s0\fR,
-\&\fB\s-1MIN\s0\fR, \fB\s-1MAX\s0\fR, \fB\s-1LAST\s0\fR. The format of \fB\s-1RRA\s0\fR line for these
+\&\fB\s-1MIN\s0\fR, \fB\s-1MAX\s0\fR, \fB\s-1LAST\s0\fR. 
+.RS 8
+.IP "\s-1AVERAGE\s0" 4
+.IX Item "AVERAGE"
+the average of the data points is stored.
+.IP "\s-1MIN\s0" 4
+.IX Item "MIN"
+the smallest of the data points is stored.
+.IP "\s-1MAX\s0" 4
+.IX Item "MAX"
+the largest of the data points is stored.
+.IP "\s-1LAST\s0" 4
+.IX Item "LAST"
+the last data points is used.
+.RE
+.RS 8
+.Sp
+Note that data aggregation inevitably leads to loss of precision and
+information. The trick is to pick the aggregate function such that the
+\&\fIinteresting\fR properties of your data is kept across the aggregation
+process.
+.Sp
+The format of \fB\s-1RRA\s0\fR line for these
 consolidation functions is:
 .Sp
 \&\fB\s-1RRA:\s0\fR\fI\s-1AVERAGE\s0 | \s-1MIN\s0 | \s-1MAX\s0 | \s-1LAST\s0\fR\fB:\fR\fIxff\fR\fB:\fR\fIsteps\fR\fB:\fR\fIrows\fR
@@ -299,6 +324,7 @@ to the number of PDPs in the interval. Thus, it ranges from 0 to 1 (exclusive).
 a \fIconsolidated data point\fR which then goes into the archive.
 .Sp
 \&\fIrows\fR defines how many generations of data values are kept in an \fB\s-1RRA\s0\fR.
+.RE
 .SH "Aberrant Behavior Detection with Holt-Winters Forecasting"
 .IX Header "Aberrant Behavior Detection with Holt-Winters Forecasting"
 In addition to the aggregate functions, there are a set of specialized
@@ -308,9 +334,11 @@ flagging aberrant behavior in the data source time series:
 .IP "\(bu" 4
 \&\fB\s-1RRA:\s0\fR\fI\s-1HWPREDICT\s0\fR\fB:\fR\fIrows\fR\fB:\fR\fIalpha\fR\fB:\fR\fIbeta\fR\fB:\fR\fIseasonal period\fR[\fB:\fR\fIrra-num\fR]
 .IP "\(bu" 4
-\&\fB\s-1RRA:\s0\fR\fI\s-1SEASONAL\s0\fR\fB:\fR\fIseasonal period\fR\fB:\fR\fIgamma\fR\fB:\fR\fIrra-num\fR
+\&\fB\s-1RRA:\s0\fR\fI\s-1MHWPREDICT\s0\fR\fB:\fR\fIrows\fR\fB:\fR\fIalpha\fR\fB:\fR\fIbeta\fR\fB:\fR\fIseasonal period\fR[\fB:\fR\fIrra-num\fR]
 .IP "\(bu" 4
-\&\fB\s-1RRA:\s0\fR\fI\s-1DEVSEASONAL\s0\fR\fB:\fR\fIseasonal period\fR\fB:\fR\fIgamma\fR\fB:\fR\fIrra-num\fR
+\&\fB\s-1RRA:\s0\fR\fI\s-1SEASONAL\s0\fR\fB:\fR\fIseasonal period\fR\fB:\fR\fIgamma\fR\fB:\fR\fIrra-num\fR[\fB:smoothing\-window=\fR\fIfraction\fR]
+.IP "\(bu" 4
+\&\fB\s-1RRA:\s0\fR\fI\s-1DEVSEASONAL\s0\fR\fB:\fR\fIseasonal period\fR\fB:\fR\fIgamma\fR\fB:\fR\fIrra-num\fR[\fB:smoothing\-window=\fR\fIfraction\fR]
 .IP "\(bu" 4
 \&\fB\s-1RRA:\s0\fR\fI\s-1DEVPREDICT\s0\fR\fB:\fR\fIrows\fR\fB:\fR\fIrra-num\fR
 .IP "\(bu" 4
@@ -319,19 +347,32 @@ flagging aberrant behavior in the data source time series:
 These \fBRRAs\fR differ from the true consolidation functions in several ways.
 First, each of the \fB\s-1RRA\s0\fRs is updated once for every primary data point.
 Second, these \fBRRAs\fR are interdependent. To generate real-time confidence
-bounds, a matched set of \s-1HWPREDICT\s0, \s-1SEASONAL\s0, \s-1DEVSEASONAL\s0, and
-\&\s-1DEVPREDICT\s0 must exist. Generating smoothed values of the primary data points
-requires both a \s-1HWPREDICT\s0 \fB\s-1RRA\s0\fR and \s-1SEASONAL\s0 \fB\s-1RRA\s0\fR. Aberrant behavior
-detection requires \s-1FAILURES\s0, \s-1HWPREDICT\s0, \s-1DEVSEASONAL\s0, and \s-1SEASONAL\s0.
-.PP
-The actual predicted, or smoothed, values are stored in the \s-1HWPREDICT\s0
-\&\fB\s-1RRA\s0\fR. The predicted deviations are stored in \s-1DEVPREDICT\s0 (think a standard
-deviation which can be scaled to yield a confidence band). The \s-1FAILURES\s0
-\&\fB\s-1RRA\s0\fR stores binary indicators. A 1 marks the indexed observation as
-failure; that is, the number of confidence bounds violations in the
-preceding window of observations met or exceeded a specified threshold. An
-example of using these \fBRRAs\fR to graph confidence bounds and failures
-appears in rrdgraph.
+bounds, a matched set of \s-1SEASONAL\s0, \s-1DEVSEASONAL\s0, \s-1DEVPREDICT\s0, and either
+\&\s-1HWPREDICT\s0 or \s-1MHWPREDICT\s0 must exist. Generating smoothed values of the primary
+data points requires a \s-1SEASONAL\s0 \fB\s-1RRA\s0\fR and either an \s-1HWPREDICT\s0 or \s-1MHWPREDICT\s0 
+\&\fB\s-1RRA\s0\fR. Aberrant behavior detection requires \s-1FAILURES\s0, \s-1DEVSEASONAL\s0, \s-1SEASONAL\s0,
+and either \s-1HWPREDICT\s0 or \s-1MHWPREDICT\s0.
+.PP
+The predicted, or smoothed, values are stored in the \s-1HWPREDICT\s0 or \s-1MHWPREDICT\s0
+\&\fB\s-1RRA\s0\fR. \s-1HWPREDICT\s0 and \s-1MHWPREDICT\s0 are actually two variations on the
+Holt-Winters method. They are interchangeable. Both attempt to decompose data
+into three components: a baseline, a trend, and a seasonal coefficient.
+\&\s-1HWPREDICT\s0 adds its seasonal coefficient to the baseline to form a prediction, whereas
+\&\s-1MHWPREDICT\s0 multiplies its seasonal coefficient by the baseline to form a
+prediction. The difference is noticeable when the baseline changes
+significantly in the course of a season; \s-1HWPREDICT\s0 will predict the seasonality
+to stay constant as the baseline changes, but \s-1MHWPREDICT\s0 will predict the
+seasonality to grow or shrink in proportion to the baseline. The proper choice
+of method depends on the thing being modeled. For simplicity, the rest of this
+discussion will refer to \s-1HWPREDICT\s0, but \s-1MHWPREDICT\s0 may be substituted in its
+place.
+.PP
+The predicted deviations are stored in \s-1DEVPREDICT\s0 (think a standard deviation
+which can be scaled to yield a confidence band). The \s-1FAILURES\s0 \fB\s-1RRA\s0\fR stores 
+binary indicators. A 1 marks the indexed observation as failure; that is, the 
+number of confidence bounds violations in the preceding window of observations 
+met or exceeded a specified threshold. An example of using these \fBRRAs\fR to graph 
+confidence bounds and failures appears in rrdgraph.
 .PP
 The \s-1SEASONAL\s0 and \s-1DEVSEASONAL\s0 \fBRRAs\fR store the seasonal coefficients for the
 Holt-Winters forecasting algorithm and the seasonal deviations, respectively.
@@ -391,6 +432,13 @@ If \s-1SEASONAL\s0 and \s-1DEVSEASONAL\s0 \fBRRAs\fR are created explicitly, \fI
 be the same for both. Note that \fIgamma\fR can also be changed via the
 \&\fBRRDtool\fR \fItune\fR command.
 .PP
+\&\fIsmoothing-window\fR specifies the fraction of a season that should be
+averaged around each point. By default, the value of \fIsmoothing-window\fR is
+0.05, which means each value in \s-1SEASONAL\s0 and \s-1DEVSEASONAL\s0 will be occasionally
+replaced by averaging it with its (\fIseasonal period\fR*0.05) nearest neighbors.
+Setting \fIsmoothing-window\fR to zero will disable the running-average smoother
+altogether.
+.PP
 \&\fIrra-num\fR provides the links between related \fBRRAs\fR. If \s-1HWPREDICT\s0 is
 specified alone and the other \fBRRAs\fR are created implicitly, then
 there is no need to worry about this argument. If \fBRRAs\fR are created
@@ -426,28 +474,24 @@ Here is an explanation by Don Baarda on the inner workings of RRDtool.
 It may help you to sort out why all this *UNKNOWN* data is popping
 up in your databases:
 .PP
-RRDtool gets fed samples at arbitrary times. From these it builds Primary
-Data Points (PDPs) at exact times on every \*(L"step\*(R" interval. The PDPs are
-then accumulated into RRAs.
+RRDtool gets fed samples/updates at arbitrary times. From these it builds Primary
+Data Points (PDPs) on every \*(L"step\*(R" interval. The PDPs are
+then accumulated into the RRAs.
 .PP
 The \*(L"heartbeat\*(R" defines the maximum acceptable interval between
-samples. If the interval between samples is less than \*(L"heartbeat\*(R",
+samples/updates. If the interval between samples is less than \*(L"heartbeat\*(R",
 then an average rate is calculated and applied for that interval. If
 the interval between samples is longer than \*(L"heartbeat\*(R", then that
 entire interval is considered \*(L"unknown\*(R". Note that there are other
 things that can make a sample interval \*(L"unknown\*(R", such as the rate
-exceeding limits, or even an \*(L"unknown\*(R" input sample.
+exceeding limits, or a sample that was explicitly marked as unknown.
 .PP
 The known rates during a \s-1PDP\s0's \*(L"step\*(R" interval are used to calculate
-an average rate for that \s-1PDP\s0. Also, if the total \*(L"unknown\*(R" time during
-the \*(L"step\*(R" interval exceeds the \*(L"heartbeat\*(R", the entire \s-1PDP\s0 is marked
+an average rate for that \s-1PDP\s0. If the total \*(L"unknown\*(R" time accounts for
+more than \fBhalf\fR the \*(L"step\*(R", the entire \s-1PDP\s0 is marked
 as \*(L"unknown\*(R". This means that a mixture of known and \*(L"unknown\*(R" sample
-times in a single \s-1PDP\s0 \*(L"step\*(R" may or may not add up to enough \*(L"unknown\*(R"
-time to exceed \*(L"heartbeat\*(R" and hence mark the whole \s-1PDP\s0 \*(L"unknown\*(R". So
-\&\*(L"heartbeat\*(R" is not only the maximum acceptable interval between
-samples, but also the maximum acceptable amount of \*(L"unknown\*(R" time per
-\&\s-1PDP\s0 (obviously this is only significant if you have \*(L"heartbeat\*(R" less
-than \*(L"step\*(R").
+times in a single \s-1PDP\s0 \*(L"step\*(R" may or may not add up to enough \*(L"known\*(R"
+time to warrent for a known \s-1PDP\s0.
 .PP
 The \*(L"heartbeat\*(R" can be short (unusual) or long (typical) relative to
 the \*(L"step\*(R" interval between PDPs. A short \*(L"heartbeat\*(R" means you
@@ -480,7 +524,7 @@ same average rate. \fI\-\- Don Baarda <don.baarda@baesystems.com>\fR
 \&       u|15|/     "swt" expired
 \&       u|16|
 \&        |17|\-\-\-\-* sample4, restart "hb", create "pdp" for step1 = 
-\&        |18|   /  = unknown due to 10 "u" labled secs > "hb"
+\&        |18|   /  = unknown due to 10 "u" labled secs > 0.5 * step
 \&        |19|  /
 \&        |20| /
 \&        |21|\-\-\-\-* sample5, restart "hb"
index a331537814b077f6657ecfd08b21e492ab32a1e1..1ebf6e0fbd412f269ead6b24a1422bb839422edc 100644 (file)
@@ -139,9 +139,9 @@ room. Internally, derive works exactly like COUNTER but without
 overflow checks. So if your counter does not reset at 32 or 64 bit you
 might want to use DERIVE and combine it with a MIN value of 0.</p>
 </dd>
-<dd>
-<p>NOTE on COUNTER vs DERIVE</p>
-</dd>
+<dl>
+<dt><strong><a name="item_note_on_counter_vs_derive">NOTE on COUNTER vs DERIVE</a></strong>
+
 <dd>
 <p>by Don Baarda &lt;<a href="mailto:don.baarda@baesystems.com">don.baarda@baesystems.com</a>&gt;</p>
 </dd>
@@ -163,6 +163,7 @@ setting will eliminate the possibility of mistaking a reset for a counter
 wrap.</p>
 </dd>
 </li>
+</dl>
 <dt><strong><a name="item_absolute"><strong>ABSOLUTE</strong></a></strong>
 
 <dd>
@@ -225,26 +226,48 @@ data point</em>.</p>
 <p>The data is also processed with the consolidation function (<em>CF</em>) of
 the archive. There are several consolidation functions that
 consolidate primary data points via an aggregate function: <strong>AVERAGE</strong>,
-<strong>MIN</strong>, <strong>MAX</strong>, <strong>LAST</strong>. The format of <strong>RRA</strong> line for these
-consolidation functions is:</p>
+<strong>MIN</strong>, <strong>MAX</strong>, <strong>LAST</strong>.</p>
+</dd>
+<dl>
+<dt><strong><a name="item_average">AVERAGE</a></strong>
+
+<dd>
+<p>the average of the data points is stored.</p>
 </dd>
+</li>
+<dt><strong><a name="item_min">MIN</a></strong>
+
 <dd>
-<p><strong>RRA:</strong><em>AVERAGE | MIN | MAX | LAST</em><strong>:</strong><em>xff</em><strong>:</strong><em>steps</em><strong>:</strong><em>rows</em></p>
+<p>the smallest of the data points is stored.</p>
+</dd>
+</li>
+<dt><strong><a name="item_max">MAX</a></strong>
+
+<dd>
+<p>the largest of the data points is stored.</p>
 </dd>
+</li>
+<dt><strong><a name="item_last">LAST</a></strong>
+
 <dd>
+<p>the last data points is used.</p>
+</dd>
+</li>
+</dl>
+<p>Note that data aggregation inevitably leads to loss of precision and
+information. The trick is to pick the aggregate function such that the
+<em>interesting</em> properties of your data is kept across the aggregation
+process.</p>
+<p>The format of <strong>RRA</strong> line for these
+consolidation functions is:</p>
+<p><strong>RRA:</strong><em>AVERAGE | MIN | MAX | LAST</em><strong>:</strong><em>xff</em><strong>:</strong><em>steps</em><strong>:</strong><em>rows</em></p>
 <p><em>xff</em> The xfiles factor defines what part of a consolidation interval may
 be made up from <em>*UNKNOWN*</em> data while the consolidated value is still
 regarded as known. It is given as the ratio of allowed <em>*UNKNOWN*</em> PDPs
 to the number of PDPs in the interval. Thus, it ranges from 0 to 1 (exclusive).</p>
-</dd>
-<dd>
 <p><em>steps</em> defines how many of these <em>primary data points</em> are used to build
 a <em>consolidated data point</em> which then goes into the archive.</p>
-</dd>
-<dd>
 <p><em>rows</em> defines how many generations of data values are kept in an <strong>RRA</strong>.</p>
-</dd>
-</li>
 </dl>
 <p>
 </p>
@@ -259,10 +282,13 @@ flagging aberrant behavior in the data source time series:</p>
 <p><strong>RRA:</strong><em>HWPREDICT</em><strong>:</strong><em>rows</em><strong>:</strong><em>alpha</em><strong>:</strong><em>beta</em><strong>:</strong><em>seasonal period</em>[<strong>:</strong><em>rra-num</em>]</p>
 </li>
 <li>
-<p><strong>RRA:</strong><em>SEASONAL</em><strong>:</strong><em>seasonal period</em><strong>:</strong><em>gamma</em><strong>:</strong><em>rra-num</em></p>
+<p><strong>RRA:</strong><em>MHWPREDICT</em><strong>:</strong><em>rows</em><strong>:</strong><em>alpha</em><strong>:</strong><em>beta</em><strong>:</strong><em>seasonal period</em>[<strong>:</strong><em>rra-num</em>]</p>
+</li>
+<li>
+<p><strong>RRA:</strong><em>SEASONAL</em><strong>:</strong><em>seasonal period</em><strong>:</strong><em>gamma</em><strong>:</strong><em>rra-num</em>[<strong>:smoothing-window=</strong><em>fraction</em>]</p>
 </li>
 <li>
-<p><strong>RRA:</strong><em>DEVSEASONAL</em><strong>:</strong><em>seasonal period</em><strong>:</strong><em>gamma</em><strong>:</strong><em>rra-num</em></p>
+<p><strong>RRA:</strong><em>DEVSEASONAL</em><strong>:</strong><em>seasonal period</em><strong>:</strong><em>gamma</em><strong>:</strong><em>rra-num</em>[<strong>:smoothing-window=</strong><em>fraction</em>]</p>
 </li>
 <li>
 <p><strong>RRA:</strong><em>DEVPREDICT</em><strong>:</strong><em>rows</em><strong>:</strong><em>rra-num</em></p>
@@ -274,18 +300,30 @@ flagging aberrant behavior in the data source time series:</p>
 <p>These <strong>RRAs</strong> differ from the true consolidation functions in several ways.
 First, each of the <strong>RRA</strong>s is updated once for every primary data point.
 Second, these <strong>RRAs</strong> are interdependent. To generate real-time confidence
-bounds, a matched set of HWPREDICT, SEASONAL, DEVSEASONAL, and
-DEVPREDICT must exist. Generating smoothed values of the primary data points
-requires both a HWPREDICT <strong>RRA</strong> and SEASONAL <strong>RRA</strong>. Aberrant behavior
-detection requires FAILURES, HWPREDICT, DEVSEASONAL, and SEASONAL.</p>
-<p>The actual predicted, or smoothed, values are stored in the HWPREDICT
-<strong>RRA</strong>. The predicted deviations are stored in DEVPREDICT (think a standard
-deviation which can be scaled to yield a confidence band). The FAILURES
-<strong>RRA</strong> stores binary indicators. A 1 marks the indexed observation as
-failure; that is, the number of confidence bounds violations in the
-preceding window of observations met or exceeded a specified threshold. An
-example of using these <strong>RRAs</strong> to graph confidence bounds and failures
-appears in <a href="././rrdgraph.html">the rrdgraph manpage</a>.</p>
+bounds, a matched set of SEASONAL, DEVSEASONAL, DEVPREDICT, and either
+HWPREDICT or MHWPREDICT must exist. Generating smoothed values of the primary
+data points requires a SEASONAL <strong>RRA</strong> and either an HWPREDICT or MHWPREDICT 
+<strong>RRA</strong>. Aberrant behavior detection requires FAILURES, DEVSEASONAL, SEASONAL,
+and either HWPREDICT or MHWPREDICT.</p>
+<p>The predicted, or smoothed, values are stored in the HWPREDICT or MHWPREDICT
+<strong>RRA</strong>. HWPREDICT and MHWPREDICT are actually two variations on the
+Holt-Winters method. They are interchangeable. Both attempt to decompose data
+into three components: a baseline, a trend, and a seasonal coefficient.
+HWPREDICT adds its seasonal coefficient to the baseline to form a prediction, whereas
+MHWPREDICT multiplies its seasonal coefficient by the baseline to form a
+prediction. The difference is noticeable when the baseline changes
+significantly in the course of a season; HWPREDICT will predict the seasonality
+to stay constant as the baseline changes, but MHWPREDICT will predict the
+seasonality to grow or shrink in proportion to the baseline. The proper choice
+of method depends on the thing being modeled. For simplicity, the rest of this
+discussion will refer to HWPREDICT, but MHWPREDICT may be substituted in its
+place.</p>
+<p>The predicted deviations are stored in DEVPREDICT (think a standard deviation
+which can be scaled to yield a confidence band). The FAILURES <strong>RRA</strong> stores 
+binary indicators. A 1 marks the indexed observation as failure; that is, the 
+number of confidence bounds violations in the preceding window of observations 
+met or exceeded a specified threshold. An example of using these <strong>RRAs</strong> to graph 
+confidence bounds and failures appears in <a href="././rrdgraph.html">the rrdgraph manpage</a>.</p>
 <p>The SEASONAL and DEVSEASONAL <strong>RRAs</strong> store the seasonal coefficients for the
 Holt-Winters forecasting algorithm and the seasonal deviations, respectively.
 There is one entry per observation time point in the seasonal cycle. For
@@ -336,6 +374,12 @@ coefficient.</p>
 <p>If SEASONAL and DEVSEASONAL <strong>RRAs</strong> are created explicitly, <em>gamma</em> need not
 be the same for both. Note that <em>gamma</em> can also be changed via the
 <strong>RRDtool</strong> <em>tune</em> command.</p>
+<p><em>smoothing-window</em> specifies the fraction of a season that should be
+averaged around each point. By default, the value of <em>smoothing-window</em> is
+0.05, which means each value in SEASONAL and DEVSEASONAL will be occasionally
+replaced by averaging it with its (<em>seasonal period</em>*0.05) nearest neighbors.
+Setting <em>smoothing-window</em> to zero will disable the running-average smoother
+altogether.</p>
 <p><em>rra-num</em> provides the links between related <strong>RRAs</strong>. If HWPREDICT is
 specified alone and the other <strong>RRAs</strong> are created implicitly, then
 there is no need to worry about this argument. If <strong>RRAs</strong> are created
@@ -377,26 +421,22 @@ default value is 9.</p>
 <p>Here is an explanation by Don Baarda on the inner workings of RRDtool.
 It may help you to sort out why all this *UNKNOWN* data is popping
 up in your databases:</p>
-<p>RRDtool gets fed samples at arbitrary times. From these it builds Primary
-Data Points (PDPs) at exact times on every ``step'' interval. The PDPs are
-then accumulated into RRAs.</p>
+<p>RRDtool gets fed samples/updates at arbitrary times. From these it builds Primary
+Data Points (PDPs) on every ``step'' interval. The PDPs are
+then accumulated into the RRAs.</p>
 <p>The ``heartbeat'' defines the maximum acceptable interval between
-samples. If the interval between samples is less than ``heartbeat'',
+samples/updates. If the interval between samples is less than ``heartbeat'',
 then an average rate is calculated and applied for that interval. If
 the interval between samples is longer than ``heartbeat'', then that
 entire interval is considered ``unknown''. Note that there are other
 things that can make a sample interval ``unknown'', such as the rate
-exceeding limits, or even an ``unknown'' input sample.</p>
+exceeding limits, or a sample that was explicitly marked as unknown.</p>
 <p>The known rates during a PDP's ``step'' interval are used to calculate
-an average rate for that PDP. Also, if the total ``unknown'' time during
-the ``step'' interval exceeds the ``heartbeat'', the entire PDP is marked
+an average rate for that PDP. If the total ``unknown'' time accounts for
+more than <strong>half</strong> the ``step'', the entire PDP is marked
 as ``unknown''. This means that a mixture of known and ``unknown'' sample
-times in a single PDP ``step'' may or may not add up to enough ``unknown''
-time to exceed ``heartbeat'' and hence mark the whole PDP ``unknown''. So
-``heartbeat'' is not only the maximum acceptable interval between
-samples, but also the maximum acceptable amount of ``unknown'' time per
-PDP (obviously this is only significant if you have ``heartbeat'' less
-than ``step'').</p>
+times in a single PDP ``step'' may or may not add up to enough ``known''
+time to warrent for a known PDP.</p>
 <p>The ``heartbeat'' can be short (unusual) or long (typical) relative to
 the ``step'' interval between PDPs. A short ``heartbeat'' means you
 require multiple samples per PDP, and if you don't get them mark the
@@ -427,7 +467,7 @@ same average rate. <em>-- Don Baarda &lt;<a href="mailto:don.baarda@baesystems.c
        u|15|/     &quot;swt&quot; expired
        u|16|
         |17|----* sample4, restart &quot;hb&quot;, create &quot;pdp&quot; for step1 = 
-        |18|   /  = unknown due to 10 &quot;u&quot; labled secs &gt; &quot;hb&quot;
+        |18|   /  = unknown due to 10 &quot;u&quot; labled secs &gt; 0.5 * step
         |19|  /
         |20| /
         |21|----* sample5, restart &quot;hb&quot;
index a47acbbaaf17e95b4c4adc7761343a0d18f19533..86817bd4dbeb60bc0c9233244744cd41e7e20165 100644 (file)
@@ -16,7 +16,7 @@ The create function of RRDtool lets you set up new Round Robin
 Database (B<RRD>) files.  The file is created at its final, full size
 and filled with I<*UNKNOWN*> data.
 
-=over
+=over 8
 
 =item I<filename>
 
@@ -63,7 +63,7 @@ In order to decide which data source type to use, review the
 definitions that follow. Also consult the section on "HOW TO MEASURE"
 for further insight.
 
-=over
+=over 4
 
 =item B<GAUGE>
 
@@ -89,7 +89,9 @@ room. Internally, derive works exactly like COUNTER but without
 overflow checks. So if your counter does not reset at 32 or 64 bit you
 might want to use DERIVE and combine it with a MIN value of 0.
 
-NOTE on COUNTER vs DERIVE
+=over
+
+=item NOTE on COUNTER vs DERIVE
 
 by Don Baarda E<lt>don.baarda@baesystems.comE<gt>
 
@@ -108,6 +110,8 @@ probably preferable. If you are using a 64bit counter, just about any max
 setting will eliminate the possibility of mistaking a reset for a counter
 wrap.
 
+=back
+
 =item B<ABSOLUTE>
 
 is for counters which get reset upon reading. This is used for fast counters
@@ -169,7 +173,35 @@ data point>.
 The data is also processed with the consolidation function (I<CF>) of
 the archive. There are several consolidation functions that
 consolidate primary data points via an aggregate function: B<AVERAGE>,
-B<MIN>, B<MAX>, B<LAST>. The format of B<RRA> line for these
+B<MIN>, B<MAX>, B<LAST>. 
+
+=over
+
+=item AVERAGE
+
+the average of the data points is stored.
+
+=item MIN
+
+the smallest of the data points is stored.
+
+=item MAX
+
+the largest of the data points is stored.
+
+=item LAST
+
+the last data points is used.
+
+=back
+
+Note that data aggregation inevitably leads to loss of precision and
+information. The trick is to pick the aggregate function such that the
+I<interesting> properties of your data is kept across the aggregation
+process.
+
+
+The format of B<RRA> line for these
 consolidation functions is:
 
 B<RRA:>I<AVERAGE | MIN | MAX | LAST>B<:>I<xff>B<:>I<steps>B<:>I<rows>
@@ -202,11 +234,15 @@ B<RRA:>I<HWPREDICT>B<:>I<rows>B<:>I<alpha>B<:>I<beta>B<:>I<seasonal period>[B<:>
 
 =item *
 
-B<RRA:>I<SEASONAL>B<:>I<seasonal period>B<:>I<gamma>B<:>I<rra-num>
+B<RRA:>I<MHWPREDICT>B<:>I<rows>B<:>I<alpha>B<:>I<beta>B<:>I<seasonal period>[B<:>I<rra-num>]
+
+=item *
+
+B<RRA:>I<SEASONAL>B<:>I<seasonal period>B<:>I<gamma>B<:>I<rra-num>[B<:smoothing-window=>I<fraction>]
 
 =item *
 
-B<RRA:>I<DEVSEASONAL>B<:>I<seasonal period>B<:>I<gamma>B<:>I<rra-num>
+B<RRA:>I<DEVSEASONAL>B<:>I<seasonal period>B<:>I<gamma>B<:>I<rra-num>[B<:smoothing-window=>I<fraction>]
 
 =item *
 
@@ -221,19 +257,32 @@ B<RRA:>I<FAILURES>B<:>I<rows>B<:>I<threshold>B<:>I<window length>B<:>I<rra-num>
 These B<RRAs> differ from the true consolidation functions in several ways.
 First, each of the B<RRA>s is updated once for every primary data point.
 Second, these B<RRAs> are interdependent. To generate real-time confidence
-bounds, a matched set of HWPREDICT, SEASONAL, DEVSEASONAL, and
-DEVPREDICT must exist. Generating smoothed values of the primary data points
-requires both a HWPREDICT B<RRA> and SEASONAL B<RRA>. Aberrant behavior
-detection requires FAILURES, HWPREDICT, DEVSEASONAL, and SEASONAL.
-
-The actual predicted, or smoothed, values are stored in the HWPREDICT
-B<RRA>. The predicted deviations are stored in DEVPREDICT (think a standard
-deviation which can be scaled to yield a confidence band). The FAILURES
-B<RRA> stores binary indicators. A 1 marks the indexed observation as
-failure; that is, the number of confidence bounds violations in the
-preceding window of observations met or exceeded a specified threshold. An
-example of using these B<RRAs> to graph confidence bounds and failures
-appears in L<rrdgraph>.
+bounds, a matched set of SEASONAL, DEVSEASONAL, DEVPREDICT, and either
+HWPREDICT or MHWPREDICT must exist. Generating smoothed values of the primary
+data points requires a SEASONAL B<RRA> and either an HWPREDICT or MHWPREDICT 
+B<RRA>. Aberrant behavior detection requires FAILURES, DEVSEASONAL, SEASONAL,
+and either HWPREDICT or MHWPREDICT.
+
+The predicted, or smoothed, values are stored in the HWPREDICT or MHWPREDICT
+B<RRA>. HWPREDICT and MHWPREDICT are actually two variations on the
+Holt-Winters method. They are interchangeable. Both attempt to decompose data
+into three components: a baseline, a trend, and a seasonal coefficient.
+HWPREDICT adds its seasonal coefficient to the baseline to form a prediction, whereas
+MHWPREDICT multiplies its seasonal coefficient by the baseline to form a
+prediction. The difference is noticeable when the baseline changes
+significantly in the course of a season; HWPREDICT will predict the seasonality
+to stay constant as the baseline changes, but MHWPREDICT will predict the
+seasonality to grow or shrink in proportion to the baseline. The proper choice
+of method depends on the thing being modeled. For simplicity, the rest of this
+discussion will refer to HWPREDICT, but MHWPREDICT may be substituted in its
+place.
+
+The predicted deviations are stored in DEVPREDICT (think a standard deviation
+which can be scaled to yield a confidence band). The FAILURES B<RRA> stores 
+binary indicators. A 1 marks the indexed observation as failure; that is, the 
+number of confidence bounds violations in the preceding window of observations 
+met or exceeded a specified threshold. An example of using these B<RRAs> to graph 
+confidence bounds and failures appears in L<rrdgraph>.
 
 The SEASONAL and DEVSEASONAL B<RRAs> store the seasonal coefficients for the
 Holt-Winters forecasting algorithm and the seasonal deviations, respectively.
@@ -293,6 +342,13 @@ If SEASONAL and DEVSEASONAL B<RRAs> are created explicitly, I<gamma> need not
 be the same for both. Note that I<gamma> can also be changed via the
 B<RRDtool> I<tune> command.
 
+I<smoothing-window> specifies the fraction of a season that should be
+averaged around each point. By default, the value of I<smoothing-window> is
+0.05, which means each value in SEASONAL and DEVSEASONAL will be occasionally
+replaced by averaging it with its (I<seasonal period>*0.05) nearest neighbors.
+Setting I<smoothing-window> to zero will disable the running-average smoother
+altogether.
+
 I<rra-num> provides the links between related B<RRAs>. If HWPREDICT is
 specified alone and the other B<RRAs> are created implicitly, then
 there is no need to worry about this argument. If B<RRAs> are created
@@ -343,28 +399,24 @@ Here is an explanation by Don Baarda on the inner workings of RRDtool.
 It may help you to sort out why all this *UNKNOWN* data is popping
 up in your databases:
 
-RRDtool gets fed samples at arbitrary times. From these it builds Primary
-Data Points (PDPs) at exact times on every "step" interval. The PDPs are
-then accumulated into RRAs.
+RRDtool gets fed samples/updates at arbitrary times. From these it builds Primary
+Data Points (PDPs) on every "step" interval. The PDPs are
+then accumulated into the RRAs.
 
 The "heartbeat" defines the maximum acceptable interval between
-samples. If the interval between samples is less than "heartbeat",
+samples/updates. If the interval between samples is less than "heartbeat",
 then an average rate is calculated and applied for that interval. If
 the interval between samples is longer than "heartbeat", then that
 entire interval is considered "unknown". Note that there are other
 things that can make a sample interval "unknown", such as the rate
-exceeding limits, or even an "unknown" input sample.
+exceeding limits, or a sample that was explicitly marked as unknown.
 
 The known rates during a PDP's "step" interval are used to calculate
-an average rate for that PDP. Also, if the total "unknown" time during
-the "step" interval exceeds the "heartbeat", the entire PDP is marked
+an average rate for that PDP. If the total "unknown" time accounts for
+more than B<half> the "step", the entire PDP is marked
 as "unknown". This means that a mixture of known and "unknown" sample
-times in a single PDP "step" may or may not add up to enough "unknown"
-time to exceed "heartbeat" and hence mark the whole PDP "unknown". So
-"heartbeat" is not only the maximum acceptable interval between
-samples, but also the maximum acceptable amount of "unknown" time per
-PDP (obviously this is only significant if you have "heartbeat" less
-than "step").
+times in a single PDP "step" may or may not add up to enough "known"
+time to warrent for a known PDP.
 
 The "heartbeat" can be short (unusual) or long (typical) relative to
 the "step" interval between PDPs. A short "heartbeat" means you
@@ -396,7 +448,7 @@ same average rate. I<-- Don Baarda E<lt>don.baarda@baesystems.comE<gt>>
        u|15|/     "swt" expired
        u|16|
         |17|----* sample4, restart "hb", create "pdp" for step1 = 
-        |18|   /  = unknown due to 10 "u" labled secs > "hb"
+        |18|   /  = unknown due to 10 "u" labled secs > 0.5 * step
         |19|  /
         |20| /
         |21|----* sample5, restart "hb"
index eaa70c156b29c7826bfb9f998fbbac1678072e31..197959d5335442217aa8d2cc56ec6582bbc41ff0 100644 (file)
@@ -15,166 +15,188 @@ D\bDE\bES\bSC\bCR\bRI\bIP\bPT\bTI\bIO\bON\bN
        with _\b*_\bU_\bN_\bK_\bN_\bO_\bW_\bN_\b* data.
 
        _\bf_\bi_\bl_\be_\bn_\ba_\bm_\be
-           The name of the R\bRR\bRD\bD you want to create. R\bRR\bRD\bD files should end with
-           the extension _\b._\br_\br_\bd. However, R\bRR\bRD\bDt\bto\boo\bol\bl will accept any filename.
+               The name of the R\bRR\bRD\bD you want to create. R\bRR\bRD\bD files should end
+               with the extension _\b._\br_\br_\bd. However, R\bRR\bRD\bDt\bto\boo\bol\bl will accept any file-
+               name.
 
        -\b--\b-s\bst\bta\bar\brt\bt|-\b-b\bb _\bs_\bt_\ba_\br_\bt _\bt_\bi_\bm_\be (default: now - 10s)
-           Specifies the time in seconds since 1970-01-01 UTC when the first
-           value should be added to the R\bRR\bRD\bD. R\bRR\bRD\bDt\bto\boo\bol\bl will not accept any data
-           timed before or at the time specified.
+               Specifies the time in seconds since 1970-01-01 UTC when the
+               first value should be added to the R\bRR\bRD\bD. R\bRR\bRD\bDt\bto\boo\bol\bl will not accept
+               any data timed before or at the time specified.
 
-           See also AT-STYLE TIME SPECIFICATION section in the _\br_\br_\bd_\bf_\be_\bt_\bc_\bh docu-
-           mentation for other ways to specify time.
+               See also AT-STYLE TIME SPECIFICATION section in the _\br_\br_\bd_\bf_\be_\bt_\bc_\bh
+               documentation for other ways to specify time.
 
        -\b--\b-s\bst\bte\bep\bp|-\b-s\bs _\bs_\bt_\be_\bp (default: 300 seconds)
-           Specifies the base interval in seconds with which data will be fed
-           into the R\bRR\bRD\bD.
+               Specifies the base interval in seconds with which data will be
+               fed into the R\bRR\bRD\bD.
 
        D\bDS\bS:\b:_\bd_\bs_\b-_\bn_\ba_\bm_\be:\b:_\bD_\bS_\bT:\b:_\bd_\bs_\bt _\ba_\br_\bg_\bu_\bm_\be_\bn_\bt_\bs
-           A single R\bRR\bRD\bD can accept input from several data sources (D\bDS\bS), for
-           example incoming and outgoing traffic on a specific communication
-           line. With the D\bDS\bS configuration option you must define some basic
-           properties of each data source you want to store in the R\bRR\bRD\bD.
-
-           _\bd_\bs_\b-_\bn_\ba_\bm_\be is the name you will use to reference this particular data
-           source from an R\bRR\bRD\bD. A _\bd_\bs_\b-_\bn_\ba_\bm_\be must be 1 to 19 characters long in
-           the characters [a-zA-Z0-9_].
-
-           _\bD_\bS_\bT defines the Data Source Type. The remaining arguments of a data
-           source entry depend on the data source type. For GAUGE, COUNTER,
-           DERIVE, and ABSOLUTE the format for a data source entry is:
-
-           D\bDS\bS:\b:_\bd_\bs_\b-_\bn_\ba_\bm_\be:\b:_\bG_\bA_\bU_\bG_\bE _\b| _\bC_\bO_\bU_\bN_\bT_\bE_\bR _\b| _\bD_\bE_\bR_\bI_\bV_\bE _\b| _\bA_\bB_\bS_\bO_\bL_\bU_\bT_\bE:\b:_\bh_\be_\ba_\br_\bt_\bb_\be_\ba_\bt:\b:_\bm_\bi_\bn:\b:_\bm_\ba_\bx
-
-           For COMPUTE data sources, the format is:
-
-           D\bDS\bS:\b:_\bd_\bs_\b-_\bn_\ba_\bm_\be:\b:_\bC_\bO_\bM_\bP_\bU_\bT_\bE:\b:_\br_\bp_\bn_\b-_\be_\bx_\bp_\br_\be_\bs_\bs_\bi_\bo_\bn
-
-           In order to decide which data source type to use, review the defi-
-           nitions that follow. Also consult the section on "HOW TO MEASURE"
-           for further insight.
-
-           G\bGA\bAU\bUG\bGE\bE
-               is for things like temperatures or number of people in a room
-               or the value of a RedHat share.
-
-           C\bCO\bOU\bUN\bNT\bTE\bER\bR
-               is for continuous incrementing counters like the ifInOctets
-               counter in a router. The C\bCO\bOU\bUN\bNT\bTE\bER\bR data source assumes that the
-               counter never decreases, except when a counter overflows.  The
-               update function takes the overflow into account.  The counter
-               is stored as a per-second rate. When the counter overflows,
-               RRDtool checks if the overflow happened at the 32bit or 64bit
-               border and acts accordingly by adding an appropriate value to
-               the result.
-
-           D\bDE\bER\bRI\bIV\bVE\bE
-               will store the derivative of the line going from the last to
-               the current value of the data source. This can be useful for
-               gauges, for example, to measure the rate of people entering or
-               leaving a room. Internally, derive works exactly like COUNTER
-               but without overflow checks. So if your counter does not reset
-               at 32 or 64 bit you might want to use DERIVE and combine it
-               with a MIN value of 0.
-
-               NOTE on COUNTER vs DERIVE
-
-               by Don Baarda <don.baarda@baesystems.com>
-
-               If you cannot tolerate ever mistaking the occasional counter
-               reset for a legitimate counter wrap, and would prefer
-               "Unknowns" for all legitimate counter wraps and resets, always
-               use DERIVE with min=0. Otherwise, using COUNTER with a suitable
-               max will return correct values for all legitimate counter
-               wraps, mark some counter resets as "Unknown", but can mistake
-               some counter resets for a legitimate counter wrap.
-
-               For a 5 minute step and 32-bit counter, the probability of mis-
-               taking a counter reset for a legitimate wrap is arguably about
-               0.8% per 1Mbps of maximum bandwidth. Note that this equates to
-               80% for 100Mbps interfaces, so for high bandwidth interfaces
-               and a 32bit counter, DERIVE with min=0 is probably preferable.
-               If you are using a 64bit counter, just about any max setting
-               will eliminate the possibility of mistaking a reset for a
-               counter wrap.
-
-           A\bAB\bBS\bSO\bOL\bLU\bUT\bTE\bE
-               is for counters which get reset upon reading. This is used for
-               fast counters which tend to overflow. So instead of reading
-               them normally you reset them after every read to make sure you
-               have a maximum time available before the next overflow. Another
-               usage is for things you count like number of messages since the
-               last update.
-
-           C\bCO\bOM\bMP\bPU\bUT\bTE\bE
-               is for storing the result of a formula applied to other data
-               sources in the R\bRR\bRD\bD. This data source is not supplied a value on
-               update, but rather its Primary Data Points (PDPs) are computed
-               from the PDPs of the data sources according to the rpn-expres-
-               sion that defines the formula. Consolidation functions are then
-               applied normally to the PDPs of the COMPUTE data source (that
-               is the rpn-expression is only applied to generate PDPs). In
-               database software, such data sets are referred to as "virtual"
-               or "computed" columns.
-
-           _\bh_\be_\ba_\br_\bt_\bb_\be_\ba_\bt defines the maximum number of seconds that may pass
-           between two updates of this data source before the value of the
-           data source is assumed to be _\b*_\bU_\bN_\bK_\bN_\bO_\bW_\bN_\b*.
-
-           _\bm_\bi_\bn and _\bm_\ba_\bx define the expected range values for data supplied by a
-           data source. If _\bm_\bi_\bn and/or _\bm_\ba_\bx any value outside the defined range
-           will be regarded as _\b*_\bU_\bN_\bK_\bN_\bO_\bW_\bN_\b*. If you do not know or care about min
-           and max, set them to U for unknown. Note that min and max always
-           refer to the processed values of the DS. For a traffic-C\bCO\bOU\bUN\bNT\bTE\bER\bR type
-           DS this would be the maximum and minimum data-rate expected from
-           the device.
-
-           _\bI_\bf _\bi_\bn_\bf_\bo_\br_\bm_\ba_\bt_\bi_\bo_\bn _\bo_\bn _\bm_\bi_\bn_\bi_\bm_\ba_\bl_\b/_\bm_\ba_\bx_\bi_\bm_\ba_\bl _\be_\bx_\bp_\be_\bc_\bt_\be_\bd _\bv_\ba_\bl_\bu_\be_\bs _\bi_\bs _\ba_\bv_\ba_\bi_\bl_\ba_\bb_\bl_\be_\b,
-           _\ba_\bl_\bw_\ba_\by_\bs _\bs_\be_\bt _\bt_\bh_\be _\bm_\bi_\bn _\ba_\bn_\bd_\b/_\bo_\br _\bm_\ba_\bx _\bp_\br_\bo_\bp_\be_\br_\bt_\bi_\be_\bs_\b. _\bT_\bh_\bi_\bs _\bw_\bi_\bl_\bl _\bh_\be_\bl_\bp _\bR_\bR_\bD_\bt_\bo_\bo_\bl _\bi_\bn
-           _\bd_\bo_\bi_\bn_\bg _\ba _\bs_\bi_\bm_\bp_\bl_\be _\bs_\ba_\bn_\bi_\bt_\by _\bc_\bh_\be_\bc_\bk _\bo_\bn _\bt_\bh_\be _\bd_\ba_\bt_\ba _\bs_\bu_\bp_\bp_\bl_\bi_\be_\bd _\bw_\bh_\be_\bn _\br_\bu_\bn_\bn_\bi_\bn_\bg
-           _\bu_\bp_\bd_\ba_\bt_\be_\b.
-
-           _\br_\bp_\bn_\b-_\be_\bx_\bp_\br_\be_\bs_\bs_\bi_\bo_\bn defines the formula used to compute the PDPs of a
-           COMPUTE data source from other data sources in the same <RRD>. It
-           is similar to defining a C\bCD\bDE\bEF\bF argument for the graph command.
-           Please refer to that manual page for a list and description of RPN
-           operations supported. For COMPUTE data sources, the following RPN
-           operations are not supported: COUNT, PREV, TIME, and LTIME. In
-           addition, in defining the RPN expression, the COMPUTE data source
-           may only refer to the names of data source listed previously in the
-           create command. This is similar to the restriction that C\bCD\bDE\bEF\bFs must
-           refer only to D\bDE\bEF\bFs and C\bCD\bDE\bEF\bFs previously defined in the same graph
-           command.
+               A single R\bRR\bRD\bD can accept input from several data sources (D\bDS\bS),
+               for example incoming and outgoing traffic on a specific commu-
+               nication line. With the D\bDS\bS configuration option you must define
+               some basic properties of each data source you want to store in
+               the R\bRR\bRD\bD.
+
+               _\bd_\bs_\b-_\bn_\ba_\bm_\be is the name you will use to reference this particular
+               data source from an R\bRR\bRD\bD. A _\bd_\bs_\b-_\bn_\ba_\bm_\be must be 1 to 19 characters
+               long in the characters [a-zA-Z0-9_].
+
+               _\bD_\bS_\bT defines the Data Source Type. The remaining arguments of a
+               data source entry depend on the data source type. For GAUGE,
+               COUNTER, DERIVE, and ABSOLUTE the format for a data source
+               entry is:
+
+               D\bDS\bS:\b:_\bd_\bs_\b-_\bn_\ba_\bm_\be:\b:_\bG_\bA_\bU_\bG_\bE _\b| _\bC_\bO_\bU_\bN_\bT_\bE_\bR _\b| _\bD_\bE_\bR_\bI_\bV_\bE _\b| _\bA_\bB_\bS_\bO_\bL_\bU_\bT_\bE:\b:_\bh_\be_\ba_\br_\bt_\b-
+               _\bb_\be_\ba_\bt:\b:_\bm_\bi_\bn:\b:_\bm_\ba_\bx
+
+               For COMPUTE data sources, the format is:
+
+               D\bDS\bS:\b:_\bd_\bs_\b-_\bn_\ba_\bm_\be:\b:_\bC_\bO_\bM_\bP_\bU_\bT_\bE:\b:_\br_\bp_\bn_\b-_\be_\bx_\bp_\br_\be_\bs_\bs_\bi_\bo_\bn
+
+               In order to decide which data source type to use, review the
+               definitions that follow. Also consult the section on "HOW TO
+               MEASURE" for further insight.
+
+               G\bGA\bAU\bUG\bGE\bE
+                   is for things like temperatures or number of people in a
+                   room or the value of a RedHat share.
+
+               C\bCO\bOU\bUN\bNT\bTE\bER\bR
+                   is for continuous incrementing counters like the ifInOctets
+                   counter in a router. The C\bCO\bOU\bUN\bNT\bTE\bER\bR data source assumes that
+                   the counter never decreases, except when a counter over-
+                   flows.  The update function takes the overflow into
+                   account.  The counter is stored as a per-second rate. When
+                   the counter overflows, RRDtool checks if the overflow hap-
+                   pened at the 32bit or 64bit border and acts accordingly by
+                   adding an appropriate value to the result.
+
+               D\bDE\bER\bRI\bIV\bVE\bE
+                   will store the derivative of the line going from the last
+                   to the current value of the data source. This can be useful
+                   for gauges, for example, to measure the rate of people
+                   entering or leaving a room. Internally, derive works
+                   exactly like COUNTER but without overflow checks. So if
+                   your counter does not reset at 32 or 64 bit you might want
+                   to use DERIVE and combine it with a MIN value of 0.
+
+                   NOTE on COUNTER vs DERIVE
+                       by Don Baarda <don.baarda@baesystems.com>
+
+                       If you cannot tolerate ever mistaking the occasional
+                       counter reset for a legitimate counter wrap, and would
+                       prefer "Unknowns" for all legitimate counter wraps and
+                       resets, always use DERIVE with min=0. Otherwise, using
+                       COUNTER with a suitable max will return correct values
+                       for all legitimate counter wraps, mark some counter
+                       resets as "Unknown", but can mistake some counter
+                       resets for a legitimate counter wrap.
+
+                       For a 5 minute step and 32-bit counter, the probability
+                       of mistaking a counter reset for a legitimate wrap is
+                       arguably about 0.8% per 1Mbps of maximum bandwidth.
+                       Note that this equates to 80% for 100Mbps interfaces,
+                       so for high bandwidth interfaces and a 32bit counter,
+                       DERIVE with min=0 is probably preferable. If you are
+                       using a 64bit counter, just about any max setting will
+                       eliminate the possibility of mistaking a reset for a
+                       counter wrap.
+
+               A\bAB\bBS\bSO\bOL\bLU\bUT\bTE\bE
+                   is for counters which get reset upon reading. This is used
+                   for fast counters which tend to overflow. So instead of
+                   reading them normally you reset them after every read to
+                   make sure you have a maximum time available before the next
+                   overflow. Another usage is for things you count like number
+                   of messages since the last update.
+
+               C\bCO\bOM\bMP\bPU\bUT\bTE\bE
+                   is for storing the result of a formula applied to other
+                   data sources in the R\bRR\bRD\bD. This data source is not supplied a
+                   value on update, but rather its Primary Data Points (PDPs)
+                   are computed from the PDPs of the data sources according to
+                   the rpn-expression that defines the formula. Consolidation
+                   functions are then applied normally to the PDPs of the COM-
+                   PUTE data source (that is the rpn-expression is only
+                   applied to generate PDPs). In database software, such data
+                   sets are referred to as "virtual" or "computed" columns.
+
+               _\bh_\be_\ba_\br_\bt_\bb_\be_\ba_\bt defines the maximum number of seconds that may pass
+               between two updates of this data source before the value of the
+               data source is assumed to be _\b*_\bU_\bN_\bK_\bN_\bO_\bW_\bN_\b*.
+
+               _\bm_\bi_\bn and _\bm_\ba_\bx define the expected range values for data supplied
+               by a data source. If _\bm_\bi_\bn and/or _\bm_\ba_\bx any value outside the
+               defined range will be regarded as _\b*_\bU_\bN_\bK_\bN_\bO_\bW_\bN_\b*. If you do not know
+               or care about min and max, set them to U for unknown. Note that
+               min and max always refer to the processed values of the DS. For
+               a traffic-C\bCO\bOU\bUN\bNT\bTE\bER\bR type DS this would be the maximum and minimum
+               data-rate expected from the device.
+
+               _\bI_\bf _\bi_\bn_\bf_\bo_\br_\bm_\ba_\bt_\bi_\bo_\bn _\bo_\bn _\bm_\bi_\bn_\bi_\bm_\ba_\bl_\b/_\bm_\ba_\bx_\bi_\bm_\ba_\bl _\be_\bx_\bp_\be_\bc_\bt_\be_\bd _\bv_\ba_\bl_\bu_\be_\bs _\bi_\bs _\ba_\bv_\ba_\bi_\bl_\ba_\bb_\bl_\be_\b,
+               _\ba_\bl_\bw_\ba_\by_\bs _\bs_\be_\bt _\bt_\bh_\be _\bm_\bi_\bn _\ba_\bn_\bd_\b/_\bo_\br _\bm_\ba_\bx _\bp_\br_\bo_\bp_\be_\br_\bt_\bi_\be_\bs_\b. _\bT_\bh_\bi_\bs _\bw_\bi_\bl_\bl _\bh_\be_\bl_\bp _\bR_\bR_\bD_\b-
+               _\bt_\bo_\bo_\bl _\bi_\bn _\bd_\bo_\bi_\bn_\bg _\ba _\bs_\bi_\bm_\bp_\bl_\be _\bs_\ba_\bn_\bi_\bt_\by _\bc_\bh_\be_\bc_\bk _\bo_\bn _\bt_\bh_\be _\bd_\ba_\bt_\ba _\bs_\bu_\bp_\bp_\bl_\bi_\be_\bd _\bw_\bh_\be_\bn
+               _\br_\bu_\bn_\bn_\bi_\bn_\bg _\bu_\bp_\bd_\ba_\bt_\be_\b.
+
+               _\br_\bp_\bn_\b-_\be_\bx_\bp_\br_\be_\bs_\bs_\bi_\bo_\bn defines the formula used to compute the PDPs of
+               a COMPUTE data source from other data sources in the same
+               <RRD>. It is similar to defining a C\bCD\bDE\bEF\bF argument for the graph
+               command. Please refer to that manual page for a list and
+               description of RPN operations supported. For COMPUTE data
+               sources, the following RPN operations are not supported: COUNT,
+               PREV, TIME, and LTIME. In addition, in defining the RPN expres-
+               sion, the COMPUTE data source may only refer to the names of
+               data source listed previously in the create command. This is
+               similar to the restriction that C\bCD\bDE\bEF\bFs must refer only to D\bDE\bEF\bFs
+               and C\bCD\bDE\bEF\bFs previously defined in the same graph command.
 
        R\bRR\bRA\bA:\b:_\bC_\bF:\b:_\bc_\bf _\ba_\br_\bg_\bu_\bm_\be_\bn_\bt_\bs
-           The purpose of an R\bRR\bRD\bD is to store data in the round robin archives
-           (R\bRR\bRA\bA). An archive consists of a number of data values or statistics
-           for each of the defined data-sources (D\bDS\bS) and is defined with an
-           R\bRR\bRA\bA line.
+               The purpose of an R\bRR\bRD\bD is to store data in the round robin
+               archives (R\bRR\bRA\bA). An archive consists of a number of data values
+               or statistics for each of the defined data-sources (D\bDS\bS) and is
+               defined with an R\bRR\bRA\bA line.
 
-           When data is entered into an R\bRR\bRD\bD, it is first fit into time slots
-           of the length defined with the -\b-s\bs option, thus becoming a _\bp_\br_\bi_\bm_\ba_\br_\by
-           _\bd_\ba_\bt_\ba _\bp_\bo_\bi_\bn_\bt.
+               When data is entered into an R\bRR\bRD\bD, it is first fit into time
+               slots of the length defined with the -\b-s\bs option, thus becoming a
+               _\bp_\br_\bi_\bm_\ba_\br_\b_\bd_\ba_\bt_\ba _\bp_\bo_\bi_\bn_\bt.
 
-           The data is also processed with the consolidation function (_\bC_\bF) of
-           the archive. There are several consolidation functions that consol-
-           idate primary data points via an aggregate function: A\bAV\bVE\bER\bRA\bAG\bGE\bE, M\bMI\bIN\bN,
-           M\bMA\bAX\bX, L\bLA\bAS\bST\bT. The format of R\bRR\bRA\bA line for these consolidation functions
-           is:
+               The data is also processed with the consolidation function (_\bC_\bF)
+               of the archive. There are several consolidation functions that
+               consolidate primary data points via an aggregate function:
+               A\bAV\bVE\bER\bRA\bAG\bGE\bE, M\bMI\bIN\bN, M\bMA\bAX\bX, L\bLA\bAS\bST\bT.
 
-           R\bRR\bRA\bA:\b:_\bA_\bV_\bE_\bR_\bA_\bG_\bE _\b| _\bM_\bI_\bN _\b| _\bM_\bA_\bX _\b| _\bL_\bA_\bS_\bT:\b:_\bx_\bf_\bf:\b:_\bs_\bt_\be_\bp_\bs:\b:_\br_\bo_\bw_\bs
+               AVERAGE
+                   the average of the data points is stored.
 
-           _\bx_\bf_\bf The xfiles factor defines what part of a consolidation interval
-           may be made up from _\b*_\bU_\bN_\bK_\bN_\bO_\bW_\bN_\b* data while the consolidated value is
-           still regarded as known. It is given as the ratio of allowed
-           _\b*_\bU_\bN_\bK_\bN_\bO_\bW_\bN_\b* PDPs to the number of PDPs in the interval. Thus, it
-           ranges from 0 to 1 (exclusive).
+               MIN the smallest of the data points is stored.
 
-           _\bs_\bt_\be_\bp_\bs defines how many of these _\bp_\br_\bi_\bm_\ba_\br_\by _\bd_\ba_\bt_\ba _\bp_\bo_\bi_\bn_\bt_\bs are used to
-           build a _\bc_\bo_\bn_\bs_\bo_\bl_\bi_\bd_\ba_\bt_\be_\bd _\bd_\ba_\bt_\ba _\bp_\bo_\bi_\bn_\bt which then goes into the archive.
+               MAX the largest of the data points is stored.
 
-           _\br_\bo_\bw_\bs defines how many generations of data values are kept in an
-           R\bRR\bRA\bA.
+               LAST
+                   the last data points is used.
+
+               Note that data aggregation inevitably leads to loss of preci-
+               sion and information. The trick is to pick the aggregate func-
+               tion such that the _\bi_\bn_\bt_\be_\br_\be_\bs_\bt_\bi_\bn_\bg properties of your data is kept
+               across the aggregation process.
+
+               The format of R\bRR\bRA\bA line for these consolidation functions is:
+
+               R\bRR\bRA\bA:\b:_\bA_\bV_\bE_\bR_\bA_\bG_\bE _\b| _\bM_\bI_\bN _\b| _\bM_\bA_\bX _\b| _\bL_\bA_\bS_\bT:\b:_\bx_\bf_\bf:\b:_\bs_\bt_\be_\bp_\bs:\b:_\br_\bo_\bw_\bs
+
+               _\bx_\bf_\bf The xfiles factor defines what part of a consolidation
+               interval may be made up from _\b*_\bU_\bN_\bK_\bN_\bO_\bW_\bN_\b* data while the consoli-
+               dated value is still regarded as known. It is given as the
+               ratio of allowed _\b*_\bU_\bN_\bK_\bN_\bO_\bW_\bN_\b* PDPs to the number of PDPs in the
+               interval. Thus, it ranges from 0 to 1 (exclusive).
+
+               _\bs_\bt_\be_\bp_\bs defines how many of these _\bp_\br_\bi_\bm_\ba_\br_\by _\bd_\ba_\bt_\ba _\bp_\bo_\bi_\bn_\bt_\bs are used to
+               build a _\bc_\bo_\bn_\bs_\bo_\bl_\bi_\bd_\ba_\bt_\be_\bd _\bd_\ba_\bt_\ba _\bp_\bo_\bi_\bn_\bt which then goes into the
+               archive.
+
+               _\br_\bo_\bw_\bs defines how many generations of data values are kept in an
+               R\bRR\bRA\bA.
 
 A\bAb\bbe\ber\brr\bra\ban\bnt\bt B\bBe\beh\bha\bav\bvi\bio\bor\br D\bDe\bet\bte\bec\bct\bti\bio\bon\bn w\bwi\bit\bth\bh H\bHo\bol\blt\bt-\b-W\bWi\bin\bnt\bte\ber\brs\bs F\bFo\bor\bre\bec\bca\bas\bst\bti\bin\bng\bg
        In addition to the aggregate functions, there are a set of specialized
@@ -184,9 +206,13 @@ A\bAb\bbe\ber\brr\bra\ban\bnt\bt B\bBe\beh\bha\bav\bvi\bio\bor\br D\bDe\bet\bte\bec\bct\bti\bio\bon\bn w\b
 
        Â·   R\bRR\bRA\bA:\b:_\bH_\bW_\bP_\bR_\bE_\bD_\bI_\bC_\bT:\b:_\br_\bo_\bw_\bs:\b:_\ba_\bl_\bp_\bh_\ba:\b:_\bb_\be_\bt_\ba:\b:_\bs_\be_\ba_\bs_\bo_\bn_\ba_\bl _\bp_\be_\br_\bi_\bo_\bd[:\b:_\br_\br_\ba_\b-_\bn_\bu_\bm]
 
-       Â·   R\bRR\bRA\bA:\b:_\bS_\bE_\bA_\bS_\bO_\bN_\bA_\bL:\b:_\bs_\be_\ba_\bs_\bo_\bn_\ba_\bl _\bp_\be_\br_\bi_\bo_\bd:\b:_\bg_\ba_\bm_\bm_\ba:\b:_\br_\br_\ba_\b-_\bn_\bu_\bm
+       Â·   R\bRR\bRA\bA:\b:_\bM_\bH_\bW_\bP_\bR_\bE_\bD_\bI_\bC_\bT:\b:_\br_\bo_\bw_\bs:\b:_\ba_\bl_\bp_\bh_\ba:\b:_\bb_\be_\bt_\ba:\b:_\bs_\be_\ba_\bs_\bo_\bn_\ba_\bl _\bp_\be_\br_\bi_\bo_\bd[:\b:_\br_\br_\ba_\b-_\bn_\bu_\bm]
 
-       Â·   R\bRR\bRA\bA:\b:_\bD_\bE_\bV_\bS_\bE_\bA_\bS_\bO_\bN_\bA_\bL:\b:_\bs_\be_\ba_\bs_\bo_\bn_\ba_\bl _\bp_\be_\br_\bi_\bo_\bd:\b:_\bg_\ba_\bm_\bm_\ba:\b:_\br_\br_\ba_\b-_\bn_\bu_\bm
+       Â·   R\bRR\bRA\bA:\b:_\bS_\bE_\bA_\bS_\bO_\bN_\bA_\bL:\b:_\bs_\be_\ba_\bs_\bo_\bn_\ba_\bl _\bp_\be_\br_\bi_\bo_\bd:\b:_\bg_\ba_\bm_\bm_\ba:\b:_\br_\br_\ba_\b-_\bn_\bu_\bm[:\b:s\bsm\bmo\boo\bot\bth\bhi\bin\bng\bg-\b-w\bwi\bin\bnd\bdo\bow\bw=\b=_\bf_\br_\ba_\bc_\b-
+           _\bt_\bi_\bo_\bn]
+
+       Â·   R\bRR\bRA\bA:\b:_\bD_\bE_\bV_\bS_\bE_\bA_\bS_\bO_\bN_\bA_\bL:\b:_\bs_\be_\ba_\bs_\bo_\bn_\ba_\bl _\bp_\be_\br_\bi_\bo_\bd:\b:_\bg_\ba_\bm_\bm_\ba:\b:_\br_\br_\ba_\b-_\bn_\bu_\bm[:\b:s\bsm\bmo\boo\bot\bth\bhi\bin\bng\bg-\b-w\bwi\bin\bn-\b-
+           d\bdo\bow\bw=\b=_\bf_\br_\ba_\bc_\bt_\bi_\bo_\bn]
 
        Â·   R\bRR\bRA\bA:\b:_\bD_\bE_\bV_\bP_\bR_\bE_\bD_\bI_\bC_\bT:\b:_\br_\bo_\bw_\bs:\b:_\br_\br_\ba_\b-_\bn_\bu_\bm
 
@@ -195,20 +221,34 @@ A\bAb\bbe\ber\brr\bra\ban\bnt\bt B\bBe\beh\bha\bav\bvi\bio\bor\br D\bDe\bet\bte\bec\bct\bti\bio\bon\bn w\b
        These R\bRR\bRA\bAs\bs differ from the true consolidation functions in several
        ways.  First, each of the R\bRR\bRA\bAs is updated once for every primary data
        point.  Second, these R\bRR\bRA\bAs\bs are interdependent. To generate real-time
-       confidence bounds, a matched set of HWPREDICT, SEASONAL, DEVSEASONAL,
-       and DEVPREDICT must exist. Generating smoothed values of the primary
-       data points requires both a HWPREDICT R\bRR\bRA\bA and SEASONAL R\bRR\bRA\bA. Aberrant
-       behavior detection requires FAILURES, HWPREDICT, DEVSEASONAL, and SEA-
-       SONAL.
-
-       The actual predicted, or smoothed, values are stored in the HWPREDICT
-       R\bRR\bRA\bA. The predicted deviations are stored in DEVPREDICT (think a stan-
-       dard deviation which can be scaled to yield a confidence band). The
-       FAILURES R\bRR\bRA\bA stores binary indicators. A 1 marks the indexed observa-
-       tion as failure; that is, the number of confidence bounds violations in
-       the preceding window of observations met or exceeded a specified
-       threshold. An example of using these R\bRR\bRA\bAs\bs to graph confidence bounds
-       and failures appears in rrdgraph.
+       confidence bounds, a matched set of SEASONAL, DEVSEASONAL, DEVPREDICT,
+       and either HWPREDICT or MHWPREDICT must exist. Generating smoothed val-
+       ues of the primary data points requires a SEASONAL R\bRR\bRA\bA and either an
+       HWPREDICT or MHWPREDICT R\bRR\bRA\bA. Aberrant behavior detection requires FAIL-
+       URES, DEVSEASONAL, SEASONAL, and either HWPREDICT or MHWPREDICT.
+
+       The predicted, or smoothed, values are stored in the HWPREDICT or MHW-
+       PREDICT R\bRR\bRA\bA. HWPREDICT and MHWPREDICT are actually two variations on
+       the Holt-Winters method. They are interchangeable. Both attempt to
+       decompose data into three components: a baseline, a trend, and a sea-
+       sonal coefficient.  HWPREDICT adds its seasonal coefficient to the
+       baseline to form a prediction, whereas MHWPREDICT multiplies its sea-
+       sonal coefficient by the baseline to form a prediction. The difference
+       is noticeable when the baseline changes significantly in the course of
+       a season; HWPREDICT will predict the seasonality to stay constant as
+       the baseline changes, but MHWPREDICT will predict the seasonality to
+       grow or shrink in proportion to the baseline. The proper choice of
+       method depends on the thing being modeled. For simplicity, the rest of
+       this discussion will refer to HWPREDICT, but MHWPREDICT may be substi-
+       tuted in its place.
+
+       The predicted deviations are stored in DEVPREDICT (think a standard
+       deviation which can be scaled to yield a confidence band). The FAILURES
+       R\bRR\bRA\bA stores binary indicators. A 1 marks the indexed observation as
+       failure; that is, the number of confidence bounds violations in the
+       preceding window of observations met or exceeded a specified threshold.
+       An example of using these R\bRR\bRA\bAs\bs to graph confidence bounds and failures
+       appears in rrdgraph.
 
        The SEASONAL and DEVSEASONAL R\bRR\bRA\bAs\bs store the seasonal coefficients for
        the Holt-Winters forecasting algorithm and the seasonal deviations,
@@ -269,6 +309,13 @@ A\bAb\bbe\ber\brr\bra\ban\bnt\bt B\bBe\beh\bha\bav\bvi\bio\bor\br D\bDe\bet\bte\bec\bct\bti\bio\bon\bn w\b
        be the same for both. Note that _\bg_\ba_\bm_\bm_\ba can also be changed via the R\bRR\bRD\bD-\b-
        t\bto\boo\bol\bl _\bt_\bu_\bn_\be command.
 
+       _\bs_\bm_\bo_\bo_\bt_\bh_\bi_\bn_\bg_\b-_\bw_\bi_\bn_\bd_\bo_\bw specifies the fraction of a season that should be
+       averaged around each point. By default, the value of _\bs_\bm_\bo_\bo_\bt_\bh_\bi_\bn_\bg_\b-_\bw_\bi_\bn_\bd_\bo_\bw
+       is 0.05, which means each value in SEASONAL and DEVSEASONAL will be
+       occasionally replaced by averaging it with its (_\bs_\be_\ba_\bs_\bo_\bn_\ba_\bl _\bp_\be_\br_\bi_\bo_\bd*0.05)
+       nearest neighbors.  Setting _\bs_\bm_\bo_\bo_\bt_\bh_\bi_\bn_\bg_\b-_\bw_\bi_\bn_\bd_\bo_\bw to zero will disable the
+       running-average smoother altogether.
+
        _\br_\br_\ba_\b-_\bn_\bu_\bm provides the links between related R\bRR\bRA\bAs\bs. If HWPREDICT is speci-
        fied alone and the other R\bRR\bRA\bAs\bs are created implicitly, then there is no
        need to worry about this argument. If R\bRR\bRA\bAs\bs are created explicitly, then
@@ -303,28 +350,24 @@ T\bTh\bhe\be H\bHE\bEA\bAR\bRT\bTB\bBE\bEA\bAT\bT a\ban\bnd\bd t\bth\bhe\be S\bST\bTE\bEP\bP
        It may help you to sort out why all this *UNKNOWN* data is popping up
        in your databases:
 
-       RRDtool gets fed samples at arbitrary times. From these it builds Pri-
-       mary Data Points (PDPs) at exact times on every "step" interval. The
-       PDPs are then accumulated into RRAs.
+       RRDtool gets fed samples/updates at arbitrary times. From these it
+       builds Primary Data Points (PDPs) on every "step" interval. The PDPs
+       are then accumulated into the RRAs.
 
        The "heartbeat" defines the maximum acceptable interval between sam-
-       ples. If the interval between samples is less than "heartbeat", then an
-       average rate is calculated and applied for that interval. If the inter-
-       val between samples is longer than "heartbeat", then that entire inter-
-       val is considered "unknown". Note that there are other things that can
-       make a sample interval "unknown", such as the rate exceeding limits, or
-       even an "unknown" input sample.
+       ples/updates. If the interval between samples is less than "heartbeat",
+       then an average rate is calculated and applied for that interval. If
+       the interval between samples is longer than "heartbeat", then that
+       entire interval is considered "unknown". Note that there are other
+       things that can make a sample interval "unknown", such as the rate
+       exceeding limits, or a sample that was explicitly marked as unknown.
 
        The known rates during a PDP's "step" interval are used to calculate an
-       average rate for that PDP. Also, if the total "unknown" time during the
-       "step" interval exceeds the "heartbeat", the entire PDP is marked as
-       "unknown". This means that a mixture of known and "unknown" sample
-       times in a single PDP "step" may or may not add up to enough "unknown"
-       time to exceed "heartbeat" and hence mark the whole PDP "unknown". So
-       "heartbeat" is not only the maximum acceptable interval between sam-
-       ples, but also the maximum acceptable amount of "unknown" time per PDP
-       (obviously this is only significant if you have "heartbeat" less than
-       "step").
+       average rate for that PDP. If the total "unknown" time accounts for
+       more than h\bha\bal\blf\bf the "step", the entire PDP is marked as "unknown". This
+       means that a mixture of known and "unknown" sample times in a single
+       PDP "step" may or may not add up to enough "known" time to warrent for
+       a known PDP.
 
        The "heartbeat" can be short (unusual) or long (typical) relative to
        the "step" interval between PDPs. A short "heartbeat" means you require
@@ -356,7 +399,7 @@ T\bTh\bhe\be H\bHE\bEA\bAR\bRT\bTB\bBE\bEA\bAT\bT a\ban\bnd\bd t\bth\bhe\be S\bST\bTE\bEP\bP
               u|15|/     "swt" expired
               u|16|
                |17|----* sample4, restart "hb", create "pdp" for step1 =
-               |18|   /  = unknown due to 10 "u" labled secs > "hb"
+               |18|   /  = unknown due to 10 "u" labled secs > 0.5 * step
                |19|  /
                |20| /
                |21|----* sample5, restart "hb"
@@ -498,4 +541,4 @@ A\bAU\bUT\bTH\bHO\bOR\bR
 
 
 
-1.2.27                            2008-02-17                      RRDCREATE(1)
+1.3rc4                            2008-05-12                      RRDCREATE(1)
index 3df1a452fdefb8177ece8b9d5edcbc6539041ced..a3c8799931c5545a65ea0c6f44754f279c7a9ead 100644 (file)
 .\" ========================================================================
 .\"
 .IX Title "RRDDUMP 1"
-.TH RRDDUMP 1 "2008-02-17" "1.2.27" "rrdtool"
+.TH RRDDUMP 1 "2008-05-16" "1.3rc4" "rrdtool"
 .SH "NAME"
 rrddump \- dump the contents of an RRD to XML format
 .SH "SYNOPSIS"
 .IX Header "SYNOPSIS"
-\&\fBrrdtool\fR \fBdump\fR \fIfilename.rrd\fR > \fIfilename.xml\fR
+\&\fBrrdtool\fR \fBdump\fR [\fB\-\-no\-header\fR|\fB\-n\fR] \fIfilename.rrd\fR > \fIfilename.xml\fR
 .PP
 or 
 .PP
-\&\fBrrdtool\fR \fBdump\fR \fIfilename.rrd\fR \fIfilename.xml\fR
+\&\fBrrdtool\fR \fBdump\fR [\fB\-\-no\-header\fR|\fB\-n\fR] \fIfilename.rrd\fR \fIfilename.xml\fR
 .SH "DESCRIPTION"
 .IX Header "DESCRIPTION"
 The \fBdump\fR function writes the contents of an \fB\s-1RRD\s0\fR in human
@@ -154,6 +154,12 @@ The name of the \fB\s-1RRD\s0\fR you want to dump.
 .IX Item "filename.xml"
 The (optional) filename that you want to write the \s-1XML\s0 output to.
 If not specified, the \s-1XML\s0 will be printed to stdout.
+.IP "[\fB\-\-no\-header\fR|\fB\-n\fR]" 8
+.IX Item "[--no-header|-n]"
+In rrdtool 1.3, the dump function started producing correct xml\-headers.
+Unfortunately the rrdtool restore function from the 1.2 series can not
+handle these headers. With this option you can supress the creatinon of
+the xml headers.
 .SH "EXAMPLES"
 .IX Header "EXAMPLES"
 To transfer an \s-1RRD\s0 between architectures, follow these steps:
index 2283122eb90f49c424f7a26cafb441db9a26e832..f4fc01b8db6e5332a31c5195d87c4a39eedace1a 100644 (file)
@@ -32,9 +32,9 @@
 </p>
 <hr />
 <h1><a name="synopsis">SYNOPSIS</a></h1>
-<p><strong>rrdtool</strong> <strong>dump</strong> <em>filename.rrd</em> &gt; <em>filename.xml</em></p>
+<p><strong>rrdtool</strong> <strong>dump</strong> [<strong>--no-header</strong>|<strong>-n</strong>] <em>filename.rrd</em> &gt; <em>filename.xml</em></p>
 <p>or</p>
-<p><strong>rrdtool</strong> <strong>dump</strong> <em>filename.rrd</em> <em>filename.xml</em></p>
+<p><strong>rrdtool</strong> <strong>dump</strong> [<strong>--no-header</strong>|<strong>-n</strong>] <em>filename.rrd</em> <em>filename.xml</em></p>
 <p>
 </p>
 <hr />
@@ -59,6 +59,15 @@ convenient manner.</p>
 If not specified, the XML will be printed to stdout.</p>
 </dd>
 </li>
+<dt><strong><a name="item__5b_2d_2dno_2dheader_7c_2dn_5d">[<strong>--no-header</strong>|<strong>-n</strong>]</a></strong>
+
+<dd>
+<p>In rrdtool 1.3, the dump function started producing correct xml-headers.
+Unfortunately the rrdtool restore function from the 1.2 series can not
+handle these headers. With this option you can supress the creatinon of
+the xml headers.</p>
+</dd>
+</li>
 </dl>
 <p>
 </p>
index 2e4cd4b2419138bab805a718c130597935a45e4c..a698d841eaa5387580fa9000e0c43020eab8de84 100644 (file)
@@ -4,11 +4,11 @@ rrddump - dump the contents of an RRD to XML format
 
 =head1 SYNOPSIS
 
-B<rrdtool> B<dump> I<filename.rrd> E<gt> I<filename.xml>
+B<rrdtool> B<dump> S<[B<--no-header>|B<-n>]> I<filename.rrd> E<gt> I<filename.xml>
 
 or 
 
-B<rrdtool> B<dump> I<filename.rrd> I<filename.xml>
+B<rrdtool> B<dump> S<[B<--no-header>|B<-n>]> I<filename.rrd> I<filename.xml>
 
 =head1 DESCRIPTION
 
@@ -20,7 +20,6 @@ manipulate the contents of an B<RRD> file in a somewhat more
 convenient manner.
 
 
-
 =over 8
 
 =item I<filename.rrd>
@@ -32,6 +31,13 @@ The name of the B<RRD> you want to dump.
 The (optional) filename that you want to write the XML output to.
 If not specified, the XML will be printed to stdout.
 
+=item S<[B<--no-header>|B<-n>]>
+
+In rrdtool 1.3, the dump function started producing correct xml-headers.
+Unfortunately the rrdtool restore function from the 1.2 series can not
+handle these headers. With this option you can supress the creatinon of
+the xml headers.
+
 =back
 
 =head1 EXAMPLES
index f995a56269d8d50662f3b90779c72c18151b5d7f..163b0d6bb776c617fe62082bfbb184a66120c9bc 100644 (file)
@@ -6,11 +6,11 @@ N\bNA\bAM\bME\bE
        rrddump - dump the contents of an RRD to XML format
 
 S\bSY\bYN\bNO\bOP\bPS\bSI\bIS\bS
-       r\brr\brd\bdt\bto\boo\bol\bl d\bdu\bum\bmp\bp _\bf_\bi_\bl_\be_\bn_\ba_\bm_\be_\b._\br_\br_\bd > _\bf_\bi_\bl_\be_\bn_\ba_\bm_\be_\b._\bx_\bm_\bl
+       r\brr\brd\bdt\bto\boo\bol\bl d\bdu\bum\bmp\b[-\b--\b-n\bno\bo-\b-h\bhe\bea\bad\bde\ber\br|-\b-n\bn] _\bf_\bi_\bl_\be_\bn_\ba_\bm_\be_\b._\br_\br_\bd > _\bf_\bi_\bl_\be_\bn_\ba_\bm_\be_\b._\bx_\bm_\bl
 
        or
 
-       r\brr\brd\bdt\bto\boo\bol\bl d\bdu\bum\bmp\bp _\bf_\bi_\bl_\be_\bn_\ba_\bm_\be_\b._\br_\br_\bd _\bf_\bi_\bl_\be_\bn_\ba_\bm_\be_\b._\bx_\bm_\bl
+       r\brr\brd\bdt\bto\boo\bol\bl d\bdu\bum\bmp\b[-\b--\b-n\bno\bo-\b-h\bhe\bea\bad\bde\ber\br|-\b-n\bn] _\bf_\bi_\bl_\be_\bn_\ba_\bm_\be_\b._\br_\br_\bd _\bf_\bi_\bl_\be_\bn_\ba_\bm_\be_\b._\bx_\bm_\bl
 
 D\bDE\bES\bSC\bCR\bRI\bIP\bPT\bTI\bIO\bON\bN
        The d\bdu\bum\bmp\bp function writes the contents of an R\bRR\bRD\bD in human readable (?)
@@ -26,6 +26,12 @@ D\bDE\bES\bSC\bCR\bRI\bIP\bPT\bTI\bIO\bON\bN
                The (optional) filename that you want to write the XML output
                to.  If not specified, the XML will be printed to stdout.
 
+       [-\b--\b-n\bno\bo-\b-h\bhe\bea\bad\bde\ber\br|-\b-n\bn]
+               In rrdtool 1.3, the dump function started producing correct
+               xml-headers.  Unfortunately the rrdtool restore function from
+               the 1.2 series can not handle these headers. With this option
+               you can supress the creatinon of the xml headers.
+
 E\bEX\bXA\bAM\bMP\bPL\bLE\bES\bS
        To transfer an RRD between architectures, follow these steps:
 
@@ -42,4 +48,4 @@ A\bAU\bUT\bTH\bHO\bOR\bR
 
 
 
-1.2.27                            2008-02-17                        RRDDUMP(1)
+1.3rc4                            2008-05-16                        RRDDUMP(1)
index 9c20fb68ba0d76cb6d2964afbfa12303493bd3ec..95912e630c5e2217f96e8100be18af33b77ee6a4 100644 (file)
 .\" ========================================================================
 .\"
 .IX Title "RRDFETCH 1"
-.TH RRDFETCH 1 "2008-02-17" "1.2.27" "rrdtool"
+.TH RRDFETCH 1 "2008-03-15" "1.3rc4" "rrdtool"
 .SH "NAME"
 rrdfetch \- Fetch data from an RRD.
 .SH "SYNOPSIS"
index e2af859b29db2fc0488410750a0440fa81cc0c06..70f24db5f7348db4ccea70ca8dd9c946ac7d72cb 100644 (file)
@@ -228,4 +228,4 @@ A\bAU\bUT\bTH\bHO\bOR\bR
 
 
 
-1.2.27                            2008-02-17                       RRDFETCH(1)
+1.3rc4                            2008-03-15                       RRDFETCH(1)
index 57e7c1a675ab5d69610be42a0baceb466b3a0f44..344193303a40af58d4b5a5dbf543b74242f356c2 100644 (file)
 .\" ========================================================================
 .\"
 .IX Title "RRDFIRST 1"
-.TH RRDFIRST 1 "2008-02-17" "1.2.27" "rrdtool"
+.TH RRDFIRST 1 "2008-03-15" "1.3rc4" "rrdtool"
 .SH "NAME"
 rrdfirst \- Return the date of the first data sample in an RRA within an RRD
 .SH "SYNOPSIS"
index 684e8bc58ecf4e583b7432df7ea93997c6094ffe..a469ff791be614a7b50a8bd24367e4f270ff1b1a 100644 (file)
@@ -26,4 +26,4 @@ A\bAU\bUT\bTH\bHO\bOR\bR
 
 
 
-1.2.27                            2008-02-17                       RRDFIRST(1)
+1.3rc4                            2008-03-15                       RRDFIRST(1)
index 674a3704ce221e80823d5bd206bd368ab4a0404a..ff44df3514d335416e24b0b0100ae9878dbd01da 100644 (file)
 .\" ========================================================================
 .\"
 .IX Title "RRDGRAPH 1"
-.TH RRDGRAPH 1 "2008-02-17" "1.2.27" "rrdtool"
+.TH RRDGRAPH 1 "2008-04-21" "1.3rc4" "rrdtool"
 .SH "NAME"
 rrdgraph \- Round Robin Database tool grapher functions
 .SH "SYNOPSIS"
 .IX Header "SYNOPSIS"
-\&\fBrrdtool graph\fR \fIfilename\fR
+\&\fBrrdtool graph|graphv\fR \fIfilename\fR
 [\fIoption\fR ...]
 [\fIdata definition\fR ...]
 [\fIdata calculation\fR ...]
@@ -170,12 +170,18 @@ Sometimes data is not exactly in the format you would like to display
 it. For instance, you might be collecting \fBbytes\fR per second, but
 want to display \fBbits\fR per second. This is what the \fBdata calculation\fR command is designed for. After
 \&\fBconsolidating\fR the data, a copy is made and this copy is modified
-using a rather powerful rrdgraph_rpn command set.
+using a rather powerful \fB\s-1RPN\s0\fR command set.
 .PP
 When you are done fetching and processing the data, it is time to
 graph it (or print it).  This ends the \fBrrdtool graph\fR sequence.
 .SH "OPTIONS"
 .IX Header "OPTIONS"
+.IP "\fBgraphv\fR" 4
+.IX Item "graphv"
+This alternate version of \fBgraph\fR takes the same arguments and performs the
+same function. The \fIv\fR stands for \fIverbose\fR, which describes the output
+returned. \fBgraphv\fR will return a lot of information about the graph using
+the same format as rrdtool info (key = value). See the bottom of the document for more information.
 .IP "filename" 4
 .IX Item "filename"
 The name and path of the graph to generate. It is recommended to
@@ -193,7 +199,7 @@ The start and end of the time series you would like to display, and which
 \&\fB\s-1RRA\s0\fR the data should come from.  Defaults are: 1 day ago until
 now, with the best possible resolution. \fBStart\fR and \fBend\fR can
 be specified in several formats, see
-rrdfetch and rrdgraph_examples.
+AT-STYLE \s-1TIME\s0 \s-1SPECIFICATION\s0 and rrdgraph_examples.
 By default, \fBrrdtool graph\fR calculates the width of one pixel in
 the time domain and tries to get data from an \fB\s-1RRA\s0\fR with that
 resolution.  With the \fBstep\fR option you can alter this behaviour.
@@ -212,10 +218,15 @@ placed string at the left hand side of the graph.
 [\fB\-w\fR|\fB\-\-width\fR \fIpixels\fR]
 [\fB\-h\fR|\fB\-\-height\fR \fIpixels\fR]
 [\fB\-j\fR|\fB\-\-only\-graph\fR]
+[\fB\-D\fR|\fB\-\-full\-size\-mode\fR]
 .Sp
-The width and height of the \fBcanvas\fR (the part of the graph with
+By default, the width and height of the \fBcanvas\fR (the part with
 the actual data and such). This defaults to 400 pixels by 100 pixels.
 .Sp
+If you specify the \fB\-\-full\-size\-mode\fR option, the width and height
+specify the final dimensions of the output image and the canvas
+is automatically resized to fit.
+.Sp
 If you specify the \fB\-\-only\-graph\fR option and set the height < 32
 pixels you will get a tiny graph image (thumbnail) to use as an icon
 for use in an overview, for example. All labeling will be stripped off
@@ -261,15 +272,19 @@ and thus the throughput may be higher than the \s-1WAN\s0 line speed.
 .Sp
 [\fB\-N\fR|\fB\-\-no\-gridfit\fR]
 .Sp
-In order to avoid anti-aliasing effects gridlines are placed on
-integer pixel values. This is by default done by extending
-the scale so that gridlines happens to be spaced using an
-integer number of pixels and also start on an integer pixel value.
-This might extend the scale too much for some logarithmic scales
-and for linear scales where \fB\-\-alt\-autoscale\fR is needed.
-Using \fB\-\-no\-gridfit\fR disables modification of the scale.
-.IP "X\-Grid" 4
-.IX Item "X-Grid"
+In order to avoid anti-aliasing blurring effects rrdtool snaps
+points to device resolution pixels, this results in a crisper
+aperance. If this is not to your liking, you can use this switch
+to turn this behaviour off.
+.Sp
+Gridfitting is turned off for \s-1PDF\s0, \s-1EPS\s0, \s-1SVG\s0 output by default.
+.IP "Grid" 4
+.IX Item "Grid"
+.RS 4
+.PD 0
+.IP "X\-Axis" 4
+.IX Item "X-Axis"
+.PD
 [\fB\-x\fR|\fB\-\-x\-grid\fR \fI\s-1GTM\s0\fR\fB:\fR\fI\s-1GST\s0\fR\fB:\fR\fI\s-1MTM\s0\fR\fB:\fR\fI\s-1MST\s0\fR\fB:\fR\fI\s-1LTM\s0\fR\fB:\fR\fI\s-1LST\s0\fR\fB:\fR\fI\s-1LPR\s0\fR\fB:\fR\fI\s-1LFM\s0\fR]
 .Sp
 [\fB\-x\fR|\fB\-\-x\-grid\fR \fBnone\fR]
@@ -300,14 +315,14 @@ and labels every 4 hours. The labels are placed under the major grid
 lines as they specify exactly that time.
 .Sp
 .Vb 1
-\& \-\-x\-grid HOUR:8:DAY:1:DAY:1:0:%A
+\& \-\-x\-grid HOUR:8:DAY:1:DAY:1:86400:%A
 .Ve
 .Sp
 This places grid lines every 8 hours, major grid lines and labels
 each day. The labels are placed exactly between two major grid lines
 as they specify the complete day and not just midnight.
-.IP "Y\-Grid" 4
-.IX Item "Y-Grid"
+.IP "Y\-Axis" 4
+.IX Item "Y-Axis"
 [\fB\-y\fR|\fB\-\-y\-grid\fR \fIgrid step\fR\fB:\fR\fIlabel factor\fR]
 .Sp
 [\fB\-y\fR|\fB\-\-y\-grid\fR \fBnone\fR]
@@ -362,6 +377,9 @@ fideling with the y\-axis labeling.
 With this option y\-axis values on logarithmic graphs will be scaled to 
 the appropriate units (k, M, etc.) instead of using exponential notation.
 Note that for linear graphs, \s-1SI\s0 notation is used by default.
+.RE
+.RS 4
+.RE
 .IP "Miscellaneous" 4
 .IX Item "Miscellaneous"
 [\fB\-z\fR|\fB\-\-lazy\fR]
@@ -409,32 +427,55 @@ elements on the \s-1RRD\s0 graphs. \f(CW\*(C`DEFAULT\*(C'\fR sets the default va
 elements, \f(CW\*(C`TITLE\*(C'\fR for the title, \f(CW\*(C`AXIS\*(C'\fR for the axis labels, \f(CW\*(C`UNIT\*(C'\fR
 for the vertical unit label, \f(CW\*(C`LEGEND\*(C'\fR for the graph legend.
 .Sp
-Use Times for the title: \f(CW\*(C`\-\-font TITLE:13:/usr/lib/fonts/times.ttf\*(C'\fR
+Use Times for the title: \f(CW\*(C`\-\-font TITLE:13:Times\*(C'\fR
 .Sp
 If you do not give a font string you can modify just the sice of the default font:
 \&\f(CW\*(C`\-\-font TITLE:13:\*(C'\fR.
 .Sp
 If you specify the size 0 then you can modify just the font without touching
 the size. This is especially usefull for altering the default font without
-resetting the default fontsizes: \f(CW\*(C`\-\-font DEFAULT:0:/usr/lib/fonts/times.ttf\*(C'\fR.
+resetting the default fontsizes: \f(CW\*(C`\-\-font DEFAULT:0:Courier\*(C'\fR.
 .Sp
 RRDtool comes with a preset default font. You can set the environment
 variable \f(CW\*(C`RRD_DEFAULT_FONT\*(C'\fR if you want to change this.
 .Sp
-Truetype fonts are only supported for \s-1PNG\s0 output. See below.
+RRDtool uses Pango for its font handling. This means you can to use
+the full Pango syntax when selecting your font:
+.Sp
+The font name has the form "[\fIFAMILY-LIST\fR] [\fISTYLE-OPTIONS\fR] [\fI\s-1SIZE\s0\fR]",
+where \fIFAMILY-LIST\fR is a comma separated list of families optionally
+terminated by a comma, \fI\s-1STYLE_OPTIONS\s0\fR is a whitespace separated list of
+words where each \s-1WORD\s0 describes one of style, variant, weight, stretch, or
+gravity, and \fI\s-1SIZE\s0\fR is a decimal number (size in points) or optionally
+followed by the unit modifier \*(L"px\*(R" for absolute size. Any one of the options
+may be absent.
+.Sp
+[\fB\-R\fR|\fB\-\-font\-render\-mode\fR {\fBnormal\fR,\fBlight\fR,\fBmono\fR}]
 .Sp
-[\fB\-R\fR|\fB\-\-font\-render\-mode\fR {\fInormal\fR,\fIlight\fR,\fImono\fR}]
+There are 3 font render modes:
 .Sp
-This lets you customize the strength of the font smoothing,
-or disable it entirely using \fImono\fR. By default, \fInormal\fR
-font smoothing is used.
+\&\fBnormal\fR: Full Hinting and Antialiasing (default)
+.Sp
+\&\fBlight\fR: Slight Hinting and Antialiasing
+.Sp
+\&\fBmono\fR: Full Hinting and \s-1NO\s0 Antialiasing
 .Sp
 [\fB\-B\fR|\fB\-\-font\-smoothing\-threshold\fR \fIsize\fR]
 .Sp
+(this gets ignored in 1.3 for now!)
+.Sp
 This specifies the largest font size which will be rendered
 bitmapped, that is, without any font smoothing. By default,
 no text is rendered bitmapped.
 .Sp
+[\fB\-G\fR|\fB\-\-graph\-render\-mode\fR {\fBnormal\fR,\fBmono\fR}]
+.Sp
+There are 2 render modes:
+.Sp
+\&\fBnormal\fR: Graphs are fully Antialiased (default)
+.Sp
+\&\fBmono\fR: No Antialiasing
+.Sp
 [\fB\-E\fR|\fB\-\-slope\-mode\fR]
 .Sp
 RRDtool graphs are composed of stair case curves by default. This is in line with
@@ -451,6 +492,8 @@ Times\-Bold, Times\-BoldItalic, Times\-Italic, Times\-Roman, and ZapfDingbats.
 .Sp
 [\fB\-i\fR|\fB\-\-interlaced\fR]
 .Sp
+(this gets ignored in 1.3 for now!)
+.Sp
 If images are interlaced they become visible on browsers more quickly.
 .Sp
 [\fB\-g\fR|\fB\-\-no\-legend\fR]
@@ -493,6 +536,59 @@ See rrdgraph_data and rrdgraph_rpn for the exact format.
 You need at least one graph element to generate an image and/or
 at least one print statement to generate a report.
 See rrdgraph_graph for the exact format.
+.IP "Markup" 4
+.IX Item "Markup"
+All text in rrdtool is rendered using Pango markup. This means text can contain embeded markup instructions.
+Simple html markup using 
+.Sp
+.Vb 1
+\& <span key="value">text</span>
+.Ve
+.Sp
+can be used. Apart from the verbose syntax, there are also the following short tags available.
+.Sp
+.Vb 9
+\& b     Bold
+\& big   Makes font relatively larger, equivalent to <span size="larger">
+\& i     Italic
+\& s     Strikethrough
+\& sub   Subscript
+\& sup   Superscript
+\& small Makes font relatively smaller, equivalent to <span size="smaller">
+\& tt    Monospace font
+\& u     Underline
+.Ve
+.Sp
+More details on http://developer.gnome.org/doc/API/2.0/pango/PangoMarkupFormat.html.
+.Sh "graphv"
+.IX Subsection "graphv"
+Calling rrdtool with the graphv option will return information in the
+rrdtool info format. On the command line this means that all output will be
+in key=value format. When used from the perl and ruby bindings a hash
+pointer will be returned from the call.
+.PP
+When the filename '\-' is given, the contents of the graph itself will also
+be returned through this interface (hash key 'image'). On the command line
+the output will look like this:
+.PP
+.Vb 12
+\& print[0] = "0.020833"
+\& print[1] = "0.0440833"
+\& graph_left = 51
+\& graph_top = 22
+\& graph_width = 400
+\& graph_height = 100
+\& image_width = 481
+\& image_height = 154
+\& value_min = 0.0000000000e+00
+\& value_max = 4.0000000000e\-02
+\& image = BLOB_SIZE:8196
+\& [... 8196 bytes of image data ...]
+.Ve
+.PP
+There is more information returned than in the standard interface.
+Especially the 'graph_*' keys are new. They help applications that want to
+know what is where on the graph.
 .SH "SEE ALSO"
 .IX Header "SEE ALSO"
 rrdgraph gives an overview of how \fBrrdtool graph\fR works.
index e7a9505f4dc15d9f694d3c4665f513588f5354e2..ec76219cea760325096152b30517a98c5c428d4c 100644 (file)
        <li><a href="#description">DESCRIPTION</a></li>
        <li><a href="#overview">OVERVIEW</a></li>
        <li><a href="#options">OPTIONS</a></li>
+       <ul>
+
+               <li><a href="#graphv">graphv</a></li>
+       </ul>
+
        <li><a href="#see_also">SEE ALSO</a></li>
        <li><a href="#author">AUTHOR</a></li>
 </ul>
@@ -34,7 +39,7 @@
 </p>
 <hr />
 <h1><a name="synopsis">SYNOPSIS</a></h1>
-<p><strong>rrdtool graph</strong> <em>filename</em>
+<p><strong>rrdtool graph|graphv</strong> <em>filename</em>
 [<em><a href="././rrdgraph.html#options">option</a></em> ...]
 [<em><a href="././rrdgraph_data.html#def">data definition</a></em> ...]
 [<em><a href="././rrdgraph_data.html#cdef">data calculation</a></em> ...]
@@ -71,7 +76,7 @@ well become unknown!</p>
 it. For instance, you might be collecting <strong>bytes</strong> per second, but
 want to display <strong>bits</strong> per second. This is what the <strong><a href="././rrdgraph_data.html#cdef">data calculation</a></strong> command is designed for. After
 <strong>consolidating</strong> the data, a copy is made and this copy is modified
-using a rather powerful <a href="././rrdgraph_rpn.html">the rrdgraph_rpn manpage</a> command set.</p>
+using a rather powerful <strong><a href="././rrdgraph_rpn.html">RPN</a></strong> command set.</p>
 <p>When you are done fetching and processing the data, it is time to
 graph it (or print it).  This ends the <strong>rrdtool graph</strong> sequence.</p>
 <p>
@@ -79,6 +84,15 @@ graph it (or print it).  This ends the <strong>rrdtool graph</strong> sequence.<
 <hr />
 <h1><a name="options">OPTIONS</a></h1>
 <dl>
+<dt><strong><a name="item_graphv"><strong>graphv</strong></a></strong>
+
+<dd>
+<p>This alternate version of <strong>graph</strong> takes the same arguments and performs the
+same function. The <em>v</em> stands for <em>verbose</em>, which describes the output
+returned. <strong>graphv</strong> will return a lot of information about the graph using
+the same format as rrdtool info (key = value). See the bottom of the document for more information.</p>
+</dd>
+</li>
 <dt><strong><a name="item_filename">filename</a></strong>
 
 <dd>
@@ -102,7 +116,7 @@ this case, no other output is generated.</p>
 <strong>RRA</strong> the data should come from.  Defaults are: 1 day ago until
 now, with the best possible resolution. <strong>Start</strong> and <strong>end</strong> can
 be specified in several formats, see
-<a href="././rrdfetch.html">the rrdfetch manpage</a> and <a href="././rrdgraph_examples.html">the rrdgraph_examples manpage</a>.
+<a href="././rrdfetch.html">AT-STYLE TIME SPECIFICATION</a> and <a href="././rrdgraph_examples.html">the rrdgraph_examples manpage</a>.
 By default, <strong>rrdtool graph</strong> calculates the width of one pixel in
 the time domain and tries to get data from an <strong>RRA</strong> with that
 resolution.  With the <strong>step</strong> option you can alter this behaviour.
@@ -127,13 +141,19 @@ placed string at the left hand side of the graph.</p>
 <dd>
 <p>[<strong>-w</strong>|<strong>--width</strong> <em>pixels</em>]
 [<strong>-h</strong>|<strong>--height</strong> <em>pixels</em>]
-[<strong>-j</strong>|<strong>--only-graph</strong>]</p>
+[<strong>-j</strong>|<strong>--only-graph</strong>]
+[<strong>-D</strong>|<strong>--full-size-mode</strong>]</p>
 </dd>
 <dd>
-<p>The width and height of the <strong>canvas</strong> (the part of the graph with
+<p>By default, the width and height of the <strong>canvas</strong> (the part with
 the actual data and such). This defaults to 400 pixels by 100 pixels.</p>
 </dd>
 <dd>
+<p>If you specify the <strong>--full-size-mode</strong> option, the width and height
+specify the final dimensions of the output image and the canvas
+is automatically resized to fit.</p>
+</dd>
+<dd>
 <p>If you specify the <strong>--only-graph</strong> option and set the height &lt; 32
 pixels you will get a tiny graph image (thumbnail) to use as an icon
 for use in an overview, for example. All labeling will be stripped off
@@ -191,16 +211,19 @@ and thus the throughput may be higher than the WAN line speed.</p>
 <p>[<strong>-N</strong>|<strong>--no-gridfit</strong>]</p>
 </dd>
 <dd>
-<p>In order to avoid anti-aliasing effects gridlines are placed on
-integer pixel values. This is by default done by extending
-the scale so that gridlines happens to be spaced using an
-integer number of pixels and also start on an integer pixel value.
-This might extend the scale too much for some logarithmic scales
-and for linear scales where <strong>--alt-autoscale</strong> is needed.
-Using <strong>--no-gridfit</strong> disables modification of the scale.</p>
+<p>In order to avoid anti-aliasing blurring effects rrdtool snaps
+points to device resolution pixels, this results in a crisper
+aperance. If this is not to your liking, you can use this switch
+to turn this behaviour off.</p>
+</dd>
+<dd>
+<p>Gridfitting is turned off for PDF, EPS, SVG output by default.</p>
 </dd>
 </li>
-<dt><strong><a name="item_x_2dgrid">X-Grid</a></strong>
+<dt><strong><a name="item_grid">Grid</a></strong>
+
+<dl>
+<dt><strong><a name="item_x_2daxis">X-Axis</a></strong>
 
 <dd>
 <p>[<strong>-x</strong>|<strong>--x-grid</strong> <em>GTM</em><strong>:</strong><em>GST</em><strong>:</strong><em>MTM</em><strong>:</strong><em>MST</em><strong>:</strong><em>LTM</em><strong>:</strong><em>LST</em><strong>:</strong><em>LPR</em><strong>:</strong><em>LFM</em>]</p>
@@ -238,7 +261,7 @@ lines as they specify exactly that time.</p>
 </dd>
 <dd>
 <pre>
- --x-grid HOUR:8:DAY:1:DAY:1:0:%A</pre>
+ --x-grid HOUR:8:DAY:1:DAY:1:86400:%A</pre>
 </dd>
 <dd>
 <p>This places grid lines every 8 hours, major grid lines and labels
@@ -246,7 +269,7 @@ each day. The labels are placed exactly between two major grid lines
 as they specify the complete day and not just midnight.</p>
 </dd>
 </li>
-<dt><strong><a name="item_y_2dgrid">Y-Grid</a></strong>
+<dt><strong><a name="item_y_2daxis">Y-Axis</a></strong>
 
 <dd>
 <p>[<strong>-y</strong>|<strong>--y-grid</strong> <em>grid step</em><strong>:</strong><em>label factor</em>]</p>
@@ -319,6 +342,7 @@ the appropriate units (k, M, etc.) instead of using exponential notation.
 Note that for linear graphs, SI notation is used by default.</p>
 </dd>
 </li>
+</dl>
 <dt><strong><a name="item_miscellaneous">Miscellaneous</a></strong>
 
 <dd>
@@ -378,7 +402,7 @@ elements, <code>TITLE</code> for the title, <code>AXIS</code> for the axis label
 for the vertical unit label, <code>LEGEND</code> for the graph legend.</p>
 </dd>
 <dd>
-<p>Use Times for the title: <code>--font TITLE:13:/usr/lib/fonts/times.ttf</code></p>
+<p>Use Times for the title: <code>--font TITLE:13:Times</code></p>
 </dd>
 <dd>
 <p>If you do not give a font string you can modify just the sice of the default font:
@@ -387,32 +411,64 @@ for the vertical unit label, <code>LEGEND</code> for the graph legend.</p>
 <dd>
 <p>If you specify the size 0 then you can modify just the font without touching
 the size. This is especially usefull for altering the default font without
-resetting the default fontsizes: <code>--font DEFAULT:0:/usr/lib/fonts/times.ttf</code>.</p>
+resetting the default fontsizes: <code>--font DEFAULT:0:Courier</code>.</p>
 </dd>
 <dd>
 <p>RRDtool comes with a preset default font. You can set the environment
 variable <code>RRD_DEFAULT_FONT</code> if you want to change this.</p>
 </dd>
 <dd>
-<p>Truetype fonts are only supported for PNG output. See below.</p>
+<p>RRDtool uses Pango for its font handling. This means you can to use
+the full Pango syntax when selecting your font:</p>
 </dd>
 <dd>
-<p>[<strong>-R</strong>|<strong>--font-render-mode</strong> {<em>normal</em>,<em>light</em>,<em>mono</em>}]</p>
+<p>The font name has the form ``[<em>FAMILY-LIST</em>] [<em>STYLE-OPTIONS</em>] [<em>SIZE</em>]'',
+where <em>FAMILY-LIST</em> is a comma separated list of families optionally
+terminated by a comma, <em>STYLE_OPTIONS</em> is a whitespace separated list of
+words where each WORD describes one of style, variant, weight, stretch, or
+gravity, and <em>SIZE</em> is a decimal number (size in points) or optionally
+followed by the unit modifier ``px'' for absolute size. Any one of the options
+may be absent.</p>
 </dd>
 <dd>
-<p>This lets you customize the strength of the font smoothing,
-or disable it entirely using <em>mono</em>. By default, <em>normal</em>
-font smoothing is used.</p>
+<p>[<strong>-R</strong>|<strong>--font-render-mode</strong> {<strong>normal</strong>,<strong>light</strong>,<strong>mono</strong>}]</p>
+</dd>
+<dd>
+<p>There are 3 font render modes:</p>
+</dd>
+<dd>
+<p><strong>normal</strong>: Full Hinting and Antialiasing (default)</p>
+</dd>
+<dd>
+<p><strong>light</strong>: Slight Hinting and Antialiasing</p>
+</dd>
+<dd>
+<p><strong>mono</strong>: Full Hinting and NO Antialiasing</p>
 </dd>
 <dd>
 <p>[<strong>-B</strong>|<strong>--font-smoothing-threshold</strong> <em>size</em>]</p>
 </dd>
 <dd>
+<p>(this gets ignored in 1.3 for now!)</p>
+</dd>
+<dd>
 <p>This specifies the largest font size which will be rendered
 bitmapped, that is, without any font smoothing. By default,
 no text is rendered bitmapped.</p>
 </dd>
 <dd>
+<p>[<strong>-G</strong>|<strong>--graph-render-mode</strong> {<strong>normal</strong>,<strong>mono</strong>}]</p>
+</dd>
+<dd>
+<p>There are 2 render modes:</p>
+</dd>
+<dd>
+<p><strong>normal</strong>: Graphs are fully Antialiased (default)</p>
+</dd>
+<dd>
+<p><strong>mono</strong>: No Antialiasing</p>
+</dd>
+<dd>
 <p>[<strong>-E</strong>|<strong>--slope-mode</strong>]</p>
 </dd>
 <dd>
@@ -434,6 +490,9 @@ Times-Bold, Times-BoldItalic, Times-Italic, Times-Roman, and ZapfDingbats.</p>
 <p>[<strong>-i</strong>|<strong>--interlaced</strong>]</p>
 </dd>
 <dd>
+<p>(this gets ignored in 1.3 for now!)</p>
+</dd>
+<dd>
 <p>If images are interlaced they become visible on browsers more quickly.</p>
 </dd>
 <dd>
@@ -497,9 +556,65 @@ at least one print statement to generate a report.
 See <a href="././rrdgraph_graph.html">the rrdgraph_graph manpage</a> for the exact format.</p>
 </dd>
 </li>
+<dt><strong><a name="item_markup">Markup</a></strong>
+
+<dd>
+<p>All text in rrdtool is rendered using Pango markup. This means text can contain embeded markup instructions.
+Simple html markup using 
+</p>
+</dd>
+<dd>
+<pre>
+
+ &lt;span key=&quot;value&quot;&gt;text&lt;/span&gt;</pre>
+</dd>
+<dd>
+<p>can be used. Apart from the verbose syntax, there are also the following short tags available.</p>
+</dd>
+<dd>
+<pre>
+ b     Bold
+ big   Makes font relatively larger, equivalent to &lt;span size=&quot;larger&quot;&gt;
+ i     Italic
+ s     Strikethrough
+ sub   Subscript
+ sup   Superscript
+ small Makes font relatively smaller, equivalent to &lt;span size=&quot;smaller&quot;&gt;
+ tt    Monospace font
+ u     Underline 
+More details on <a href="http://developer.gnome.org/doc/API/2.0/pango/PangoMarkupFormat.html">http://developer.gnome.org/doc/API/2.0/pango/PangoMarkupFormat.html</a>.</pre>
+</dd>
+</li>
 </dl>
 <p>
 </p>
+<h2><a name="graphv">graphv</a></h2>
+<p>Calling rrdtool with the graphv option will return information in the
+rrdtool info format. On the command line this means that all output will be
+in key=value format. When used from the perl and ruby bindings a hash
+pointer will be returned from the call.</p>
+<p>When the filename '-' is given, the contents of the graph itself will also
+be returned through this interface (hash key 'image'). On the command line
+the output will look like this:</p>
+<pre>
+ print[0] = &quot;0.020833&quot;
+ print[1] = &quot;0.0440833&quot;
+ graph_left = 51
+ graph_top = 22
+ graph_width = 400
+ graph_height = 100
+ image_width = 481
+ image_height = 154
+ value_min = 0.0000000000e+00
+ value_max = 4.0000000000e-02
+ image = BLOB_SIZE:8196
+ [... 8196 bytes of image data ...]</pre>
+<p>There is more information returned than in the standard interface.
+Especially the 'graph_*' keys are new. They help applications that want to
+know what is where on the graph.</p>
+<p>
+</p>
 <hr />
 <h1><a name="see_also">SEE ALSO</a></h1>
 <p><a href="././rrdgraph.html">the rrdgraph manpage</a> gives an overview of how <strong>rrdtool graph</strong> works.
@@ -512,7 +627,9 @@ See <a href="././rrdgraph_graph.html">the rrdgraph_graph manpage</a> for the exa
 <hr />
 <h1><a name="author">AUTHOR</a></h1>
 <p>Program by Tobias Oetiker &lt;<a href="mailto:tobi@oetiker.ch">tobi@oetiker.ch</a>&gt;</p>
-<p>This manual page by Alex van den Bogaerdt &lt;<a href="mailto:alex@ergens.op.het.net">alex@ergens.op.het.net</a>&gt;</p>
+<p>This manual page by Alex van den Bogaerdt &lt;<a href="mailto:alex@ergens.op.het.net">alex@ergens.op.het.net</a>&gt;
+
+</p>
 
 </body>
 
index 11b447e37cf5c1fa5378c03e7b88da04fbf6e7b7..54fd5b0cbae83ada1ff137f7b4a9ca90c6e20418 100644 (file)
@@ -4,7 +4,7 @@ rrdgraph - Round Robin Database tool grapher functions
 
 =head1 SYNOPSIS
 
-B<rrdtool graph> I<filename>
+B<rrdtool graph|graphv> I<filename>
 [I<L<option|rrdgraph/OPTIONS>> ...]
 [I<L<data definition|rrdgraph_data/DEF>> ...]
 [I<L<data calculation|rrdgraph_data/CDEF>> ...]
@@ -43,7 +43,7 @@ it. For instance, you might be collecting B<bytes> per second, but
 want to display B<bits> per second. This is what the B<L<data
 calculation|rrdgraph_data/CDEF>> command is designed for. After
 B<consolidating> the data, a copy is made and this copy is modified
-using a rather powerful L<rrdgraph_rpn> command set.
+using a rather powerful B<L<RPN|rrdgraph_rpn/>> command set.
 
 When you are done fetching and processing the data, it is time to
 graph it (or print it).  This ends the B<rrdtool graph> sequence.
@@ -52,6 +52,14 @@ graph it (or print it).  This ends the B<rrdtool graph> sequence.
 
 =over 4
 
+=item B<graphv>
+
+This alternate version of B<graph> takes the same arguments and performs the
+same function. The I<v> stands for I<verbose>, which describes the output
+returned. B<graphv> will return a lot of information about the graph using
+the same format as rrdtool info (key = value). See the bottom of the document for more information.
+
+
 =item filename
 
 The name and path of the graph to generate. It is recommended to
@@ -70,7 +78,7 @@ The start and end of the time series you would like to display, and which
 B<RRA> the data should come from.  Defaults are: 1 day ago until
 now, with the best possible resolution. B<Start> and B<end> can
 be specified in several formats, see
-L<rrdfetch> and L<rrdgraph_examples>.
+L<AT-STYLE TIME SPECIFICATION|rrdfetch/> and L<rrdgraph_examples>.
 By default, B<rrdtool graph> calculates the width of one pixel in
 the time domain and tries to get data from an B<RRA> with that
 resolution.  With the B<step> option you can alter this behaviour.
@@ -91,10 +99,15 @@ placed string at the left hand side of the graph.
 [B<-w>|B<--width> I<pixels>]
 [B<-h>|B<--height> I<pixels>]
 [B<-j>|B<--only-graph>]
+[B<-D>|B<--full-size-mode>]
 
-The width and height of the B<canvas> (the part of the graph with
+By default, the width and height of the B<canvas> (the part with
 the actual data and such). This defaults to 400 pixels by 100 pixels.
 
+If you specify the B<--full-size-mode> option, the width and height
+specify the final dimensions of the output image and the canvas
+is automatically resized to fit.
+
 If you specify the B<--only-graph> option and set the height E<lt> 32
 pixels you will get a tiny graph image (thumbnail) to use as an icon
 for use in an overview, for example. All labeling will be stripped off
@@ -141,15 +154,18 @@ and thus the throughput may be higher than the WAN line speed.
 
 [B<-N>|B<--no-gridfit>]
 
-In order to avoid anti-aliasing effects gridlines are placed on
-integer pixel values. This is by default done by extending
-the scale so that gridlines happens to be spaced using an
-integer number of pixels and also start on an integer pixel value.
-This might extend the scale too much for some logarithmic scales
-and for linear scales where B<--alt-autoscale> is needed.
-Using B<--no-gridfit> disables modification of the scale.
+In order to avoid anti-aliasing blurring effects rrdtool snaps
+points to device resolution pixels, this results in a crisper
+aperance. If this is not to your liking, you can use this switch
+to turn this behaviour off.
 
-=item X-Grid
+Gridfitting is turned off for PDF, EPS, SVG output by default.
+
+=item Grid
+
+=over 4
+
+=item X-Axis
 
 [B<-x>|B<--x-grid> I<GTM>B<:>I<GST>B<:>I<MTM>B<:>I<MST>B<:>I<LTM>B<:>I<LST>B<:>I<LPR>B<:>I<LFM>]
 
@@ -178,13 +194,13 @@ This places grid lines every 10 minutes, major grid lines every hour,
 and labels every 4 hours. The labels are placed under the major grid
 lines as they specify exactly that time.
 
- --x-grid HOUR:8:DAY:1:DAY:1:0:%A
+ --x-grid HOUR:8:DAY:1:DAY:1:86400:%A
 
 This places grid lines every 8 hours, major grid lines and labels
 each day. The labels are placed exactly between two major grid lines
 as they specify the complete day and not just midnight.
 
-=item Y-Grid
+=item Y-Axis
 
 [B<-y>|B<--y-grid> I<grid step>B<:>I<label factor>]
 
@@ -241,6 +257,8 @@ With this option y-axis values on logarithmic graphs will be scaled to
 the appropriate units (k, M, etc.) instead of using exponential notation.
 Note that for linear graphs, SI notation is used by default.
 
+=back
+
 =item Miscellaneous
 
 [B<-z>|B<--lazy>]
@@ -286,32 +304,56 @@ elements on the RRD graphs. C<DEFAULT> sets the default value for all
 elements, C<TITLE> for the title, C<AXIS> for the axis labels, C<UNIT>
 for the vertical unit label, C<LEGEND> for the graph legend.
 
-Use Times for the title: C<--font TITLE:13:/usr/lib/fonts/times.ttf>
+Use Times for the title: C<--font TITLE:13:Times>
 
 If you do not give a font string you can modify just the sice of the default font:
 C<--font TITLE:13:>.
 
 If you specify the size 0 then you can modify just the font without touching
 the size. This is especially usefull for altering the default font without
-resetting the default fontsizes: C<--font DEFAULT:0:/usr/lib/fonts/times.ttf>.
+resetting the default fontsizes: C<--font DEFAULT:0:Courier>.
 
 RRDtool comes with a preset default font. You can set the environment
 variable C<RRD_DEFAULT_FONT> if you want to change this.
 
-Truetype fonts are only supported for PNG output. See below.
+RRDtool uses Pango for its font handling. This means you can to use
+the full Pango syntax when selecting your font:
+
+The font name has the form "[I<FAMILY-LIST>] [I<STYLE-OPTIONS>] [I<SIZE>]",
+where I<FAMILY-LIST> is a comma separated list of families optionally
+terminated by a comma, I<STYLE_OPTIONS> is a whitespace separated list of
+words where each WORD describes one of style, variant, weight, stretch, or
+gravity, and I<SIZE> is a decimal number (size in points) or optionally
+followed by the unit modifier "px" for absolute size. Any one of the options
+may be absent.
+
+[B<-R>|B<--font-render-mode> {B<normal>,B<light>,B<mono>}]
+
+There are 3 font render modes:
 
-[B<-R>|B<--font-render-mode> {I<normal>,I<light>,I<mono>}]
+B<normal>: Full Hinting and Antialiasing (default)
+
+B<light>: Slight Hinting and Antialiasing
+
+B<mono>: Full Hinting and NO Antialiasing
 
-This lets you customize the strength of the font smoothing,
-or disable it entirely using I<mono>. By default, I<normal>
-font smoothing is used.
 
 [B<-B>|B<--font-smoothing-threshold> I<size>]
 
+(this gets ignored in 1.3 for now!)
+
 This specifies the largest font size which will be rendered
 bitmapped, that is, without any font smoothing. By default,
 no text is rendered bitmapped.
 
+[B<-G>|B<--graph-render-mode> {B<normal>,B<mono>}]
+
+There are 2 render modes:
+
+B<normal>: Graphs are fully Antialiased (default)
+
+B<mono>: No Antialiasing
+
 [B<-E>|B<--slope-mode>]
 
 RRDtool graphs are composed of stair case curves by default. This is in line with
@@ -328,6 +370,8 @@ Times-Bold, Times-BoldItalic, Times-Italic, Times-Roman, and ZapfDingbats.
 
 [B<-i>|B<--interlaced>]
 
+(this gets ignored in 1.3 for now!)
+
 If images are interlaced they become visible on browsers more quickly.
 
 [B<-g>|B<--no-legend>]
@@ -373,8 +417,57 @@ You need at least one graph element to generate an image and/or
 at least one print statement to generate a report.
 See L<rrdgraph_graph> for the exact format.
 
+=item Markup
+
+All text in rrdtool is rendered using Pango markup. This means text can contain embeded markup instructions.
+Simple html markup using 
+ <span key="value">text</span>
+
+can be used. Apart from the verbose syntax, there are also the following short tags available.
+
+ b     Bold
+ big   Makes font relatively larger, equivalent to <span size="larger">
+ i     Italic
+ s     Strikethrough
+ sub   Subscript
+ sup   Superscript
+ small Makes font relatively smaller, equivalent to <span size="smaller">
+ tt    Monospace font
+ u     Underline 
+More details on http://developer.gnome.org/doc/API/2.0/pango/PangoMarkupFormat.html.
+
 =back
 
+=head2 graphv
+
+Calling rrdtool with the graphv option will return information in the
+rrdtool info format. On the command line this means that all output will be
+in key=value format. When used from the perl and ruby bindings a hash
+pointer will be returned from the call.
+
+When the filename '-' is given, the contents of the graph itself will also
+be returned through this interface (hash key 'image'). On the command line
+the output will look like this:
+
+ print[0] = "0.020833"
+ print[1] = "0.0440833"
+ graph_left = 51
+ graph_top = 22
+ graph_width = 400
+ graph_height = 100
+ image_width = 481
+ image_height = 154
+ value_min = 0.0000000000e+00
+ value_max = 4.0000000000e-02
+ image = BLOB_SIZE:8196
+ [... 8196 bytes of image data ...]
+
+There is more information returned than in the standard interface.
+Especially the 'graph_*' keys are new. They help applications that want to
+know what is where on the graph.
+
 =head1 SEE ALSO
 
 L<rrdgraph> gives an overview of how B<rrdtool graph> works.
index d1a493afee18104d552f14f657cfa8ec4fd8df53..51a0b5ffa3379e6184d7091399039f8e4d4d0b07 100644 (file)
@@ -6,9 +6,9 @@ N\bNA\bAM\bME\bE
        rrdgraph - Round Robin Database tool grapher functions
 
 S\bSY\bYN\bNO\bOP\bPS\bSI\bIS\bS
-       r\brr\brd\bdt\bto\boo\bol\bl g\bgr\bra\bap\bph\bh _\bf_\bi_\bl_\be_\bn_\ba_\bm_\be [_\bo_\bp_\bt_\bi_\bo_\bn ...]  [_\bd_\ba_\bt_\ba _\bd_\be_\bf_\bi_\bn_\bi_\bt_\bi_\bo_\bn ...]  [_\bd_\ba_\bt_\ba _\bc_\ba_\bl_\b-
-       _\bc_\bu_\bl_\ba_\bt_\bi_\bo_\bn ...]  [_\bv_\ba_\br_\bi_\ba_\bb_\bl_\be _\bd_\be_\bf_\bi_\bn_\bi_\bt_\bi_\bo_\bn ...]  [_\bg_\br_\ba_\bp_\bh _\be_\bl_\be_\bm_\be_\bn_\bt ...]  [_\bp_\br_\bi_\bn_\bt
-       _\be_\bl_\be_\bm_\be_\bn_\bt ...]
+       r\brr\brd\bdt\bto\boo\bol\bl g\bgr\bra\bap\bph\bh|\b|g\bgr\bra\bap\bph\bhv\bv _\bf_\bi_\bl_\be_\bn_\ba_\bm_\be [_\bo_\bp_\bt_\bi_\bo_\bn ...]  [_\bd_\ba_\bt_\ba _\bd_\be_\bf_\bi_\bn_\bi_\bt_\bi_\bo_\bn ...]
+       [_\bd_\ba_\bt_\ba _\bc_\ba_\bl_\bc_\bu_\bl_\ba_\bt_\bi_\bo_\bn ...]  [_\bv_\ba_\br_\bi_\ba_\bb_\bl_\be _\bd_\be_\bf_\bi_\bn_\bi_\bt_\bi_\bo_\bn ...]  [_\bg_\br_\ba_\bp_\bh _\be_\bl_\be_\bm_\be_\bn_\bt ...]
+       [_\bp_\br_\bi_\bn_\b_\be_\bl_\be_\bm_\be_\bn_\bt ...]
 
 D\bDE\bES\bSC\bCR\bRI\bIP\bPT\bTI\bIO\bON\bN
        The g\bgr\bra\bap\bph\bh function of R\bRR\bRD\bDt\bto\boo\bol\bl is used to present the data from an R\bRR\bRD\bD
@@ -35,12 +35,19 @@ O\bOV\bVE\bER\bRV\bVI\bIE\bEW\bW
        it. For instance, you might be collecting b\bby\byt\bte\bes\bs per second, but want to
        display b\bbi\bit\bts\bs per second. This is what the d\bda\bat\bta\ba c\bca\bal\blc\bcu\bul\bla\bat\bti\bio\bon\bn command is
        designed for. After c\bco\bon\bns\bso\bol\bli\bid\bda\bat\bti\bin\bng\bg the data, a copy is made and this
-       copy is modified using a rather powerful rrdgraph_rpn command set.
+       copy is modified using a rather powerful R\bRP\bPN\bN command set.
 
        When you are done fetching and processing the data, it is time to graph
        it (or print it).  This ends the r\brr\brd\bdt\bto\boo\bol\bl g\bgr\bra\bap\bph\bh sequence.
 
 O\bOP\bPT\bTI\bIO\bON\bNS\bS
+       g\bgr\bra\bap\bph\bhv\bv
+           This alternate version of g\bgr\bra\bap\bph\bh takes the same arguments and per-
+           forms the same function. The _\bv stands for _\bv_\be_\br_\bb_\bo_\bs_\be, which describes
+           the output returned. g\bgr\bra\bap\bph\bhv\bv will return a lot of information about
+           the graph using the same format as rrdtool info (key = value). See
+           the bottom of the document for more information.
+
        filename
            The name and path of the graph to generate. It is recommended to
            end this in ".png", ".svg" or ".eps", but R\bRR\bRD\bDt\bto\boo\bol\bl does not enforce
@@ -55,13 +62,13 @@ O\bOP\bPT\bTI\bIO\bON\bNS\bS
            The start and end of the time series you would like to display, and
            which R\bRR\bRA\bA the data should come from.  Defaults are: 1 day ago until
            now, with the best possible resolution. S\bSt\bta\bar\brt\bt and e\ben\bnd\bd can be speci-
-           fied in several formats, see rrdfetch and rrdgraph_examples.  By
-           default, r\brr\brd\bdt\bto\boo\bol\bl g\bgr\bra\bap\bph\bh calculates the width of one pixel in the
-           time domain and tries to get data from an R\bRR\bRA\bA with that resolution.
-           With the s\bst\bte\bep\bp option you can alter this behaviour.  If you want
-           r\brr\brd\bdt\bto\boo\bol\bl g\bgr\bra\bap\bph\bh to get data at a one-hour resolution from the R\bRR\bRD\bD,
-           set s\bst\bte\bep\bp to 3'600. Note: a step smaller than one pixel will
-           silently be ignored.
+           fied in several formats, see AT-STYLE TIME SPECIFICATION and rrd-
+           graph_examples.  By default, r\brr\brd\bdt\bto\boo\bol\bl g\bgr\bra\bap\bph\bh calculates the width of
+           one pixel in the time domain and tries to get data from an R\bRR\bRA\bA with
+           that resolution.  With the s\bst\bte\bep\bp option you can alter this
+           behaviour.  If you want r\brr\brd\bdt\bto\boo\bol\bl g\bgr\bra\bap\bph\bh to get data at a one-hour
+           resolution from the R\bRR\bRD\bD, set s\bst\bte\bep\bp to 3'600. Note: a step smaller
+           than one pixel will silently be ignored.
 
        Labels
            [-\b-t\bt|-\b--\b-t\bti\bit\btl\ble\be _\bs_\bt_\br_\bi_\bn_\bg] [-\b-v\bv|-\b--\b-v\bve\ber\brt\bti\bic\bca\bal\bl-\b-l\bla\bab\bbe\bel\bl _\bs_\bt_\br_\bi_\bn_\bg]
@@ -71,10 +78,15 @@ O\bOP\bPT\bTI\bIO\bON\bNS\bS
 
        Size
            [-\b-w\bw|-\b--\b-w\bwi\bid\bdt\bth\bh _\bp_\bi_\bx_\be_\bl_\bs] [-\b-h\bh|-\b--\b-h\bhe\bei\big\bgh\bht\bt _\bp_\bi_\bx_\be_\bl_\bs] [-\b-j\bj|-\b--\b-o\bon\bnl\bly\by-\b-g\bgr\bra\bap\bph\bh]
+           [-\b-D\bD|-\b--\b-f\bfu\bul\bll\bl-\b-s\bsi\biz\bze\be-\b-m\bmo\bod\bde\be]
 
-           The width and height of the c\bca\ban\bnv\bva\bas\bs (the part of the graph with the
+           By default, the width and height of the c\bca\ban\bnv\bva\bas\bs (the part with the
            actual data and such). This defaults to 400 pixels by 100 pixels.
 
+           If you specify the -\b--\b-f\bfu\bul\bll\bl-\b-s\bsi\biz\bze\be-\b-m\bmo\bod\bde\be option, the width and height
+           specify the final dimensions of the output image and the canvas is
+           automatically resized to fit.
+
            If you specify the -\b--\b-o\bon\bnl\bly\by-\b-g\bgr\bra\bap\bph\bh option and set the height < 32 pix-
            els you will get a tiny graph image (thumbnail) to use as an icon
            for use in an overview, for example. All labeling will be stripped
@@ -121,107 +133,110 @@ O\bOP\bPT\bTI\bIO\bON\bNS\bS
 
            [-\b-N\bN|-\b--\b-n\bno\bo-\b-g\bgr\bri\bid\bdf\bfi\bit\bt]
 
-           In order to avoid anti-aliasing effects gridlines are placed on
-           integer pixel values. This is by default done by extending the
-           scale so that gridlines happens to be spaced using an integer num-
-           ber of pixels and also start on an integer pixel value.  This might
-           extend the scale too much for some logarithmic scales and for lin-
-           ear scales where -\b--\b-a\bal\blt\bt-\b-a\bau\but\bto\bos\bsc\bca\bal\ble\be is needed.  Using -\b--\b-n\bno\bo-\b-g\bgr\bri\bid\bdf\bfi\bit\bt
-           disables modification of the scale.
-
-       X-Grid
-           [-\b-x\bx|-\b--\b-x\bx-\b-g\bgr\bri\bid\bd _\bG_\bT_\bM:\b:_\bG_\bS_\bT:\b:_\bM_\bT_\bM:\b:_\bM_\bS_\bT:\b:_\bL_\bT_\bM:\b:_\bL_\bS_\bT:\b:_\bL_\bP_\bR:\b:_\bL_\bF_\bM]
-
-           [-\b-x\bx|-\b--\b-x\bx-\b-g\bgr\bri\bid\bd n\bno\bon\bne\be]
-
-           The x-axis label is quite complex to configure. If you don't have
-           very special needs it is probably best to rely on the autoconfigu-
-           ration to get this right. You can specify the string "none" to sup-
-           press the grid and labels altogether.
-
-           The grid is defined by specifying a certain amount of time in the
-           _\b?_\bT_\bM positions. You can choose from "SECOND", "MINUTE", "HOUR",
-           "DAY", "WEEK", "MONTH" or "YEAR". Then you define how many of these
-           should pass between each line or label.  This pair (_\b?_\bT_\bM_\b:_\b?_\bS_\bT) needs
-           to be specified for the base grid (_\bG_\b?_\b?), the major grid (_\bM_\b?_\b?) and
-           the labels (_\bL_\b?_\b?). For the labels you also must define a precision
-           in _\bL_\bP_\bR and a _\bs_\bt_\br_\bf_\bt_\bi_\bm_\be format string in _\bL_\bF_\bM.  _\bL_\bP_\bR defines where each
-           label will be placed. If it is zero, the label will be placed right
-           under the corresponding line (useful for hours, dates etcetera).
-           If you specify a number of seconds here the label is centered on
-           this interval (useful for Monday, January etcetera).
-
-            --x-grid MINUTE:10:HOUR:1:HOUR:4:0:%X
-
-           This places grid lines every 10 minutes, major grid lines every
-           hour, and labels every 4 hours. The labels are placed under the
-           major grid lines as they specify exactly that time.
-
-            --x-grid HOUR:8:DAY:1:DAY:1:0:%A
-
-           This places grid lines every 8 hours, major grid lines and labels
-           each day. The labels are placed exactly between two major grid
-           lines as they specify the complete day and not just midnight.
-
-       Y-Grid
-           [-\b-y\by|-\b--\b-y\by-\b-g\bgr\bri\bid\bd _\bg_\br_\bi_\bd _\bs_\bt_\be_\bp:\b:_\bl_\ba_\bb_\be_\bl _\bf_\ba_\bc_\bt_\bo_\br]
-
-           [-\b-y\by|-\b--\b-y\by-\b-g\bgr\bri\bid\bd n\bno\bon\bne\be]
-
-           Y-axis grid lines appear at each _\bg_\br_\bi_\bd _\bs_\bt_\be_\bp interval.  Labels are
-           placed every _\bl_\ba_\bb_\be_\bl _\bf_\ba_\bc_\bt_\bo_\br lines.  You can specify "-y none" to sup-
-           press the grid and labels altogether.  The default for this option
-           is to automatically select sensible values.
-
-           If you have set --y-grid to 'none' not only the labels get
-           supressed, also the space reserved for the labels is removed. You
-           can still add space manually if you use the --units-length command
-           to explicitly reserve space.
-
-           [-\b-Y\bY|-\b--\b-a\bal\blt\bt-\b-y\by-\b-g\bgr\bri\bid\bd]
-
-           Place the Y grid dynamically based on the graph's Y range. The
-           algorithm ensures that you always have a grid, that there are
-           enough but not too many grid lines, and that the grid is metric.
-           That is the grid lines are placed every 1, 2, 5 or 10 units. This
-           parameter will also ensure that you get enough decimals displayed
-           even if your graph goes from 69.998 to 70.001.  (contributed by
-           Sasha Mikheev).
+           In order to avoid anti-aliasing blurring effects rrdtool snaps
+           points to device resolution pixels, this results in a crisper aper-
+           ance. If this is not to your liking, you can use this switch to
+           turn this behaviour off.
+
+           Gridfitting is turned off for PDF, EPS, SVG output by default.
+
+       Grid
+           X-Axis
+               [-\b-x\bx|-\b--\b-x\bx-\b-g\bgr\bri\bid\bd _\bG_\bT_\bM:\b:_\bG_\bS_\bT:\b:_\bM_\bT_\bM:\b:_\bM_\bS_\bT:\b:_\bL_\bT_\bM:\b:_\bL_\bS_\bT:\b:_\bL_\bP_\bR:\b:_\bL_\bF_\bM]
+
+               [-\b-x\bx|-\b--\b-x\bx-\b-g\bgr\bri\bid\bd n\bno\bon\bne\be]
+
+               The x-axis label is quite complex to configure. If you don't
+               have very special needs it is probably best to rely on the
+               autoconfiguration to get this right. You can specify the string
+               "none" to suppress the grid and labels altogether.
+
+               The grid is defined by specifying a certain amount of time in
+               the _\b?_\bT_\bM positions. You can choose from "SECOND", "MINUTE",
+               "HOUR", "DAY", "WEEK", "MONTH" or "YEAR". Then you define how
+               many of these should pass between each line or label.  This
+               pair (_\b?_\bT_\bM_\b:_\b?_\bS_\bT) needs to be specified for the base grid (_\bG_\b?_\b?),
+               the major grid (_\bM_\b?_\b?) and the labels (_\bL_\b?_\b?). For the labels you
+               also must define a precision in _\bL_\bP_\bR and a _\bs_\bt_\br_\bf_\bt_\bi_\bm_\be format
+               string in _\bL_\bF_\bM.  _\bL_\bP_\bR defines where each label will be placed. If
+               it is zero, the label will be placed right under the corre-
+               sponding line (useful for hours, dates etcetera).  If you spec-
+               ify a number of seconds here the label is centered on this
+               interval (useful for Monday, January etcetera).
+
+                --x-grid MINUTE:10:HOUR:1:HOUR:4:0:%X
+
+               This places grid lines every 10 minutes, major grid lines every
+               hour, and labels every 4 hours. The labels are placed under the
+               major grid lines as they specify exactly that time.
+
+                --x-grid HOUR:8:DAY:1:DAY:1:86400:%A
+
+               This places grid lines every 8 hours, major grid lines and
+               labels each day. The labels are placed exactly between two
+               major grid lines as they specify the complete day and not just
+               midnight.
+
+           Y-Axis
+               [-\b-y\by|-\b--\b-y\by-\b-g\bgr\bri\bid\bd _\bg_\br_\bi_\bd _\bs_\bt_\be_\bp:\b:_\bl_\ba_\bb_\be_\bl _\bf_\ba_\bc_\bt_\bo_\br]
+
+               [-\b-y\by|-\b--\b-y\by-\b-g\bgr\bri\bid\bd n\bno\bon\bne\be]
+
+               Y-axis grid lines appear at each _\bg_\br_\bi_\bd _\bs_\bt_\be_\bp interval.  Labels
+               are placed every _\bl_\ba_\bb_\be_\bl _\bf_\ba_\bc_\bt_\bo_\br lines.  You can specify "-y none"
+               to suppress the grid and labels altogether.  The default for
+               this option is to automatically select sensible values.
 
-           [-\b-o\bo|-\b--\b-l\blo\bog\bga\bar\bri\bit\bth\bhm\bmi\bic\bc]
+               If you have set --y-grid to 'none' not only the labels get
+               supressed, also the space reserved for the labels is removed.
+               You can still add space manually if you use the --units-length
+               command to explicitly reserve space.
 
-           Logarithmic y-axis scaling.
+               [-\b-Y\bY|-\b--\b-a\bal\blt\bt-\b-y\by-\b-g\bgr\bri\bid\bd]
 
-           [-\b-X\bX|-\b--\b-u\bun\bni\bit\bts\bs-\b-e\bex\bxp\bpo\bon\bne\ben\bnt\bt _\bv_\ba_\bl_\bu_\be]
+               Place the Y grid dynamically based on the graph's Y range. The
+               algorithm ensures that you always have a grid, that there are
+               enough but not too many grid lines, and that the grid is met-
+               ric. That is the grid lines are placed every 1, 2, 5 or 10
+               units. This parameter will also ensure that you get enough dec-
+               imals displayed even if your graph goes from 69.998 to 70.001.
+               (contributed by Sasha Mikheev).
 
-           This sets the 10**exponent scaling of the y-axis values. Normally,
-           values will be scaled to the appropriate units (k, M, etc.).  How-
-           ever, you may wish to display units always in k (Kilo, 10e3) even
-           if the data is in the M (Mega, 10e6) range, for instance. Value
-           should be an integer which is a multiple of 3 between -18 and 18
-           inclusively.  It is the exponent on the units you wish to use. For
-           example, use 3 to display the y-axis values in k (Kilo, 10e3, thou-
-           sands), use -6 to display the y-axis values in u (Micro, 10e-6,
-           millionths).  Use a value of 0 to prevent any scaling of the y-axis
-           values.
+               [-\b-o\bo|-\b--\b-l\blo\bog\bga\bar\bri\bit\bth\bhm\bmi\bic\bc]
 
-           This option is very effective at confusing the heck out of the
-           default rrdtool autoscaler and grid painter. If rrdtool detects
-           that it is not successful in labeling the graph under the given
-           circumstances, it will switch to the more robust -\b--\b-a\bal\blt\bt-\b-y\by-\b-g\bgr\bri\bid\bd mode.
+               Logarithmic y-axis scaling.
 
-           [-\b-L\bL|-\b--\b-u\bun\bni\bit\bts\bs-\b-l\ble\ben\bng\bgt\bth\bh _\bv_\ba_\bl_\bu_\be]
+               [-\b-X\bX|-\b--\b-u\bun\bni\bit\bts\bs-\b-e\bex\bxp\bpo\bon\bne\ben\bnt\bt _\bv_\ba_\bl_\bu_\be]
 
-           How many digits should rrdtool assume the y-axis labels to be? You
-           may have to use this option to make enough space once you start
-           fideling with the y-axis labeling.
+               This sets the 10**exponent scaling of the y-axis values. Nor-
+               mally, values will be scaled to the appropriate units (k, M,
+               etc.).  However, you may wish to display units always in k
+               (Kilo, 10e3) even if the data is in the M (Mega, 10e6) range,
+               for instance. Value should be an integer which is a multiple of
+               3 between -18 and 18 inclusively.  It is the exponent on the
+               units you wish to use. For example, use 3 to display the y-axis
+               values in k (Kilo, 10e3, thousands), use -6 to display the
+               y-axis values in u (Micro, 10e-6, millionths).  Use a value of
+               0 to prevent any scaling of the y-axis values.
 
-           [-\b--\b-u\bun\bni\bit\bts\bs=\b=s\bsi\bi]
+               This option is very effective at confusing the heck out of the
+               default rrdtool autoscaler and grid painter. If rrdtool detects
+               that it is not successful in labeling the graph under the given
+               circumstances, it will switch to the more robust -\b--\b-a\bal\blt\bt-\b-y\by-\b-g\bgr\bri\bid\bd
+               mode.
 
-           With this option y-axis values on logarithmic graphs will be scaled
-           to the appropriate units (k, M, etc.) instead of using exponential
-           notation.  Note that for linear graphs, SI notation is used by
-           default.
+               [-\b-L\bL|-\b--\b-u\bun\bni\bit\bts\bs-\b-l\ble\ben\bng\bgt\bth\bh _\bv_\ba_\bl_\bu_\be]
+
+               How many digits should rrdtool assume the y-axis labels to be?
+               You may have to use this option to make enough space once you
+               start fideling with the y-axis labeling.
+
+               [-\b--\b-u\bun\bni\bit\bts\bs=\b=s\bsi\bi]
+
+               With this option y-axis values on logarithmic graphs will be
+               scaled to the appropriate units (k, M, etc.) instead of using
+               exponential notation.  Note that for linear graphs, SI notation
+               is used by default.
 
        Miscellaneous
            [-\b-z\bz|-\b--\b-l\bla\baz\bzy\by]
@@ -268,7 +283,7 @@ O\bOP\bPT\bTI\bIO\bON\bNS\bS
            elements, "TITLE" for the title, "AXIS" for the axis labels, "UNIT"
            for the vertical unit label, "LEGEND" for the graph legend.
 
-           Use Times for the title: "--font TITLE:13:/usr/lib/fonts/times.ttf"
+           Use Times for the title: "--font TITLE:13:Times"
 
            If you do not give a font string you can modify just the sice of
            the default font: "--font TITLE:13:".
@@ -276,25 +291,48 @@ O\bOP\bPT\bTI\bIO\bON\bNS\bS
            If you specify the size 0 then you can modify just the font without
            touching the size. This is especially usefull for altering the
            default font without resetting the default fontsizes: "--font
-           DEFAULT:0:/usr/lib/fonts/times.ttf".
+           DEFAULT:0:Courier".
 
            RRDtool comes with a preset default font. You can set the environ-
            ment variable "RRD_DEFAULT_FONT" if you want to change this.
 
-           Truetype fonts are only supported for PNG output. See below.
+           RRDtool uses Pango for its font handling. This means you can to use
+           the full Pango syntax when selecting your font:
+
+           The font name has the form "[_\bF_\bA_\bM_\bI_\bL_\bY_\b-_\bL_\bI_\bS_\bT] [_\bS_\bT_\bY_\bL_\bE_\b-_\bO_\bP_\bT_\bI_\bO_\bN_\bS] [_\bS_\bI_\bZ_\bE]",
+           where _\bF_\bA_\bM_\bI_\bL_\bY_\b-_\bL_\bI_\bS_\bT is a comma separated list of families optionally
+           terminated by a comma, _\bS_\bT_\bY_\bL_\bE_\b__\bO_\bP_\bT_\bI_\bO_\bN_\bS is a whitespace separated list
+           of words where each WORD describes one of style, variant, weight,
+           stretch, or gravity, and _\bS_\bI_\bZ_\bE is a decimal number (size in points)
+           or optionally followed by the unit modifier "px" for absolute size.
+           Any one of the options may be absent.
+
+           [-\b-R\bR|-\b--\b-f\bfo\bon\bnt\bt-\b-r\bre\ben\bnd\bde\ber\br-\b-m\bmo\bod\bde\be {n\bno\bor\brm\bma\bal\bl,l\bli\big\bgh\bht\bt,m\bmo\bon\bno\bo}]
+
+           There are 3 font render modes:
+
+           n\bno\bor\brm\bma\bal\bl: Full Hinting and Antialiasing (default)
 
-           [-\b-R\bR|-\b--\b-f\bfo\bon\bnt\bt-\b-r\bre\ben\bnd\bde\ber\br-\b-m\bmo\bod\bde\be {_\bn_\bo_\br_\bm_\ba_\bl,_\bl_\bi_\bg_\bh_\bt,_\bm_\bo_\bn_\bo}]
+           l\bli\big\bgh\bht\bt: Slight Hinting and Antialiasing
 
-           This lets you customize the strength of the font smoothing, or dis-
-           able it entirely using _\bm_\bo_\bn_\bo. By default, _\bn_\bo_\br_\bm_\ba_\bl font smoothing is
-           used.
+           m\bmo\bon\bno\bo: Full Hinting and NO Antialiasing
 
            [-\b-B\bB|-\b--\b-f\bfo\bon\bnt\bt-\b-s\bsm\bmo\boo\bot\bth\bhi\bin\bng\bg-\b-t\bth\bhr\bre\bes\bsh\bho\bol\bld\bd _\bs_\bi_\bz_\be]
 
+           (this gets ignored in 1.3 for now!)
+
            This specifies the largest font size which will be rendered
            bitmapped, that is, without any font smoothing. By default, no text
            is rendered bitmapped.
 
+           [-\b-G\bG|-\b--\b-g\bgr\bra\bap\bph\bh-\b-r\bre\ben\bnd\bde\ber\br-\b-m\bmo\bod\bde\be {n\bno\bor\brm\bma\bal\bl,m\bmo\bon\bno\bo}]
+
+           There are 2 render modes:
+
+           n\bno\bor\brm\bma\bal\bl: Graphs are fully Antialiased (default)
+
+           m\bmo\bon\bno\bo: No Antialiasing
+
            [-\b-E\bE|-\b--\b-s\bsl\blo\bop\bpe\be-\b-m\bmo\bod\bde\be]
 
            RRDtool graphs are composed of stair case curves by default. This
@@ -313,6 +351,8 @@ O\bOP\bPT\bTI\bIO\bON\bNS\bS
 
            [-\b-i\bi|-\b--\b-i\bin\bnt\bte\ber\brl\bla\bac\bce\bed\bd]
 
+           (this gets ignored in 1.3 for now!)
+
            If images are interlaced they become visible on browsers more
            quickly.
 
@@ -358,6 +398,56 @@ O\bOP\bPT\bTI\bIO\bON\bNS\bS
            least one print statement to generate a report.  See rrdgraph_graph
            for the exact format.
 
+       Markup
+           All text in rrdtool is rendered using Pango markup. This means text
+           can contain embeded markup instructions.  Simple html markup using
+
+            <span key="value">text</span>
+
+           can be used. Apart from the verbose syntax, there are also the fol-
+           lowing short tags available.
+
+            b     Bold
+            big   Makes font relatively larger, equivalent to <span size="larger">
+            i     Italic
+            s     Strikethrough
+            sub   Subscript
+            sup   Superscript
+            small Makes font relatively smaller, equivalent to <span size="smaller">
+            tt    Monospace font
+            u     Underline
+
+           More details on http://developer.gnome.org/doc/API/2.0/pango/Pango-
+           MarkupFormat.html.
+
+       g\bgr\bra\bap\bph\bhv\bv
+
+       Calling rrdtool with the graphv option will return information in the
+       rrdtool info format. On the command line this means that all output
+       will be in key=value format. When used from the perl and ruby bindings
+       a hash pointer will be returned from the call.
+
+       When the filename '-' is given, the contents of the graph itself will
+       also be returned through this interface (hash key 'image'). On the com-
+       mand line the output will look like this:
+
+        print[0] = "0.020833"
+        print[1] = "0.0440833"
+        graph_left = 51
+        graph_top = 22
+        graph_width = 400
+        graph_height = 100
+        image_width = 481
+        image_height = 154
+        value_min = 0.0000000000e+00
+        value_max = 4.0000000000e-02
+        image = BLOB_SIZE:8196
+        [... 8196 bytes of image data ...]
+
+       There is more information returned than in the standard interface.
+       Especially the 'graph_*' keys are new. They help applications that want
+       to know what is where on the graph.
+
 S\bSE\bEE\bE A\bAL\bLS\bSO\bO
        rrdgraph gives an overview of how r\brr\brd\bdt\bto\boo\bol\bl g\bgr\bra\bap\bph\bh works.  rrdgraph_data
        describes D\bDE\bEF\bF,C\bCD\bDE\bEF\bF and V\bVD\bDE\bEF\bF in detail.  rrdgraph_rpn describes the R\bRP\bPN\bN
@@ -373,4 +463,4 @@ A\bAU\bUT\bTH\bHO\bOR\bR
 
 
 
-1.2.27                            2008-02-17                       RRDGRAPH(1)
+1.3rc4                            2008-04-21                       RRDGRAPH(1)
index 5c427f69fdeec7eb9f4d8266e3cc55ca7c04d0e1..5c05adc1fea10ea19548d40d1a21184a3065bcda 100644 (file)
 .\" ========================================================================
 .\"
 .IX Title "RRDGRAPH_DATA 1"
-.TH RRDGRAPH_DATA 1 "2008-02-17" "1.2.27" "rrdtool"
+.TH RRDGRAPH_DATA 1 "2008-03-15" "1.3rc4" "rrdtool"
 .SH "NAME"
 rrdgraph_data \- preparing data for graphing in rrdtool graph
 .SH "SYNOPSIS"
index e6f6923da270f94c559e546a138647797925a646..b29191ecd8739667293648cc199a65c302712ff5 100644 (file)
@@ -104,4 +104,4 @@ A\bAU\bUT\bTH\bHO\bOR\bR
 
 
 
-1.2.27                            2008-02-17                  RRDGRAPH_DATA(1)
+1.3rc4                            2008-03-15                  RRDGRAPH_DATA(1)
index 80fd8424737380df6c130dbcbe63847ac1f769d7..23ffb5c655cd7a7c5d79e29509cc2ddccc7dc62a 100644 (file)
 .\" ========================================================================
 .\"
 .IX Title "RRDGRAPH_EXAMPLES 1"
-.TH RRDGRAPH_EXAMPLES 1 "2008-02-17" "1.2.27" "rrdtool"
+.TH RRDGRAPH_EXAMPLES 1 "2008-03-25" "1.3rc4" "rrdtool"
 .SH "NAME"
 rrdgraph_examples \- Examples for rrdtool graph
 .SH "SYNOPSIS"
@@ -238,6 +238,15 @@ Note: the second line gets stacked on top of the first one
 .Vb 1
 \&    LINE1:data#FF0000:"Data with offset":STACK
 .Ve
+.Sh "Drawing dashed lines"
+.IX Subsection "Drawing dashed lines"
+Also works for \s-1HRULE\s0 and \s-1VRULE\s0
+.IP "\(bu" 4
+default style: \- \- \- \- \-
+    LINE1:data#FF0000:\*(L"dashed line\*(R":dashes
+.IP "\(bu" 4
+more fancy style with offset: \- \-  \-\-\- \-  \-\-\- \-
+    LINE1:data#FF0000:\*(L"another dashed line\*(R":dashes=15,5,5,10:dash\-offset=10
 .Sh "Time ranges"
 .IX Subsection "Time ranges"
 .Vb 6
@@ -264,6 +273,63 @@ Shift the data forward by one week (604800 seconds)
 \&    AREA:lastweek#0000FF:Last\e week
 \&    LINE1:thisweek#FF0000:This\e week
 .Ve
+.Sh "Aberrant Behaviour Detection"
+.IX Subsection "Aberrant Behaviour Detection"
+If the specialized function \fBRRAs\fR exist for aberrant behavior detection, they
+can be used to generate the graph of a time series with confidence bands and
+failures.
+.PP
+.Vb 14
+\&   rrdtool graph example.png \e
+\&          DEF:obs=monitor.rrd:ifOutOctets:AVERAGE \e
+\&          DEF:pred=monitor.rrd:ifOutOctets:HWPREDICT \e
+\&          DEF:dev=monitor.rrd:ifOutOctets:DEVPREDICT \e
+\&          DEF:fail=monitor.rrd:ifOutOctets:FAILURES \e
+\&          TICK:fail#ffffa0:1.0:"Failures\e: Average bits out" \e
+\&          CDEF:scaledobs=obs,8,* \e
+\&          CDEF:upper=pred,dev,2,*,+ \e
+\&          CDEF:lower=pred,dev,2,*,\- \e
+\&          CDEF:scaledupper=upper,8,* \e
+\&          CDEF:scaledlower=lower,8,* \e
+\&          LINE2:scaledobs#0000ff:"Average bits out" \e
+\&          LINE1:scaledupper#ff0000:"Upper Confidence Bound: Average bits out" \e
+\&          LINE1:scaledlower#ff0000:"Lower Confidence Bound: Average bits out"
+.Ve
+.PP
+This example generates a graph of the data series in blue (\s-1LINE2\s0 with the scaledobs
+virtual data source), confidence bounds in red (scaledupper and scaledlower virtual
+data sources), and potential failures (i.e. potential aberrant aberrant behavior)
+marked by vertical yellow lines (the fail data source).
+.PP
+The raw data comes from an \s-1AVERAGE\s0 \fB\s-1RRA\s0\fR, the finest resolution of the observed
+time series (one consolidated data point per primary data point). The predicted
+(or smoothed) values are stored in the \s-1HWPREDICT\s0 \fB\s-1RRA\s0\fR. The predicted deviations
+(think standard deviation) values are stored in the \s-1DEVPREDICT\s0 \fB\s-1RRA\s0\fR. Finally,
+the \s-1FAILURES\s0 \fB\s-1RRA\s0\fR contains indicators, with 1 denoting a potential failure.
+.PP
+All of the data is rescaled to bits (instead of Octets) by multiplying by 8.
+The confidence bounds are computed by an offset of 2 deviations both above
+and below the predicted values (the CDEFs upper and lower). Vertical lines
+indicated potential failures are graphed via the \s-1TICK\s0 graph element, which
+converts non-zero values in an \fB\s-1RRA\s0\fR into tick marks. Here an axis-fraction
+argument of 1.0 means the tick marks span the entire y\-axis, and hence become
+vertical lines on the graph.
+.PP
+The choice of 2 deviations (a scaling factor) matches the default used internally
+by the \s-1FAILURES\s0 \fB\s-1RRA\s0\fR. If the internal value is changed (see rrdtune), this
+graphing command should be changed to be consistent.
+.PP
+\fIA note on data reduction:\fR
+.IX Subsection "A note on data reduction:"
+.PP
+The \fBrrdtool\fR \fIgraph\fR command is designed to plot data at a specified temporal
+resolution, regardless of the actually resolution of the data in the \s-1RRD\s0 file.
+This can present a problem for the specialized consolidation functions which
+maintain a one-to-one mapping between primary data points and consolidated
+data points. If a graph insists on viewing the contents of these \fBRRAs\fR on a
+coarser temporal scale, the \fIgraph\fR command tries to do something intelligent,
+but the confidence bands and failures no longer have the same meaning and may
+be misleading.
 .SH "SEE ALSO"
 .IX Header "SEE ALSO"
 rrdgraph gives an overview of how \fBrrdtool graph\fR works.
index 5ba61d6e47c5930a7d91168cae5061c175a243a1..f8d3809290877cee25f2ccf892c81a3edf2baea1 100644 (file)
                <li><a href="#data_with_multiple_resolutions">Data with multiple resolutions</a></li>
                <li><a href="#nicely_formatted_legend_section">Nicely formatted legend section</a></li>
                <li><a href="#offsetting_a_line_on_the_yaxis">Offsetting a line on the y-axis</a></li>
+               <li><a href="#drawing_dashed_lines">Drawing dashed lines</a></li>
                <li><a href="#time_ranges">Time ranges</a></li>
                <li><a href="#viewing_the_current_and_previous_week_together">Viewing the current and previous week together</a></li>
+               <li><a href="#aberrant_behaviour_detection">Aberrant Behaviour Detection</a></li>
+               <ul>
+
+                       <li><a href="#a_note_on_data_reduction_">A note on data reduction:</a></li>
+               </ul>
+
        </ul>
 
        <li><a href="#see_also">SEE ALSO</a></li>
@@ -132,6 +139,20 @@ ready because comments are intermixed with the examples.</p>
 </ul>
 <p>
 </p>
+<h2><a name="drawing_dashed_lines">Drawing dashed lines</a></h2>
+<p>Also works for HRULE and VRULE</p>
+<ul>
+<li>
+<p>default style: - - - - -
+    LINE1:data#FF0000:``dashed line'':dashes</p>
+</li>
+<li>
+<p>more fancy style with offset: - -  --- -  --- -
+    LINE1:data#FF0000:``another dashed line'':dashes=15,5,5,10:dash-offset=10</p>
+</li>
+</ul>
+<p>
+</p>
 <h2><a name="time_ranges">Time ranges</a></h2>
 <pre>
     Last four weeks: --start end-4w --end 00:00
@@ -155,6 +176,57 @@ ready because comments are intermixed with the examples.</p>
     LINE1:thisweek#FF0000:This\ week</pre>
 <p>
 </p>
+<h2><a name="aberrant_behaviour_detection">Aberrant Behaviour Detection</a></h2>
+<p>If the specialized function <strong>RRAs</strong> exist for aberrant behavior detection, they
+can be used to generate the graph of a time series with confidence bands and
+failures.</p>
+<pre>
+   rrdtool graph example.png \
+          DEF:obs=monitor.rrd:ifOutOctets:AVERAGE \
+          DEF:pred=monitor.rrd:ifOutOctets:HWPREDICT \
+          DEF:dev=monitor.rrd:ifOutOctets:DEVPREDICT \
+          DEF:fail=monitor.rrd:ifOutOctets:FAILURES \
+          TICK:fail#ffffa0:1.0:&quot;Failures\: Average bits out&quot; \
+          CDEF:scaledobs=obs,8,* \
+          CDEF:upper=pred,dev,2,*,+ \
+          CDEF:lower=pred,dev,2,*,- \
+          CDEF:scaledupper=upper,8,* \
+          CDEF:scaledlower=lower,8,* \
+          LINE2:scaledobs#0000ff:&quot;Average bits out&quot; \
+          LINE1:scaledupper#ff0000:&quot;Upper Confidence Bound: Average bits out&quot; \
+          LINE1:scaledlower#ff0000:&quot;Lower Confidence Bound: Average bits out&quot;</pre>
+<p>This example generates a graph of the data series in blue (LINE2 with the scaledobs
+virtual data source), confidence bounds in red (scaledupper and scaledlower virtual
+data sources), and potential failures (i.e. potential aberrant aberrant behavior)
+marked by vertical yellow lines (the fail data source).</p>
+<p>The raw data comes from an AVERAGE <strong>RRA</strong>, the finest resolution of the observed
+time series (one consolidated data point per primary data point). The predicted
+(or smoothed) values are stored in the HWPREDICT <strong>RRA</strong>. The predicted deviations
+(think standard deviation) values are stored in the DEVPREDICT <strong>RRA</strong>. Finally,
+the FAILURES <strong>RRA</strong> contains indicators, with 1 denoting a potential failure.</p>
+<p>All of the data is rescaled to bits (instead of Octets) by multiplying by 8.
+The confidence bounds are computed by an offset of 2 deviations both above
+and below the predicted values (the CDEFs upper and lower). Vertical lines
+indicated potential failures are graphed via the TICK graph element, which
+converts non-zero values in an <strong>RRA</strong> into tick marks. Here an axis-fraction
+argument of 1.0 means the tick marks span the entire y-axis, and hence become
+vertical lines on the graph.</p>
+<p>The choice of 2 deviations (a scaling factor) matches the default used internally
+by the FAILURES <strong>RRA</strong>. If the internal value is changed (see <a href="././rrdtune.html">the rrdtune manpage</a>), this
+graphing command should be changed to be consistent.</p>
+<p>
+</p>
+<h3><a name="a_note_on_data_reduction_">A note on data reduction:</a></h3>
+<p>The <strong>rrdtool</strong> <em>graph</em> command is designed to plot data at a specified temporal
+resolution, regardless of the actually resolution of the data in the RRD file.
+This can present a problem for the specialized consolidation functions which
+maintain a one-to-one mapping between primary data points and consolidated
+data points. If a graph insists on viewing the contents of these <strong>RRAs</strong> on a
+coarser temporal scale, the <em>graph</em> command tries to do something intelligent,
+but the confidence bands and failures no longer have the same meaning and may
+be misleading.</p>
+<p>
+</p>
 <hr />
 <h1><a name="see_also">SEE ALSO</a></h1>
 <p><a href="././rrdgraph.html">the rrdgraph manpage</a> gives an overview of how <strong>rrdtool graph</strong> works.
index 64e38404e5bf057a2b2054dbd767fe575a487d05..e0920ed7e70884ce4ba92e0164cd24081afde9d7 100644 (file)
@@ -70,7 +70,7 @@ Note: the column titles have to be as wide as the columns
 
 Depending on your needs you can do this in two ways:
 
-=over 4
+=over
 
 =item *
 
@@ -99,6 +99,24 @@ Note: the second line gets stacked on top of the first one
 
 =back
 
+=head2 Drawing dashed lines
+
+Also works for HRULE and VRULE
+
+=over
+
+=item *
+
+default style: - - - - -
+    LINE1:data#FF0000:"dashed line":dashes
+
+=item *
+
+more fancy style with offset: - -  --- -  --- -
+    LINE1:data#FF0000:"another dashed line":dashes=15,5,5,10:dash-offset=10
+
+=back
+
 =head2 Time ranges
 
     Last four weeks: --start end-4w --end 00:00
@@ -121,6 +139,62 @@ Shift the data forward by one week (604800 seconds)
     AREA:lastweek#0000FF:Last\ week
     LINE1:thisweek#FF0000:This\ week
 
+=head2 Aberrant Behaviour Detection
+
+If the specialized function B<RRAs> exist for aberrant behavior detection, they
+can be used to generate the graph of a time series with confidence bands and
+failures.
+
+   rrdtool graph example.png \
+          DEF:obs=monitor.rrd:ifOutOctets:AVERAGE \
+          DEF:pred=monitor.rrd:ifOutOctets:HWPREDICT \
+          DEF:dev=monitor.rrd:ifOutOctets:DEVPREDICT \
+          DEF:fail=monitor.rrd:ifOutOctets:FAILURES \
+          TICK:fail#ffffa0:1.0:"Failures\: Average bits out" \
+          CDEF:scaledobs=obs,8,* \
+          CDEF:upper=pred,dev,2,*,+ \
+          CDEF:lower=pred,dev,2,*,- \
+          CDEF:scaledupper=upper,8,* \
+          CDEF:scaledlower=lower,8,* \
+          LINE2:scaledobs#0000ff:"Average bits out" \
+          LINE1:scaledupper#ff0000:"Upper Confidence Bound: Average bits out" \
+          LINE1:scaledlower#ff0000:"Lower Confidence Bound: Average bits out"
+
+This example generates a graph of the data series in blue (LINE2 with the scaledobs
+virtual data source), confidence bounds in red (scaledupper and scaledlower virtual
+data sources), and potential failures (i.e. potential aberrant aberrant behavior)
+marked by vertical yellow lines (the fail data source).
+
+The raw data comes from an AVERAGE B<RRA>, the finest resolution of the observed
+time series (one consolidated data point per primary data point). The predicted
+(or smoothed) values are stored in the HWPREDICT B<RRA>. The predicted deviations
+(think standard deviation) values are stored in the DEVPREDICT B<RRA>. Finally,
+the FAILURES B<RRA> contains indicators, with 1 denoting a potential failure.
+
+All of the data is rescaled to bits (instead of Octets) by multiplying by 8.
+The confidence bounds are computed by an offset of 2 deviations both above
+and below the predicted values (the CDEFs upper and lower). Vertical lines
+indicated potential failures are graphed via the TICK graph element, which
+converts non-zero values in an B<RRA> into tick marks. Here an axis-fraction
+argument of 1.0 means the tick marks span the entire y-axis, and hence become
+vertical lines on the graph.
+
+The choice of 2 deviations (a scaling factor) matches the default used internally
+by the FAILURES B<RRA>. If the internal value is changed (see L<rrdtune>), this
+graphing command should be changed to be consistent.
+
+=head3 A note on data reduction:
+
+The B<rrdtool> I<graph> command is designed to plot data at a specified temporal
+resolution, regardless of the actually resolution of the data in the RRD file.
+This can present a problem for the specialized consolidation functions which
+maintain a one-to-one mapping between primary data points and consolidated
+data points. If a graph insists on viewing the contents of these B<RRAs> on a
+coarser temporal scale, the I<graph> command tries to do something intelligent,
+but the confidence bands and failures no longer have the same meaning and may
+be misleading.
+
+
 =head1 SEE ALSO
 
 L<rrdgraph> gives an overview of how B<rrdtool graph> works.
index ca58ce7696ad29b0f477179e27f1b50f3a83e366..8dc2e6e72c08dff91d30e68451fecff4fe095007 100644 (file)
@@ -91,6 +91,17 @@ E\bEX\bXA\bAM\bMP\bPL\bLE\bES\bS
 
                LINE1:data#FF0000:"Data with offset":STACK
 
+       D\bDr\bra\baw\bwi\bin\bng\bg d\bda\bas\bsh\bhe\bed\bd l\bli\bin\bne\bes\bs
+
+       Also works for HRULE and VRULE
+
+       Â·   default style: - - - - -
+               LINE1:data#FF0000:"dashed line":dashes
+
+       Â·   more fancy style with offset: - -  --- -  --- -
+               LINE1:data#FF0000:"another dashed
+           line":dashes=15,5,5,10:dash-offset=10
+
        T\bTi\bim\bme\be r\bra\ban\bng\bge\bes\bs
 
            Last four weeks: --start end-4w --end 00:00
@@ -113,6 +124,63 @@ E\bEX\bXA\bAM\bMP\bPL\bLE\bES\bS
            AREA:lastweek#0000FF:Last\ week
            LINE1:thisweek#FF0000:This\ week
 
+       A\bAb\bbe\ber\brr\bra\ban\bnt\bt B\bBe\beh\bha\bav\bvi\bio\bou\bur\br D\bDe\bet\bte\bec\bct\bti\bio\bon\bn
+
+       If the specialized function R\bRR\bRA\bAs\bs exist for aberrant behavior detection,
+       they can be used to generate the graph of a time series with confidence
+       bands and failures.
+
+          rrdtool graph example.png \
+                 DEF:obs=monitor.rrd:ifOutOctets:AVERAGE \
+                 DEF:pred=monitor.rrd:ifOutOctets:HWPREDICT \
+                 DEF:dev=monitor.rrd:ifOutOctets:DEVPREDICT \
+                 DEF:fail=monitor.rrd:ifOutOctets:FAILURES \
+                 TICK:fail#ffffa0:1.0:"Failures\: Average bits out" \
+                 CDEF:scaledobs=obs,8,* \
+                 CDEF:upper=pred,dev,2,*,+ \
+                 CDEF:lower=pred,dev,2,*,- \
+                 CDEF:scaledupper=upper,8,* \
+                 CDEF:scaledlower=lower,8,* \
+                 LINE2:scaledobs#0000ff:"Average bits out" \
+                 LINE1:scaledupper#ff0000:"Upper Confidence Bound: Average bits out" \
+                 LINE1:scaledlower#ff0000:"Lower Confidence Bound: Average bits out"
+
+       This example generates a graph of the data series in blue (LINE2 with
+       the scaledobs virtual data source), confidence bounds in red (scaledup-
+       per and scaledlower virtual data sources), and potential failures (i.e.
+       potential aberrant aberrant behavior) marked by vertical yellow lines
+       (the fail data source).
+
+       The raw data comes from an AVERAGE R\bRR\bRA\bA, the finest resolution of the
+       observed time series (one consolidated data point per primary data
+       point). The predicted (or smoothed) values are stored in the HWPREDICT
+       R\bRR\bRA\bA. The predicted deviations (think standard deviation) values are
+       stored in the DEVPREDICT R\bRR\bRA\bA. Finally, the FAILURES R\bRR\bRA\bA contains indi-
+       cators, with 1 denoting a potential failure.
+
+       All of the data is rescaled to bits (instead of Octets) by multiplying
+       by 8.  The confidence bounds are computed by an offset of 2 deviations
+       both above and below the predicted values (the CDEFs upper and lower).
+       Vertical lines indicated potential failures are graphed via the TICK
+       graph element, which converts non-zero values in an R\bRR\bRA\bA into tick
+       marks. Here an axis-fraction argument of 1.0 means the tick marks span
+       the entire y-axis, and hence become vertical lines on the graph.
+
+       The choice of 2 deviations (a scaling factor) matches the default used
+       internally by the FAILURES R\bRR\bRA\bA. If the internal value is changed (see
+       rrdtune), this graphing command should be changed to be consistent.
+
+       _\bA _\bn_\bo_\bt_\be _\bo_\bn _\bd_\ba_\bt_\ba _\br_\be_\bd_\bu_\bc_\bt_\bi_\bo_\bn_\b:
+
+       The r\brr\brd\bdt\bto\boo\bol\bl _\bg_\br_\ba_\bp_\bh command is designed to plot data at a specified tem-
+       poral resolution, regardless of the actually resolution of the data in
+       the RRD file.  This can present a problem for the specialized consoli-
+       dation functions which maintain a one-to-one mapping between primary
+       data points and consolidated data points. If a graph insists on viewing
+       the contents of these R\bRR\bRA\bAs\bs on a coarser temporal scale, the _\bg_\br_\ba_\bp_\bh com-
+       mand tries to do something intelligent, but the confidence bands and
+       failures no longer have the same meaning and may be misleading.
+
 S\bSE\bEE\bE A\bAL\bLS\bSO\bO
        rrdgraph gives an overview of how r\brr\brd\bdt\bto\boo\bol\bl g\bgr\bra\bap\bph\bh works.  rrdgraph_data
        describes D\bDE\bEF\bF,C\bCD\bDE\bEF\bF and V\bVD\bDE\bEF\bF in detail.  rrdgraph_rpn describes the R\bRP\bPN\bN
@@ -128,4 +196,4 @@ A\bAU\bUT\bTH\bHO\bOR\bR
 
 
 
-1.2.27                            2008-02-17              RRDGRAPH_EXAMPLES(1)
+1.3rc4                            2008-03-25              RRDGRAPH_EXAMPLES(1)
index f7429f9f109b835c54afc498a9a538351a63d4b5..ce55b98fafd593bf03898b00a24174ed04e37813 100644 (file)
 .\" ========================================================================
 .\"
 .IX Title "RRDGRAPH_GRAPH 1"
-.TH RRDGRAPH_GRAPH 1 "2008-02-17" "1.2.27" "rrdtool"
+.TH RRDGRAPH_GRAPH 1 "2008-03-15" "1.3rc4" "rrdtool"
 .SH "NAME"
 rrdgraph_graph \- rrdtool graph command reference
 .SH "SYNOPSIS"
@@ -140,11 +140,11 @@ rrdgraph_graph \- rrdtool graph command reference
 .PP
 \&\fB\s-1COMMENT\s0\fR\fB:\fR\fItext\fR
 .PP
-\&\fB\s-1VRULE\s0\fR\fB:\fR\fItime\fR\fB#\fR\fIcolor\fR[\fB:\fR\fIlegend\fR]
+\&\fB\s-1VRULE\s0\fR\fB:\fR\fItime\fR\fB#\fR\fIcolor\fR[\fB:\fR\fIlegend\fR][\fB:dashes\fR[\fB=\fR\fIon_s\fR[,\fIoff_s\fR[,\fIon_s\fR,\fIoff_s\fR]...]][\fB:dash\-offset=\fR\fIoffset\fR]]
 .PP
-\&\fB\s-1HRULE\s0\fR\fB:\fR\fIvalue\fR\fB#\fR\fIcolor\fR[\fB:\fR\fIlegend\fR]
+\&\fB\s-1HRULE\s0\fR\fB:\fR\fIvalue\fR\fB#\fR\fIcolor\fR[\fB:\fR\fIlegend\fR][\fB:dashes\fR[\fB=\fR\fIon_s\fR[,\fIoff_s\fR[,\fIon_s\fR,\fIoff_s\fR]...]][\fB:dash\-offset=\fR\fIoffset\fR]]
 .PP
-\&\fB\s-1LINE\s0\fR[\fIwidth\fR]\fB:\fR\fIvalue\fR[\fB#\fR\fIcolor\fR][\fB:\fR[\fIlegend\fR][\fB:STACK\fR]]
+\&\fB\s-1LINE\s0\fR[\fIwidth\fR]\fB:\fR\fIvalue\fR[\fB#\fR\fIcolor\fR][\fB:\fR[\fIlegend\fR][\fB:STACK\fR]][\fB:dashes\fR[\fB=\fR\fIon_s\fR[,\fIoff_s\fR[,\fIon_s\fR,\fIoff_s\fR]...]][\fB:dash\-offset=\fR\fIoffset\fR]]
 .PP
 \&\fB\s-1AREA\s0\fR\fB:\fR\fIvalue\fR[\fB#\fR\fIcolor\fR][\fB:\fR[\fIlegend\fR][\fB:STACK\fR]]
 .PP
@@ -152,6 +152,8 @@ rrdgraph_graph \- rrdtool graph command reference
 .PP
 \&\fB\s-1SHIFT\s0\fR\fB:\fR\fIvname\fR\fB:\fR\fIoffset\fR
 .PP
+\&\fB\s-1TEXTALIGN\s0\fR\fB:\fR{\fBleft\fR|\fBright\fR|\fBjustified\fR|\fBcenter\fR}
+.PP
 \&\fB\s-1PRINT\s0\fR\fB:\fR\fIvname\fR\fB:\fR\fI\s-1CF\s0\fR\fB:\fR\fIformat\fR (deprecated)
 .PP
 \&\fB\s-1GPRINT\s0\fR\fB:\fR\fIvname\fR\fB:\fR\fI\s-1CF\s0\fR\fB:\fR\fIformat\fR (deprecated)
@@ -162,8 +164,8 @@ rrdgraph_graph \- rrdtool graph command reference
 These instructions allow you to generate your image or report.
 If you don't use any graph elements, no graph is generated.
 Similarly, no report is generated if you don't use print options.
-.Sh "\s-1PRINT\s0"
-.IX Subsection "PRINT"
+.SH "PRINT"
+.IX Header "PRINT"
 .IP "\fB\s-1PRINT:\s0\fR\fIvname\fR\fB:\fR\fIformat\fR[\fB:strftime\fR]" 4
 .IX Item "PRINT:vname:format[:strftime]"
 Depending on the context, either the value component or the time
@@ -175,88 +177,122 @@ The percent character introduces a formatter string. This string
 can be:
 .Sp
 For printing values:
-.Sp
-\&\fB%%\fR \- just prints a literal '%' character
-.Sp
-\&\fB%#.#le\fR \- prints numbers like 1.2346e+04. The optional integers # denote field
+.RS 4
+.IP "\fB%%\fR" 4
+.IX Item "%%"
+just prints a literal '%' character
+.IP "\fB%#.#le\fR" 4
+.IX Item "%#.#le"
+prints numbers like 1.2346e+04. The optional integers # denote field
 width and decimal precision.
-.Sp
-\&\fB%#.#lf\fR \- prints numbers like 12345.6789, with optional field width
+.IP "\fB%#.#lf\fR" 4
+.IX Item "%#.#lf"
+prints numbers like 12345.6789, with optional field width
 and precision.
-.Sp
-\&\fB%s\fR \- place this after \fB%le\fR, \fB%lf\fR or \fB%lg\fR. This will be replaced by the
+.IP "\fB%s\fR" 4
+.IX Item "%s"
+place this after \fB%le\fR, \fB%lf\fR or \fB%lg\fR. This will be replaced by the
 appropriate \s-1SI\s0 magnitude unit and the value will be scaled
 accordingly (123456 \-> 123.456 k).
-.Sp
-\&\fB%S\fR \- is similar to \fB%s\fR. It does, however, use a previously defined
+.IP "\fB%S\fR" 4
+.IX Item "%S"
+is similar to \fB%s\fR. It does, however, use a previously defined
 magnitude unit. If there is no such unit yet, it tries to define
 one (just like \fB%s\fR) unless the value is zero, in which case the magnitude
 unit stays undefined. Thus, formatter strings using \fB%S\fR and no \fB%s\fR
 will all use the same magnitude unit except for zero values.
+.RE
+.RS 4
 .Sp
 If you \s-1PRINT\s0 a \s-1VDEF\s0 value, you can also print the time associated with it by appending the string
 \&\fB:strftime\fR to the format. Note that rrdtool uses the strftime function of your OSs clibrary. This means that
 the conversion specifier may vary. Check the manual page if you are uncertain. The following is a list of
 conversion specifiers usually supported across the board. 
-.Sp
-\&\fB%a\fR \- The abbreviated weekday name according to the current locale.
-.Sp
-\&\fB%A\fR \- The full weekday name according to the current locale.
-.Sp
-\&\fB%b\fR \- The abbreviated month name according to the current locale.
-.Sp
-\&\fB%B\fR \- The full month name according to the current locale.
-.Sp
-\&\fB%c\fR \- The preferred date and time representation for the current locale.
-.Sp
-\&\fB%d\fR \- The day of the month as a decimal number (range 01 to 31).
-.Sp
-\&\fB%H\fR \- The hour as a decimal number using a 24\-hour clock (range 00 to 23).
-.Sp
-\&\fB%I\fR \- The hour as a decimal number using a 12\-hour clock (range 01 to 12).
-.Sp
-\&\fB%j\fR \- The day of the year as a decimal number (range 001 to 366).
-.Sp
-\&\fB%m\fR \- The month as a decimal number (range 01 to 12).
-.Sp
-\&\fB%M\fR \- The minute as a decimal number (range 00 to 59).
-.Sp
-\&\fB%p\fR \- Either `\s-1AM\s0' or `\s-1PM\s0' according to the given time value, or the corresponding
+.IP "\fB%a\fR" 4
+.IX Item "%a"
+The abbreviated weekday name according to the current locale.
+.IP "\fB%A\fR" 4
+.IX Item "%A"
+The full weekday name according to the current locale.
+.IP "\fB%b\fR" 4
+.IX Item "%b"
+The abbreviated month name according to the current locale.
+.IP "\fB%B\fR" 4
+.IX Item "%B"
+The full month name according to the current locale.
+.IP "\fB%c\fR" 4
+.IX Item "%c"
+The preferred date and time representation for the current locale.
+.IP "\fB%d\fR" 4
+.IX Item "%d"
+The day of the month as a decimal number (range 01 to 31).
+.IP "\fB%H\fR" 4
+.IX Item "%H"
+The hour as a decimal number using a 24\-hour clock (range 00 to 23).
+.IP "\fB%I\fR" 4
+.IX Item "%I"
+The hour as a decimal number using a 12\-hour clock (range 01 to 12).
+.IP "\fB%j\fR" 4
+.IX Item "%j"
+The day of the year as a decimal number (range 001 to 366).
+.IP "\fB%m\fR" 4
+.IX Item "%m"
+The month as a decimal number (range 01 to 12).
+.IP "\fB%M\fR" 4
+.IX Item "%M"
+The minute as a decimal number (range 00 to 59).
+.IP "\fB%p\fR" 4
+.IX Item "%p"
+Either `\s-1AM\s0' or `\s-1PM\s0' according to the given time value, or the corresponding
 strings for the current locale.  Noon is treated as `pm' and midnight as
 `am'.  Note that in many locales and `pm' notation is unsupported and in
 such cases \f(CW%p\fR will return an empty string.
-.Sp
-\&\fB%S\fR \- The second as a decimal number (range 00 to 61).
-.Sp
-\&\fB%U\fR \- The  week  number  of  the current year as a decimal number, range 00 to 53, starting with the
+.IP "\fB%S\fR" 4
+.IX Item "%S"
+The second as a decimal number (range 00 to 61).
+.IP "\fB%U\fR" 4
+.IX Item "%U"
+The  week  number  of  the current year as a decimal number, range 00 to 53, starting with the
 first Sunday as the first day of week 01. See also \f(CW%V\fR and \f(CW%W\fR.
-.Sp
-\&\fB%V\fR \- The \s-1ISO\s0 8601:1988 week number of the current year as a decimal number, range 01 to  53,  where
+.IP "\fB%V\fR" 4
+.IX Item "%V"
+The \s-1ISO\s0 8601:1988 week number of the current year as a decimal number, range 01 to  53,  where
 week  1 is the first week that has at least 4 days in the current year, and with Monday as the
 first day of the week. See also \f(CW%U\fR and \f(CW%W\fR.
-.Sp
-\&\fB%w\fR \- The day of the week as a decimal, range 0 to 6, Sunday being 0.  See also \f(CW%u\fR.
-.Sp
-\&\fB%W\fR \- The week number of the current year as a decimal number, range 00 to  53,  starting  with  the
+.IP "\fB%w\fR" 4
+.IX Item "%w"
+The day of the week as a decimal, range 0 to 6, Sunday being 0.  See also \f(CW%u\fR.
+.IP "\fB%W\fR" 4
+.IX Item "%W"
+The week number of the current year as a decimal number, range 00 to  53,  starting  with  the
 first Monday as the first day of week 01.
-.Sp
-\&\fB%x\fR \- The preferred date representation for the current locale without the time.
-.Sp
-\&\fB%X\fR \- The preferred time representation for the current locale without the date.
-.Sp
-\&\fB%y\fR \- The year as a decimal number without a century (range 00 to 99).
-.Sp
-\&\fB%Y\fR \- The year as a decimal number including the century.
-.Sp
-\&\fB%Z\fR \- The time zone or name or abbreviation.
-.Sp
-\&\fB%%\fR \- A literal `%' character.
+.IP "\fB%x\fR" 4
+.IX Item "%x"
+The preferred date representation for the current locale without the time.
+.IP "\fB%X\fR" 4
+.IX Item "%X"
+The preferred time representation for the current locale without the date.
+.IP "\fB%y\fR" 4
+.IX Item "%y"
+The year as a decimal number without a century (range 00 to 99).
+.IP "\fB%Y\fR" 4
+.IX Item "%Y"
+The year as a decimal number including the century.
+.IP "\fB%Z\fR" 4
+.IX Item "%Z"
+The time zone or name or abbreviation.
+.IP "\fB%%\fR" 4
+.IX Item "%%"
+A literal `%' character.
+.RE
+.RS 4
+.RE
 .IP "\fB\s-1PRINT:\s0\fR\fIvname\fR\fB:\fR\fI\s-1CF\s0\fR\fB:\fR\fIformat\fR" 4
 .IX Item "PRINT:vname:CF:format"
 \&\fIDeprecated. Use the new form of this command in new scripts.\fR
 The first form of this command is to be used with \fB\s-1CDEF\s0\fR \fIvname\fRs.
-.Sh "\s-1GRAPH\s0"
-.IX Subsection "GRAPH"
+.SH "GRAPH"
+.IX Header "GRAPH"
 .IP "\fB\s-1GPRINT\s0\fR\fB:\fR\fIvname\fR\fB:\fR\fIformat\fR" 4
 .IX Item "GPRINT:vname:format"
 This is the same as \f(CW\*(C`PRINT\*(C'\fR, but printed inside the graph.
@@ -269,20 +305,22 @@ This is the same as \f(CW\*(C`PRINT\*(C'\fR, but printed inside the graph.
 Text is printed literally in the legend section of the graph. Note that in
 RRDtool 1.2 you have to escape colons in \s-1COMMENT\s0 text in the same way you
 have to escape them in \fB*PRINT\fR commands by writing \fB'\e:'\fR.
-.IP "\fB\s-1VRULE\s0\fR\fB:\fR\fItime\fR\fB#\fR\fIcolor\fR [\fB:\fR\fIlegend\fR ]" 4
-.IX Item "VRULE:time#color [:legend ]"
+.IP "\fB\s-1VRULE\s0\fR\fB:\fR\fItime\fR\fB#\fR\fIcolor\fR[\fB:\fR\fIlegend\fR][\fB:dashes\fR[\fB=\fR\fIon_s\fR[,\fIoff_s\fR[,\fIon_s\fR,\fIoff_s\fR]...]][\fB:dash\-offset=\fR\fIoffset\fR]]" 4
+.IX Item "VRULE:time#color[:legend][:dashes[=on_s[,off_s[,on_s,off_s]...]][:dash-offset=offset]]"
 Draw a vertical line at \fItime\fR.  Its color is composed from three
 hexadecimal numbers specifying the rgb color components (00 is off, \s-1FF\s0 is
 maximum) red, green and blue followed by an optional alpha. Optionally, a legend box and string is
 printed in the legend section. \fItime\fR may be a number or a variable
 from a \fB\s-1VDEF\s0\fR. It is an error to use \fIvname\fRs from \fB\s-1DEF\s0\fR or \fB\s-1CDEF\s0\fR here.
-.IP "\fB\s-1HRULE\s0\fR\fB:\fR\fIvalue\fR\fB#\fR\fIcolor\fR [ :\fIlegend\fR ]" 4
-.IX Item "HRULE:value#color [ :legend ]"
+Dashed lines can be drawn using the \fBdashes\fR modifier. See \fB\s-1LINE\s0\fR for more
+details.
+.IP "\fB\s-1HRULE\s0\fR\fB:\fR\fIvalue\fR\fB#\fR\fIcolor\fR[\fB:\fR\fIlegend\fR][\fB:dashes\fR[\fB=\fR\fIon_s\fR[,\fIoff_s\fR[,\fIon_s\fR,\fIoff_s\fR]...]][\fB:dash\-offset=\fR\fIoffset\fR]]" 4
+.IX Item "HRULE:value#color[:legend][:dashes[=on_s[,off_s[,on_s,off_s]...]][:dash-offset=offset]]"
 Draw a horizontal line at \fIvalue\fR.  \s-1HRULE\s0 acts much like \s-1LINE\s0 except that
 will have no effect on the scale of the graph. If a \s-1HRULE\s0 is outside the
 graphing area it will just not be visible.
-.IP "\fB\s-1LINE\s0\fR[\fIwidth\fR]\fB:\fR\fIvalue\fR[\fB#\fR\fIcolor\fR][\fB:\fR[\fIlegend\fR][\fB:STACK\fR]]" 4
-.IX Item "LINE[width]:value[#color][:[legend][:STACK]]"
+.IP "\fB\s-1LINE\s0\fR[\fIwidth\fR]\fB:\fR\fIvalue\fR[\fB#\fR\fIcolor\fR][\fB:\fR[\fIlegend\fR][\fB:STACK\fR]][\fB:dashes\fR[\fB=\fR\fIon_s\fR[,\fIoff_s\fR[,\fIon_s\fR,\fIoff_s\fR]...]][\fB:dash\-offset=\fR\fIoffset\fR]]" 4
+.IX Item "LINE[width]:value[#color][:[legend][:STACK]][:dashes[=on_s[,off_s[,on_s,off_s]...]][:dash-offset=offset]]"
 Draw a line of the specified width onto the graph. \fIwidth\fR can be a
 floating point number. If the color is not specified, the drawing is done
 \&'invisibly'. This is useful when stacking something else on top of this
@@ -292,6 +330,14 @@ the legend section if specified. The \fBvalue\fR can be generated by \fB\s-1DEF\
 is stacked on top of the previous element which can be a \fB\s-1LINE\s0\fR or an
 \&\fB\s-1AREA\s0\fR.
 .Sp
+The \fBdashes\fR modifier enables dashed line style. Without any further options
+a symmetric dashed line with a segment length of 5 pixels will be drawn. The
+dash pattern can be changed if the \fBdashes=\fR parameter is followed by either
+one value or an even number (1, 2, 4, 6, ...) of positive values. Each value
+provides the length of alternate \fIon_s\fR and \fIoff_s\fR portions of the
+stroke. The \fBdash-offset\fR parameter specifies an \fIoffset\fR into the pattern
+at which the stroke begins.
+.Sp
 When you do not specify a color, you cannot specify a legend.  Should
 you want to use \s-1STACK\s0, use the \*(L"LINEx:<value>::STACK\*(R" form.
 .IP "\fB\s-1AREA\s0\fR\fB:\fR\fIvalue\fR[\fB#\fR\fIcolor\fR][\fB:\fR[\fIlegend\fR][\fB:STACK\fR]]" 4
@@ -314,6 +360,13 @@ offset of (\ 7*24*60*60\ =\ )\ 604'800\ seconds to \*(L"look back\*(R" one
 week. Make sure to tell the viewer of your graph you did this ...
 As with the other graphing elements, you can specify a number or
 a variable here.
+.IP "\fB\s-1TEXTALIGN\s0\fR\fB:\fR{\fBleft\fR|\fBright\fR|\fBjustified\fR|\fBcenter\fR}" 4
+.IX Item "TEXTALIGN:{left|right|justified|center}"
+Labels are placed below the graph. When they overflow to the left, they wrap
+to the next line. By default, lines are justified left and right. The
+\&\fB\s-1TEXTALIGN\s0\fR function lets you change this default. This is a command and
+not an option, so that you can change the default several times in your
+argument list.
 .IP "\fB\s-1STACK\s0\fR\fB:\fR\fIvname\fR\fB#\fR\fIcolor\fR[\fB:\fR\fIlegend\fR]" 4
 .IX Item "STACK:vname#color[:legend]"
 \&\fIDeprecated.  Use the \f(BI\s-1STACK\s0\fI modifiers on the other commands.\fR
@@ -373,6 +426,106 @@ If you are using the proportional font in your graph, you can use tab
 characters or the sequence \fB\et\fR to line-up legend elements. Note that
 the tabs inserted are relative to the start of the current legend
 element!
+.PP
+Since RRDtool 1.3 is using Pango for rending text, you can use Pango markup.
+Pango uses the xml \fBspan\fR tags for inline formatting instructions.:
+.PP
+A simple example of a marked-up string might be: 
+.PP
+.Vb 1
+\& <span foreground="blue" size="x\-large">Blue text</span> is <i>cool</i>!
+.Ve
+.PP
+The complete list of attributes for the span tag (taken from the pango documentation):
+.IP "\fBfont_desc\fR" 4
+.IX Item "font_desc"
+A font description string, such as \*(L"Sans Italic 12\*(R"; note that any other span attributes will override this description. So if you have \*(L"Sans Italic\*(R" and also a style=\*(L"normal\*(R" attribute, you will get Sans normal, not italic.
+.IP "\fBfont_family\fR" 4
+.IX Item "font_family"
+A font family name
+.IP "\fBface\fR" 4
+.IX Item "face"
+Synonym for font_family
+.IP "\fBsize\fR" 4
+.IX Item "size"
+Font size in 1024ths of a point, or one of the absolute sizes 'xx\-small', 'x\-small', 'small', 'medium', 'large', 'x\-large', 'xx\-large', or one of the relative sizes 'smaller' or 'larger'. If you want to specify a absolute size, it's usually easier to take advantage of the ability to specify a partial font description using 'font_desc'; you can use font_desc='12.5' rather than size='12800'.
+.IP "\fBstyle\fR" 4
+.IX Item "style"
+One of 'normal', 'oblique', 'italic'
+.IP "\fBweight\fR" 4
+.IX Item "weight"
+One of 'ultralight', 'light', 'normal', 'bold', 'ultrabold', 'heavy', or a numeric weight
+.IP "\fBvariant\fR" 4
+.IX Item "variant"
+\&'normal' or 'smallcaps'
+.IP "\fBstretch\fR" 4
+.IX Item "stretch"
+One of 'ultracondensed', 'extracondensed', 'condensed', 'semicondensed', 'normal', 'semiexpanded', 'expanded', 'extraexpanded', 'ultraexpanded'
+.IP "\fBforeground\fR" 4
+.IX Item "foreground"
+An \s-1RGB\s0 color specification such as '#00FF00' or a color name such as 'red'
+.IP "\fBbackground\fR" 4
+.IX Item "background"
+An \s-1RGB\s0 color specification such as '#00FF00' or a color name such as 'red'
+.IP "\fBunderline\fR" 4
+.IX Item "underline"
+One of 'none', 'single', 'double', 'low', 'error'
+.IP "\fBunderline_color\fR" 4
+.IX Item "underline_color"
+The color of underlines; an \s-1RGB\s0 color specification such as '#00FF00' or a color name such as 'red'
+.IP "\fBrise\fR" 4
+.IX Item "rise"
+Vertical displacement, in 10000ths of an em. Can be negative for subscript, positive for superscript.
+.IP "\fBstrikethrough\fR" 4
+.IX Item "strikethrough"
+\&'true' or 'false' whether to strike through the text
+.IP "\fBstrikethrough_color\fR" 4
+.IX Item "strikethrough_color"
+The color of strikethrough lines; an \s-1RGB\s0 color specification such as '#00FF00' or a color name such as 'red'
+.IP "\fBfallback\fR" 4
+.IX Item "fallback"
+\&'true' or 'false' whether to enable fallback. If disabled, then characters will only be used from the closest matching font on the system. No fallback will be done to other fonts on the system that might contain the characters in the text. Fallback is enabled by default. Most applications should not disable fallback.
+.IP "\fBlang\fR" 4
+.IX Item "lang"
+A language code, indicating the text language
+.IP "\fBletter_spacing\fR" 4
+.IX Item "letter_spacing"
+Inter-letter spacing in 1024ths of a point.
+.IP "\fBgravity\fR" 4
+.IX Item "gravity"
+One of 'south', 'east', 'north', 'west', 'auto'.
+.IP "\fBgravity_hint\fR" 4
+.IX Item "gravity_hint"
+One of 'natural', 'strong', 'line'.
+.PP
+To save you some typing, there are also some shortcuts:
+.IP "\fBb\fR" 4
+.IX Item "b"
+Bold
+.IP "\fBbig\fR" 4
+.IX Item "big"
+Makes font relatively larger, equivalent to <span size=\*(L"larger\*(R">
+.IP "\fBi\fR" 4
+.IX Item "i"
+Italic
+.IP "\fBs\fR" 4
+.IX Item "s"
+Strikethrough
+.IP "\fBsub\fR" 4
+.IX Item "sub"
+Subscript
+.IP "\fBsup\fR" 4
+.IX Item "sup"
+Superscript
+.IP "\fBsmall\fR" 4
+.IX Item "small"
+Makes font relatively smaller, equivalent to <span size=\*(L"smaller\*(R">
+.IP "\fBtt\fR" 4
+.IX Item "tt"
+Monospace font
+.IP "\fBu\fR" 4
+.IX Item "u"
+Underline 
 .SH "SEE ALSO"
 .IX Header "SEE ALSO"
 rrdgraph gives an overview of how \fBrrdtool graph\fR works.
index 78aae248891171cbce61f122b8c4bf1044f2fa16..d53067015a9be7f28148b9c5d795553038744ed8 100644 (file)
        <li><a href="#name">NAME</a></li>
        <li><a href="#synopsis">SYNOPSIS</a></li>
        <li><a href="#description">DESCRIPTION</a></li>
-       <ul>
-
-               <li><a href="#print">PRINT</a></li>
-               <li><a href="#graph">GRAPH</a></li>
-       </ul>
-
+       <li><a href="#print">PRINT</a></li>
+       <li><a href="#graph">GRAPH</a></li>
        <li><a href="#notes_on_legend_arguments">NOTES on legend arguments</a></li>
        <ul>
 
 <p><strong>PRINT</strong><strong>:</strong><em>vname</em><strong>:</strong><em>format</em></p>
 <p><strong>GPRINT</strong><strong>:</strong><em>vname</em><strong>:</strong><em>format</em></p>
 <p><strong>COMMENT</strong><strong>:</strong><em>text</em></p>
-<p><strong>VRULE</strong><strong>:</strong><em>time</em><strong>#</strong><em>color</em>[<strong>:</strong><em>legend</em>]</p>
-<p><strong>HRULE</strong><strong>:</strong><em>value</em><strong>#</strong><em>color</em>[<strong>:</strong><em>legend</em>]</p>
-<p><strong>LINE</strong>[<em>width</em>]<strong>:</strong><em>value</em>[<strong>#</strong><em>color</em>][<strong>:</strong>[<em>legend</em>][<strong>:STACK</strong>]]</p>
+<p><strong>VRULE</strong><strong>:</strong><em>time</em><strong>#</strong><em>color</em>[<strong>:</strong><em>legend</em>][<strong>:dashes</strong>[<strong>=</strong><em>on_s</em>[,<em>off_s</em>[,<em>on_s</em>,<em>off_s</em>]...]][<strong>:dash-offset=</strong><em>offset</em>]]</p>
+<p><strong>HRULE</strong><strong>:</strong><em>value</em><strong>#</strong><em>color</em>[<strong>:</strong><em>legend</em>][<strong>:dashes</strong>[<strong>=</strong><em>on_s</em>[,<em>off_s</em>[,<em>on_s</em>,<em>off_s</em>]...]][<strong>:dash-offset=</strong><em>offset</em>]]</p>
+<p><strong>LINE</strong>[<em>width</em>]<strong>:</strong><em>value</em>[<strong>#</strong><em>color</em>][<strong>:</strong>[<em>legend</em>][<strong>:STACK</strong>]][<strong>:dashes</strong>[<strong>=</strong><em>on_s</em>[,<em>off_s</em>[,<em>on_s</em>,<em>off_s</em>]...]][<strong>:dash-offset=</strong><em>offset</em>]]</p>
 <p><strong>AREA</strong><strong>:</strong><em>value</em>[<strong>#</strong><em>color</em>][<strong>:</strong>[<em>legend</em>][<strong>:STACK</strong>]]</p>
 <p><strong>TICK</strong><strong>:</strong><em>vname</em><strong>#</strong><em>rrggbb</em>[<em>aa</em>][<strong>:</strong><em>fraction</em>[<strong>:</strong><em>legend</em>]]</p>
 <p><strong>SHIFT</strong><strong>:</strong><em>vname</em><strong>:</strong><em>offset</em></p>
+<p><strong>TEXTALIGN</strong><strong>:</strong>{<strong>left</strong>|<strong>right</strong>|<strong>justified</strong>|<strong>center</strong>}</p>
 <p><strong>PRINT</strong><strong>:</strong><em>vname</em><strong>:</strong><em>CF</em><strong>:</strong><em>format</em> (deprecated)</p>
 <p><strong>GPRINT</strong><strong>:</strong><em>vname</em><strong>:</strong><em>CF</em><strong>:</strong><em>format</em> (deprecated)</p>
 <p><strong>STACK</strong><strong>:</strong><em>vname</em><strong>#</strong><em>color</em>[<strong>:</strong><em>legend</em>] (deprecated)</p>
@@ -67,7 +64,8 @@ If you don't use any graph elements, no graph is generated.
 Similarly, no report is generated if you don't use print options.</p>
 <p>
 </p>
-<h2><a name="print">PRINT</a></h2>
+<hr />
+<h1><a name="print">PRINT</a></h1>
 <dl>
 <dt><strong><a name="item_print_3avname_3aformat_5b_3astrftime_5d"><strong>PRINT:</strong><em>vname</em><strong>:</strong><em>format</em>[<strong>:strftime</strong>]</a></strong>
 
@@ -84,112 +82,197 @@ can be:</p>
 <dd>
 <p>For printing values:</p>
 </dd>
+<dl>
+<dt><strong><a name="item___"><strong>%%</strong></a></strong>
+
 <dd>
-<p><strong>%%</strong> - just prints a literal '%' character</p>
+<p>just prints a literal '%' character</p>
 </dd>
+</li>
+<dt><strong><a name="item_____le"><strong>%#.#le</strong></a></strong>
+
 <dd>
-<p><strong>%#.#le</strong> - prints numbers like 1.2346e+04. The optional integers # denote field
+<p>prints numbers like 1.2346e+04. The optional integers # denote field
 width and decimal precision.</p>
 </dd>
+</li>
+<dt><strong><a name="item_____lf"><strong>%#.#lf</strong></a></strong>
+
 <dd>
-<p><strong>%#.#lf</strong> - prints numbers like 12345.6789, with optional field width
+<p>prints numbers like 12345.6789, with optional field width
 and precision.</p>
 </dd>
+</li>
+<dt><strong><a name="item__s"><strong>%s</strong></a></strong>
+
 <dd>
-<p><strong>%s</strong> - place this after <strong>%le</strong>, <strong>%lf</strong> or <strong>%lg</strong>. This will be replaced by the
+<p>place this after <strong>%le</strong>, <strong>%lf</strong> or <strong>%lg</strong>. This will be replaced by the
 appropriate SI magnitude unit and the value will be scaled
 accordingly (123456 -&gt; 123.456 k).</p>
 </dd>
+</li>
+<dt><strong><a name="item__s"><strong>%S</strong></a></strong>
+
 <dd>
-<p><strong>%S</strong> - is similar to <strong>%s</strong>. It does, however, use a previously defined
+<p>is similar to <strong>%s</strong>. It does, however, use a previously defined
 magnitude unit. If there is no such unit yet, it tries to define
 one (just like <strong>%s</strong>) unless the value is zero, in which case the magnitude
 unit stays undefined. Thus, formatter strings using <strong>%S</strong> and no <strong>%s</strong>
 will all use the same magnitude unit except for zero values.</p>
 </dd>
-<dd>
+</li>
+</dl>
 <p>If you PRINT a VDEF value, you can also print the time associated with it by appending the string
 <strong>:strftime</strong> to the format. Note that rrdtool uses the strftime function of your OSs clibrary. This means that
 the conversion specifier may vary. Check the manual page if you are uncertain. The following is a list of
 conversion specifiers usually supported across the board.</p>
-</dd>
+<dl>
+<dt><strong><a name="item__a"><strong>%a</strong></a></strong>
+
 <dd>
-<p><strong>%a</strong> - The abbreviated weekday name according to the current locale.</p>
+<p>The abbreviated weekday name according to the current locale.</p>
 </dd>
+</li>
+<dt><strong><a name="item__a"><strong>%A</strong></a></strong>
+
 <dd>
-<p><strong>%A</strong> - The full weekday name according to the current locale.</p>
+<p>The full weekday name according to the current locale.</p>
 </dd>
+</li>
+<dt><strong><a name="item__b"><strong>%b</strong></a></strong>
+
 <dd>
-<p><strong>%b</strong> - The abbreviated month name according to the current locale.</p>
+<p>The abbreviated month name according to the current locale.</p>
 </dd>
+</li>
+<dt><strong><a name="item__b"><strong>%B</strong></a></strong>
+
 <dd>
-<p><strong>%B</strong> - The full month name according to the current locale.</p>
+<p>The full month name according to the current locale.</p>
 </dd>
+</li>
+<dt><strong><a name="item__c"><strong>%c</strong></a></strong>
+
 <dd>
-<p><strong>%c</strong> - The preferred date and time representation for the current locale.</p>
+<p>The preferred date and time representation for the current locale.</p>
 </dd>
+</li>
+<dt><strong><a name="item__d"><strong>%d</strong></a></strong>
+
 <dd>
-<p><strong>%d</strong> - The day of the month as a decimal number (range 01 to 31).</p>
+<p>The day of the month as a decimal number (range 01 to 31).</p>
 </dd>
+</li>
+<dt><strong><a name="item__h"><strong>%H</strong></a></strong>
+
 <dd>
-<p><strong>%H</strong> - The hour as a decimal number using a 24-hour clock (range 00 to 23).</p>
+<p>The hour as a decimal number using a 24-hour clock (range 00 to 23).</p>
 </dd>
+</li>
+<dt><strong><a name="item__i"><strong>%I</strong></a></strong>
+
 <dd>
-<p><strong>%I</strong> - The hour as a decimal number using a 12-hour clock (range 01 to 12).</p>
+<p>The hour as a decimal number using a 12-hour clock (range 01 to 12).</p>
 </dd>
+</li>
+<dt><strong><a name="item__j"><strong>%j</strong></a></strong>
+
 <dd>
-<p><strong>%j</strong> - The day of the year as a decimal number (range 001 to 366).</p>
+<p>The day of the year as a decimal number (range 001 to 366).</p>
 </dd>
+</li>
+<dt><strong><a name="item__m"><strong>%m</strong></a></strong>
+
 <dd>
-<p><strong>%m</strong> - The month as a decimal number (range 01 to 12).</p>
+<p>The month as a decimal number (range 01 to 12).</p>
 </dd>
+</li>
+<dt><strong><a name="item__m"><strong>%M</strong></a></strong>
+
 <dd>
-<p><strong>%M</strong> - The minute as a decimal number (range 00 to 59).</p>
+<p>The minute as a decimal number (range 00 to 59).</p>
 </dd>
+</li>
+<dt><strong><a name="item__p"><strong>%p</strong></a></strong>
+
 <dd>
-<p><strong>%p</strong> - Either `AM' or `PM' according to the given time value, or the corresponding
+<p>Either `AM' or `PM' according to the given time value, or the corresponding
 strings for the current locale.  Noon is treated as `pm' and midnight as
 `am'.  Note that in many locales and `pm' notation is unsupported and in
 such cases %p will return an empty string.</p>
 </dd>
+</li>
+<dt><strong><strong>%S</strong></strong>
+
 <dd>
-<p><strong>%S</strong> - The second as a decimal number (range 00 to 61).</p>
+<p>The second as a decimal number (range 00 to 61).</p>
 </dd>
+</li>
+<dt><strong><a name="item__u"><strong>%U</strong></a></strong>
+
 <dd>
-<p><strong>%U</strong> - The  week  number  of  the current year as a decimal number, range 00 to 53, starting with the
+<p>The  week  number  of  the current year as a decimal number, range 00 to 53, starting with the
 first Sunday as the first day of week 01. See also %V and %W.</p>
 </dd>
+</li>
+<dt><strong><a name="item__v"><strong>%V</strong></a></strong>
+
 <dd>
-<p><strong>%V</strong> - The ISO 8601:1988 week number of the current year as a decimal number, range 01 to  53,  where
+<p>The ISO 8601:1988 week number of the current year as a decimal number, range 01 to  53,  where
 week  1 is the first week that has at least 4 days in the current year, and with Monday as the
 first day of the week. See also %U and %W.</p>
 </dd>
+</li>
+<dt><strong><a name="item__w"><strong>%w</strong></a></strong>
+
 <dd>
-<p><strong>%w</strong> - The day of the week as a decimal, range 0 to 6, Sunday being 0.  See also %u.</p>
+<p>The day of the week as a decimal, range 0 to 6, Sunday being 0.  See also %u.</p>
 </dd>
+</li>
+<dt><strong><a name="item__w"><strong>%W</strong></a></strong>
+
 <dd>
-<p><strong>%W</strong> - The week number of the current year as a decimal number, range 00 to  53,  starting  with  the
+<p>The week number of the current year as a decimal number, range 00 to  53,  starting  with  the
 first Monday as the first day of week 01.</p>
 </dd>
+</li>
+<dt><strong><a name="item__x"><strong>%x</strong></a></strong>
+
 <dd>
-<p><strong>%x</strong> - The preferred date representation for the current locale without the time.</p>
+<p>The preferred date representation for the current locale without the time.</p>
 </dd>
+</li>
+<dt><strong><a name="item__x"><strong>%X</strong></a></strong>
+
 <dd>
-<p><strong>%X</strong> - The preferred time representation for the current locale without the date.</p>
+<p>The preferred time representation for the current locale without the date.</p>
 </dd>
+</li>
+<dt><strong><a name="item__y"><strong>%y</strong></a></strong>
+
 <dd>
-<p><strong>%y</strong> - The year as a decimal number without a century (range 00 to 99).</p>
+<p>The year as a decimal number without a century (range 00 to 99).</p>
 </dd>
+</li>
+<dt><strong><a name="item__y"><strong>%Y</strong></a></strong>
+
 <dd>
-<p><strong>%Y</strong> - The year as a decimal number including the century.</p>
+<p>The year as a decimal number including the century.</p>
 </dd>
+</li>
+<dt><strong><a name="item__z"><strong>%Z</strong></a></strong>
+
 <dd>
-<p><strong>%Z</strong> - The time zone or name or abbreviation.</p>
+<p>The time zone or name or abbreviation.</p>
 </dd>
+</li>
+<dt><strong><strong>%%</strong></strong>
+
 <dd>
-<p><strong>%%</strong> - A literal `%' character.</p>
+<p>A literal `%' character.</p>
 </dd>
 </li>
+</dl>
 <dt><strong><a name="item_print_3avname_3acf_3aformat"><strong>PRINT:</strong><em>vname</em><strong>:</strong><em>CF</em><strong>:</strong><em>format</em></a></strong>
 
 <dd>
@@ -200,7 +283,8 @@ The first form of this command is to be used with <strong>CDEF</strong> <em>vnam
 </dl>
 <p>
 </p>
-<h2><a name="graph">GRAPH</a></h2>
+<hr />
+<h1><a name="graph">GRAPH</a></h1>
 <dl>
 <dt><strong><a name="item_gprint_3avname_3aformat"><strong>GPRINT</strong><strong>:</strong><em>vname</em><strong>:</strong><em>format</em></a></strong>
 
@@ -223,17 +307,19 @@ RRDtool 1.2 you have to escape colons in COMMENT text in the same way you
 have to escape them in <strong>*PRINT</strong> commands by writing <strong>'\:'</strong>.</p>
 </dd>
 </li>
-<dt><strong><a name="item_vrule_3atime_23color__5b_3alegend__5d"><strong>VRULE</strong><strong>:</strong><em>time</em><strong>#</strong><em>color</em> [<strong>:</strong><em>legend</em> ]</a></strong>
+<dt><strong><a name="item_vrule_3atime_23color_5b_3alegend_5d_5b_3adashes_5b"><strong>VRULE</strong><strong>:</strong><em>time</em><strong>#</strong><em>color</em>[<strong>:</strong><em>legend</em>][<strong>:dashes</strong>[<strong>=</strong><em>on_s</em>[,<em>off_s</em>[,<em>on_s</em>,<em>off_s</em>]...]][<strong>:dash-offset=</strong><em>offset</em>]]</a></strong>
 
 <dd>
 <p>Draw a vertical line at <em>time</em>.  Its color is composed from three
 hexadecimal numbers specifying the rgb color components (00 is off, FF is
 maximum) red, green and blue followed by an optional alpha. Optionally, a legend box and string is
 printed in the legend section. <em>time</em> may be a number or a variable
-from a <strong>VDEF</strong>. It is an error to use <em>vname</em>s from <strong>DEF</strong> or <strong>CDEF</strong> here.</p>
+from a <strong>VDEF</strong>. It is an error to use <em>vname</em>s from <strong>DEF</strong> or <strong>CDEF</strong> here.
+Dashed lines can be drawn using the <strong>dashes</strong> modifier. See <strong>LINE</strong> for more
+details.</p>
 </dd>
 </li>
-<dt><strong><a name="item_hrule_3avalue_23color__5b__3alegend__5d"><strong>HRULE</strong><strong>:</strong><em>value</em><strong>#</strong><em>color</em> [ :<em>legend</em> ]</a></strong>
+<dt><strong><a name="item_hrule_3avalue_23color_5b_3alegend_5d_5b_3adashes_5"><strong>HRULE</strong><strong>:</strong><em>value</em><strong>#</strong><em>color</em>[<strong>:</strong><em>legend</em>][<strong>:dashes</strong>[<strong>=</strong><em>on_s</em>[,<em>off_s</em>[,<em>on_s</em>,<em>off_s</em>]...]][<strong>:dash-offset=</strong><em>offset</em>]]</a></strong>
 
 <dd>
 <p>Draw a horizontal line at <em>value</em>.  HRULE acts much like LINE except that
@@ -241,7 +327,7 @@ will have no effect on the scale of the graph. If a HRULE is outside the
 graphing area it will just not be visible.</p>
 </dd>
 </li>
-<dt><strong><a name="item_line_5bwidth_5d_3avalue_5b_23color_5d_5b_3a_5blege"><strong>LINE</strong>[<em>width</em>]<strong>:</strong><em>value</em>[<strong>#</strong><em>color</em>][<strong>:</strong>[<em>legend</em>][<strong>:STACK</strong>]]</a></strong>
+<dt><strong><a name="item_line_5bwidth_5d_3avalue_5b_23color_5d_5b_3a_5blege"><strong>LINE</strong>[<em>width</em>]<strong>:</strong><em>value</em>[<strong>#</strong><em>color</em>][<strong>:</strong>[<em>legend</em>][<strong>:STACK</strong>]][<strong>:dashes</strong>[<strong>=</strong><em>on_s</em>[,<em>off_s</em>[,<em>on_s</em>,<em>off_s</em>]...]][<strong>:dash-offset=</strong><em>offset</em>]]</a></strong>
 
 <dd>
 <p>Draw a line of the specified width onto the graph. <em>width</em> can be a
@@ -254,6 +340,15 @@ is stacked on top of the previous element which can be a <strong>LINE</strong> o
 <strong>AREA</strong>.</p>
 </dd>
 <dd>
+<p>The <strong>dashes</strong> modifier enables dashed line style. Without any further options
+a symmetric dashed line with a segment length of 5 pixels will be drawn. The
+dash pattern can be changed if the <strong>dashes=</strong> parameter is followed by either
+one value or an even number (1, 2, 4, 6, ...) of positive values. Each value
+provides the length of alternate <em>on_s</em> and <em>off_s</em> portions of the
+stroke. The <strong>dash-offset</strong> parameter specifies an <em>offset</em> into the pattern
+at which the stroke begins.</p>
+</dd>
+<dd>
 <p>When you do not specify a color, you cannot specify a legend.  Should
 you want to use STACK, use the ``LINEx:&lt;value&gt;::STACK'' form.</p>
 </dd>
@@ -287,6 +382,16 @@ As with the other graphing elements, you can specify a number or
 a variable here.</p>
 </dd>
 </li>
+<dt><strong><a name="item_textalign_3a_7bleft_7cright_7cjustified_7ccenter_7"><strong>TEXTALIGN</strong><strong>:</strong>{<strong>left</strong>|<strong>right</strong>|<strong>justified</strong>|<strong>center</strong>}</a></strong>
+
+<dd>
+<p>Labels are placed below the graph. When they overflow to the left, they wrap
+to the next line. By default, lines are justified left and right. The
+<strong>TEXTALIGN</strong> function lets you change this default. This is a command and
+not an option, so that you can change the default several times in your
+argument list.</p>
+</dd>
+</li>
 <dt><strong><a name="item_stack_3avname_23color_5b_3alegend_5d"><strong>STACK</strong><strong>:</strong><em>vname</em><strong>#</strong><em>color</em>[<strong>:</strong><em>legend</em>]</a></strong>
 
 <dd>
@@ -342,6 +447,191 @@ before placing the next row of legends.</p>
 characters or the sequence <strong>\t</strong> to line-up legend elements. Note that
 the tabs inserted are relative to the start of the current legend
 element!</p>
+<p>Since RRDtool 1.3 is using Pango for rending text, you can use Pango markup.
+Pango uses the xml <strong>span</strong> tags for inline formatting instructions.:</p>
+<p>A simple example of a marked-up string might be:</p>
+<pre>
+ &lt;span foreground=&quot;blue&quot; size=&quot;x-large&quot;&gt;Blue text&lt;/span&gt; is &lt;i&gt;cool&lt;/i&gt;!</pre>
+<p>The complete list of attributes for the span tag (taken from the pango documentation):</p>
+<dl>
+<dt><strong><a name="item_font_desc"><strong>font_desc</strong></a></strong>
+
+<dd>
+<p>A font description string, such as ``Sans Italic 12''; note that any other span attributes will override this description. So if you have ``Sans Italic'' and also a style=``normal'' attribute, you will get Sans normal, not italic.</p>
+</dd>
+</li>
+<dt><strong><a name="item_font_family"><strong>font_family</strong></a></strong>
+
+<dd>
+<p>A font family name</p>
+</dd>
+</li>
+<dt><strong><a name="item_face"><strong>face</strong></a></strong>
+
+<dd>
+<p>Synonym for font_family</p>
+</dd>
+</li>
+<dt><strong><a name="item_size"><strong>size</strong></a></strong>
+
+<dd>
+<p>Font size in 1024ths of a point, or one of the absolute sizes 'xx-small', 'x-small', 'small', 'medium', 'large', 'x-large', 'xx-large', or one of the relative sizes 'smaller' or 'larger'. If you want to specify a absolute size, it's usually easier to take advantage of the ability to specify a partial font description using 'font_desc'; you can use font_desc='12.5' rather than size='12800'.</p>
+</dd>
+</li>
+<dt><strong><a name="item_style"><strong>style</strong></a></strong>
+
+<dd>
+<p>One of 'normal', 'oblique', 'italic'</p>
+</dd>
+</li>
+<dt><strong><a name="item_weight"><strong>weight</strong></a></strong>
+
+<dd>
+<p>One of 'ultralight', 'light', 'normal', 'bold', 'ultrabold', 'heavy', or a numeric weight</p>
+</dd>
+</li>
+<dt><strong><a name="item_variant"><strong>variant</strong></a></strong>
+
+<dd>
+<p>'normal' or 'smallcaps'</p>
+</dd>
+</li>
+<dt><strong><a name="item_stretch"><strong>stretch</strong></a></strong>
+
+<dd>
+<p>One of 'ultracondensed', 'extracondensed', 'condensed', 'semicondensed', 'normal', 'semiexpanded', 'expanded', 'extraexpanded', 'ultraexpanded'</p>
+</dd>
+</li>
+<dt><strong><a name="item_foreground"><strong>foreground</strong></a></strong>
+
+<dd>
+<p>An RGB color specification such as '#00FF00' or a color name such as 'red'</p>
+</dd>
+</li>
+<dt><strong><a name="item_background"><strong>background</strong></a></strong>
+
+<dd>
+<p>An RGB color specification such as '#00FF00' or a color name such as 'red'</p>
+</dd>
+</li>
+<dt><strong><a name="item_underline"><strong>underline</strong></a></strong>
+
+<dd>
+<p>One of 'none', 'single', 'double', 'low', 'error'</p>
+</dd>
+</li>
+<dt><strong><a name="item_underline_color"><strong>underline_color</strong></a></strong>
+
+<dd>
+<p>The color of underlines; an RGB color specification such as '#00FF00' or a color name such as 'red'</p>
+</dd>
+</li>
+<dt><strong><a name="item_rise"><strong>rise</strong></a></strong>
+
+<dd>
+<p>Vertical displacement, in 10000ths of an em. Can be negative for subscript, positive for superscript.</p>
+</dd>
+</li>
+<dt><strong><a name="item_strikethrough"><strong>strikethrough</strong></a></strong>
+
+<dd>
+<p>'true' or 'false' whether to strike through the text</p>
+</dd>
+</li>
+<dt><strong><a name="item_strikethrough_color"><strong>strikethrough_color</strong></a></strong>
+
+<dd>
+<p>The color of strikethrough lines; an RGB color specification such as '#00FF00' or a color name such as 'red'</p>
+</dd>
+</li>
+<dt><strong><a name="item_fallback"><strong>fallback</strong></a></strong>
+
+<dd>
+<p>'true' or 'false' whether to enable fallback. If disabled, then characters will only be used from the closest matching font on the system. No fallback will be done to other fonts on the system that might contain the characters in the text. Fallback is enabled by default. Most applications should not disable fallback.</p>
+</dd>
+</li>
+<dt><strong><a name="item_lang"><strong>lang</strong></a></strong>
+
+<dd>
+<p>A language code, indicating the text language</p>
+</dd>
+</li>
+<dt><strong><a name="item_letter_spacing"><strong>letter_spacing</strong></a></strong>
+
+<dd>
+<p>Inter-letter spacing in 1024ths of a point.</p>
+</dd>
+</li>
+<dt><strong><a name="item_gravity"><strong>gravity</strong></a></strong>
+
+<dd>
+<p>One of 'south', 'east', 'north', 'west', 'auto'.</p>
+</dd>
+</li>
+<dt><strong><a name="item_gravity_hint"><strong>gravity_hint</strong></a></strong>
+
+<dd>
+<p>One of 'natural', 'strong', 'line'.</p>
+</dd>
+</li>
+</dl>
+<p>To save you some typing, there are also some shortcuts:</p>
+<dl>
+<dt><strong><a name="item_b"><strong>b</strong></a></strong>
+
+<dd>
+<p>Bold</p>
+</dd>
+</li>
+<dt><strong><a name="item_big"><strong>big</strong></a></strong>
+
+<dd>
+<p>Makes font relatively larger, equivalent to &lt;span size=``larger''&gt;</p>
+</dd>
+</li>
+<dt><strong><a name="item_i"><strong>i</strong></a></strong>
+
+<dd>
+<p>Italic</p>
+</dd>
+</li>
+<dt><strong><a name="item_s"><strong>s</strong></a></strong>
+
+<dd>
+<p>Strikethrough</p>
+</dd>
+</li>
+<dt><strong><a name="item_sub"><strong>sub</strong></a></strong>
+
+<dd>
+<p>Subscript</p>
+</dd>
+</li>
+<dt><strong><a name="item_sup"><strong>sup</strong></a></strong>
+
+<dd>
+<p>Superscript</p>
+</dd>
+</li>
+<dt><strong><a name="item_small"><strong>small</strong></a></strong>
+
+<dd>
+<p>Makes font relatively smaller, equivalent to &lt;span size=``smaller''&gt;</p>
+</dd>
+</li>
+<dt><strong><a name="item_tt"><strong>tt</strong></a></strong>
+
+<dd>
+<p>Monospace font</p>
+</dd>
+</li>
+<dt><strong><a name="item_u"><strong>u</strong></a></strong>
+
+<dd>
+<p>Underline</p>
+</dd>
+</li>
+</dl>
 <p>
 </p>
 <hr />
index 85591e620c8ab179b79ac371772ebb6b822f2bf3..f40877cbae03d70ddd22b756f3f0054cf6697c07 100644 (file)
@@ -12,11 +12,11 @@ B<GPRINT>B<:>I<vname>B<:>I<format>
 
 B<COMMENT>B<:>I<text>
 
-B<VRULE>B<:>I<time>B<#>I<color>[B<:>I<legend>]
+B<VRULE>B<:>I<time>B<#>I<color>[B<:>I<legend>][B<:dashes>[B<=>I<on_s>[,I<off_s>[,I<on_s>,I<off_s>]...]][B<:dash-offset=>I<offset>]]
 
-B<HRULE>B<:>I<value>B<#>I<color>[B<:>I<legend>]
+B<HRULE>B<:>I<value>B<#>I<color>[B<:>I<legend>][B<:dashes>[B<=>I<on_s>[,I<off_s>[,I<on_s>,I<off_s>]...]][B<:dash-offset=>I<offset>]]
 
-B<LINE>[I<width>]B<:>I<value>[B<#>I<color>][B<:>[I<legend>][B<:STACK>]]
+B<LINE>[I<width>]B<:>I<value>[B<#>I<color>][B<:>[I<legend>][B<:STACK>]][B<:dashes>[B<=>I<on_s>[,I<off_s>[,I<on_s>,I<off_s>]...]][B<:dash-offset=>I<offset>]]
 
 B<AREA>B<:>I<value>[B<#>I<color>][B<:>[I<legend>][B<:STACK>]]
 
@@ -24,6 +24,8 @@ B<TICK>B<:>I<vname>B<#>I<rrggbb>[I<aa>][B<:>I<fraction>[B<:>I<legend>]]
 
 B<SHIFT>B<:>I<vname>B<:>I<offset>
 
+B<TEXTALIGN>B<:>{B<left>|B<right>|B<justified>|B<center>}
+
 B<PRINT>B<:>I<vname>B<:>I<CF>B<:>I<format> (deprecated)
 
 B<GPRINT>B<:>I<vname>B<:>I<CF>B<:>I<format> (deprecated)
@@ -36,9 +38,10 @@ These instructions allow you to generate your image or report.
 If you don't use any graph elements, no graph is generated.
 Similarly, no report is generated if you don't use print options.
 
-=head2 PRINT
+=head1 PRINT
+
+=over 4
 
-=over
 
 =item B<PRINT:>I<vname>B<:>I<format>[B<:strftime>]
 
@@ -52,81 +55,145 @@ can be:
 
 For printing values:
 
-B<%%> - just prints a literal '%' character
+=over 4
+
+=item B<%%>
 
-B<%#.#le> - prints numbers like 1.2346e+04. The optional integers # denote field
+just prints a literal '%' character
+
+=item B<%#.#le>
+
+prints numbers like 1.2346e+04. The optional integers # denote field
 width and decimal precision.
 
-B<%#.#lf> - prints numbers like 12345.6789, with optional field width
+=item B<%#.#lf>
+
+prints numbers like 12345.6789, with optional field width
 and precision.
 
-B<%s> - place this after B<%le>, B<%lf> or B<%lg>. This will be replaced by the
+=item B<%s>
+
+place this after B<%le>, B<%lf> or B<%lg>. This will be replaced by the
 appropriate SI magnitude unit and the value will be scaled
 accordingly (123456 -> 123.456 k).
 
-B<%S> - is similar to B<%s>. It does, however, use a previously defined
+=item B<%S>
+
+is similar to B<%s>. It does, however, use a previously defined
 magnitude unit. If there is no such unit yet, it tries to define
 one (just like B<%s>) unless the value is zero, in which case the magnitude
 unit stays undefined. Thus, formatter strings using B<%S> and no B<%s>
 will all use the same magnitude unit except for zero values.
 
+=back
+
 If you PRINT a VDEF value, you can also print the time associated with it by appending the string
 B<:strftime> to the format. Note that rrdtool uses the strftime function of your OSs clibrary. This means that
 the conversion specifier may vary. Check the manual page if you are uncertain. The following is a list of
 conversion specifiers usually supported across the board. 
 
-B<%a> - The abbreviated weekday name according to the current locale.
+=over 4
+
+=item B<%a>
+
+The abbreviated weekday name according to the current locale.
+
+=item B<%A>
+
+The full weekday name according to the current locale.
 
-B<%A> - The full weekday name according to the current locale.
+=item B<%b>
 
-B<%b> - The abbreviated month name according to the current locale.
+The abbreviated month name according to the current locale.
 
-B<%B> - The full month name according to the current locale.
+=item B<%B>
 
-B<%c> - The preferred date and time representation for the current locale.
+The full month name according to the current locale.
 
-B<%d> - The day of the month as a decimal number (range 01 to 31).
+=item B<%c>
 
-B<%H> - The hour as a decimal number using a 24-hour clock (range 00 to 23).
+The preferred date and time representation for the current locale.
 
-B<%I> - The hour as a decimal number using a 12-hour clock (range 01 to 12).
+=item B<%d>
 
-B<%j> - The day of the year as a decimal number (range 001 to 366).
+The day of the month as a decimal number (range 01 to 31).
 
-B<%m> - The month as a decimal number (range 01 to 12).
+=item B<%H>
 
-B<%M> - The minute as a decimal number (range 00 to 59).
+The hour as a decimal number using a 24-hour clock (range 00 to 23).
 
-B<%p> - Either `AM' or `PM' according to the given time value, or the corresponding
+=item B<%I>
+
+The hour as a decimal number using a 12-hour clock (range 01 to 12).
+
+=item B<%j>
+
+The day of the year as a decimal number (range 001 to 366).
+
+=item B<%m>
+
+The month as a decimal number (range 01 to 12).
+
+=item B<%M>
+
+The minute as a decimal number (range 00 to 59).
+
+=item B<%p>
+
+Either `AM' or `PM' according to the given time value, or the corresponding
 strings for the current locale.  Noon is treated as `pm' and midnight as
 `am'.  Note that in many locales and `pm' notation is unsupported and in
 such cases %p will return an empty string.
 
-B<%S> - The second as a decimal number (range 00 to 61).
+=item B<%S>
+
+The second as a decimal number (range 00 to 61).
+
+=item B<%U>
 
-B<%U> - The  week  number  of  the current year as a decimal number, range 00 to 53, starting with the
+The  week  number  of  the current year as a decimal number, range 00 to 53, starting with the
 first Sunday as the first day of week 01. See also %V and %W.
 
-B<%V> - The ISO 8601:1988 week number of the current year as a decimal number, range 01 to  53,  where
+=item B<%V>
+
+The ISO 8601:1988 week number of the current year as a decimal number, range 01 to  53,  where
 week  1 is the first week that has at least 4 days in the current year, and with Monday as the
 first day of the week. See also %U and %W.
 
-B<%w> - The day of the week as a decimal, range 0 to 6, Sunday being 0.  See also %u.
+=item B<%w>
+
+The day of the week as a decimal, range 0 to 6, Sunday being 0.  See also %u.
+
+=item B<%W>
 
-B<%W> - The week number of the current year as a decimal number, range 00 to  53,  starting  with  the
+The week number of the current year as a decimal number, range 00 to  53,  starting  with  the
 first Monday as the first day of week 01.
 
-B<%x> - The preferred date representation for the current locale without the time.
+=item B<%x>
 
-B<%X> - The preferred time representation for the current locale without the date.
+The preferred date representation for the current locale without the time.
 
-B<%y> - The year as a decimal number without a century (range 00 to 99).
+=item B<%X>
 
-B<%Y> - The year as a decimal number including the century.
+The preferred time representation for the current locale without the date.
 
-B<%Z> - The time zone or name or abbreviation.
+=item B<%y>
 
-B<%%> - A literal `%' character.
+The year as a decimal number without a century (range 00 to 99).
+
+=item B<%Y>
+
+The year as a decimal number including the century.
+
+=item B<%Z>
+
+The time zone or name or abbreviation.
+
+=item B<%%>
+
+A literal `%' character.
+
+=back
 
 =item B<PRINT:>I<vname>B<:>I<CF>B<:>I<format>
 
@@ -135,9 +202,9 @@ The first form of this command is to be used with B<CDEF> I<vname>s.
 
 =back
 
-=head2 GRAPH
+=head1 GRAPH
 
-=over
+=over 4
 
 =item B<GPRINT>B<:>I<vname>B<:>I<format>
 
@@ -154,21 +221,23 @@ Text is printed literally in the legend section of the graph. Note that in
 RRDtool 1.2 you have to escape colons in COMMENT text in the same way you
 have to escape them in B<*PRINT> commands by writing B<'\:'>.
 
-=item B<VRULE>B<:>I<time>B<#>I<color> [B<:>I<legend> ]
+=item B<VRULE>B<:>I<time>B<#>I<color>[B<:>I<legend>][B<:dashes>[B<=>I<on_s>[,I<off_s>[,I<on_s>,I<off_s>]...]][B<:dash-offset=>I<offset>]]
 
 Draw a vertical line at I<time>.  Its color is composed from three
 hexadecimal numbers specifying the rgb color components (00 is off, FF is
 maximum) red, green and blue followed by an optional alpha. Optionally, a legend box and string is
 printed in the legend section. I<time> may be a number or a variable
 from a B<VDEF>. It is an error to use I<vname>s from B<DEF> or B<CDEF> here.
+Dashed lines can be drawn using the B<dashes> modifier. See B<LINE> for more
+details.
 
-=item B<HRULE>B<:>I<value>B<#>I<color> [ :I<legend> ]
+=item B<HRULE>B<:>I<value>B<#>I<color>[B<:>I<legend>][B<:dashes>[B<=>I<on_s>[,I<off_s>[,I<on_s>,I<off_s>]...]][B<:dash-offset=>I<offset>]]
 
 Draw a horizontal line at I<value>.  HRULE acts much like LINE except that
 will have no effect on the scale of the graph. If a HRULE is outside the
 graphing area it will just not be visible.
 
-=item B<LINE>[I<width>]B<:>I<value>[B<#>I<color>][B<:>[I<legend>][B<:STACK>]]
+=item B<LINE>[I<width>]B<:>I<value>[B<#>I<color>][B<:>[I<legend>][B<:STACK>]][B<:dashes>[B<=>I<on_s>[,I<off_s>[,I<on_s>,I<off_s>]...]][B<:dash-offset=>I<offset>]]
 
 Draw a line of the specified width onto the graph. I<width> can be a
 floating point number. If the color is not specified, the drawing is done
@@ -179,6 +248,14 @@ B<VDEF>, and B<CDEF>.  If the optional B<STACK> modifier is used, this line
 is stacked on top of the previous element which can be a B<LINE> or an
 B<AREA>.
 
+The B<dashes> modifier enables dashed line style. Without any further options
+a symmetric dashed line with a segment length of 5 pixels will be drawn. The
+dash pattern can be changed if the B<dashes=> parameter is followed by either
+one value or an even number (1, 2, 4, 6, ...) of positive values. Each value
+provides the length of alternate I<on_s> and I<off_s> portions of the
+stroke. The B<dash-offset> parameter specifies an I<offset> into the pattern
+at which the stroke begins.
+
 When you do not specify a color, you cannot specify a legend.  Should
 you want to use STACK, use the "LINEx:<value>::STACK" form.
 
@@ -205,6 +282,36 @@ week. Make sure to tell the viewer of your graph you did this ...
 As with the other graphing elements, you can specify a number or
 a variable here.
 
+=item B<TEXTALIGN>B<:>{B<left>|B<right>|B<justified>|B<center>}
+
+Labels are placed below the graph. When they overflow to the left, they wrap
+to the next line. By default, lines are justified left and right. The
+B<TEXTALIGN> function lets you change this default. This is a command and
+not an option, so that you can change the default several times in your
+argument list.
+
+=cut
+
+# This section describes the curruently defunct
+# PieChart code.
+#
+# =item B<PART>B<:>I<vname>B<#>I<rrggbb>[I<aa>][B<:>I<legend>]
+#
+# B<RRDtool> has now support for B<pie charts>. If you include the
+# B<PART> command, the canvas is extended to make room for a chart.
+# The size of the canvas is determined by the lesser of
+# L<width and height|rrdgraph/item_Size>.
+#
+# Pie parts will be concatenated, the first one will start at the
+# top and parts will be created clockwise.  The size of the part
+# is defined by the value part of the L<VDEF|rrdgraph_data/VDEF>
+# function.  It should return a number between 0 and 100, being a
+# percentage.  Providing wrong input will produce undefined results.
+#
+#
+
+=pod
+
 =item B<STACK>B<:>I<vname>B<#>I<color>[B<:>I<legend>]
 
 I<Deprecated.  Use the B<STACK> modifiers on the other commands.>
@@ -267,6 +374,141 @@ characters or the sequence B<\t> to line-up legend elements. Note that
 the tabs inserted are relative to the start of the current legend
 element!
 
+Since RRDtool 1.3 is using Pango for rending text, you can use Pango markup.
+Pango uses the xml B<span> tags for inline formatting instructions.:
+
+A simple example of a marked-up string might be: 
+
+ <span foreground="blue" size="x-large">Blue text</span> is <i>cool</i>!
+
+The complete list of attributes for the span tag (taken from the pango documentation):
+
+=over
+
+=item B<font_desc>
+
+A font description string, such as "Sans Italic 12"; note that any other span attributes will override this description. So if you have "Sans Italic" and also a style="normal" attribute, you will get Sans normal, not italic.
+
+=item B<font_family>
+
+A font family name
+
+=item B<face>
+
+Synonym for font_family
+
+=item B<size>
+
+Font size in 1024ths of a point, or one of the absolute sizes 'xx-small', 'x-small', 'small', 'medium', 'large', 'x-large', 'xx-large', or one of the relative sizes 'smaller' or 'larger'. If you want to specify a absolute size, it's usually easier to take advantage of the ability to specify a partial font description using 'font_desc'; you can use font_desc='12.5' rather than size='12800'.
+
+=item B<style>
+
+One of 'normal', 'oblique', 'italic'
+
+=item B<weight>
+
+One of 'ultralight', 'light', 'normal', 'bold', 'ultrabold', 'heavy', or a numeric weight
+
+=item B<variant>
+
+'normal' or 'smallcaps'
+
+=item B<stretch>
+
+One of 'ultracondensed', 'extracondensed', 'condensed', 'semicondensed', 'normal', 'semiexpanded', 'expanded', 'extraexpanded', 'ultraexpanded'
+
+=item B<foreground>
+
+An RGB color specification such as '#00FF00' or a color name such as 'red'
+
+=item B<background>
+
+An RGB color specification such as '#00FF00' or a color name such as 'red'
+
+=item B<underline>
+
+One of 'none', 'single', 'double', 'low', 'error'
+
+=item B<underline_color>
+
+The color of underlines; an RGB color specification such as '#00FF00' or a color name such as 'red'
+
+=item B<rise>
+
+Vertical displacement, in 10000ths of an em. Can be negative for subscript, positive for superscript.
+
+=item B<strikethrough>
+
+'true' or 'false' whether to strike through the text
+
+=item B<strikethrough_color>
+
+The color of strikethrough lines; an RGB color specification such as '#00FF00' or a color name such as 'red'
+
+=item B<fallback>
+
+'true' or 'false' whether to enable fallback. If disabled, then characters will only be used from the closest matching font on the system. No fallback will be done to other fonts on the system that might contain the characters in the text. Fallback is enabled by default. Most applications should not disable fallback.
+
+=item B<lang>
+
+A language code, indicating the text language
+
+=item B<letter_spacing>
+
+Inter-letter spacing in 1024ths of a point.
+
+=item B<gravity>
+
+One of 'south', 'east', 'north', 'west', 'auto'.
+
+=item B<gravity_hint>
+
+One of 'natural', 'strong', 'line'.
+
+=back
+
+To save you some typing, there are also some shortcuts:
+
+=over
+
+=item B<b>
+
+Bold
+
+=item B<big>
+
+Makes font relatively larger, equivalent to <span size="larger">
+
+=item B<i>
+
+Italic
+
+=item B<s>
+
+Strikethrough
+
+=item B<sub>
+
+Subscript
+
+=item B<sup>
+
+Superscript
+
+=item B<small>
+
+Makes font relatively smaller, equivalent to <span size="smaller">
+
+=item B<tt>
+
+Monospace font
+
+=item B<u>
+
+Underline 
+
+=back
+
 =head1 SEE ALSO
 
 L<rrdgraph> gives an overview of how B<rrdtool graph> works.
index 800dcca6e79b3e6ad018559caaec01b2486793f8..2d5cd1e857ec65fac7065876ccdfef17ffeb2b4c 100644 (file)
@@ -12,11 +12,15 @@ S\bSY\bYN\bNO\bOP\bPS\bSI\bIS\bS
 
        C\bCO\bOM\bMM\bME\bEN\bNT\bT:\b:_\bt_\be_\bx_\bt
 
-       V\bVR\bRU\bUL\bLE\bE:\b:_\bt_\bi_\bm_\be#\b#_\bc_\bo_\bl_\bo_\br[:\b:_\bl_\be_\bg_\be_\bn_\bd]
+       V\bVR\bRU\bUL\bLE\bE:\b:_\bt_\bi_\bm_\be#\b#_\bc_\bo_\bl_\bo_\br[:\b:_\bl_\be_\bg_\b-
+       _\be_\bn_\bd][:\b:d\bda\bas\bsh\bhe\bes\bs[=\b=_\bo_\bn_\b__\bs[,_\bo_\bf_\bf_\b__\bs[,_\bo_\bn_\b__\bs,_\bo_\bf_\bf_\b__\bs]...]][:\b:d\bda\bas\bsh\bh-\b-o\bof\bff\bfs\bse\bet\bt=\b=_\bo_\bf_\bf_\bs_\be_\bt]]
 
-       H\bHR\bRU\bUL\bLE\bE:\b:_\bv_\ba_\bl_\bu_\be#\b#_\bc_\bo_\bl_\bo_\br[:\b:_\bl_\be_\bg_\be_\bn_\bd]
+       H\bHR\bRU\bUL\bLE\bE:\b:_\bv_\ba_\bl_\bu_\be#\b#_\bc_\bo_\bl_\bo_\br[:\b:_\bl_\be_\bg_\b-
+       _\be_\bn_\bd][:\b:d\bda\bas\bsh\bhe\bes\bs[=\b=_\bo_\bn_\b__\bs[,_\bo_\bf_\bf_\b__\bs[,_\bo_\bn_\b__\bs,_\bo_\bf_\bf_\b__\bs]...]][:\b:d\bda\bas\bsh\bh-\b-o\bof\bff\bfs\bse\bet\bt=\b=_\bo_\bf_\bf_\bs_\be_\bt]]
 
-       L\bLI\bIN\bNE\bE[_\bw_\bi_\bd_\bt_\bh]:\b:_\bv_\ba_\bl_\bu_\be[#\b#_\bc_\bo_\bl_\bo_\br][:\b:[_\bl_\be_\bg_\be_\bn_\bd][:\b:S\bST\bTA\bAC\bCK\bK]]
+       L\bLI\bIN\bNE\bE[_\bw_\bi_\bd_\bt_\bh]:\b:_\bv_\ba_\bl_\bu_\be[#\b#_\bc_\bo_\bl_\bo_\br][:\b:[_\bl_\be_\bg_\b-
+       _\be_\bn_\bd][:\b:S\bST\bTA\bAC\bCK\bK]][:\b:d\bda\bas\bsh\bhe\bes\bs[=\b=_\bo_\bn_\b__\bs[,_\bo_\bf_\bf_\b__\bs[,_\bo_\bn_\b__\bs,_\bo_\bf_\bf_\b__\bs]...]][:\b:d\bda\bas\bsh\bh-\b-o\bof\bff\bfs\bse\bet\bt=\b=_\bo_\bf_\bf_\b-
+       _\bs_\be_\bt]]
 
        A\bAR\bRE\bEA\bA:\b:_\bv_\ba_\bl_\bu_\be[#\b#_\bc_\bo_\bl_\bo_\br][:\b:[_\bl_\be_\bg_\be_\bn_\bd][:\b:S\bST\bTA\bAC\bCK\bK]]
 
@@ -24,6 +28,8 @@ S\bSY\bYN\bNO\bOP\bPS\bSI\bIS\bS
 
        S\bSH\bHI\bIF\bFT\bT:\b:_\bv_\bn_\ba_\bm_\be:\b:_\bo_\bf_\bf_\bs_\be_\bt
 
+       T\bTE\bEX\bXT\bTA\bAL\bLI\bIG\bGN\bN:\b:{l\ble\bef\bft\bt|r\bri\big\bgh\bht\bt|j\bju\bus\bst\bti\bif\bfi\bie\bed\bd|c\bce\ben\bnt\bte\ber\br}
+
        P\bPR\bRI\bIN\bNT\bT:\b:_\bv_\bn_\ba_\bm_\be:\b:_\bC_\bF:\b:_\bf_\bo_\br_\bm_\ba_\bt (deprecated)
 
        G\bGP\bPR\bRI\bIN\bNT\bT:\b:_\bv_\bn_\ba_\bm_\be:\b:_\bC_\bF:\b:_\bf_\bo_\br_\bm_\ba_\bt (deprecated)
@@ -35,9 +41,7 @@ D\bDE\bES\bSC\bCR\bRI\bIP\bPT\bTI\bIO\bON\bN
        don't use any graph elements, no graph is generated.  Similarly, no
        report is generated if you don't use print options.
 
-       P\bPR\bRI\bIN\bNT\bT
-
-
+P\bPR\bRI\bIN\bNT\bT
        P\bPR\bRI\bIN\bNT\bT:\b:_\bv_\bn_\ba_\bm_\be:\b:_\bf_\bo_\br_\bm_\ba_\bt[:\b:s\bst\btr\brf\bft\bti\bim\bme\be]
            Depending on the context, either the value component or the time
            component of a V\bVD\bDE\bEF\bF is printed using _\bf_\bo_\br_\bm_\ba_\bt. It is an error to
@@ -49,24 +53,26 @@ D\bDE\bES\bSC\bCR\bRI\bIP\bPT\bTI\bIO\bON\bN
 
            For printing values:
 
-           %\b%%\b- just prints a literal '%' character
+           %\b%%\b%  just prints a literal '%' character
 
-           %\b%#\b#.\b.#\b#l\ble\be - prints numbers like 1.2346e+04. The optional integers #
-           denote field width and decimal precision.
+           %\b%#\b#.\b.#\b#l\ble\be
+               prints numbers like 1.2346e+04. The optional integers # denote
+               field width and decimal precision.
 
-           %\b%#\b#.\b.#\b#l\blf\bf - prints numbers like 12345.6789, with optional field width
-           and precision.
+           %\b%#\b#.\b.#\b#l\blf\bf
+               prints numbers like 12345.6789, with optional field width and
+               precision.
 
-           %\b%s\b- place this after %\b%l\ble\be, %\b%l\blf\bf or %\b%l\blg\bg. This will be replaced by the
-           appropriate SI magnitude unit and the value will be scaled accord-
-           ingly (123456 -> 123.456 k).
+           %\b%s\bs  place this after %\b%l\ble\be, %\b%l\blf\bf or %\b%l\blg\bg. This will be replaced by the
+               appropriate SI magnitude unit and the value will be scaled
+               accordingly (123456 -> 123.456 k).
 
-           %\b%S\b- is similar to %\b%s\bs. It does, however, use a previously defined
-           magnitude unit. If there is no such unit yet, it tries to define
-           one (just like %\b%s\bs) unless the value is zero, in which case the
-           magnitude unit stays undefined. Thus, formatter strings using %\b%S\bS
-           and no %\b%s\bs will all use the same magnitude unit except for zero val-
-           ues.
+           %\b%S\bS  is similar to %\b%s\bs. It does, however, use a previously defined
+               magnitude unit. If there is no such unit yet, it tries to
+               define one (just like %\b%s\bs) unless the value is zero, in which
+               case the magnitude unit stays undefined. Thus, formatter
+               strings using %\b%S\bS and no %\b%s\bs will all use the same magnitude unit
+               except for zero values.
 
            If you PRINT a VDEF value, you can also print the time associated
            with it by appending the string :\b:s\bst\btr\brf\bft\bti\bim\bme\be to the format. Note that
@@ -75,77 +81,75 @@ D\bDE\bES\bSC\bCR\bRI\bIP\bPT\bTI\bIO\bON\bN
            you are uncertain. The following is a list of conversion specifiers
            usually supported across the board.
 
-           %\b%a\b- The abbreviated weekday name according to the current locale.
+           %\b%a\ba  The abbreviated weekday name according to the current locale.
 
-           %\b%A\b- The full weekday name according to the current locale.
+           %\b%A\bA  The full weekday name according to the current locale.
 
-           %\b%b\b- The abbreviated month name according to the current locale.
+           %\b%b\bb  The abbreviated month name according to the current locale.
 
-           %\b%B\b- The full month name according to the current locale.
+           %\b%B\bB  The full month name according to the current locale.
 
-           %\b%c\b- The preferred date and time representation for the current
-           locale.
+           %\b%c\bc  The preferred date and time representation for the current
+               locale.
 
-           %\b%d\b- The day of the month as a decimal number (range 01 to 31).
+           %\b%d\bd  The day of the month as a decimal number (range 01 to 31).
 
-           %\b%H\b- The hour as a decimal number using a 24-hour clock (range 00
-           to 23).
+           %\b%H\b The hour as a decimal number using a 24-hour clock (range 00 to
+               23).
 
-           %\b%I\b- The hour as a decimal number using a 12-hour clock (range 01
-           to 12).
+           %\b%I\b The hour as a decimal number using a 12-hour clock (range 01 to
+               12).
 
-           %\b%j\b- The day of the year as a decimal number (range 001 to 366).
+           %\b%j\bj  The day of the year as a decimal number (range 001 to 366).
 
-           %\b%m\b- The month as a decimal number (range 01 to 12).
+           %\b%m\bm  The month as a decimal number (range 01 to 12).
 
-           %\b%M\b- The minute as a decimal number (range 00 to 59).
+           %\b%M\bM  The minute as a decimal number (range 00 to 59).
 
-           %\b%p\b- Either `AM' or `PM' according to the given time value, or the
-           corresponding strings for the current locale.  Noon is treated as
-           `pm' and midnight as `am'.  Note that in many locales and `pm'
-           notation is unsupported and in such cases %p will return an empty
-           string.
+           %\b%p\bp  Either `AM' or `PM' according to the given time value, or the
+               corresponding strings for the current locale.  Noon is treated
+               as `pm' and midnight as `am'.  Note that in many locales and
+               `pm' notation is unsupported and in such cases %p will return
+               an empty string.
 
-           %\b%S\b- The second as a decimal number (range 00 to 61).
+           %\b%S\bS  The second as a decimal number (range 00 to 61).
 
-           %\b%U\b- The  week  number  of  the current year as a decimal number,
-           range 00 to 53, starting with the first Sunday as the first day of
-           week 01. See also %V and %W.
+           %\b%U\bU  The  week  number  of  the current year as a decimal number,
+               range 00 to 53, starting with the first Sunday as the first day
+               of week 01. See also %V and %W.
 
-           %\b%V\b- The ISO 8601:1988 week number of the current year as a decimal
-           number, range 01 to  53,  where week  1 is the first week that has
-           at least 4 days in the current year, and with Monday as the first
-           day of the week. See also %U and %W.
+           %\b%V\bV  The ISO 8601:1988 week number of the current year as a decimal
+               number, range 01 to  53,  where week  1 is the first week that
+               has at least 4 days in the current year, and with Monday as the
+               first day of the week. See also %U and %W.
 
-           %\b%w\b- The day of the week as a decimal, range 0 to 6, Sunday being
-           0.  See also %u.
+           %\b%w\b The day of the week as a decimal, range 0 to 6, Sunday being 0.
+               See also %u.
 
-           %\b%W\b- The week number of the current year as a decimal number, range
-           00 to  53,  starting  with  the first Monday as the first day of
-           week 01.
+           %\b%W\bW  The week number of the current year as a decimal number, range
+               00 to  53,  starting  with  the first Monday as the first day
+               of week 01.
 
-           %\b%x\b- The preferred date representation for the current locale with-
-           out the time.
+           %\b%x\bx  The preferred date representation for the current locale with-
+               out the time.
 
-           %\b%X\b- The preferred time representation for the current locale with-
-           out the date.
+           %\b%X\bX  The preferred time representation for the current locale with-
+               out the date.
 
-           %\b%y\b- The year as a decimal number without a century (range 00 to
-           99).
+           %\b%y\by  The year as a decimal number without a century (range 00 to
+               99).
 
-           %\b%Y\b- The year as a decimal number including the century.
+           %\b%Y\bY  The year as a decimal number including the century.
 
-           %\b%Z\b- The time zone or name or abbreviation.
+           %\b%Z\bZ  The time zone or name or abbreviation.
 
-           %\b%%\b- A literal `%' character.
+           %\b%%\b%  A literal `%' character.
 
        P\bPR\bRI\bIN\bNT\bT:\b:_\bv_\bn_\ba_\bm_\be:\b:_\bC_\bF:\b:_\bf_\bo_\br_\bm_\ba_\bt
            _\bD_\be_\bp_\br_\be_\bc_\ba_\bt_\be_\bd_\b. _\bU_\bs_\be _\bt_\bh_\be _\bn_\be_\bw _\bf_\bo_\br_\bm _\bo_\bf _\bt_\bh_\bi_\bs _\bc_\bo_\bm_\bm_\ba_\bn_\bd _\bi_\bn _\bn_\be_\bw _\bs_\bc_\br_\bi_\bp_\bt_\bs_\b.  The
            first form of this command is to be used with C\bCD\bDE\bEF\bF _\bv_\bn_\ba_\bm_\bes.
 
-       G\bGR\bRA\bAP\bPH\bH
-
-
+G\bGR\bRA\bAP\bPH\bH
        G\bGP\bPR\bRI\bIN\bNT\bT:\b:_\bv_\bn_\ba_\bm_\be:\b:_\bf_\bo_\br_\bm_\ba_\bt
            This is the same as "PRINT", but printed inside the graph.
 
@@ -159,20 +163,25 @@ D\bDE\bES\bSC\bCR\bRI\bIP\bPT\bTI\bIO\bON\bN
            the same way you have to escape them in *\b*P\bPR\bRI\bIN\bNT\bT commands by writing
            '\b'\\b\:\b:'\b'.
 
-       V\bVR\bRU\bUL\bLE\bE:\b:_\bt_\bi_\bm_\be#\b#_\bc_\bo_\bl_\bo_\br [:\b:_\bl_\be_\bg_\be_\bn_\bd ]
+       V\bVR\bRU\bUL\bLE\bE:\b:_\bt_\bi_\bm_\be#\b#_\bc_\bo_\bl_\bo_\br[:\b:_\bl_\be_\bg_\b-
+       _\be_\bn_\bd][:\b:d\bda\bas\bsh\bhe\bes\bs[=\b=_\bo_\bn_\b__\bs[,_\bo_\bf_\bf_\b__\bs[,_\bo_\bn_\b__\bs,_\bo_\bf_\bf_\b__\bs]...]][:\b:d\bda\bas\bsh\bh-\b-o\bof\bff\bfs\bse\bet\bt=\b=_\bo_\bf_\bf_\bs_\be_\bt]]
            Draw a vertical line at _\bt_\bi_\bm_\be.  Its color is composed from three
            hexadecimal numbers specifying the rgb color components (00 is off,
            FF is maximum) red, green and blue followed by an optional alpha.
            Optionally, a legend box and string is printed in the legend sec-
            tion. _\bt_\bi_\bm_\be may be a number or a variable from a V\bVD\bDE\bEF\bF. It is an
-           error to use _\bv_\bn_\ba_\bm_\bes from D\bDE\bEF\bF or C\bCD\bDE\bEF\bF here.
+           error to use _\bv_\bn_\ba_\bm_\bes from D\bDE\bEF\bF or C\bCD\bDE\bEF\bF here.  Dashed lines can be
+           drawn using the d\bda\bas\bsh\bhe\bes\bs modifier. See L\bLI\bIN\bNE\bE for more details.
 
-       H\bHR\bRU\bUL\bLE\bE:\b:_\bv_\ba_\bl_\bu_\be#\b#_\bc_\bo_\bl_\bo_\br [ :_\bl_\be_\bg_\be_\bn_\bd ]
+       H\bHR\bRU\bUL\bLE\bE:\b:_\bv_\ba_\bl_\bu_\be#\b#_\bc_\bo_\bl_\bo_\br[:\b:_\bl_\be_\bg_\b-
+       _\be_\bn_\bd][:\b:d\bda\bas\bsh\bhe\bes\bs[=\b=_\bo_\bn_\b__\bs[,_\bo_\bf_\bf_\b__\bs[,_\bo_\bn_\b__\bs,_\bo_\bf_\bf_\b__\bs]...]][:\b:d\bda\bas\bsh\bh-\b-o\bof\bff\bfs\bse\bet\bt=\b=_\bo_\bf_\bf_\bs_\be_\bt]]
            Draw a horizontal line at _\bv_\ba_\bl_\bu_\be.  HRULE acts much like LINE except
            that will have no effect on the scale of the graph. If a HRULE is
            outside the graphing area it will just not be visible.
 
-       L\bLI\bIN\bNE\bE[_\bw_\bi_\bd_\bt_\bh]:\b:_\bv_\ba_\bl_\bu_\be[#\b#_\bc_\bo_\bl_\bo_\br][:\b:[_\bl_\be_\bg_\be_\bn_\bd][:\b:S\bST\bTA\bAC\bCK\bK]]
+       L\bLI\bIN\bNE\bE[_\bw_\bi_\bd_\bt_\bh]:\b:_\bv_\ba_\bl_\bu_\be[#\b#_\bc_\bo_\bl_\bo_\br][:\b:[_\bl_\be_\bg_\b-
+       _\be_\bn_\bd][:\b:S\bST\bTA\bAC\bCK\bK]][:\b:d\bda\bas\bsh\bhe\bes\bs[=\b=_\bo_\bn_\b__\bs[,_\bo_\bf_\bf_\b__\bs[,_\bo_\bn_\b__\bs,_\bo_\bf_\bf_\b__\bs]...]][:\b:d\bda\bas\bsh\bh-\b-o\bof\bff\bfs\bse\bet\bt=\b=_\bo_\bf_\bf_\b-
+       _\bs_\be_\bt]]
            Draw a line of the specified width onto the graph. _\bw_\bi_\bd_\bt_\bh can be a
            floating point number. If the color is not specified, the drawing
            is done 'invisibly'. This is useful when stacking something else on
@@ -182,6 +191,15 @@ D\bDE\bES\bSC\bCR\bRI\bIP\bPT\bTI\bIO\bON\bN
            fier is used, this line is stacked on top of the previous element
            which can be a L\bLI\bIN\bNE\bE or an A\bAR\bRE\bEA\bA.
 
+           The d\bda\bas\bsh\bhe\bes\bs modifier enables dashed line style. Without any further
+           options a symmetric dashed line with a segment length of 5 pixels
+           will be drawn. The dash pattern can be changed if the d\bda\bas\bsh\bhe\bes\bs=\b=
+           parameter is followed by either one value or an even number (1, 2,
+           4, 6, ...) of positive values. Each value provides the length of
+           alternate _\bo_\bn_\b__\bs and _\bo_\bf_\bf_\b__\bs portions of the stroke. The d\bda\bas\bsh\bh-\b-o\bof\bff\bfs\bse\bet\bt
+           parameter specifies an _\bo_\bf_\bf_\bs_\be_\bt into the pattern at which the stroke
+           begins.
+
            When you do not specify a color, you cannot specify a legend.
            Should you want to use STACK, use the "LINEx:<value>::STACK" form.
 
@@ -206,6 +224,13 @@ D\bDE\bES\bSC\bCR\bRI\bIP\bPT\bTI\bIO\bON\bN
            other graphing elements, you can specify a number or a variable
            here.
 
+       T\bTE\bEX\bXT\bTA\bAL\bLI\bIG\bGN\bN:\b:{l\ble\bef\bft\bt|r\bri\big\bgh\bht\bt|j\bju\bus\bst\bti\bif\bfi\bie\bed\bd|c\bce\ben\bnt\bte\ber\br}
+           Labels are placed below the graph. When they overflow to the left,
+           they wrap to the next line. By default, lines are justified left
+           and right. The T\bTE\bEX\bXT\bTA\bAL\bLI\bIG\bGN\bN function lets you change this default.
+           This is a command and not an option, so that you can change the
+           default several times in your argument list.
+
        S\bST\bTA\bAC\bCK\bK:\b:_\bv_\bn_\ba_\bm_\be#\b#_\bc_\bo_\bl_\bo_\br[:\b:_\bl_\be_\bg_\be_\bn_\bd]
            _\bD_\be_\bp_\br_\be_\bc_\ba_\bt_\be_\bd_\b.  _\bU_\bs_\be _\bt_\bh_\be _\bS\bS_\bT\bT_\bA\bA_\bC\bC_\bK\bK _\bm_\bo_\bd_\bi_\bf_\bi_\be_\br_\bs _\bo_\bn _\bt_\bh_\be _\bo_\bt_\bh_\be_\br _\bc_\bo_\bm_\bm_\ba_\bn_\bd_\bs_\b.
 
@@ -263,6 +288,119 @@ N\bNO\bOT\bTE\bES\bS o\bon\bn l\ble\beg\bge\ben\bnd\bd a\bar\brg\bgu\bum\bme\ben\bnt\bts\bs
        characters or the sequence \\b\t\bt to line-up legend elements. Note that the
        tabs inserted are relative to the start of the current legend element!
 
+       Since RRDtool 1.3 is using Pango for rending text, you can use Pango
+       markup.  Pango uses the xml s\bsp\bpa\ban\bn tags for inline formatting instruc-
+       tions.:
+
+       A simple example of a marked-up string might be:
+
+        <span foreground="blue" size="x-large">Blue text</span> is <i>cool</i>!
+
+       The complete list of attributes for the span tag (taken from the pango
+       documentation):
+
+       f\bfo\bon\bnt\bt_\b_d\bde\bes\bsc\bc
+           A font description string, such as "Sans Italic 12"; note that any
+           other span attributes will override this description. So if you
+           have "Sans Italic" and also a style="normal" attribute, you will
+           get Sans normal, not italic.
+
+       f\bfo\bon\bnt\bt_\b_f\bfa\bam\bmi\bil\bly\by
+           A font family name
+
+       f\bfa\bac\bce\be
+           Synonym for font_family
+
+       s\bsi\biz\bze\be
+           Font size in 1024ths of a point, or one of the absolute sizes
+           'xx-small', 'x-small', 'small', 'medium', 'large', 'x-large',
+           'xx-large', or one of the relative sizes 'smaller' or 'larger'. If
+           you want to specify a absolute size, it's usually easier to take
+           advantage of the ability to specify a partial font description
+           using 'font_desc'; you can use font_desc='12.5' rather than
+           size='12800'.
+
+       s\bst\bty\byl\ble\be
+           One of 'normal', 'oblique', 'italic'
+
+       w\bwe\bei\big\bgh\bht\bt
+           One of 'ultralight', 'light', 'normal', 'bold', 'ultrabold',
+           'heavy', or a numeric weight
+
+       v\bva\bar\bri\bia\ban\bnt\bt
+           'normal' or 'smallcaps'
+
+       s\bst\btr\bre\bet\btc\bch\bh
+           One of 'ultracondensed', 'extracondensed', 'condensed', 'semicon-
+           densed', 'normal', 'semiexpanded', 'expanded', 'extraexpanded',
+           'ultraexpanded'
+
+       f\bfo\bor\bre\beg\bgr\bro\bou\bun\bnd\bd
+           An RGB color specification such as '#00FF00' or a color name such
+           as 'red'
+
+       b\bba\bac\bck\bkg\bgr\bro\bou\bun\bnd\bd
+           An RGB color specification such as '#00FF00' or a color name such
+           as 'red'
+
+       u\bun\bnd\bde\ber\brl\bli\bin\bne\be
+           One of 'none', 'single', 'double', 'low', 'error'
+
+       u\bun\bnd\bde\ber\brl\bli\bin\bne\be_\b_c\bco\bol\blo\bor\br
+           The color of underlines; an RGB color specification such as
+           '#00FF00' or a color name such as 'red'
+
+       r\bri\bis\bse\be
+           Vertical displacement, in 10000ths of an em. Can be negative for
+           subscript, positive for superscript.
+
+       s\bst\btr\bri\bik\bke\bet\bth\bhr\bro\bou\bug\bgh\bh
+           'true' or 'false' whether to strike through the text
+
+       s\bst\btr\bri\bik\bke\bet\bth\bhr\bro\bou\bug\bgh\bh_\b_c\bco\bol\blo\bor\br
+           The color of strikethrough lines; an RGB color specification such
+           as '#00FF00' or a color name such as 'red'
+
+       f\bfa\bal\bll\blb\bba\bac\bck\bk
+           'true' or 'false' whether to enable fallback. If disabled, then
+           characters will only be used from the closest matching font on the
+           system. No fallback will be done to other fonts on the system that
+           might contain the characters in the text. Fallback is enabled by
+           default. Most applications should not disable fallback.
+
+       l\bla\ban\bng\bg
+           A language code, indicating the text language
+
+       l\ble\bet\btt\bte\ber\br_\b_s\bsp\bpa\bac\bci\bin\bng\bg
+           Inter-letter spacing in 1024ths of a point.
+
+       g\bgr\bra\bav\bvi\bit\bty\by
+           One of 'south', 'east', 'north', 'west', 'auto'.
+
+       g\bgr\bra\bav\bvi\bit\bty\by_\b_h\bhi\bin\bnt\bt
+           One of 'natural', 'strong', 'line'.
+
+       To save you some typing, there are also some shortcuts:
+
+       b\bb   Bold
+
+       b\bbi\big\bg Makes font relatively larger, equivalent to <span size="larger">
+
+       i\bi   Italic
+
+       s\bs   Strikethrough
+
+       s\bsu\bub\bb Subscript
+
+       s\bsu\bup\bp Superscript
+
+       s\bsm\bma\bal\bll\bl
+           Makes font relatively smaller, equivalent to <span size="smaller">
+
+       t\btt\bt  Monospace font
+
+       u\bu   Underline
+
 S\bSE\bEE\bE A\bAL\bLS\bSO\bO
        rrdgraph gives an overview of how r\brr\brd\bdt\bto\boo\bol\bl g\bgr\bra\bap\bph\bh works.  rrdgraph_data
        describes D\bDE\bEF\bF,C\bCD\bDE\bEF\bF and V\bVD\bDE\bEF\bF in detail.  rrdgraph_rpn describes the R\bRP\bPN\bN
@@ -278,4 +416,4 @@ A\bAU\bUT\bTH\bHO\bOR\bR
 
 
 
-1.2.27                            2008-02-17                 RRDGRAPH_GRAPH(1)
+1.3rc4                            2008-03-15                 RRDGRAPH_GRAPH(1)
index a51f542b380098ba35e9fff84b15b54da9afa2bf..91daee45d14367fb8c4eb1170c16e94ccef7cc5a 100644 (file)
 .\" ========================================================================
 .\"
 .IX Title "RRDGRAPH_RPN 1"
-.TH RRDGRAPH_RPN 1 "2008-02-17" "1.2.27" "rrdtool"
+.TH RRDGRAPH_RPN 1 "2008-03-15" "1.3rc4" "rrdtool"
 .SH "NAME"
 rrdgraph_rpn \- About RPN Math in rrdtool graph
 .SH "SYNOPSIS"
@@ -191,6 +191,8 @@ otherwise the value popped second is pushed back. This does, indeed,
 mean that any value other than 0 is considered to be true.
 .Sp
 Example: \f(CW\*(C`A,B,C,IF\*(C'\fR should be read as \f(CW\*(C`if (A) then (B) else (C)\*(C'\fR
+.Sp
+\&\&
 .IP "Comparing values" 4
 .IX Item "Comparing values"
 \&\fB\s-1MIN\s0, \s-1MAX\s0\fR
@@ -213,12 +215,19 @@ will always return an \fIunknown\fR
 .Sp
 Example: \f(CW\*(C`CDEF:a=alpha,0,100,LIMIT\*(C'\fR will return \fIunknown\fR if
 alpha is lower than 0 or if it is higher than 100.
+.Sp
+\&\&
 .IP "Arithmetics" 4
 .IX Item "Arithmetics"
 \&\fB+, \-, *, /, %\fR
 .Sp
 Add, subtract, multiply, divide, modulo
 .Sp
+\&\fB\s-1ADDNAN\s0\fR
+.Sp
+NAN-safe addition. If one parameter is \s-1NAN/UNKNOWN\s0 it'll be treated as
+zero. If both parameters are \s-1NAN/UNKNOWN\s0, \s-1NAN/UNKNOWN\s0 will be returned.
+.Sp
 \&\fB\s-1SIN\s0, \s-1COS\s0, \s-1LOG\s0, \s-1EXP\s0, \s-1SQRT\s0\fR
 .Sp
 Sine and cosine (input in radians), log and exp (natural logarithm),
@@ -269,7 +278,7 @@ average, ignoring all \s-1UNKNOWN\s0 values in the process.
 .Sp
 Example: \f(CW\*(C`CDEF:x=a,b,c,d,4,AVG\*(C'\fR
 .Sp
-\&\fB\s-1TREND\s0\fR
+\&\fB\s-1TREND\s0, \s-1TRENDNAN\s0\fR
 .Sp
 Create a \*(L"sliding window\*(R" average of another data series.
 .Sp
@@ -295,6 +304,11 @@ average is essentially computed as shown here:
 \&     Value at sample (t1) will be the average between (t1\-delay) and (t1)
 \&     Value at sample (t2) will be the average between (t2\-delay) and (t2)
 .Ve
+.Sp
+\&\s-1TRENDNAN\s0 is \- in contrast to \s-1TREND\s0 \- NAN\-safe. If you use \s-1TREND\s0 and one 
+source value is \s-1NAN\s0 the complete sliding window is affected. The \s-1TRENDNAN\s0 
+operation ignores all NAN-values in a sliding window and computes the 
+average of the remaining values.
 .IP "Special values" 4
 .IX Item "Special values"
 \&\fB\s-1UNKN\s0\fR
@@ -352,6 +366,8 @@ in the examples section below on how to use this.
 .Sp
 Duplicate the top element, remove the top element, exchange the two
 top elements.
+.Sp
+\&\&
 .SH "VARIABLES"
 .IX Header "VARIABLES"
 These operators work only on \fB\s-1VDEF\s0\fR statements. Note that currently \s-1ONLY\s0 these work for \fB\s-1VDEF\s0\fR.
@@ -361,6 +377,11 @@ Return the corresponding value, \s-1MAXIMUM\s0 and \s-1MINIMUM\s0 also return
 the first occurrence of that value in the time component.
 .Sp
 Example: \f(CW\*(C`VDEF:avg=mydata,AVERAGE\*(C'\fR
+.IP "\s-1STDEV\s0" 4
+.IX Item "STDEV"
+Returns the standard deviation of the values.
+.Sp
+Example: \f(CW\*(C`VDEF:stdev=mydata,STDEV\*(C'\fR
 .IP "\s-1LAST\s0, \s-1FIRST\s0" 4
 .IX Item "LAST, FIRST"
 Return the last/first value including its time.  The time for
index a972313afc9ce6f654144cd929d415d9d6743b80..d5fccbbb015332149fb59920effe99d7c19f17f3 100644 (file)
@@ -99,6 +99,9 @@ mean that any value other than 0 is considered to be true.</p>
 <dd>
 <p>Example: <code>A,B,C,IF</code> should be read as <code>if (A) then (B) else (C)</code></p>
 </dd>
+<dd>
+<p></p>
+</dd>
 </li>
 <dt><strong><a name="item_comparing_values">Comparing values</a></strong>
 
@@ -129,6 +132,9 @@ will always return an <em>unknown</em></p>
 <p>Example: <code>CDEF:a=alpha,0,100,LIMIT</code> will return <em>unknown</em> if
 alpha is lower than 0 or if it is higher than 100.</p>
 </dd>
+<dd>
+<p></p>
+</dd>
 </li>
 <dt><strong><a name="item_arithmetics">Arithmetics</a></strong>
 
@@ -139,6 +145,13 @@ alpha is lower than 0 or if it is higher than 100.</p>
 <p>Add, subtract, multiply, divide, modulo</p>
 </dd>
 <dd>
+<p><strong>ADDNAN</strong></p>
+</dd>
+<dd>
+<p>NAN-safe addition. If one parameter is NAN/UNKNOWN it'll be treated as
+zero. If both parameters are NAN/UNKNOWN, NAN/UNKNOWN will be returned.</p>
+</dd>
+<dd>
 <p><strong>SIN, COS, LOG, EXP, SQRT</strong></p>
 </dd>
 <dd>
@@ -210,7 +223,7 @@ average, ignoring all UNKNOWN values in the process.</p>
 <p>Example: <code>CDEF:x=a,b,c,d,4,AVG</code></p>
 </dd>
 <dd>
-<p><strong>TREND</strong></p>
+<p><strong>TREND, TRENDNAN</strong></p>
 </dd>
 <dd>
 <p>Create a ``sliding window'' average of another data series.</p>
@@ -240,6 +253,12 @@ average is essentially computed as shown here:</p>
      Value at sample (t1) will be the average between (t1-delay) and (t1)
      Value at sample (t2) will be the average between (t2-delay) and (t2)</pre>
 </dd>
+<dd>
+<p>TRENDNAN is - in contrast to TREND - NAN-safe. If you use TREND and one 
+source value is NAN the complete sliding window is affected. The TRENDNAN 
+operation ignores all NAN-values in a sliding window and computes the 
+average of the remaining values.</p>
+</dd>
 </li>
 <dt><strong><a name="item_special_values">Special values</a></strong>
 
@@ -322,6 +341,9 @@ in the examples section below on how to use this.</p>
 <p>Duplicate the top element, remove the top element, exchange the two
 top elements.</p>
 </dd>
+<dd>
+<p></p>
+</dd>
 </li>
 </dl>
 <p>
@@ -340,6 +362,15 @@ the first occurrence of that value in the time component.</p>
 <p>Example: <code>VDEF:avg=mydata,AVERAGE</code></p>
 </dd>
 </li>
+<dt><strong><a name="item_stdev">STDEV</a></strong>
+
+<dd>
+<p>Returns the standard deviation of the values.</p>
+</dd>
+<dd>
+<p>Example: <code>VDEF:stdev=mydata,STDEV</code></p>
+</dd>
+</li>
 <dt><strong><a name="item_last_2c_first">LAST, FIRST</a></strong>
 
 <dd>
index 454f7367691a045fefa0ae1e1ce295d84eb5b299..aabd7383e43979ae6396d0fc210aa3c879a55563 100644 (file)
@@ -66,6 +66,8 @@ mean that any value other than 0 is considered to be true.
 
 Example: C<A,B,C,IF> should be read as C<if (A) then (B) else (C)>
 
+Z<>
+
 =item Comparing values
 
 B<MIN, MAX>
@@ -89,12 +91,19 @@ will always return an I<unknown>
 Example: C<CDEF:a=alpha,0,100,LIMIT> will return I<unknown> if
 alpha is lower than 0 or if it is higher than 100.
 
+Z<>
+
 =item Arithmetics
 
 B<+, -, *, /, %>
 
 Add, subtract, multiply, divide, modulo
 
+B<ADDNAN>
+
+NAN-safe addition. If one parameter is NAN/UNKNOWN it'll be treated as
+zero. If both parameters are NAN/UNKNOWN, NAN/UNKNOWN will be returned.
+
 B<SIN, COS, LOG, EXP, SQRT>
 
 Sine and cosine (input in radians), log and exp (natural logarithm),
@@ -146,7 +155,7 @@ average, ignoring all UNKNOWN values in the process.
 
 Example: C<CDEF:x=a,b,c,d,4,AVG>
 
-B<TREND>
+B<TREND, TRENDNAN>
 
 Create a "sliding window" average of another data series.
 
@@ -170,6 +179,12 @@ average is essentially computed as shown here:
      Value at sample (t1) will be the average between (t1-delay) and (t1)
      Value at sample (t2) will be the average between (t2-delay) and (t2)
 
+TRENDNAN is - in contrast to TREND - NAN-safe. If you use TREND and one 
+source value is NAN the complete sliding window is affected. The TRENDNAN 
+operation ignores all NAN-values in a sliding window and computes the 
+average of the remaining values.
+
+
 =item Special values
 
 B<UNKN>
@@ -230,6 +245,8 @@ B<DUP, POP, EXC>
 Duplicate the top element, remove the top element, exchange the two
 top elements.
 
+Z<>
+
 =back
 
 =head1 VARIABLES
@@ -245,6 +262,12 @@ the first occurrence of that value in the time component.
 
 Example: C<VDEF:avg=mydata,AVERAGE>
 
+=item STDEV
+
+Returns the standard deviation of the values.
+
+Example: C<VDEF:stdev=mydata,STDEV>
+
 =item LAST, FIRST
 
 Return the last/first value including its time.  The time for
index 5f022a444a91bd80ecd83d1e478471a3a1fa6625..8be61de7ca0d739256e2c19bc5bcefa3ecde40ae 100644 (file)
@@ -63,6 +63,8 @@ O\bOP\bPE\bER\bRA\bAT\bTO\bOR\bRS\bS
 
            Example: "A,B,C,IF" should be read as "if (A) then (B) else (C)"
 
+
+
        Comparing values
            M\bMI\bIN\bN,\b, M\bMA\bAX\bX
 
@@ -85,11 +87,19 @@ O\bOP\bPE\bER\bRA\bAT\bTO\bOR\bRS\bS
            Example: "CDEF:a=alpha,0,100,LIMIT" will return _\bu_\bn_\bk_\bn_\bo_\bw_\bn if alpha is
            lower than 0 or if it is higher than 100.
 
+
+
        Arithmetics
            +\b+,\b, -\b-,\b, *\b*,\b, /\b/,\b, %\b%
 
            Add, subtract, multiply, divide, modulo
 
+           A\bAD\bDD\bDN\bNA\bAN\bN
+
+           NAN-safe addition. If one parameter is NAN/UNKNOWN it'll be treated
+           as zero. If both parameters are NAN/UNKNOWN, NAN/UNKNOWN will be
+           returned.
+
            S\bSI\bIN\bN,\b, C\bCO\bOS\bS,\b, L\bLO\bOG\bG,\b, E\bEX\bXP\bP,\b, S\bSQ\bQR\bRT\bT
 
            Sine and cosine (input in radians), log and exp (natural loga-
@@ -139,7 +149,7 @@ O\bOP\bPE\bER\bRA\bAT\bTO\bOR\bRS\bS
 
            Example: "CDEF:x=a,b,c,d,4,AVG"
 
-           T\bTR\bRE\bEN\bND\bD
+           T\bTR\bRE\bEN\bND\bD,\b, T\bTR\bRE\bEN\bND\bDN\bNA\bAN\bN
 
            Create a "sliding window" average of another data series.
 
@@ -161,6 +171,11 @@ O\bOP\bPE\bER\bRA\bAT\bTO\bOR\bRS\bS
                 Value at sample (t1) will be the average between (t1-delay) and (t1)
                 Value at sample (t2) will be the average between (t2-delay) and (t2)
 
+           TRENDNAN is - in contrast to TREND - NAN-safe. If you use TREND and
+           one source value is NAN the complete sliding window is affected.
+           The TRENDNAN operation ignores all NAN-values in a sliding window
+           and computes the average of the remaining values.
+
        Special values
            U\bUN\bNK\bKN\bN
 
@@ -219,6 +234,8 @@ O\bOP\bPE\bER\bRA\bAT\bTO\bOR\bRS\bS
            Duplicate the top element, remove the top element, exchange the two
            top elements.
 
+
+
 V\bVA\bAR\bRI\bIA\bAB\bBL\bLE\bES\bS
        These operators work only on V\bVD\bDE\bEF\bF statements. Note that currently ONLY
        these work for V\bVD\bDE\bEF\bF.
@@ -229,6 +246,11 @@ V\bVA\bAR\bRI\bIA\bAB\bBL\bLE\bES\bS
 
            Example: "VDEF:avg=mydata,AVERAGE"
 
+       STDEV
+           Returns the standard deviation of the values.
+
+           Example: "VDEF:stdev=mydata,STDEV"
+
        LAST, FIRST
            Return the last/first value including its time.  The time for FIRST
            is actually the start of the corresponding interval, whereas LAST
@@ -284,4 +306,4 @@ A\bAU\bUT\bTH\bHO\bOR\bR
 
 
 
-1.2.27                            2008-02-17                   RRDGRAPH_RPN(1)
+1.3rc4                            2008-03-15                   RRDGRAPH_RPN(1)
index bab666fa6e0a6fa43ead3f96a79ca6f32e723703..d4f8573dad8e16a57cf8931cbf7f9728549050e4 100644 (file)
 .\" ========================================================================
 .\"
 .IX Title "RRDINFO 1"
-.TH RRDINFO 1 "2008-02-17" "1.2.27" "rrdtool"
+.TH RRDINFO 1 "2008-03-15" "1.3rc4" "rrdtool"
 .SH "NAME"
 rrdinfo \- extract header information from an RRD
 .SH "SYNOPSIS"
index e6a173114f13381be267c09d08ef862d4adfe54d..4f733f1cd9c552faead80452c6520d29a3d320ae 100644 (file)
@@ -55,4 +55,4 @@ A\bAU\bUT\bTH\bHO\bOR\bR
 
 
 
-1.2.27                            2008-02-17                        RRDINFO(1)
+1.3rc4                            2008-03-15                        RRDINFO(1)
index 41191397a0123d397d661904756e0a0ff37c16c2..e62dde7bf0f72ee1bbf51cf90541f4626bdc8510 100644 (file)
 .\" ========================================================================
 .\"
 .IX Title "RRDLAST 1"
-.TH RRDLAST 1 "2008-02-17" "1.2.27" "rrdtool"
+.TH RRDLAST 1 "2008-03-15" "1.3rc4" "rrdtool"
 .SH "NAME"
 rrdlast \- Return the date of the last data sample in an RRD
 .SH "SYNOPSIS"
index 14e28a3310d0b4c40b0ad12706b59def9e2e2d43..202d82dd8a62bd77eaf9a3d4ae045192d9671728 100644 (file)
@@ -20,4 +20,4 @@ A\bAU\bUT\bTH\bHO\bOR\bR
 
 
 
-1.2.27                            2008-02-17                        RRDLAST(1)
+1.3rc4                            2008-03-15                        RRDLAST(1)
index 4d1a19d4b9d00fca58033782d4f3861923fd86e6..39f49f00075a386b7334a7552cc7c854cc6dd42d 100644 (file)
 .\" ========================================================================
 .\"
 .IX Title "RRDLASTUPDATE 1"
-.TH RRDLASTUPDATE 1 "2008-02-17" "1.2.27" "rrdtool"
+.TH RRDLASTUPDATE 1 "2008-03-15" "1.3rc4" "rrdtool"
 .SH "NAME"
 rrdlastupdate \- Return the most recent update to an RRD
 .SH "SYNOPSIS"
index 70b5e863b4be4bff60260960e98927574d828a3d..c5332234aae2b26bfb28fe9e85dec7cec130bcc6 100644 (file)
@@ -20,4 +20,4 @@ A\bAU\bUT\bTH\bHO\bOR\bR
 
 
 
-1.2.27                            2008-02-17                  RRDLASTUPDATE(1)
+1.3rc4                            2008-03-15                  RRDLASTUPDATE(1)
index 2ad3df2c14b1a47304183d830911a826f2225cd6..101dd5d612475c7e21b86a0c019d3ffdc9efdf73 100644 (file)
 .\" ========================================================================
 .\"
 .IX Title "RRDRESIZE 1"
-.TH RRDRESIZE 1 "2008-02-17" "1.2.27" "rrdtool"
+.TH RRDRESIZE 1 "2008-03-15" "1.3rc4" "rrdtool"
 .SH "NAME"
 rrdresize \- alters the size of an RRA and creates a new .rrd file
 .SH "SYNOPSIS"
index 817090ec8d3e27a6fe2029029422a63c30f182fb..e9f7a8be1d6a0c339f3d746cd09368c14438b5d3 100644 (file)
@@ -41,4 +41,4 @@ A\bAU\bUT\bTH\bHO\bOR\bR
 
 
 
-1.2.27                            2008-02-17                      RRDRESIZE(1)
+1.3rc4                            2008-03-15                      RRDRESIZE(1)
index fcd8455e4e39ccc1a477f9f197a595c2210eb713..379de767d5a16643b98e4ce7d2b664f7e587ce2d 100644 (file)
 .\" ========================================================================
 .\"
 .IX Title "RRDRESTORE 1"
-.TH RRDRESTORE 1 "2008-02-17" "1.2.27" "rrdtool"
+.TH RRDRESTORE 1 "2008-03-15" "1.3rc4" "rrdtool"
 .SH "NAME"
 rrdrestore \- Restore the contents of an RRD from its XML dump format
 .SH "SYNOPSIS"
index 49abd7690655e592f82c13f0b251c92209084366..ba1d3bf8f225a02c437f5410f2ea34eac2dc5f1e 100644 (file)
@@ -30,4 +30,4 @@ A\bAU\bUT\bTH\bHO\bOR\bR
 
 
 
-1.2.27                            2008-02-17                     RRDRESTORE(1)
+1.3rc4                            2008-03-15                     RRDRESTORE(1)
index d3b496e322b62d72183ff4057e5715dd4be0936d..f9baa9ad2e78eec75d96730f2cfadaa053093d7c 100644 (file)
 .\" ========================================================================
 .\"
 .IX Title "RRDTHREADS 1"
-.TH RRDTHREADS 1 "2008-02-17" "1.2.27" "rrdtool"
+.TH RRDTHREADS 1 "2008-03-15" "1.3rc4" "rrdtool"
 .SH "NAME"
 rrdthreads \- Provisions for linking the RRD library to use in multi\-threaded programs
 .SH "SYNOPSIS"
index 86adb3a59cdbbf43176fc1714a1c1bf3a737be61..b15343b2ae9a2b2c03c342077cc94973733a0a9d 100644 (file)
@@ -100,4 +100,4 @@ A\bAU\bUT\bTH\bHO\bOR\bR
 
 
 
-1.2.27                            2008-02-17                     RRDTHREADS(1)
+1.3rc4                            2008-03-15                     RRDTHREADS(1)
index 4d20cc898ec9bc6041834efffb00030272eeea3b..d19a2e9e10cd8930d28fc7994b80942cfcd01947 100644 (file)
 .\" ========================================================================
 .\"
 .IX Title "RRDTOOL 1"
-.TH RRDTOOL 1 "2008-02-17" "1.2.27" "rrdtool"
+.TH RRDTOOL 1 "2008-03-15" "1.3rc4" "rrdtool"
 .SH "NAME"
 rrdtool \- Round Robin Database Tool
 .SH "SYNOPSIS"
index 3e986ac73e196fc8ac19e57b0e6fc56f2cac3ab3..72999a0fcfa628094acad6ae638a7be7d0d1b250 100644 (file)
@@ -273,4 +273,4 @@ A\bAU\bUT\bTH\bHO\bOR\bR
 
 
 
-1.2.27                            2008-02-17                        RRDTOOL(1)
+1.3rc4                            2008-03-15                        RRDTOOL(1)
index a961ee86f35fd7dfa7bfbcd62628d59b91ae73aa..c3a3fd86febf17afe97353b343b7200876235553 100644 (file)
 .\" ========================================================================
 .\"
 .IX Title "RRDTUNE 1"
-.TH RRDTUNE 1 "2008-02-17" "1.2.27" "rrdtool"
+.TH RRDTUNE 1 "2008-03-15" "1.3rc4" "rrdtool"
 .SH "NAME"
 rrdtune \- Modify some basic properties of a Round Robin Database
 .SH "SYNOPSIS"
@@ -148,6 +148,8 @@ rrdtune \- Modify some basic properties of a Round Robin Database
 [\fB\-\-beta\fR\ \fIadaption-parameter\fR]
 [\fB\-\-gamma\fR\ \fIadaption-parameter\fR]
 [\fB\-\-gamma\-deviation\fR\ \fIadaption-parameter\fR]
+[\fB\-\-smoothing\-window\fR\ \fIfraction-of-season\fR]
+[\fB\-\-smoothing\-window\-deviation\fR\ \fIfraction-of-season\fR]
 [\fB\-\-aberrant\-reset\fR\ \fIds-name\fR]
 .SH "DESCRIPTION"
 .IX Header "DESCRIPTION"
@@ -229,18 +231,27 @@ Alter the seasonal coefficient adaptation parameter for the \s-1SEASONAL\s0
 .IX Item "--gamma-deviationadaption-parameter"
 Alter the seasonal deviation adaptation parameter for the \s-1DEVSEASONAL\s0
 \&\fB\s-1RRA\s0\fR. This parameter must be between 0 and 1.
+.IP "\fB\-\-smoothing\-window\fR\ \fIfraction-of-season\fR" 8
+.IX Item "--smoothing-windowfraction-of-season"
+Alter the size of the smoothing window for the \s-1SEASONAL\s0 \fB\s-1RRA\s0\fR. This must
+be between 0 and 1.
+.IP "\fB\-\-smoothing\-window\-deviation\fR\ \fIfraction-of-season\fR" 8
+.IX Item "--smoothing-window-deviationfraction-of-season"
+Alter the size of the smoothing window for the \s-1DEVSEASONAL\s0 \fB\s-1RRA\s0\fR. This must
+be between 0 and 1.
 .IP "\fB\-\-aberrant\-reset\fR\ \fIds-name\fR" 8
 .IX Item "--aberrant-resetds-name"
 This option causes the aberrant behavior detection algorithm to reset
 for the specified data source; that is, forget all it is has learnt so far.
-Specifically, for the \s-1HWPREDICT\s0 \fB\s-1RRA\s0\fR, it sets the intercept and slope
-coefficients to unknown. For the \s-1SEASONAL\s0 \fB\s-1RRA\s0\fR, it sets all seasonal
+Specifically, for the \s-1HWPREDICT\s0 or \s-1MHWPREDICT\s0 \fB\s-1RRA\s0\fR, it sets the intercept and
+slope coefficients to unknown. For the \s-1SEASONAL\s0 \fB\s-1RRA\s0\fR, it sets all seasonal
 coefficients to unknown. For the \s-1DEVSEASONAL\s0 \fB\s-1RRA\s0\fR, it sets all seasonal
-deviation coefficients to unknown. For the \s-1FAILURES\s0 \fB\s-1RRA\s0\fR, it erases
-the violation history. Note that reset does not erase past predictions
-(the values of the \s-1HWPREDICT\s0 \fB\s-1RRA\s0\fR), predicted deviations (the values of the
-\&\s-1DEVPREDICT\s0 \fB\s-1RRA\s0\fR), or failure history (the values of the \s-1FAILURES\s0 \fB\s-1RRA\s0\fR).
-This option will function even if not all the listed \fBRRAs\fR are present.
+deviation coefficients to unknown. For the \s-1FAILURES\s0 \fB\s-1RRA\s0\fR, it erases the
+violation history. Note that reset does not erase past predictions
+(the values of the \s-1HWPREDICT\s0 or \s-1MHWPREDICT\s0 \fB\s-1RRA\s0\fR), predicted deviations (the
+values of the \s-1DEVPREDICT\s0 \fB\s-1RRA\s0\fR), or failure history (the values of the 
+\&\s-1FAILURES\s0 \fB\s-1RRA\s0\fR).  This option will function even if not all the listed 
+\&\fBRRAs\fR are present.
 .Sp
 Due to the implementation of this option, there is an indirect impact on
 other data sources in the \s-1RRD\s0. A smoothing algorithm is applied to
index 59925ff366177cbd23ca507a497df5a0c03407b3..7bd6cce32e49890ee45cf740b914e0b4fe8e049c 100644 (file)
@@ -47,6 +47,8 @@
 [<strong>--beta</strong>&nbsp;<em>adaption-parameter</em>]
 [<strong>--gamma</strong>&nbsp;<em>adaption-parameter</em>]
 [<strong>--gamma-deviation</strong>&nbsp;<em>adaption-parameter</em>]
+[<strong>--smoothing-window</strong>&nbsp;<em>fraction-of-season</em>]
+[<strong>--smoothing-window-deviation</strong>&nbsp;<em>fraction-of-season</em>]
 [<strong>--aberrant-reset</strong>&nbsp;<em>ds-name</em>]</p>
 <p>
 </p>
@@ -171,19 +173,34 @@ algorithm. This parameter must be between 0 and 1.</p>
 <strong>RRA</strong>. This parameter must be between 0 and 1.</p>
 </dd>
 </li>
+<dt><strong><a name="item__2d_2dsmoothing_2dwindow_fraction_2dof_2dseason"><strong>--smoothing-window</strong>&nbsp;<em>fraction-of-season</em></a></strong>
+
+<dd>
+<p>Alter the size of the smoothing window for the SEASONAL <strong>RRA</strong>. This must
+be between 0 and 1.</p>
+</dd>
+</li>
+<dt><strong><a name="item__2d_2dsmoothing_2dwindow_2ddeviation_fraction_2dof"><strong>--smoothing-window-deviation</strong>&nbsp;<em>fraction-of-season</em></a></strong>
+
+<dd>
+<p>Alter the size of the smoothing window for the DEVSEASONAL <strong>RRA</strong>. This must
+be between 0 and 1.</p>
+</dd>
+</li>
 <dt><strong><a name="item__2d_2daberrant_2dreset_ds_2dname"><strong>--aberrant-reset</strong>&nbsp;<em>ds-name</em></a></strong>
 
 <dd>
 <p>This option causes the aberrant behavior detection algorithm to reset
 for the specified data source; that is, forget all it is has learnt so far.
-Specifically, for the HWPREDICT <strong>RRA</strong>, it sets the intercept and slope
-coefficients to unknown. For the SEASONAL <strong>RRA</strong>, it sets all seasonal
+Specifically, for the HWPREDICT or MHWPREDICT <strong>RRA</strong>, it sets the intercept and
+slope coefficients to unknown. For the SEASONAL <strong>RRA</strong>, it sets all seasonal
 coefficients to unknown. For the DEVSEASONAL <strong>RRA</strong>, it sets all seasonal
-deviation coefficients to unknown. For the FAILURES <strong>RRA</strong>, it erases
-the violation history. Note that reset does not erase past predictions
-(the values of the HWPREDICT <strong>RRA</strong>), predicted deviations (the values of the
-DEVPREDICT <strong>RRA</strong>), or failure history (the values of the FAILURES <strong>RRA</strong>).
-This option will function even if not all the listed <strong>RRAs</strong> are present.</p>
+deviation coefficients to unknown. For the FAILURES <strong>RRA</strong>, it erases the
+violation history. Note that reset does not erase past predictions
+(the values of the HWPREDICT or MHWPREDICT <strong>RRA</strong>), predicted deviations (the
+values of the DEVPREDICT <strong>RRA</strong>), or failure history (the values of the 
+FAILURES <strong>RRA</strong>).  This option will function even if not all the listed 
+<strong>RRAs</strong> are present.</p>
 </dd>
 <dd>
 <p>Due to the implementation of this option, there is an indirect impact on
index 5e9029bf12a2772a4267c249262645e59fee2e7b..859c14345f407d7c77f6813fc9dd8de8b7071074 100644 (file)
@@ -18,6 +18,8 @@ S<[B<--alpha> I<adaption-parameter>]>
 S<[B<--beta> I<adaption-parameter>]>
 S<[B<--gamma> I<adaption-parameter>]>
 S<[B<--gamma-deviation> I<adaption-parameter>]>
+S<[B<--smoothing-window> I<fraction-of-season>]>
+S<[B<--smoothing-window-deviation> I<fraction-of-season>]>
 S<[B<--aberrant-reset> I<ds-name>]>
 
 =head1 DESCRIPTION
@@ -117,18 +119,29 @@ B<RRA>. This parameter must be between 0 and 1.
 Alter the seasonal deviation adaptation parameter for the DEVSEASONAL
 B<RRA>. This parameter must be between 0 and 1.
 
+=item S<B<--smoothing-window> I<fraction-of-season>>
+
+Alter the size of the smoothing window for the SEASONAL B<RRA>. This must
+be between 0 and 1.
+
+=item S<B<--smoothing-window-deviation> I<fraction-of-season>>
+
+Alter the size of the smoothing window for the DEVSEASONAL B<RRA>. This must
+be between 0 and 1.
+
 =item S<B<--aberrant-reset> I<ds-name>>
 
 This option causes the aberrant behavior detection algorithm to reset
 for the specified data source; that is, forget all it is has learnt so far.
-Specifically, for the HWPREDICT B<RRA>, it sets the intercept and slope
-coefficients to unknown. For the SEASONAL B<RRA>, it sets all seasonal
+Specifically, for the HWPREDICT or MHWPREDICT B<RRA>, it sets the intercept and
+slope coefficients to unknown. For the SEASONAL B<RRA>, it sets all seasonal
 coefficients to unknown. For the DEVSEASONAL B<RRA>, it sets all seasonal
-deviation coefficients to unknown. For the FAILURES B<RRA>, it erases
-the violation history. Note that reset does not erase past predictions
-(the values of the HWPREDICT B<RRA>), predicted deviations (the values of the
-DEVPREDICT B<RRA>), or failure history (the values of the FAILURES B<RRA>).
-This option will function even if not all the listed B<RRAs> are present.
+deviation coefficients to unknown. For the FAILURES B<RRA>, it erases the
+violation history. Note that reset does not erase past predictions
+(the values of the HWPREDICT or MHWPREDICT B<RRA>), predicted deviations (the
+values of the DEVPREDICT B<RRA>), or failure history (the values of the 
+FAILURES B<RRA>).  This option will function even if not all the listed 
+B<RRAs> are present.
 
 Due to the implementation of this option, there is an indirect impact on
 other data sources in the RRD. A smoothing algorithm is applied to
index 0ce504666de1d35b164a71e40a983375b57a0b30..2d6d9e94a04626050abc019218562c045bdf7eed 100644 (file)
@@ -12,8 +12,9 @@ S\bSY\bYN\bNO\bOP\bPS\bSI\bIS\bS
        _\bn_\ba_\bm_\be:_\bn_\be_\bw_\b-_\bn_\ba_\bm_\be] [-\b--\b-d\bde\bel\blt\bta\bap\bpo\bos\bs _\bs_\bc_\ba_\bl_\be_\b-_\bv_\ba_\bl_\bu_\be] [-\b--\b-d\bde\bel\blt\bta\ban\bne\beg\bg _\bs_\bc_\ba_\bl_\be_\b-_\bv_\ba_\bl_\bu_\be]
        [-\b--\b-f\bfa\bai\bil\blu\bur\bre\be-\b-t\bth\bhr\bre\bes\bsh\bho\bol\bld\bd _\bf_\ba_\bi_\bl_\bu_\br_\be_\b-_\bt_\bh_\br_\be_\bs_\bh_\bo_\bl_\bd] [-\b--\b-w\bwi\bin\bnd\bdo\bow\bw-\b-l\ble\ben\bng\bgt\bth\bh _\bw_\bi_\bn_\bd_\bo_\bw_\b-_\bl_\be_\bn_\bg_\bt_\bh]
        [-\b--\b-a\bal\blp\bph\bha\ba _\ba_\bd_\ba_\bp_\bt_\bi_\bo_\bn_\b-_\bp_\ba_\br_\ba_\bm_\be_\bt_\be_\br] [-\b--\b-b\bbe\bet\bta\ba _\ba_\bd_\ba_\bp_\bt_\bi_\bo_\bn_\b-_\bp_\ba_\br_\ba_\bm_\be_\bt_\be_\br] [-\b--\b-g\bga\bam\bmm\bma\ba _\ba_\bd_\ba_\bp_\b-
-       _\bt_\bi_\bo_\bn_\b-_\bp_\ba_\br_\ba_\bm_\be_\bt_\be_\br] [-\b--\b-g\bga\bam\bmm\bma\ba-\b-d\bde\bev\bvi\bia\bat\bti\bio\bon\bn _\ba_\bd_\ba_\bp_\bt_\bi_\bo_\bn_\b-_\bp_\ba_\br_\ba_\bm_\be_\bt_\be_\br] [-\b--\b-a\bab\bbe\ber\br-\b-
-       r\bra\ban\bnt\bt-\b-r\bre\bes\bse\bet\bt _\bd_\bs_\b-_\bn_\ba_\bm_\be]
+       _\bt_\bi_\bo_\bn_\b-_\bp_\ba_\br_\ba_\bm_\be_\bt_\be_\br] [-\b--\b-g\bga\bam\bmm\bma\ba-\b-d\bde\bev\bvi\bia\bat\bti\bio\bon\bn _\ba_\bd_\ba_\bp_\bt_\bi_\bo_\bn_\b-_\bp_\ba_\br_\ba_\bm_\be_\bt_\be_\br] [-\b--\b-s\bsm\bmo\boo\bot\bth\bh-\b-
+       i\bin\bng\bg-\b-w\bwi\bin\bnd\bdo\bow\bw _\bf_\br_\ba_\bc_\bt_\bi_\bo_\bn_\b-_\bo_\bf_\b-_\bs_\be_\ba_\bs_\bo_\bn] [-\b--\b-s\bsm\bmo\boo\bot\bth\bhi\bin\bng\bg-\b-w\bwi\bin\bnd\bdo\bow\bw-\b-d\bde\bev\bvi\bia\bat\bti\bio\bon\bn _\bf_\br_\ba_\bc_\bt_\bi_\bo_\bn_\b-
+       _\bo_\bf_\b-_\bs_\be_\ba_\bs_\bo_\bn] [-\b--\b-a\bab\bbe\ber\brr\bra\ban\bnt\bt-\b-r\bre\bes\bse\bet\bt _\bd_\bs_\b-_\bn_\ba_\bm_\be]
 
 D\bDE\bES\bSC\bCR\bRI\bIP\bPT\bTI\bIO\bON\bN
        The tune option allows you to alter some of the basic configuration
@@ -99,19 +100,28 @@ D\bDE\bES\bSC\bCR\bRI\bIP\bPT\bTI\bIO\bON\bN
                Alter the seasonal deviation adaptation parameter for the
                DEVSEASONAL R\bRR\bRA\bA. This parameter must be between 0 and 1.
 
+       -\b--\b-s\bsm\bmo\boo\bot\bth\bhi\bin\bng\bg-\b-w\bwi\bin\bnd\bdo\bow\bw _\bf_\br_\ba_\bc_\bt_\bi_\bo_\bn_\b-_\bo_\bf_\b-_\bs_\be_\ba_\bs_\bo_\bn
+               Alter the size of the smoothing window for the SEASONAL R\bRR\bRA\bA.
+               This must be between 0 and 1.
+
+       -\b--\b-s\bsm\bmo\boo\bot\bth\bhi\bin\bng\bg-\b-w\bwi\bin\bnd\bdo\bow\bw-\b-d\bde\bev\bvi\bia\bat\bti\bio\bon\bn _\bf_\br_\ba_\bc_\bt_\bi_\bo_\bn_\b-_\bo_\bf_\b-_\bs_\be_\ba_\bs_\bo_\bn
+               Alter the size of the smoothing window for the DEVSEASONAL R\bRR\bRA\bA.
+               This must be between 0 and 1.
+
        -\b--\b-a\bab\bbe\ber\brr\bra\ban\bnt\bt-\b-r\bre\bes\bse\bet\bt _\bd_\bs_\b-_\bn_\ba_\bm_\be
                This option causes the aberrant behavior detection algorithm to
                reset for the specified data source; that is, forget all it is
-               has learnt so far.  Specifically, for the HWPREDICT R\bRR\bRA\bA, it
-               sets the intercept and slope coefficients to unknown. For the
-               SEASONAL R\bRR\bRA\bA, it sets all seasonal coefficients to unknown. For
-               the DEVSEASONAL R\bRR\bRA\bA, it sets all seasonal deviation coeffi-
-               cients to unknown. For the FAILURES R\bRR\bRA\bA, it erases the viola-
-               tion history. Note that reset does not erase past predictions
-               (the values of the HWPREDICT R\bRR\bRA\bA), predicted deviations (the
-               values of the DEVPREDICT R\bRR\bRA\bA), or failure history (the values
-               of the FAILURES R\bRR\bRA\bA).  This option will function even if not
-               all the listed R\bRR\bRA\bAs\bs are present.
+               has learnt so far.  Specifically, for the HWPREDICT or MHWPRE-
+               DICT R\bRR\bRA\bA, it sets the intercept and slope coefficients to
+               unknown. For the SEASONAL R\bRR\bRA\bA, it sets all seasonal coeffi-
+               cients to unknown. For the DEVSEASONAL R\bRR\bRA\bA, it sets all sea-
+               sonal deviation coefficients to unknown. For the FAILURES R\bRR\bRA\bA,
+               it erases the violation history. Note that reset does not erase
+               past predictions (the values of the HWPREDICT or MHWPREDICT
+               R\bRR\bRA\bA), predicted deviations (the values of the DEVPREDICT R\bRR\bRA\bA),
+               or failure history (the values of the FAILURES R\bRR\bRA\bA).  This
+               option will function even if not all the listed R\bRR\bRA\bAs\bs are
+               present.
 
                Due to the implementation of this option, there is an indirect
                impact on other data sources in the RRD. A smoothing algorithm
@@ -149,4 +159,4 @@ A\bAU\bUT\bTH\bHO\bOR\bR
 
 
 
-1.2.27                            2008-02-17                        RRDTUNE(1)
+1.3rc4                            2008-03-15                        RRDTUNE(1)
index 7efe014f5ce9bed028ca317f8adad3e5ffb19365..5a22139f28450629d3fe32313306ae87bd5d6dda 100644 (file)
 .\" ========================================================================
 .\"
 .IX Title "RRDTUTORIAL 1"
-.TH RRDTUTORIAL 1 "2008-02-17" "1.2.27" "rrdtool"
+.TH RRDTUTORIAL 1 "2008-03-15" "1.3rc4" "rrdtool"
 .SH "NAME"
 rrdtutorial \- Alex van den Bogaerdt's RRDtool tutorial
 .SH "DESCRIPTION"
@@ -238,7 +238,7 @@ By following the examples you get some hands-on experience and, even
 more important, some background information of how it works.
 .PP
 You will need to know something about hexadecimal numbers. If you don't
-then start with reading bin_dec_hex tutorial before you continue here.
+then start with reading bin_dec_hex before you continue here.
 .Sh "Your first Round Robin Database"
 .IX Subsection "Your first Round Robin Database"
 In my opinion the best way to learn something is to actually do it.
index 7ae3bf180a14be2317a2e64a201a5e753ad7d71e..86eb7dba1d59f948910c56a1cfae6786993e2a51 100644 (file)
@@ -161,7 +161,7 @@ you did understand, you may have missed something.</p>
 <p>By following the examples you get some hands-on experience and, even
 more important, some background information of how it works.</p>
 <p>You will need to know something about hexadecimal numbers. If you don't
-then start with reading bin_dec_hex tutorial before you continue here.</p>
+then start with reading <a href="././bin_dec_hex.html">the bin_dec_hex manpage</a> before you continue here.</p>
 <p>
 </p>
 <h2><a name="your_first_round_robin_database">Your first Round Robin Database</a></h2>
index 1ccfa379f9fde51f873c16e32a6500beac5c1ec0..30a4868d30c7b175cff702e884f076106ed2ce1e 100644 (file)
@@ -114,7 +114,7 @@ By following the examples you get some hands-on experience and, even
 more important, some background information of how it works.
 
 You will need to know something about hexadecimal numbers. If you don't
-then start with reading bin_dec_hex tutorial before you continue here.
+then start with reading L<bin_dec_hex> before you continue here.
 
 =head2 Your first Round Robin Database
 
index e223045993be53b431018be706c6e2bf98f1f9b5..ac6d83b9eca5074ad2d25763dd68ff6677bd67d2 100644 (file)
@@ -116,7 +116,7 @@ T\bTU\bUT\bTO\bOR\bRI\bIA\bAL\bL
        more important, some background information of how it works.
 
        You will need to know something about hexadecimal numbers. If you don't
-       then start with reading bin_dec_hex tutorial before you continue here.
+       then start with reading bin_dec_hex before you continue here.
 
        Y\bYo\bou\bur\br f\bfi\bir\brs\bst\bt R\bRo\bou\bun\bnd\bd R\bRo\bob\bbi\bin\bn D\bDa\bat\bta\bab\bba\bas\bse\be
 
@@ -1149,4 +1149,4 @@ A\bAU\bUT\bTH\bHO\bOR\bR
 
 
 
-1.2.27                            2008-02-17                    RRDTUTORIAL(1)
+1.3rc4                            2008-03-15                    RRDTUTORIAL(1)
index cb1e9edd861b6ff0b05a64de888ac0a536a70087..d3ef44b879eaaab4106b28f06fe6972ed0dc1998 100644 (file)
 .\" ========================================================================
 .\"
 .IX Title "RRDUPDATE 1"
-.TH RRDUPDATE 1 "2008-02-17" "1.2.27" "rrdtool"
+.TH RRDUPDATE 1 "2008-03-15" "1.3rc4" "rrdtool"
 .SH "NAME"
 rrdupdate \- Store a new set of values into the RRD
 .SH "SYNOPSIS"
index 582da4e677b194de6add50303f7a9bc11dbb9f0f..80e58d8fb800b4ce84852f05d0cb20bd006723ee 100644 (file)
@@ -91,4 +91,4 @@ A\bAU\bUT\bTH\bHO\bOR\bR
 
 
 
-1.2.27                            2008-02-17                      RRDUPDATE(1)
+1.3rc4                            2008-03-15                      RRDUPDATE(1)
index 276852a4f8dd9db9002b47e858c51c9ba41b54b8..db4c7cd1e575b0b9a29a2d28101d6870b665066e 100644 (file)
 .\" ========================================================================
 .\"
 .IX Title "RRDXPORT 1"
-.TH RRDXPORT 1 "2008-02-17" "1.2.27" "rrdtool"
+.TH RRDXPORT 1 "2008-03-15" "1.3rc4" "rrdtool"
 .SH "NAME"
 rrdxport \- Export data in XML format based on data from one or several RRD
 .SH "SYNOPSIS"
index b9f8d305d3f9a8f2c7119d25c9543b422d9e4004..7c23b20a93958bcf4ea75b58e2dcf9468f41d674 100644 (file)
@@ -125,4 +125,4 @@ A\bAU\bUT\bTH\bHO\bOR\bR
 
 
 
-1.2.27                            2008-02-17                       RRDXPORT(1)
+1.3rc4                            2008-03-15                       RRDXPORT(1)
index 9e7dc840ec7e443ded94e337d8200d44fa9081f9..e568965841c1d1f7f797e8f3d4bd309b7e854e32 100644 (file)
@@ -10,7 +10,7 @@ examplesdir = $(pkgdatadir)/examples
 examples_SCRIPTS = cgi-demo.cgi piped-demo.pl shared-demo.pl \
        stripes.pl bigtops.pl minmax.pl 4charts.pl perftest.pl
 
-cgi-demo.cgi: cgi-demo.cgi.in $(top_builddir)/config.status
-       sed 's,@''exec_prefix@,$(exec_prefix),' cgi-demo.cgi.in > $@
+cgi-demo.cgi: @srcdir@/cgi-demo.cgi.in $(top_builddir)/config.status
+       sed 's,@''exec_prefix@,$(exec_prefix),' @srcdir@/cgi-demo.cgi.in > $@
        chmod a+x $@
 
index 40a8525a447e8eca2103e1967d216cb96078a18f..9c726406af11dd0155db3cd748e17cc062309f2d 100644 (file)
@@ -64,6 +64,7 @@ DIST_SOURCES =
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 ACLOCAL = @ACLOCAL@
 ALL_LIBS = @ALL_LIBS@
+ALL_LINGUAS = @ALL_LINGUAS@
 AMDEP_FALSE = @AMDEP_FALSE@
 AMDEP_TRUE = @AMDEP_TRUE@
 AMTAR = @AMTAR@
@@ -72,6 +73,8 @@ AUTOCONF = @AUTOCONF@
 AUTOHEADER = @AUTOHEADER@
 AUTOMAKE = @AUTOMAKE@
 AWK = @AWK@
+BUILD_LIBINTL_FALSE = @BUILD_LIBINTL_FALSE@
+BUILD_LIBINTL_TRUE = @BUILD_LIBINTL_TRUE@
 BUILD_MULTITHREAD_FALSE = @BUILD_MULTITHREAD_FALSE@
 BUILD_MULTITHREAD_TRUE = @BUILD_MULTITHREAD_TRUE@
 BUILD_RRDCGI_FALSE = @BUILD_RRDCGI_FALSE@
@@ -80,6 +83,8 @@ BUILD_TCL_FALSE = @BUILD_TCL_FALSE@
 BUILD_TCL_SITE_FALSE = @BUILD_TCL_SITE_FALSE@
 BUILD_TCL_SITE_TRUE = @BUILD_TCL_SITE_TRUE@
 BUILD_TCL_TRUE = @BUILD_TCL_TRUE@
+CATALOGS = @CATALOGS@
+CATOBJEXT = @CATOBJEXT@
 CC = @CC@
 CCDEPMODE = @CCDEPMODE@
 CFLAGS = @CFLAGS@
@@ -94,6 +99,7 @@ CXXCPP = @CXXCPP@
 CXXDEPMODE = @CXXDEPMODE@
 CXXFLAGS = @CXXFLAGS@
 CYGPATH_W = @CYGPATH_W@
+DATADIRNAME = @DATADIRNAME@
 DEFS = @DEFS@
 DEPDIR = @DEPDIR@
 ECHO = @ECHO@
@@ -104,18 +110,57 @@ EGREP = @EGREP@
 EXEEXT = @EXEEXT@
 F77 = @F77@
 FFLAGS = @FFLAGS@
+GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
+GMOFILES = @GMOFILES@
+GMSGFMT = @GMSGFMT@
 GREP = @GREP@
 INSTALL_DATA = @INSTALL_DATA@
 INSTALL_PROGRAM = @INSTALL_PROGRAM@
 INSTALL_SCRIPT = @INSTALL_SCRIPT@
 INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INSTOBJEXT = @INSTOBJEXT@
+INTLLIBS = @INTLLIBS@
+INTLTOOL_CAVES_RULE = @INTLTOOL_CAVES_RULE@
+INTLTOOL_DESKTOP_RULE = @INTLTOOL_DESKTOP_RULE@
+INTLTOOL_DIRECTORY_RULE = @INTLTOOL_DIRECTORY_RULE@
+INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@
+INTLTOOL_ICONV = @INTLTOOL_ICONV@
+INTLTOOL_KBD_RULE = @INTLTOOL_KBD_RULE@
+INTLTOOL_KEYS_RULE = @INTLTOOL_KEYS_RULE@
+INTLTOOL_MERGE = @INTLTOOL_MERGE@
+INTLTOOL_MSGFMT = @INTLTOOL_MSGFMT@
+INTLTOOL_MSGMERGE = @INTLTOOL_MSGMERGE@
+INTLTOOL_OAF_RULE = @INTLTOOL_OAF_RULE@
+INTLTOOL_PERL = @INTLTOOL_PERL@
+INTLTOOL_PONG_RULE = @INTLTOOL_PONG_RULE@
+INTLTOOL_PROP_RULE = @INTLTOOL_PROP_RULE@
+INTLTOOL_SCHEMAS_RULE = @INTLTOOL_SCHEMAS_RULE@
+INTLTOOL_SERVER_RULE = @INTLTOOL_SERVER_RULE@
+INTLTOOL_SERVICE_RULE = @INTLTOOL_SERVICE_RULE@
+INTLTOOL_SHEET_RULE = @INTLTOOL_SHEET_RULE@
+INTLTOOL_SOUNDLIST_RULE = @INTLTOOL_SOUNDLIST_RULE@
+INTLTOOL_THEME_RULE = @INTLTOOL_THEME_RULE@
+INTLTOOL_UI_RULE = @INTLTOOL_UI_RULE@
+INTLTOOL_UPDATE = @INTLTOOL_UPDATE@
+INTLTOOL_XAM_RULE = @INTLTOOL_XAM_RULE@
+INTLTOOL_XGETTEXT = @INTLTOOL_XGETTEXT@
+INTLTOOL_XML_NOMERGE_RULE = @INTLTOOL_XML_NOMERGE_RULE@
+INTLTOOL_XML_RULE = @INTLTOOL_XML_RULE@
 LDFLAGS = @LDFLAGS@
 LIBOBJS = @LIBOBJS@
 LIBS = @LIBS@
 LIBTOOL = @LIBTOOL@
+LIBVERS = @LIBVERS@
+LIB_LIBINTL = @LIB_LIBINTL@
 LN_S = @LN_S@
 LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@
+MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@
 MAKEINFO = @MAKEINFO@
+MKINSTALLDIRS = @MKINSTALLDIRS@
+MSGFMT = @MSGFMT@
+MSGFMT_OPTS = @MSGFMT_OPTS@
 MULTITHREAD_CFLAGS = @MULTITHREAD_CFLAGS@
 MULTITHREAD_LDFLAGS = @MULTITHREAD_LDFLAGS@
 NROFF = @NROFF@
@@ -138,6 +183,12 @@ PERL_CC = @PERL_CC@
 PERL_MAKE_OPTIONS = @PERL_MAKE_OPTIONS@
 PERL_VERSION = @PERL_VERSION@
 PKGCONFIG = @PKGCONFIG@
+POD2HTML = @POD2HTML@
+POD2MAN = @POD2MAN@
+POFILES = @POFILES@
+POSUB = @POSUB@
+PO_IN_DATADIR_FALSE = @PO_IN_DATADIR_FALSE@
+PO_IN_DATADIR_TRUE = @PO_IN_DATADIR_TRUE@
 PTHREAD_CC = @PTHREAD_CC@
 PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
 PTHREAD_LIBS = @PTHREAD_LIBS@
@@ -155,7 +206,10 @@ RUBY = @RUBY@
 RUBY_MAKE_OPTIONS = @RUBY_MAKE_OPTIONS@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
+STATIC_PROGRAMS_FALSE = @STATIC_PROGRAMS_FALSE@
+STATIC_PROGRAMS_TRUE = @STATIC_PROGRAMS_TRUE@
 STRIP = @STRIP@
+TCL_INC_DIR = @TCL_INC_DIR@
 TCL_LD_SEARCH_FLAGS = @TCL_LD_SEARCH_FLAGS@
 TCL_PACKAGE_DIR = @TCL_PACKAGE_DIR@
 TCL_PACKAGE_PATH = @TCL_PACKAGE_PATH@
@@ -166,7 +220,9 @@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@
 TCL_STUB_LIB_SPEC = @TCL_STUB_LIB_SPEC@
 TCL_VERSION = @TCL_VERSION@
 TROFF = @TROFF@
+USE_NLS = @USE_NLS@
 VERSION = @VERSION@
+XGETTEXT = @XGETTEXT@
 ac_ct_CC = @ac_ct_CC@
 ac_ct_CXX = @ac_ct_CXX@
 ac_ct_F77 = @ac_ct_F77@
@@ -231,7 +287,7 @@ examples_SCRIPTS = cgi-demo.cgi piped-demo.pl shared-demo.pl \
 all: all-am
 
 .SUFFIXES:
-$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
        @for dep in $?; do \
          case '$(am__configure_deps)' in \
            *$$dep*) \
@@ -256,9 +312,9 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
 $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
        cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
 
-$(top_srcdir)/configure:  $(am__configure_deps)
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
        cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
        cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
 shared-demo.pl: $(top_builddir)/config.status $(srcdir)/shared-demo.pl.in
        cd $(top_builddir) && $(SHELL) ./config.status $(subdir)/$@
@@ -426,8 +482,8 @@ uninstall-am: uninstall-examplesSCRIPTS uninstall-info-am
        uninstall-info-am
 
 
-cgi-demo.cgi: cgi-demo.cgi.in $(top_builddir)/config.status
-       sed 's,@''exec_prefix@,$(exec_prefix),' cgi-demo.cgi.in > $@
+cgi-demo.cgi: @srcdir@/cgi-demo.cgi.in $(top_builddir)/config.status
+       sed 's,@''exec_prefix@,$(exec_prefix),' @srcdir@/cgi-demo.cgi.in > $@
        chmod a+x $@
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
 # Otherwise a system limit (for SysV at least) may be exceeded.
index b10f59f5c68dc852544469797b020c8a38a45756..022a954473a8270b37d320d7a3c04218144d4ffc 100755 (executable)
@@ -7,27 +7,38 @@
 #
 #makes programm work AFTER install
 
-use lib qw( @prefix@/lib/perl );
+my $Chunk = shift @ARGV || 10000;
+
+use lib qw( ../bindings/perl-shared/blib/lib ../bindings/perl-shared/blib/arch @prefix@/lib/perl );
 
 print <<NOTE;
 
 RRDtool Performance Tester
 --------------------------
-Runnion on $RRDs::VERSION;
+Running on $RRDs::VERSION;
 
 RRDtool update performance is ultimately disk-bound. Since very little data
 does actually get written to disk in a single update, the performance
-is highly dependent on the cache situation in your machine.
+is highly dependent on the cache situation of your machine.
 
 This test tries to cater for this. It works like this:
 
-1) Create 100 RRD files (and sync them to disk)
+1) Create $Chunk RRD files in a tree
+
+2) For $Chunk -> Update RRD file, Sync
+
+3) goto 1)
 
-2) Update the 100 RRD file three times in a row.
-   We run the Update several times to see the difference
-   it makes in the cache.
+The numbers at the start of the row, show which
+RRA is being updated. So if several RRAs are being updated,
+you should see a slowdown as data has to be read from disk.
 
-3) Go back to 1)
+The growning number in the second column shows how many RRD have been
+updated ... If everything is in cache, the number will Jump to $Chunk almost
+immediately. Then the system will seem to hang as 'sync' runs, to make sure
+all data has been written to disk prior to the next perftest run. This may
+not be 100% real-life, so you may want to remove the sync just for fun
+(then it is even less real-life, but different)
 
 NOTE
 
@@ -66,9 +77,6 @@ sub update($$){
   my $out = rand(1000);
   my $start = time;
   my $ret = RRDs::updatev($file.".rrd", $time.":$in:$out");
-#  print join("",map {"  $_ " . $ret->{$_}."\n" } grep /AVERAGE.\[1\]/, sort keys %$ret)."\n** $time\n\n";
-  # sync updates to disk immediately  
-#  usleep(1) if (rand(3) <1 );
   my $total = time - $start;
   my $error =  RRDs::error;
   die $error if $error;
@@ -112,6 +120,7 @@ sub makerrds($$$$){
     my $list = shift;
     my $time = shift;
     my @files;
+    my $now = int(time);
     for (1..$count){
         my $id = sprintf ("%07d",$total);
         $id =~ s/^(.)(.)(.)(.)(.)//;
@@ -123,26 +132,19 @@ sub makerrds($$$$){
         -d "$1/$2/$3/$4/$5" or mkdir "$1/$2/$3/$4/$5";
        push @files, $list->[$total];
         create $list->[$total++],$time-2;
-       print STDERR ".";
-    }
-   for (@files){ 
-       my $fd = new IO::File("$_.rrd","r");
-       if (defined $fd) {
-           $fd->sync;
-           $fd->close;
-        } else {
-            warn "failed to sync $_\n";
-        }        
+       if ($now < int(time)){
+         $now = int(time);
+         print STDERR "Creating RRDs: ", $count - $_," rrds to go. \r";
+        }
     }
     return $count;
 }
-    
-    
 sub main (){
     mkdir "db-$$" or die $!;
     chdir "db-$$";
 
-    my $step = 100000; # number of rrds to creat for every round
+    my $step = $Chunk; # number of rrds to creat for every round
     
     my @path;
     my $time=int(time);
@@ -156,37 +158,56 @@ sub main (){
     my %count =( cr => 0, up => 0 );
 
     my $printtime = time;
-    while (1) {
+    my %step;
+    for (qw(1 6 24 144)){
+          $step{$_} = int($time / 300 / $_);
+    }
+    
+    for (0..2) {
         # enhance the track
-           $time += 300;
+        $time += 300;
         $tracksize += makerrds $step,$tracksize,\@path,$time;            
         # run benchmark
-        for (0..10){
+    
+        for (0..50){
            $time += 300;
             my $count = 0;
             my $sum = 0;
             my $squaresum = 0;
+            my $prefix = "";
+            for (qw(1 6 24 144)){
+                if (int($time / 300 / $_) > $step{$_})  {
+                    $prefix .= "$_  ";
+                    $step{$_} = int($time / 300 / $_);
+                 }
+                 else {
+                    $prefix .= (" " x length("$_")) . "  ";
+                 }   
+            }
+            my $now = int(time);
             for (my $i = 0; $i<$tracksize;$i ++){
-               my $elapsed = update($path[$i],$time); 
+               my $ntime = int(time);
+               if ($now < $ntime or $i == $tracksize){
+                   printf STDERR "$prefix %7d \r",$i;
+                   $now = $ntime;
+               }
+               my $elapsed = update($path[$i],$time);                
                $sum += $elapsed;
                $squaresum += $elapsed**2;
                $count++;
             };
-#            for (my $i = 0; $i<$tracksize;$i ++){
-#             my $fh = new IO::File "$path[$i].rrd","r";
-#             if (defined $fh) {
-#                 $fh->sync;
-#                 $fh->close;
-#                } else {
-#                 warn "failed to sync $path[$i]\n";
-#              }       
-#            }
+            my $startsync = time;
+            print STDERR 's';
+            system "sync";
+            print STDERR "\h";
+            my $synctime = time-$startsync;     
+            $sum += $synctime;
+            $squaresum += $synctime**2;
             my $ups = $count/$sum;
             my $sdv = stddev($sum,$squaresum,$count);
-            printf STDERR "%4d %6.0f Up/s (%6.5f sdv)\n",$count,$ups,$sdv;
+            printf STDERR "$prefix %7d %6.0f Up/s (%6.5f sdv)\n",$count,$ups,$sdv;
         }
        print STDERR "\n";
-       exit ;
     }
 }
 
diff --git a/intltool-extract.in b/intltool-extract.in
new file mode 100644 (file)
index 0000000..0d7c4ff
--- /dev/null
@@ -0,0 +1,875 @@
+#!@INTLTOOL_PERL@ -w 
+# -*- Mode: perl; indent-tabs-mode: nil; c-basic-offset: 4  -*-
+
+#
+#  The Intltool Message Extractor
+#
+#  Copyright (C) 2000-2001, 2003 Free Software Foundation.
+#
+#  Intltool is free software; you can redistribute it and/or
+#  modify it under the terms of the GNU General Public License as
+#  published by the Free Software Foundation; either version 2 of the
+#  License, or (at your option) any later version.
+#
+#  Intltool is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#  General Public License for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with this program; if not, write to the Free Software
+#  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+#  As a special exception to the GNU General Public License, if you
+#  distribute this file as part of a program that contains a
+#  configuration script generated by Autoconf, you may include it under
+#  the same distribution terms that you use for the rest of that program.
+#
+#  Authors: Kenneth Christiansen <kenneth@gnu.org>
+#           Darin Adler <darin@bentspoon.com>
+#
+
+## Release information
+my $PROGRAM      = "intltool-extract";
+my $PACKAGE      = "intltool";
+my $VERSION      = "0.37.0";
+
+## Loaded modules
+use strict; 
+use File::Basename;
+use Getopt::Long;
+
+## Scalars used by the option stuff
+my $TYPE_ARG   = "0";
+my $LOCAL_ARG  = "0";
+my $HELP_ARG   = "0";
+my $VERSION_ARG = "0";
+my $UPDATE_ARG  = "0";
+my $QUIET_ARG   = "0";
+my $SRCDIR_ARG = ".";
+
+my $FILE;
+my $OUTFILE;
+
+my $gettext_type = "";
+my $input;
+my %messages = ();
+my %loc = ();
+my %count = ();
+my %comments = ();
+my $strcount = 0;
+
+my $XMLCOMMENT = "";
+
+## Use this instead of \w for XML files to handle more possible characters.
+my $w = "[-A-Za-z0-9._:]";
+
+## Always print first
+$| = 1;
+
+## Handle options
+GetOptions (
+           "type=s"     => \$TYPE_ARG,
+            "local|l"    => \$LOCAL_ARG,
+            "help|h"     => \$HELP_ARG,
+            "version|v"  => \$VERSION_ARG,
+            "update"     => \$UPDATE_ARG,
+           "quiet|q"    => \$QUIET_ARG,
+           "srcdir=s"   => \$SRCDIR_ARG,
+            ) or &error;
+
+&split_on_argument;
+
+
+## Check for options. 
+## This section will check for the different options.
+
+sub split_on_argument {
+
+    if ($VERSION_ARG) {
+        &version;
+
+    } elsif ($HELP_ARG) {
+       &help;
+        
+    } elsif ($LOCAL_ARG) {
+        &place_local;
+        &extract;
+
+    } elsif ($UPDATE_ARG) {
+       &place_normal;
+       &extract;
+
+    } elsif (@ARGV > 0) {
+       &place_normal;
+       &message;
+       &extract;
+
+    } else {
+       &help;
+
+    }  
+}    
+
+sub place_normal {
+    $FILE       = $ARGV[0];
+    $OUTFILE     = "$FILE.h";
+
+    my $dirname = dirname ($OUTFILE);
+    if (! -d "$dirname" && $dirname ne "") {
+        system ("mkdir -p $dirname");
+    }
+}   
+
+sub place_local {
+    $FILE       = $ARGV[0];
+    $OUTFILE     = fileparse($FILE, ());
+    if (!-e "tmp/") { 
+        system("mkdir tmp/"); 
+    }
+    $OUTFILE     = "./tmp/$OUTFILE.h"
+}
+
+sub determine_type {
+   if ($TYPE_ARG =~ /^gettext\/(.*)/) {
+       $gettext_type=$1
+   }
+}
+
+## Sub for printing release information
+sub version{
+    print <<_EOF_;
+${PROGRAM} (${PACKAGE}) $VERSION
+Copyright (C) 2000, 2003 Free Software Foundation, Inc.
+Written by Kenneth Christiansen, 2000.
+
+This is free software; see the source for copying conditions.  There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+_EOF_
+    exit;
+}
+
+## Sub for printing usage information
+sub help {
+    print <<_EOF_;
+Usage: ${PROGRAM} [OPTION]... [FILENAME]
+Generates a header file from an XML source file.
+
+It grabs all strings between <_translatable_node> and its end tag in
+XML files. Read manpage (man ${PROGRAM}) for more info.
+
+      --type=TYPE   Specify the file type of FILENAME. Currently supports:
+                    "gettext/glade", "gettext/ini", "gettext/keys"
+                    "gettext/rfc822deb", "gettext/schemas",
+                    "gettext/scheme", "gettext/xml", "gettext/quoted",
+                    "gettext/quotedxml"
+  -l, --local       Writes output into current working directory
+                    (conflicts with --update)
+      --update      Writes output into the same directory the source file 
+                    reside (conflicts with --local)
+      --srcdir      Root of the source tree
+  -v, --version     Output version information and exit
+  -h, --help        Display this help and exit
+  -q, --quiet       Quiet mode
+
+Report bugs to http://bugzilla.gnome.org/ (product name "$PACKAGE")
+or send email to <xml-i18n-tools\@gnome.org>.
+_EOF_
+    exit;
+}
+
+## Sub for printing error messages
+sub error{
+    print STDERR "Try `${PROGRAM} --help' for more information.\n";
+    exit;
+}
+
+sub message {
+    print "Generating C format header file for translation.\n" unless $QUIET_ARG;
+}
+
+sub extract {
+    &determine_type;
+
+    &convert;
+
+    open OUT, ">$OUTFILE";
+    binmode (OUT) if $^O eq 'MSWin32';
+    &msg_write;
+    close OUT;
+
+    print "Wrote $OUTFILE\n" unless $QUIET_ARG;
+}
+
+sub convert {
+
+    ## Reading the file
+    {
+       local (*IN);
+       local $/; #slurp mode
+       open (IN, "<$SRCDIR_ARG/$FILE") || die "can't open $SRCDIR_ARG/$FILE: $!";
+       $input = <IN>;
+    }
+
+    &type_ini if $gettext_type eq "ini";
+    &type_keys if $gettext_type eq "keys";
+    &type_xml if $gettext_type eq "xml";
+    &type_glade if $gettext_type eq "glade";
+    &type_scheme if $gettext_type eq "scheme";
+    &type_schemas  if $gettext_type eq "schemas";
+    &type_rfc822deb  if $gettext_type eq "rfc822deb";
+    &type_quoted if $gettext_type eq "quoted";
+    &type_quotedxml if $gettext_type eq "quotedxml";
+}
+
+sub entity_decode_minimal
+{
+    local ($_) = @_;
+
+    s/&apos;/'/g; # '
+    s/&quot;/"/g; # "
+    s/&amp;/&/g;
+
+    return $_;
+}
+
+sub entity_decode
+{
+    local ($_) = @_;
+
+    s/&apos;/'/g; # '
+    s/&quot;/"/g; # "
+    s/&lt;/</g;
+    s/&gt;/>/g;
+    s/&amp;/&/g;
+
+    return $_;
+}
+
+sub escape_char
+{
+    return '\"' if $_ eq '"';
+    return '\n' if $_ eq "\n";
+    return '\\\\' if $_ eq '\\';
+
+    return $_;
+}
+
+sub escape
+{
+    my ($string) = @_;
+    return join "", map &escape_char, split //, $string;
+}
+
+sub type_ini {
+    ### For generic translatable desktop files ###
+    while ($input =~ /^(#(.+)\n)?^_.*=(.*)$/mg) {
+        if (defined($2))  {
+            $comments{$3} = $2;
+        }
+        $messages{$3} = [];
+    }
+}
+
+sub type_keys {
+    ### For generic translatable mime/keys files ###
+    while ($input =~ /^\s*_\w+=(.*)$/mg) {
+        $messages{$1} = [];
+    }
+}
+
+sub type_xml {
+    ### For generic translatable XML files ###
+    my $tree = readXml($input);
+    parseTree(0, $tree);
+}
+
+sub print_var {
+    my $var = shift;
+    my $vartype = ref $var;
+    
+    if ($vartype =~ /ARRAY/) {
+        my @arr = @{$var};
+        print "[ ";
+        foreach my $el (@arr) {
+            print_var($el);
+            print ", ";
+        }
+        print "] ";
+    } elsif ($vartype =~ /HASH/) {
+        my %hash = %{$var};
+        print "{ ";
+        foreach my $key (keys %hash) {
+            print "$key => ";
+            print_var($hash{$key});
+            print ", ";
+        }
+        print "} ";
+    } else {
+        print $var;
+    }
+}
+
+# Same syntax as getAttributeString in intltool-merge.in.in, similar logic (look for ## differences comment)
+sub getAttributeString
+{
+    my $sub = shift;
+    my $do_translate = shift || 1;
+    my $language = shift || "";
+    my $translate = shift;
+    my $result = "";
+    foreach my $e (reverse(sort(keys %{ $sub }))) {
+       my $key    = $e;
+       my $string = $sub->{$e};
+       my $quote = '"';
+       
+       $string =~ s/^[\s]+//;
+       $string =~ s/[\s]+$//;
+       
+       if ($string =~ /^'.*'$/)
+       {
+           $quote = "'";
+       }
+       $string =~ s/^['"]//g;
+       $string =~ s/['"]$//g;
+
+        ## differences from intltool-merge.in.in
+       if ($key =~ /^_/) {
+            $comments{entity_decode($string)} = $XMLCOMMENT if $XMLCOMMENT;
+            $messages{entity_decode($string)} = [];
+            $$translate = 2;
+       }
+        ## differences end here from intltool-merge.in.in
+       $result .= " $key=$quote$string$quote";
+    }
+    return $result;
+}
+
+# Verbatim copy from intltool-merge.in.in
+sub getXMLstring
+{
+    my $ref = shift;
+    my $spacepreserve = shift || 0;
+    my @list = @{ $ref };
+    my $result = "";
+
+    my $count = scalar(@list);
+    my $attrs = $list[0];
+    my $index = 1;
+
+    $spacepreserve = 1 if ((exists $attrs->{"xml:space"}) && ($attrs->{"xml:space"} =~ /^["']?preserve["']?$/));
+    $spacepreserve = 0 if ((exists $attrs->{"xml:space"}) && ($attrs->{"xml:space"} =~ /^["']?default["']?$/));
+
+    while ($index < $count) {
+       my $type = $list[$index];
+       my $content = $list[$index+1];
+        if (! $type ) {
+           # We've got CDATA
+           if ($content) {
+               # lets strip the whitespace here, and *ONLY* here
+                $content =~ s/\s+/ /gs if (!$spacepreserve);
+               $result .= $content;
+           }
+       } elsif ( "$type" ne "1" ) {
+           # We've got another element
+           $result .= "<$type";
+           $result .= getAttributeString(@{$content}[0], 0); # no nested translatable elements
+           if ($content) {
+               my $subresult = getXMLstring($content, $spacepreserve);
+               if ($subresult) {
+                   $result .= ">".$subresult . "</$type>";
+               } else {
+                   $result .= "/>";
+               }
+           } else {
+               $result .= "/>";
+           }
+       }
+       $index += 2;
+    }
+    return $result;
+}
+
+# Verbatim copy from intltool-merge.in.in, except for MULTIPLE_OUTPUT handling removed
+# Translate list of nodes if necessary
+sub translate_subnodes
+{
+    my $fh = shift;
+    my $content = shift;
+    my $language = shift || "";
+    my $singlelang = shift || 0;
+    my $spacepreserve = shift || 0;
+
+    my @nodes = @{ $content };
+
+    my $count = scalar(@nodes);
+    my $index = 0;
+    while ($index < $count) {
+        my $type = $nodes[$index];
+        my $rest = $nodes[$index+1];
+        traverse($fh, $type, $rest, $language, $spacepreserve);
+        $index += 2;
+    }
+}
+
+# Based on traverse() in intltool-merge.in.in
+sub traverse
+{
+    my $fh = shift; # unused, to allow us to sync code between -merge and -extract
+    my $nodename = shift;
+    my $content = shift;
+    my $language = shift || "";
+    my $spacepreserve = shift || 0;
+
+    if ($nodename && "$nodename" eq "1") {
+        $XMLCOMMENT = $content;
+    } elsif ($nodename) {
+       # element
+       my @all = @{ $content };
+       my $attrs = shift @all;
+       my $translate = 0;
+       my $outattr = getAttributeString($attrs, 1, $language, \$translate);
+
+       if ($nodename =~ /^_/) {
+           $translate = 1;
+           $nodename =~ s/^_//;
+       }
+       my $lookup = '';
+
+        $spacepreserve = 0 if ((exists $attrs->{"xml:space"}) && ($attrs->{"xml:space"} =~ /^["']?default["']?$/));
+        $spacepreserve = 1 if ((exists $attrs->{"xml:space"}) && ($attrs->{"xml:space"} =~ /^["']?preserve["']?$/));
+
+       if ($translate) {
+           $lookup = getXMLstring($content, $spacepreserve);
+            if (!$spacepreserve) {
+                $lookup =~ s/^\s+//s;
+                $lookup =~ s/\s+$//s;
+            }
+
+           if ($lookup && $translate != 2) {
+                $comments{$lookup} = $XMLCOMMENT if $XMLCOMMENT;
+                $messages{$lookup} = [];
+            } elsif ($translate == 2) {
+                translate_subnodes($fh, \@all, $language, 1, $spacepreserve);
+           }
+       } else {
+            $XMLCOMMENT = "";
+           my $count = scalar(@all);
+           if ($count > 0) {
+                my $index = 0;
+                while ($index < $count) {
+                    my $type = $all[$index];
+                    my $rest = $all[$index+1];
+                    traverse($fh, $type, $rest, $language, $spacepreserve);
+                    $index += 2;
+                }
+           }
+       }
+        $XMLCOMMENT = "";
+    }
+}
+
+
+# Verbatim copy from intltool-merge.in.in, $fh for compatibility
+sub parseTree
+{
+    my $fh        = shift;
+    my $ref       = shift;
+    my $language  = shift || "";
+
+    my $name = shift @{ $ref };
+    my $cont = shift @{ $ref };
+
+    while (!$name || "$name" eq "1") {
+        $name = shift @{ $ref };
+        $cont = shift @{ $ref };
+    }
+
+    my $spacepreserve = 0;
+    my $attrs = @{$cont}[0];
+    $spacepreserve = 1 if ((exists $attrs->{"xml:space"}) && ($attrs->{"xml:space"} =~ /^["']?preserve["']?$/));
+
+    traverse($fh, $name, $cont, $language, $spacepreserve);
+}
+
+# Verbatim copy from intltool-merge.in.in
+sub intltool_tree_comment
+{
+    my $expat = shift;
+    my $data  = $expat->original_string();
+    my $clist = $expat->{Curlist};
+    my $pos   = $#$clist;
+
+    $data =~ s/^<!--//s;
+    $data =~ s/-->$//s;
+    push @$clist, 1 => $data;
+}
+
+# Verbatim copy from intltool-merge.in.in
+sub intltool_tree_cdatastart
+{
+    my $expat    = shift;
+    my $clist = $expat->{Curlist};
+    my $pos   = $#$clist;
+
+    push @$clist, 0 => $expat->original_string();
+}
+
+# Verbatim copy from intltool-merge.in.in
+sub intltool_tree_cdataend
+{
+    my $expat    = shift;
+    my $clist = $expat->{Curlist};
+    my $pos   = $#$clist;
+
+    $clist->[$pos] .= $expat->original_string();
+}
+
+# Verbatim copy from intltool-merge.in.in
+sub intltool_tree_char
+{
+    my $expat = shift;
+    my $text  = shift;
+    my $clist = $expat->{Curlist};
+    my $pos   = $#$clist;
+
+    # Use original_string so that we retain escaped entities
+    # in CDATA sections.
+    #
+    if ($pos > 0 and $clist->[$pos - 1] eq '0') {
+        $clist->[$pos] .= $expat->original_string();
+    } else {
+        push @$clist, 0 => $expat->original_string();
+    }
+}
+
+# Verbatim copy from intltool-merge.in.in
+sub intltool_tree_start
+{
+    my $expat    = shift;
+    my $tag      = shift;
+    my @origlist = ();
+
+    # Use original_string so that we retain escaped entities
+    # in attribute values.  We must convert the string to an
+    # @origlist array to conform to the structure of the Tree
+    # Style.
+    #
+    my @original_array = split /\x/, $expat->original_string();
+    my $source         = $expat->original_string();
+
+    # Remove leading tag.
+    #
+    $source =~ s|^\s*<\s*(\S+)||s;
+
+    # Grab attribute key/value pairs and push onto @origlist array.
+    #
+    while ($source)
+    {
+       if ($source =~ /^\s*([\w:-]+)\s*[=]\s*["]/)
+       {
+           $source =~ s|^\s*([\w:-]+)\s*[=]\s*["]([^"]*)["]||s;
+           push @origlist, $1;
+           push @origlist, '"' . $2 . '"';
+       }
+       elsif ($source =~ /^\s*([\w:-]+)\s*[=]\s*[']/)
+       {
+           $source =~ s|^\s*([\w:-]+)\s*[=]\s*[']([^']*)[']||s;
+           push @origlist, $1;
+           push @origlist, "'" . $2 . "'";
+       }
+       else
+       {
+           last;
+       }
+    }
+
+    my $ol = [ { @origlist } ];
+
+    push @{ $expat->{Lists} }, $expat->{Curlist};
+    push @{ $expat->{Curlist} }, $tag => $ol;
+    $expat->{Curlist} = $ol;
+}
+
+# Copied from intltool-merge.in.in and added comment handler.
+sub readXml
+{
+    my $xmldoc = shift || return;
+    my $ret = eval 'require XML::Parser';
+    if(!$ret) {
+        die "You must have XML::Parser installed to run $0\n\n";
+    }
+    my $xp = new XML::Parser(Style => 'Tree');
+    $xp->setHandlers(Char => \&intltool_tree_char);
+    $xp->setHandlers(Start => \&intltool_tree_start);
+    $xp->setHandlers(CdataStart => \&intltool_tree_cdatastart);
+    $xp->setHandlers(CdataEnd => \&intltool_tree_cdataend);
+
+    ## differences from intltool-merge.in.in
+    $xp->setHandlers(Comment => \&intltool_tree_comment);
+    ## differences end here from intltool-merge.in.in
+
+    my $tree = $xp->parse($xmldoc);
+    #print_var($tree);
+
+# <foo><!-- comment --><head id="a">Hello <em>there</em></head><bar>Howdy<ref/></bar>do</foo>
+# would be:
+# [foo, [{}, 1, "comment", head, [{id => "a"}, 0, "Hello ",  em, [{}, 0, "there"]], bar, 
+# [{}, 0, "Howdy",  ref, [{}]], 0, "do" ] ]
+
+    return $tree;
+}
+
+sub type_schemas {
+    ### For schemas XML files ###
+         
+    # FIXME: We should handle escaped < (less than)
+    while ($input =~ /
+                      <locale\ name="C">\s*
+                          (<default>\s*(?:<!--([^>]*?)-->\s*)?(.*?)\s*<\/default>\s*)?
+                          (<short>\s*(?:<!--([^>]*?)-->\s*)?(.*?)\s*<\/short>\s*)?
+                          (<long>\s*(?:<!--([^>]*?)-->\s*)?(.*?)\s*<\/long>\s*)?
+                      <\/locale>
+                     /sgx) {
+        my @totranslate = ($3,$6,$9);
+        my @eachcomment = ($2,$5,$8);
+        foreach (@totranslate) {
+            my $currentcomment = shift @eachcomment;
+            next if !$_;
+            s/\s+/ /g;
+            $messages{entity_decode_minimal($_)} = [];
+            $comments{entity_decode_minimal($_)} = $currentcomment if (defined($currentcomment));
+        }
+    }
+}
+
+sub type_rfc822deb {
+    ### For rfc822-style Debian configuration files ###
+
+    my $lineno = 1;
+    my $type = '';
+    while ($input =~ /\G(.*?)(^|\n)(_+)([^:]+):[ \t]*(.*?)(?=\n\S|$)/sg)
+    {
+        my ($pre, $newline, $underscore, $tag, $text) = ($1, $2, $3, $4, $5);
+        while ($pre =~ m/\n/g)
+        {
+            $lineno ++;
+        }
+        $lineno += length($newline);
+        my @str_list = rfc822deb_split(length($underscore), $text);
+        for my $str (@str_list)
+        {
+            $strcount++;
+            $messages{$str} = [];
+            $loc{$str} = $lineno;
+            $count{$str} = $strcount;
+            my $usercomment = '';
+            while($pre =~ s/(^|\n)#([^\n]*)$//s)
+            {
+                $usercomment = "\n" . $2 . $usercomment;
+            }
+            $comments{$str} = $tag . $usercomment;
+        }
+        $lineno += ($text =~ s/\n//g);
+    }
+}
+
+sub rfc822deb_split {
+    # Debian defines a special way to deal with rfc822-style files:
+    # when a value contain newlines, it consists of
+    #   1.  a short form (first line)
+    #   2.  a long description, all lines begin with a space,
+    #       and paragraphs are separated by a single dot on a line
+    # This routine returns an array of all paragraphs, and reformat
+    # them.
+    # When first argument is 2, the string is a comma separated list of
+    # values.
+    my $type = shift;
+    my $text = shift;
+    $text =~ s/^[ \t]//mg;
+    return (split(/, */, $text, 0)) if $type ne 1;
+    return ($text) if $text !~ /\n/;
+
+    $text =~ s/([^\n]*)\n//;
+    my @list = ($1);
+    my $str = '';
+    for my $line (split (/\n/, $text))
+    {
+        chomp $line;
+        if ($line =~ /^\.\s*$/)
+        {
+            #  New paragraph
+            $str =~ s/\s*$//;
+            push(@list, $str);
+            $str = '';
+        }
+        elsif ($line =~ /^\s/)
+        {
+            #  Line which must not be reformatted
+            $str .= "\n" if length ($str) && $str !~ /\n$/;
+            $line =~ s/\s+$//;
+            $str .= $line."\n";
+        }
+        else
+        {
+            #  Continuation line, remove newline
+            $str .= " " if length ($str) && $str !~ /\n$/;
+            $str .= $line;
+        }
+    }
+    $str =~ s/\s*$//;
+    push(@list, $str) if length ($str);
+    return @list;
+}
+
+sub type_quoted {
+    while ($input =~ /\"(([^\"]|\\\")*[^\\\"])\"/g) {
+        my $message = $1;
+        my $before = $`;
+        $message =~ s/\\\"/\"/g;
+        $before =~ s/[^\n]//g;
+        $messages{$message} = [];
+        $loc{$message} = length ($before) + 2;
+    }
+}
+
+sub type_quotedxml {
+    while ($input =~ /\"(([^\"]|\\\")*[^\\\"])\"/g) {
+        my $message = $1;
+        my $before = $`;
+        $message =~ s/\\\"/\"/g;
+        $message = entity_decode($message);
+        $before =~ s/[^\n]//g;
+        $messages{$message} = [];
+        $loc{$message} = length ($before) + 2;
+    }
+}
+
+sub type_glade {
+    ### For translatable Glade XML files ###
+
+    my $tags = "label|title|text|format|copyright|comments|preview_text|tooltip|message";
+
+    while ($input =~ /<($tags)>([^<]+)<\/($tags)>/sg) {
+       # Glade sometimes uses tags that normally mark translatable things for
+        # little bits of non-translatable content. We work around this by not
+        # translating strings that only includes something like label4 or window1.
+       $messages{entity_decode($2)} = [] unless $2 =~ /^(window|label|dialog)[0-9]+$/;
+    }
+    
+    while ($input =~ /<items>(..[^<]*)<\/items>/sg) {
+       for my $item (split (/\n/, $1)) {
+           $messages{entity_decode($item)} = [];
+       }
+    }
+
+    ## handle new glade files
+    while ($input =~ /<(property|atkproperty)\s+[^>]*translatable\s*=\s*"yes"(?:\s+[^>]*comments\s*=\s*"([^"]*)")?[^>]*>([^<]+)<\/\1>/sg) {
+       $messages{entity_decode($3)} = [] unless $3 =~ /^(window|label)[0-9]+$/;
+        if (defined($2) and !($3 =~ /^(window|label)[0-9]+$/)) {
+          $comments{entity_decode($3)} = entity_decode($2) ;
+        }
+    }
+    while ($input =~ /<atkaction\s+action_name="([^>]*)"\s+description="([^>]+)"\/>/sg) {
+        $messages{entity_decode_minimal($2)} = [];
+    }
+}
+
+sub type_scheme {
+    my ($line, $i, $state, $str, $trcomment, $char);
+    for $line (split(/\n/, $input)) {
+        $i = 0;
+        $state = 0; # 0 - nothing, 1 - string, 2 - translatable string
+        while ($i < length($line)) {
+            if (substr($line,$i,1) eq "\"") {
+                if ($state == 2) {
+                    $comments{$str} = $trcomment if ($trcomment);
+                    $messages{$str} = [];
+                    $str = '';
+                    $state = 0; $trcomment = "";
+                } elsif ($state == 1) {
+                    $str = '';
+                    $state = 0; $trcomment = "";
+                } else {
+                    $state = 1;
+                    $str = '';
+                    if ($i>0 && substr($line,$i-1,1) eq '_') {
+                        $state = 2;
+                    }
+                }
+            } elsif (!$state) {
+                if (substr($line,$i,1) eq ";") {
+                    $trcomment = substr($line,$i+1);
+                    $trcomment =~ s/^;*\s*//;
+                    $i = length($line);
+                } elsif ($trcomment && substr($line,$i,1) !~ /\s|\(|\)|_/) {
+                    $trcomment = "";
+                }
+            } else {
+                if (substr($line,$i,1) eq "\\") {
+                    $char = substr($line,$i+1,1);
+                    if ($char ne "\"" && $char ne "\\") {
+                       $str = $str . "\\";
+                    }
+                    $i++;
+                }
+                $str = $str . substr($line,$i,1);
+            }
+            $i++;
+        }
+    }
+}
+
+sub msg_write {
+    my @msgids;
+    if (%count)
+    {
+        @msgids = sort { $count{$a} <=> $count{$b} } keys %count;
+    }
+    else
+    {
+        @msgids = sort keys %messages;
+    }
+    for my $message (@msgids)
+    {
+       my $offsetlines = 1;
+       $offsetlines++ if $message =~ /%/;
+       if (defined ($comments{$message}))
+       {
+               while ($comments{$message} =~ m/\n/g)
+               {
+                   $offsetlines++;
+               }
+       }
+       print OUT "# ".($loc{$message} - $offsetlines).  " \"$FILE\"\n"
+               if defined $loc{$message};
+       print OUT "/* ".$comments{$message}." */\n"
+                if defined $comments{$message};
+       print OUT "/* xgettext:no-c-format */\n" if $message =~ /%/;
+        
+       my @lines = split (/\n/, $message, -1);
+       for (my $n = 0; $n < @lines; $n++)
+       {
+            if ($n == 0)
+            {
+               print OUT "char *s = N_(\""; 
+            }
+            else
+            {  
+                print OUT "             \""; 
+            }
+
+            print OUT escape($lines[$n]);
+
+            if ($n < @lines - 1)
+            {
+                print OUT "\\n\"\n"; 
+            }
+            else
+            {
+                print OUT "\");\n";  
+           }
+        }
+    }
+}
+
diff --git a/intltool-merge.in b/intltool-merge.in
new file mode 100644 (file)
index 0000000..493d910
--- /dev/null
@@ -0,0 +1,1506 @@
+#!@INTLTOOL_PERL@ -w
+# -*- Mode: perl; indent-tabs-mode: nil; c-basic-offset: 4  -*-
+
+#
+#  The Intltool Message Merger
+#
+#  Copyright (C) 2000, 2003 Free Software Foundation.
+#  Copyright (C) 2000, 2001 Eazel, Inc
+#
+#  Intltool is free software; you can redistribute it and/or
+#  modify it under the terms of the GNU General Public License 
+#  version 2 published by the Free Software Foundation.
+#
+#  Intltool is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#  General Public License for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with this program; if not, write to the Free Software
+#  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+#  As a special exception to the GNU General Public License, if you
+#  distribute this file as part of a program that contains a
+#  configuration script generated by Autoconf, you may include it under
+#  the same distribution terms that you use for the rest of that program.
+#
+#  Authors:  Maciej Stachowiak <mjs@noisehavoc.org>
+#            Kenneth Christiansen <kenneth@gnu.org>
+#            Darin Adler <darin@bentspoon.com>
+#
+#  Proper XML UTF-8'ification written by Cyrille Chepelov <chepelov@calixo.net>
+#
+
+## Release information
+my $PROGRAM = "intltool-merge";
+my $PACKAGE = "intltool";
+my $VERSION = "0.37.0";
+
+## Loaded modules
+use strict; 
+use Getopt::Long;
+use Text::Wrap;
+use File::Basename;
+
+my $must_end_tag      = -1;
+my $last_depth        = -1;
+my $translation_depth = -1;
+my @tag_stack = ();
+my @entered_tag = ();
+my @translation_strings = ();
+my $leading_space = "";
+
+## Scalars used by the option stuff
+my $HELP_ARG = 0;
+my $VERSION_ARG = 0;
+my $BA_STYLE_ARG = 0;
+my $XML_STYLE_ARG = 0;
+my $KEYS_STYLE_ARG = 0;
+my $DESKTOP_STYLE_ARG = 0;
+my $SCHEMAS_STYLE_ARG = 0;
+my $RFC822DEB_STYLE_ARG = 0;
+my $QUOTED_STYLE_ARG = 0;
+my $QUOTEDXML_STYLE_ARG = 0;
+my $QUIET_ARG = 0;
+my $PASS_THROUGH_ARG = 0;
+my $UTF8_ARG = 0;
+my $MULTIPLE_OUTPUT = 0;
+my $cache_file;
+
+## Handle options
+GetOptions 
+(
+ "help" => \$HELP_ARG,
+ "version" => \$VERSION_ARG,
+ "quiet|q" => \$QUIET_ARG,
+ "oaf-style|o" => \$BA_STYLE_ARG, ## for compatibility
+ "ba-style|b" => \$BA_STYLE_ARG,
+ "xml-style|x" => \$XML_STYLE_ARG,
+ "keys-style|k" => \$KEYS_STYLE_ARG,
+ "desktop-style|d" => \$DESKTOP_STYLE_ARG,
+ "schemas-style|s" => \$SCHEMAS_STYLE_ARG,
+ "rfc822deb-style|r" => \$RFC822DEB_STYLE_ARG,
+ "quoted-style" => \$QUOTED_STYLE_ARG,
+ "quotedxml-style" => \$QUOTEDXML_STYLE_ARG,
+ "pass-through|p" => \$PASS_THROUGH_ARG,
+ "utf8|u" => \$UTF8_ARG,
+ "multiple-output|m" => \$MULTIPLE_OUTPUT,
+ "cache|c=s" => \$cache_file
+ ) or &error;
+
+my $PO_DIR;
+my $FILE;
+my $OUTFILE;
+
+my %po_files_by_lang = ();
+my %translations = ();
+my $iconv = $ENV{"ICONV"} || "iconv";
+my $devnull = ($^O eq 'MSWin32' ? 'NUL:' : '/dev/null');
+
+sub isProgramInPath
+{
+    my ($file) = @_;
+    # If either a file exists, or when run it returns 0 exit status
+    return 1 if ((-x $file) or (system("$file -l >$devnull") == 0));
+    return 0;
+}
+
+if (! isProgramInPath ("$iconv"))
+{
+       print STDERR " *** iconv is not found on this system!\n".
+                    " *** Without it, intltool-merge can not convert encodings.\n";
+       exit;
+}
+
+# Use this instead of \w for XML files to handle more possible characters.
+my $w = "[-A-Za-z0-9._:]";
+
+# XML quoted string contents
+my $q = "[^\\\"]*";
+
+## Check for options. 
+
+if ($VERSION_ARG) 
+{
+       &print_version;
+} 
+elsif ($HELP_ARG) 
+{
+       &print_help;
+} 
+elsif ($BA_STYLE_ARG && @ARGV > 2) 
+{
+       &utf8_sanity_check;
+       &preparation;
+       &print_message;
+       &ba_merge_translations;
+       &finalize;
+} 
+elsif ($XML_STYLE_ARG && @ARGV > 2) 
+{
+       &utf8_sanity_check;
+       &preparation;
+       &print_message;
+       &xml_merge_output;
+       &finalize;
+} 
+elsif ($KEYS_STYLE_ARG && @ARGV > 2) 
+{
+       &utf8_sanity_check;
+       &preparation;
+       &print_message;
+        &keys_merge_translations;
+       &finalize;
+} 
+elsif ($DESKTOP_STYLE_ARG && @ARGV > 2) 
+{
+       &utf8_sanity_check;
+       &preparation;
+       &print_message;
+       &desktop_merge_translations;
+       &finalize;
+} 
+elsif ($SCHEMAS_STYLE_ARG && @ARGV > 2) 
+{
+       &utf8_sanity_check;
+       &preparation;
+       &print_message;
+       &schemas_merge_translations;
+       &finalize;
+} 
+elsif ($RFC822DEB_STYLE_ARG && @ARGV > 2) 
+{
+       &preparation;
+       &print_message;
+       &rfc822deb_merge_translations;
+       &finalize;
+} 
+elsif (($QUOTED_STYLE_ARG || $QUOTEDXML_STYLE_ARG) && @ARGV > 2)
+{
+       &utf8_sanity_check;
+       &preparation;
+       &print_message;
+       &quoted_merge_translations($QUOTEDXML_STYLE_ARG);
+       &finalize;
+} 
+else 
+{
+       &print_help;
+}
+
+exit;
+
+## Sub for printing release information
+sub print_version
+{
+    print <<_EOF_;
+${PROGRAM} (${PACKAGE}) ${VERSION}
+Written by Maciej Stachowiak, Darin Adler and Kenneth Christiansen.
+
+Copyright (C) 2000-2003 Free Software Foundation, Inc.
+Copyright (C) 2000-2001 Eazel, Inc.
+This is free software; see the source for copying conditions.  There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+_EOF_
+    exit;
+}
+
+## Sub for printing usage information
+sub print_help
+{
+    print <<_EOF_;
+Usage: ${PROGRAM} [OPTION]... PO_DIRECTORY FILENAME OUTPUT_FILE
+Generates an output file that includes some localized attributes from an
+untranslated source file.
+
+Mandatory options: (exactly one must be specified)
+  -b, --ba-style         includes translations in the bonobo-activation style
+  -d, --desktop-style    includes translations in the desktop style
+  -k, --keys-style       includes translations in the keys style
+  -s, --schemas-style    includes translations in the schemas style
+  -r, --rfc822deb-style  includes translations in the RFC822 style
+      --quoted-style     includes translations in the quoted string style
+      --quotedxml-style  includes translations in the quoted xml string style
+  -x, --xml-style        includes translations in the standard xml style
+
+Other options:
+  -u, --utf8             convert all strings to UTF-8 before merging 
+                         (default for everything except RFC822 style)
+  -p, --pass-through     deprecated, does nothing and issues a warning
+  -m, --multiple-output  output one localized file per locale, instead of 
+                        a single file containing all localized elements
+  -c, --cache=FILE       specify cache file name
+                         (usually \$top_builddir/po/.intltool-merge-cache)
+  -q, --quiet            suppress most messages
+      --help             display this help and exit
+      --version          output version information and exit
+
+Report bugs to http://bugzilla.gnome.org/ (product name "$PACKAGE")
+or send email to <xml-i18n-tools\@gnome.org>.
+_EOF_
+    exit;
+}
+
+
+## Sub for printing error messages
+sub print_error
+{
+    print STDERR "Try `${PROGRAM} --help' for more information.\n";
+    exit;
+}
+
+
+sub print_message 
+{
+    print "Merging translations into $OUTFILE.\n" unless $QUIET_ARG;
+}
+
+
+sub preparation 
+{
+    $PO_DIR = $ARGV[0];
+    $FILE = $ARGV[1];
+    $OUTFILE = $ARGV[2];
+
+    &gather_po_files;
+    &get_translation_database;
+}
+
+# General-purpose code for looking up translations in .po files
+
+sub po_file2lang
+{
+    my ($tmp) = @_; 
+    $tmp =~ s/^.*\/(.*)\.po$/$1/; 
+    return $tmp; 
+}
+
+sub gather_po_files
+{
+    if (my $linguas = $ENV{"LINGUAS"})
+    {
+        for my $lang (split / /, $linguas) {
+            my $po_file = $PO_DIR . "/" . $lang . ".po";
+            if (-e $po_file) {
+                $po_files_by_lang{$lang} = $po_file;
+            }
+        }
+    }
+    else
+    {
+        if (open LINGUAS_FILE, "$PO_DIR/LINGUAS")
+        {
+            while (<LINGUAS_FILE>)
+            {
+                next if /^#/;
+
+                for my $lang (split)
+                {
+                    chomp ($lang);
+                    my $po_file = $PO_DIR . "/" . $lang . ".po";
+                    if (-e $po_file) {
+                        $po_files_by_lang{$lang} = $po_file;
+                    }
+                }
+            }
+
+            close LINGUAS_FILE;
+        }
+        else
+        {
+            for my $po_file (glob "$PO_DIR/*.po") {
+                $po_files_by_lang{po_file2lang($po_file)} = $po_file;
+            }
+        }
+    }
+}
+
+sub get_local_charset
+{
+    my ($encoding) = @_;
+    my $alias_file = $ENV{"G_CHARSET_ALIAS"} || "@INTLTOOL_LIBDIR@/charset.alias";
+
+    # seek character encoding aliases in charset.alias (glib)
+
+    if (open CHARSET_ALIAS, $alias_file) 
+    {
+       while (<CHARSET_ALIAS>) 
+        {
+            next if /^\#/;
+            return $1 if (/^\s*([-._a-zA-Z0-9]+)\s+$encoding\b/i)
+        }
+
+        close CHARSET_ALIAS;
+    }
+
+    # if not found, return input string
+
+    return $encoding;
+}
+
+sub get_po_encoding
+{
+    my ($in_po_file) = @_;
+    my $encoding = "";
+
+    open IN_PO_FILE, $in_po_file or die;
+    while (<IN_PO_FILE>) 
+    {
+        ## example: "Content-Type: text/plain; charset=ISO-8859-1\n"
+        if (/Content-Type\:.*charset=([-a-zA-Z0-9]+)\\n/) 
+        {
+            $encoding = $1; 
+            last;
+        }
+    }
+    close IN_PO_FILE;
+
+    if (!$encoding) 
+    {
+        print STDERR "Warning: no encoding found in $in_po_file. Assuming ISO-8859-1\n" unless $QUIET_ARG;
+        $encoding = "ISO-8859-1";
+    }
+
+    system ("$iconv -f $encoding -t UTF-8 <$devnull 2>$devnull");
+    if ($?) {
+       $encoding = get_local_charset($encoding);
+    }
+
+    return $encoding
+}
+
+sub utf8_sanity_check 
+{
+    print STDERR "Warning: option --pass-through has been removed.\n" if $PASS_THROUGH_ARG;
+    $UTF8_ARG = 1;
+}
+
+sub get_translation_database
+{
+    if ($cache_file) {
+       &get_cached_translation_database;
+    } else {
+        &create_translation_database;
+    }
+}
+
+sub get_newest_po_age
+{
+    my $newest_age;
+
+    foreach my $file (values %po_files_by_lang) 
+    {
+       my $file_age = -M $file;
+       $newest_age = $file_age if !$newest_age || $file_age < $newest_age;
+    }
+
+    $newest_age = 0 if !$newest_age;
+
+    return $newest_age;
+}
+
+sub create_cache
+{
+    print "Generating and caching the translation database\n" unless $QUIET_ARG;
+
+    &create_translation_database;
+
+    open CACHE, ">$cache_file" || die;
+    print CACHE join "\x01", %translations;
+    close CACHE;
+}
+
+sub load_cache 
+{
+    print "Found cached translation database\n" unless $QUIET_ARG;
+
+    my $contents;
+    open CACHE, "<$cache_file" || die;
+    {
+        local $/;
+        $contents = <CACHE>;
+    }
+    close CACHE;
+    %translations = split "\x01", $contents;
+}
+
+sub get_cached_translation_database
+{
+    my $cache_file_age = -M $cache_file;
+    if (defined $cache_file_age) 
+    {
+        if ($cache_file_age <= &get_newest_po_age) 
+        {
+            &load_cache;
+            return;
+        }
+        print "Found too-old cached translation database\n" unless $QUIET_ARG;
+    }
+
+    &create_cache;
+}
+
+sub create_translation_database
+{
+    for my $lang (keys %po_files_by_lang) 
+    {
+       my $po_file = $po_files_by_lang{$lang};
+
+        if ($UTF8_ARG) 
+        {
+            my $encoding = get_po_encoding ($po_file);
+
+            if (lc $encoding eq "utf-8") 
+            {
+                open PO_FILE, "<$po_file";     
+            } 
+            else 
+            {
+               print "NOTICE: $po_file is not in UTF-8 but $encoding, converting...\n" unless $QUIET_ARG;;
+
+                open PO_FILE, "$iconv -f $encoding -t UTF-8 $po_file|";        
+            }
+        } 
+        else 
+        {
+            open PO_FILE, "<$po_file"; 
+        }
+
+       my $nextfuzzy = 0;
+       my $inmsgid = 0;
+       my $inmsgstr = 0;
+       my $msgid = "";
+       my $msgstr = "";
+
+        while (<PO_FILE>) 
+        {
+           $nextfuzzy = 1 if /^#, fuzzy/;
+       
+           if (/^msgid "((\\.|[^\\]+)*)"/ ) 
+            {
+               $translations{$lang, $msgid} = $msgstr if $inmsgstr && $msgid && $msgstr;
+               $msgid = "";
+               $msgstr = "";
+
+               if ($nextfuzzy) {
+                   $inmsgid = 0;
+               } else {
+                   $msgid = unescape_po_string($1);
+                   $inmsgid = 1;
+               }
+               $inmsgstr = 0;
+               $nextfuzzy = 0;
+           }
+
+           if (/^msgstr "((\\.|[^\\]+)*)"/) 
+            {
+               $msgstr = unescape_po_string($1);
+               $inmsgstr = 1;
+               $inmsgid = 0;
+           }
+
+           if (/^"((\\.|[^\\]+)*)"/) 
+            {
+               $msgid .= unescape_po_string($1) if $inmsgid;
+               $msgstr .= unescape_po_string($1) if $inmsgstr;
+           }
+       }
+       $translations{$lang, $msgid} = $msgstr if $inmsgstr && $msgid && $msgstr;
+    }
+}
+
+sub finalize
+{
+}
+
+sub unescape_one_sequence
+{
+    my ($sequence) = @_;
+
+    return "\\" if $sequence eq "\\\\";
+    return "\"" if $sequence eq "\\\"";
+    return "\n" if $sequence eq "\\n";
+    return "\r" if $sequence eq "\\r";
+    return "\t" if $sequence eq "\\t";
+    return "\b" if $sequence eq "\\b";
+    return "\f" if $sequence eq "\\f";
+    return "\a" if $sequence eq "\\a";
+    return chr(11) if $sequence eq "\\v"; # vertical tab, see ascii(7)
+
+    return chr(hex($1)) if ($sequence =~ /\\x([0-9a-fA-F]{2})/);
+    return chr(oct($1)) if ($sequence =~ /\\([0-7]{3})/);
+
+    # FIXME: Is \0 supported as well? Kenneth and Rodney don't want it, see bug #48489
+
+    return $sequence;
+}
+
+sub unescape_po_string
+{
+    my ($string) = @_;
+
+    $string =~ s/(\\x[0-9a-fA-F]{2}|\\[0-7]{3}|\\.)/unescape_one_sequence($1)/eg;
+
+    return $string;
+}
+
+sub entity_decode
+{
+    local ($_) = @_;
+
+    s/&apos;/'/g; # '
+    s/&quot;/"/g; # "
+    s/&lt;/</g;
+    s/&gt;/>/g;
+    s/&amp;/&/g;
+
+    return $_;
+}
+# entity_encode: (string)
+#
+# Encode the given string to XML format (encode '<' etc).
+
+sub entity_encode
+{
+    my ($pre_encoded) = @_;
+
+    my @list_of_chars = unpack ('C*', $pre_encoded);
+
+    # with UTF-8 we only encode minimalistic
+    return join ('', map (&entity_encode_int_minimalist, @list_of_chars));
+}
+
+sub entity_encode_int_minimalist
+{
+    return "&quot;" if $_ == 34;
+    return "&amp;" if $_ == 38;
+    return "&apos;" if $_ == 39;
+    return "&lt;" if $_ == 60;
+    return "&gt;" if $_ == 62;
+    return chr $_;
+}
+
+sub entity_encoded_translation
+{
+    my ($lang, $string) = @_;
+
+    my $translation = $translations{$lang, $string};
+    return $string if !$translation;
+    return entity_encode ($translation);
+}
+
+## XML (bonobo-activation specific) merge code
+
+sub ba_merge_translations
+{
+    my $source;
+
+    {
+       local $/; # slurp mode
+       open INPUT, "<$FILE" or die "can't open $FILE: $!";
+       $source = <INPUT>;
+       close INPUT;
+    }
+
+    open OUTPUT, ">$OUTFILE" or die "can't open $OUTFILE: $!";
+    # Binmode so that selftest works ok if using a native Win32 Perl...
+    binmode (OUTPUT) if $^O eq 'MSWin32';
+
+    while ($source =~ s|^(.*?)([ \t]*<\s*$w+\s+($w+\s*=\s*"$q"\s*)+/?>)([ \t]*\n)?||s) 
+    {
+        print OUTPUT $1;
+
+        my $node = $2 . "\n";
+
+        my @strings = ();
+        $_ = $node;
+       while (s/(\s)_($w+\s*=\s*"($q)")/$1$2/s) {
+             push @strings, entity_decode($3);
+        }
+       print OUTPUT;
+
+       my %langs;
+       for my $string (@strings) 
+        {
+           for my $lang (keys %po_files_by_lang) 
+            {
+                $langs{$lang} = 1 if $translations{$lang, $string};
+           }
+       }
+       
+       for my $lang (sort keys %langs) 
+        {
+           $_ = $node;
+           s/(\sname\s*=\s*)"($q)"/$1"$2-$lang"/s;
+           s/(\s)_($w+\s*=\s*")($q)"/$1 . $2 . entity_encoded_translation($lang, $3) . '"'/seg;
+           print OUTPUT;
+        }
+    }
+
+    print OUTPUT $source;
+
+    close OUTPUT;
+}
+
+
+## XML (non-bonobo-activation) merge code
+
+
+# Process tag attributes
+#   Only parameter is a HASH containing attributes -> values mapping
+sub getAttributeString
+{
+    my $sub = shift;
+    my $do_translate = shift || 0;
+    my $language = shift || "";
+    my $result = "";
+    my $translate = shift;
+    foreach my $e (reverse(sort(keys %{ $sub }))) {
+       my $key    = $e;
+       my $string = $sub->{$e};
+       my $quote = '"';
+       
+       $string =~ s/^[\s]+//;
+       $string =~ s/[\s]+$//;
+       
+       if ($string =~ /^'.*'$/)
+       {
+           $quote = "'";
+       }
+       $string =~ s/^['"]//g;
+       $string =~ s/['"]$//g;
+
+       if ($do_translate && $key =~ /^_/) {
+           $key =~ s|^_||g;
+           if ($language) {
+               # Handle translation
+               my $decode_string = entity_decode($string);
+               my $translation = $translations{$language, $decode_string};
+               if ($translation) {
+                   $translation = entity_encode($translation);
+                   $string = $translation;
+                }
+                $$translate = 2;
+            } else {
+                 $$translate = 2 if ($translate && (!$$translate)); # watch not to "overwrite" $translate
+            }
+       }
+       
+       $result .= " $key=$quote$string$quote";
+    }
+    return $result;
+}
+
+# Returns a translatable string from XML node, it works on contents of every node in XML::Parser tree
+sub getXMLstring
+{
+    my $ref = shift;
+    my $spacepreserve = shift || 0;
+    my @list = @{ $ref };
+    my $result = "";
+
+    my $count = scalar(@list);
+    my $attrs = $list[0];
+    my $index = 1;
+
+    $spacepreserve = 1 if ((exists $attrs->{"xml:space"}) && ($attrs->{"xml:space"} =~ /^["']?preserve["']?$/));
+    $spacepreserve = 0 if ((exists $attrs->{"xml:space"}) && ($attrs->{"xml:space"} =~ /^["']?default["']?$/));
+
+    while ($index < $count) {
+       my $type = $list[$index];
+       my $content = $list[$index+1];
+        if (! $type ) {
+           # We've got CDATA
+           if ($content) {
+               # lets strip the whitespace here, and *ONLY* here
+                $content =~ s/\s+/ /gs if (!$spacepreserve);
+               $result .= $content;
+           }
+       } elsif ( "$type" ne "1" ) {
+           # We've got another element
+           $result .= "<$type";
+           $result .= getAttributeString(@{$content}[0], 0); # no nested translatable elements
+           if ($content) {
+               my $subresult = getXMLstring($content, $spacepreserve);
+               if ($subresult) {
+                   $result .= ">".$subresult . "</$type>";
+               } else {
+                   $result .= "/>";
+               }
+           } else {
+               $result .= "/>";
+           }
+       }
+       $index += 2;
+    }
+    return $result;
+}
+
+# Translate list of nodes if necessary
+sub translate_subnodes
+{
+    my $fh = shift;
+    my $content = shift;
+    my $language = shift || "";
+    my $singlelang = shift || 0;
+    my $spacepreserve = shift || 0;
+
+    my @nodes = @{ $content };
+
+    my $count = scalar(@nodes);
+    my $index = 0;
+    while ($index < $count) {
+        my $type = $nodes[$index];
+        my $rest = $nodes[$index+1];
+        if ($singlelang) {
+            my $oldMO = $MULTIPLE_OUTPUT;
+            $MULTIPLE_OUTPUT = 1;
+            traverse($fh, $type, $rest, $language, $spacepreserve);
+            $MULTIPLE_OUTPUT = $oldMO;
+        } else {
+            traverse($fh, $type, $rest, $language, $spacepreserve);
+        }
+        $index += 2;
+    }
+}
+
+sub isWellFormedXmlFragment
+{
+    my $ret = eval 'require XML::Parser';
+    if(!$ret) {
+        die "You must have XML::Parser installed to run $0\n\n";
+    } 
+
+    my $fragment = shift;
+    return 0 if (!$fragment);
+
+    $fragment = "<root>$fragment</root>";
+    my $xp = new XML::Parser(Style => 'Tree');
+    my $tree = 0;
+    eval { $tree = $xp->parse($fragment); };
+    return $tree;
+}
+
+sub traverse
+{
+    my $fh = shift; 
+    my $nodename = shift;
+    my $content = shift;
+    my $language = shift || "";
+    my $spacepreserve = shift || 0;
+
+    if (!$nodename) {
+       if ($content =~ /^[\s]*$/) {
+           $leading_space .= $content;
+       }
+       print $fh $content;
+    } else {
+       # element
+       my @all = @{ $content };
+       my $attrs = shift @all;
+       my $translate = 0;
+       my $outattr = getAttributeString($attrs, 1, $language, \$translate);
+
+       if ($nodename =~ /^_/) {
+           $translate = 1;
+           $nodename =~ s/^_//;
+       }
+       my $lookup = '';
+
+        $spacepreserve = 0 if ((exists $attrs->{"xml:space"}) && ($attrs->{"xml:space"} =~ /^["']?default["']?$/));
+        $spacepreserve = 1 if ((exists $attrs->{"xml:space"}) && ($attrs->{"xml:space"} =~ /^["']?preserve["']?$/));
+
+       print $fh "<$nodename", $outattr;
+       if ($translate) {
+           $lookup = getXMLstring($content, $spacepreserve);
+            if (!$spacepreserve) {
+                $lookup =~ s/^\s+//s;
+                $lookup =~ s/\s+$//s;
+            }
+
+           if ($lookup || $translate == 2) {
+                my $translation = $translations{$language, $lookup} if isWellFormedXmlFragment($translations{$language, $lookup});
+                if ($MULTIPLE_OUTPUT && ($translation || $translate == 2)) {
+                    $translation = $lookup if (!$translation);
+                    print $fh " xml:lang=\"", $language, "\"" if $language;
+                    print $fh ">";
+                    if ($translate == 2) {
+                        translate_subnodes($fh, \@all, $language, 1, $spacepreserve);
+                    } else {
+                        print $fh $translation;
+                    }
+                    print $fh "</$nodename>";
+
+                    return; # this means there will be no same translation with xml:lang="$language"...
+                            # if we want them both, just remove this "return"
+                } else {
+                    print $fh ">";
+                    if ($translate == 2) {
+                        translate_subnodes($fh, \@all, $language, 1, $spacepreserve);
+                    } else {
+                        print $fh $lookup;
+                    }
+                    print $fh "</$nodename>";
+                }
+           } else {
+               print $fh "/>";
+           }
+
+           for my $lang (sort keys %po_files_by_lang) {
+                    if ($MULTIPLE_OUTPUT && $lang ne "$language") {
+                        next;
+                    }
+                   if ($lang) {
+                        # Handle translation
+                        #
+                        my $translate = 0;
+                        my $localattrs = getAttributeString($attrs, 1, $lang, \$translate);
+                        my $translation = $translations{$lang, $lookup} if isWellFormedXmlFragment($translations{$lang, $lookup});
+                        if ($translate && !$translation) {
+                            $translation = $lookup;
+                        }
+
+                        if ($translation || $translate) {
+                           print $fh "\n";
+                           $leading_space =~ s/.*\n//g;
+                           print $fh $leading_space;
+                           print $fh "<", $nodename, " xml:lang=\"", $lang, "\"", $localattrs, ">";
+                            if ($translate == 2) {
+                               translate_subnodes($fh, \@all, $lang, 1, $spacepreserve);
+                            } else {
+                                print $fh $translation;
+                            }
+                            print $fh "</$nodename>";
+                       }
+                    }
+           }
+
+       } else {
+           my $count = scalar(@all);
+           if ($count > 0) {
+               print $fh ">";
+                my $index = 0;
+                while ($index < $count) {
+                    my $type = $all[$index];
+                    my $rest = $all[$index+1];
+                    traverse($fh, $type, $rest, $language, $spacepreserve);
+                    $index += 2;
+                }
+               print $fh "</$nodename>";
+           } else {
+               print $fh "/>";
+           }
+       }
+    }
+}
+
+sub intltool_tree_comment
+{
+    my $expat = shift;
+    my $data  = shift;
+    my $clist = $expat->{Curlist};
+    my $pos   = $#$clist;
+
+    push @$clist, 1 => $data;
+}
+
+sub intltool_tree_cdatastart
+{
+    my $expat    = shift;
+    my $clist = $expat->{Curlist};
+    my $pos   = $#$clist;
+
+    push @$clist, 0 => $expat->original_string();
+}
+
+sub intltool_tree_cdataend
+{
+    my $expat    = shift;
+    my $clist = $expat->{Curlist};
+    my $pos   = $#$clist;
+
+    $clist->[$pos] .= $expat->original_string();
+}
+
+sub intltool_tree_char
+{
+    my $expat = shift;
+    my $text  = shift;
+    my $clist = $expat->{Curlist};
+    my $pos   = $#$clist;
+
+    # Use original_string so that we retain escaped entities
+    # in CDATA sections.
+    #
+    if ($pos > 0 and $clist->[$pos - 1] eq '0') {
+        $clist->[$pos] .= $expat->original_string();
+    } else {
+        push @$clist, 0 => $expat->original_string();
+    }
+}
+
+sub intltool_tree_start
+{
+    my $expat    = shift;
+    my $tag      = shift;
+    my @origlist = ();
+
+    # Use original_string so that we retain escaped entities
+    # in attribute values.  We must convert the string to an
+    # @origlist array to conform to the structure of the Tree
+    # Style.
+    #
+    my @original_array = split /\x/, $expat->original_string();
+    my $source         = $expat->original_string();
+
+    # Remove leading tag.
+    #
+    $source =~ s|^\s*<\s*(\S+)||s;
+
+    # Grab attribute key/value pairs and push onto @origlist array.
+    #
+    while ($source)
+    {
+       if ($source =~ /^\s*([\w:-]+)\s*[=]\s*["]/)
+       {
+           $source =~ s|^\s*([\w:-]+)\s*[=]\s*["]([^"]*)["]||s;
+           push @origlist, $1;
+           push @origlist, '"' . $2 . '"';
+       }
+       elsif ($source =~ /^\s*([\w:-]+)\s*[=]\s*[']/)
+       {
+           $source =~ s|^\s*([\w:-]+)\s*[=]\s*[']([^']*)[']||s;
+           push @origlist, $1;
+           push @origlist, "'" . $2 . "'";
+       }
+       else
+       {
+           last;
+       }
+    }
+
+    my $ol = [ { @origlist } ];
+
+    push @{ $expat->{Lists} }, $expat->{Curlist};
+    push @{ $expat->{Curlist} }, $tag => $ol;
+    $expat->{Curlist} = $ol;
+}
+
+sub readXml
+{
+    my $filename = shift || return;
+    if(!-f $filename) {
+        die "ERROR Cannot find filename: $filename\n";
+    }
+
+    my $ret = eval 'require XML::Parser';
+    if(!$ret) {
+        die "You must have XML::Parser installed to run $0\n\n";
+    } 
+    my $xp = new XML::Parser(Style => 'Tree');
+    $xp->setHandlers(Char => \&intltool_tree_char);
+    $xp->setHandlers(Start => \&intltool_tree_start);
+    $xp->setHandlers(CdataStart => \&intltool_tree_cdatastart);
+    $xp->setHandlers(CdataEnd => \&intltool_tree_cdataend);
+    my $tree = $xp->parsefile($filename);
+
+# <foo><head id="a">Hello <em>there</em></head><bar>Howdy<ref/></bar>do</foo>
+# would be:
+# [foo, [{}, head, [{id => "a"}, 0, "Hello ",  em, [{}, 0, "there"]], bar, [{},
+# 0, "Howdy",  ref, [{}]], 0, "do" ] ]
+
+    return $tree;
+}
+
+sub print_header
+{
+    my $infile = shift;
+    my $fh = shift;
+    my $source;
+
+    if(!-f $infile) {
+        die "ERROR Cannot find filename: $infile\n";
+    }
+
+    print $fh qq{<?xml version="1.0" encoding="UTF-8"?>\n};
+    {
+        local $/;
+        open DOCINPUT, "<${FILE}" or die;
+        $source = <DOCINPUT>;
+        close DOCINPUT;
+    }
+    if ($source =~ /(<!DOCTYPE.*\[.*\]\s*>)/s)
+    {
+        print $fh "$1\n";
+    }
+    elsif ($source =~ /(<!DOCTYPE[^>]*>)/s)
+    {
+        print $fh "$1\n";
+    }
+}
+
+sub parseTree
+{
+    my $fh        = shift;
+    my $ref       = shift;
+    my $language  = shift || "";
+
+    my $name = shift @{ $ref };
+    my $cont = shift @{ $ref };
+    
+    while (!$name || "$name" eq "1") {
+        $name = shift @{ $ref };
+        $cont = shift @{ $ref };
+    }
+
+    my $spacepreserve = 0;
+    my $attrs = @{$cont}[0];
+    $spacepreserve = 1 if ((exists $attrs->{"xml:space"}) && ($attrs->{"xml:space"} =~ /^["']?preserve["']?$/));
+
+    traverse($fh, $name, $cont, $language, $spacepreserve);
+}
+
+sub xml_merge_output
+{
+    my $source;
+
+    if ($MULTIPLE_OUTPUT) {
+        for my $lang (sort keys %po_files_by_lang) {
+           if ( ! -d $lang ) {
+               mkdir $lang or -d $lang or die "Cannot create subdirectory $lang: $!\n";
+            }
+            open OUTPUT, ">$lang/$OUTFILE" or die "Cannot open $lang/$OUTFILE: $!\n";
+            binmode (OUTPUT) if $^O eq 'MSWin32';
+            my $tree = readXml($FILE);
+            print_header($FILE, \*OUTPUT);
+            parseTree(\*OUTPUT, $tree, $lang);
+            close OUTPUT;
+            print "CREATED $lang/$OUTFILE\n" unless $QUIET_ARG;
+        }
+        if ( ! -d "C" ) {
+            mkdir "C" or -d "C" or die "Cannot create subdirectory C: $!\n";
+        }
+        open OUTPUT, ">C/$OUTFILE" or die "Cannot open C/$OUTFILE: $!\n";
+        binmode (OUTPUT) if $^O eq 'MSWin32';
+        my $tree = readXml($FILE);
+        print_header($FILE, \*OUTPUT);
+        parseTree(\*OUTPUT, $tree);
+        close OUTPUT;
+        print "CREATED C/$OUTFILE\n" unless $QUIET_ARG;
+    } else {
+        open OUTPUT, ">$OUTFILE" or die "Cannot open $OUTFILE: $!\n";
+        binmode (OUTPUT) if $^O eq 'MSWin32';
+        my $tree = readXml($FILE);
+        print_header($FILE, \*OUTPUT);
+        parseTree(\*OUTPUT, $tree);
+        close OUTPUT;
+        print "CREATED $OUTFILE\n" unless $QUIET_ARG;
+    }
+}
+
+sub keys_merge_translation
+{
+    my ($lang) = @_;
+
+    if ( ! -d $lang && $MULTIPLE_OUTPUT)
+    {
+        mkdir $lang or -d $lang or die "Cannot create subdirectory $lang: $!\n";
+    }
+
+    open INPUT, "<${FILE}" or die "Cannot open ${FILE}: $!\n";
+    open OUTPUT, ">$lang/$OUTFILE" or die "Cannot open $lang/$OUTFILE: $!\n";
+    binmode (OUTPUT) if $^O eq 'MSWin32';
+
+    while (<INPUT>)
+    {
+        if (s/^(\s*)_(\w+=(.*))/$1$2/)
+        {
+            my $string = $3;
+
+            if (!$MULTIPLE_OUTPUT)
+            {
+                print OUTPUT;
+
+                my $non_translated_line = $_;
+
+                for my $lang (sort keys %po_files_by_lang)
+                {
+                    my $translation = $translations{$lang, $string};
+                    next if !$translation;
+
+                    $_ = $non_translated_line;
+                    s/(\w+)=.*/[$lang]$1=$translation/;
+                    print OUTPUT;
+                }
+            }
+            else
+            {
+                my $non_translated_line = $_;
+                my $translation = $translations{$lang, $string};
+                $translation = $string if !$translation;
+
+                $_ = $non_translated_line;
+                s/(\w+)=.*/$1=$translation/;
+                print OUTPUT;
+            }
+        }
+        else
+        {
+            print OUTPUT;
+        }
+    }
+
+    close OUTPUT;
+    close INPUT;
+
+    print "CREATED $lang/$OUTFILE\n" unless $QUIET_ARG;
+}
+
+sub keys_merge_translations
+{
+    if ($MULTIPLE_OUTPUT)
+    {
+        for my $lang (sort keys %po_files_by_lang)
+        {
+            keys_merge_translation ($lang);
+        }
+        keys_merge_translation ("C");
+    }
+    else
+    {
+        keys_merge_translation (".");
+    }
+}
+
+sub desktop_merge_translations
+{
+    open INPUT, "<${FILE}" or die;
+    open OUTPUT, ">${OUTFILE}" or die;
+    binmode (OUTPUT) if $^O eq 'MSWin32';
+
+    while (<INPUT>) 
+    {
+        if (s/^(\s*)_(\w+=(.*))/$1$2/)  
+        {
+           my $string = $3;
+
+            print OUTPUT;
+
+           my $non_translated_line = $_;
+
+            for my $lang (sort keys %po_files_by_lang) 
+            {
+                my $translation = $translations{$lang, $string};
+                next if !$translation;
+
+                $_ = $non_translated_line;
+                s/(\w+)=.*/${1}[$lang]=$translation/;
+                print OUTPUT;
+            }
+       } 
+        else 
+        {
+            print OUTPUT;
+        }
+    }
+
+    close OUTPUT;
+    close INPUT;
+}
+
+sub schemas_merge_translations
+{
+    my $source;
+
+    {
+       local $/; # slurp mode
+       open INPUT, "<$FILE" or die "can't open $FILE: $!";
+       $source = <INPUT>;
+       close INPUT;
+    }
+
+    open OUTPUT, ">$OUTFILE" or die;
+    binmode (OUTPUT) if $^O eq 'MSWin32';
+
+    # FIXME: support attribute translations
+
+    # Empty nodes never need translation, so unmark all of them.
+    # For example, <_foo/> is just replaced by <foo/>.
+    $source =~ s|<\s*_($w+)\s*/>|<$1/>|g;
+
+    while ($source =~ s/
+                        (.*?)
+                        (\s+)(<locale\ name="C">(\s*)
+                            (<default>\s*(?:<!--[^>]*?-->\s*)?(.*?)\s*<\/default>)?(\s*)
+                            (<short>\s*(?:<!--[^>]*?-->\s*)?(.*?)\s*<\/short>)?(\s*)
+                            (<long>\s*(?:<!--[^>]*?-->\s*)?(.*?)\s*<\/long>)?(\s*)
+                        <\/locale>)
+                       //sx) 
+    {
+        print OUTPUT $1;
+
+       my $locale_start_spaces = $2 ? $2 : '';
+       my $default_spaces = $4 ? $4 : '';
+       my $short_spaces = $7 ? $7 : '';
+       my $long_spaces = $10 ? $10 : '';
+       my $locale_end_spaces = $13 ? $13 : '';
+       my $c_default_block = $3 ? $3 : '';
+       my $default_string = $6 ? $6 : '';
+       my $short_string = $9 ? $9 : '';
+       my $long_string = $12 ? $12 : '';
+
+       print OUTPUT "$locale_start_spaces$c_default_block";
+
+        $default_string =~ s/\s+/ /g;
+        $default_string = entity_decode($default_string);
+       $short_string =~ s/\s+/ /g;
+       $short_string = entity_decode($short_string);
+       $long_string =~ s/\s+/ /g;
+       $long_string = entity_decode($long_string);
+
+       for my $lang (sort keys %po_files_by_lang) 
+        {
+           my $default_translation = $translations{$lang, $default_string};
+           my $short_translation = $translations{$lang, $short_string};
+           my $long_translation  = $translations{$lang, $long_string};
+
+           next if (!$default_translation && !$short_translation && 
+                     !$long_translation);
+
+           print OUTPUT "\n$locale_start_spaces<locale name=\"$lang\">";
+
+        print OUTPUT "$default_spaces";    
+
+        if ($default_translation)
+        {
+            $default_translation = entity_encode($default_translation);
+            print OUTPUT "<default>$default_translation</default>";
+        }
+
+           print OUTPUT "$short_spaces";
+
+           if ($short_translation)
+           {
+                       $short_translation = entity_encode($short_translation);
+                       print OUTPUT "<short>$short_translation</short>";
+           }
+
+           print OUTPUT "$long_spaces";
+
+           if ($long_translation)
+           {
+                       $long_translation = entity_encode($long_translation);
+                       print OUTPUT "<long>$long_translation</long>";
+           }       
+
+           print OUTPUT "$locale_end_spaces</locale>";
+        }
+    }
+
+    print OUTPUT $source;
+
+    close OUTPUT;
+}
+
+sub rfc822deb_merge_translations
+{
+    my %encodings = ();
+    for my $lang (keys %po_files_by_lang) {
+        $encodings{$lang} = ($UTF8_ARG ? 'UTF-8' : get_po_encoding($po_files_by_lang{$lang}));
+    }
+
+    my $source;
+
+    $Text::Wrap::huge = 'overflow';
+    $Text::Wrap::break = qr/\n|\s(?=\S)/;
+
+    {
+       local $/; # slurp mode
+       open INPUT, "<$FILE" or die "can't open $FILE: $!";
+       $source = <INPUT>;
+       close INPUT;
+    }
+
+    open OUTPUT, ">${OUTFILE}" or die;
+    binmode (OUTPUT) if $^O eq 'MSWin32';
+
+    while ($source =~ /(^|\n+)(_*)([^:\s]+)(:[ \t]*)(.*?)(?=\n[\S\n]|$)/sg)
+    {
+           my $sep = $1;
+           my $non_translated_line = $3.$4;
+           my $string = $5;
+           my $underscore = length($2);
+           next if $underscore eq 0 && $non_translated_line =~ /^#/;
+           #  Remove [] dummy strings
+           my $stripped = $string;
+           $stripped =~ s/\[\s[^\[\]]*\],/,/g if $underscore eq 2;
+           $stripped =~ s/\[\s[^\[\]]*\]$//;
+           $non_translated_line .= $stripped;
+
+           print OUTPUT $sep.$non_translated_line;
+    
+           if ($underscore) 
+           {
+               my @str_list = rfc822deb_split($underscore, $string);
+
+               for my $lang (sort keys %po_files_by_lang) 
+                {
+                    my $is_translated = 1;
+                    my $str_translated = '';
+                    my $first = 1;
+                
+                    for my $str (@str_list) 
+                    {
+                        my $translation = $translations{$lang, $str};
+                    
+                        if (!$translation) 
+                        {
+                            $is_translated = 0;
+                            last;
+                        }
+
+                       #  $translation may also contain [] dummy
+                        #  strings, mostly to indicate an empty string
+                       $translation =~ s/\[\s[^\[\]]*\]$//;
+                        
+                        if ($first) 
+                        {
+                            if ($underscore eq 2)
+                            {
+                                $str_translated .= $translation;
+                            }
+                            else
+                            {
+                                $str_translated .=
+                                    Text::Tabs::expand($translation) .
+                                    "\n";
+                            }
+                        } 
+                        else 
+                        {
+                            if ($underscore eq 2)
+                            {
+                                $str_translated .= ', ' . $translation;
+                            }
+                            else
+                            {
+                                $str_translated .= Text::Tabs::expand(
+                                    Text::Wrap::wrap(' ', ' ', $translation)) .
+                                    "\n .\n";
+                            }
+                        }
+                        $first = 0;
+
+                        #  To fix some problems with Text::Wrap::wrap
+                        $str_translated =~ s/(\n )+\n/\n .\n/g;
+                    }
+                    next unless $is_translated;
+
+                    $str_translated =~ s/\n \.\n$//;
+                    $str_translated =~ s/\s+$//;
+
+                    $_ = $non_translated_line;
+                    s/^(\w+):\s*.*/$sep${1}-$lang.$encodings{$lang}: $str_translated/s;
+                    print OUTPUT;
+                }
+           }
+    }
+    print OUTPUT "\n";
+
+    close OUTPUT;
+    close INPUT;
+}
+
+sub rfc822deb_split 
+{
+    # Debian defines a special way to deal with rfc822-style files:
+    # when a value contain newlines, it consists of
+    #   1.  a short form (first line)
+    #   2.  a long description, all lines begin with a space,
+    #       and paragraphs are separated by a single dot on a line
+    # This routine returns an array of all paragraphs, and reformat
+    # them.
+    # When first argument is 2, the string is a comma separated list of
+    # values.
+    my $type = shift;
+    my $text = shift;
+    $text =~ s/^[ \t]//mg;
+    return (split(/, */, $text, 0)) if $type ne 1;
+    return ($text) if $text !~ /\n/;
+
+    $text =~ s/([^\n]*)\n//;
+    my @list = ($1);
+    my $str = '';
+
+    for my $line (split (/\n/, $text)) 
+    {
+        chomp $line;
+        if ($line =~ /^\.\s*$/)
+        {
+            #  New paragraph
+            $str =~ s/\s*$//;
+            push(@list, $str);
+            $str = '';
+        } 
+        elsif ($line =~ /^\s/) 
+        {
+            #  Line which must not be reformatted
+            $str .= "\n" if length ($str) && $str !~ /\n$/;
+            $line =~ s/\s+$//;
+            $str .= $line."\n";
+        } 
+        else 
+        {
+            #  Continuation line, remove newline
+            $str .= " " if length ($str) && $str !~ /\n$/;
+            $str .= $line;
+        }
+    }
+
+    $str =~ s/\s*$//;
+    push(@list, $str) if length ($str);
+
+    return @list;
+}
+
+sub quoted_translation
+{
+    my ($xml_mode, $lang, $string) = @_;
+
+    $string = entity_decode($string) if $xml_mode;
+    $string =~ s/\\\"/\"/g;
+
+    my $translation = $translations{$lang, $string};
+    $translation = $string if !$translation;
+    $translation = entity_encode($translation) if $xml_mode;
+    $translation =~ s/\"/\\\"/g;
+    return $translation
+}
+
+sub quoted_merge_translations
+{
+    my ($xml_mode) = @_;
+
+    if (!$MULTIPLE_OUTPUT) {
+        print "Quoted only supports Multiple Output.\n";
+        exit(1);
+    }
+
+    for my $lang (sort keys %po_files_by_lang) {
+        if ( ! -d $lang ) {
+            mkdir $lang or -d $lang or die "Cannot create subdirectory $lang: $!\n";
+        }
+        open INPUT, "<${FILE}" or die;
+        open OUTPUT, ">$lang/$OUTFILE" or die "Cannot open $lang/$OUTFILE: $!\n";
+        binmode (OUTPUT) if $^O eq 'MSWin32';
+        while (<INPUT>) 
+        {
+            s/\"(([^\"]|\\\")*[^\\\"])\"/"\"" . &quoted_translation($xml_mode, $lang, $1) . "\""/ge;
+            print OUTPUT;
+        }
+        close OUTPUT;
+        close INPUT;
+    }
+}
diff --git a/intltool-update.in b/intltool-update.in
new file mode 100644 (file)
index 0000000..0e6d083
--- /dev/null
@@ -0,0 +1,1164 @@
+#!@INTLTOOL_PERL@ -w
+# -*- Mode: perl; indent-tabs-mode: nil; c-basic-offset: 4  -*-
+
+#
+#  The Intltool Message Updater
+#
+#  Copyright (C) 2000-2003 Free Software Foundation.
+#
+#  Intltool is free software; you can redistribute it and/or
+#  modify it under the terms of the GNU General Public License 
+#  version 2 published by the Free Software Foundation.
+#
+#  Intltool is distributed in the hope that it will be useful,
+#  but WITHOUT ANY WARRANTY; without even the implied warranty of
+#  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
+#  General Public License for more details.
+#
+#  You should have received a copy of the GNU General Public License
+#  along with this program; if not, write to the Free Software
+#  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
+#
+#  As a special exception to the GNU General Public License, if you
+#  distribute this file as part of a program that contains a
+#  configuration script generated by Autoconf, you may include it under
+#  the same distribution terms that you use for the rest of that program.
+#
+#  Authors: Kenneth Christiansen <kenneth@gnu.org>
+#           Maciej Stachowiak
+#           Darin Adler <darin@bentspoon.com>
+
+## Release information
+my $PROGRAM = "intltool-update";
+my $VERSION = "0.37.0";
+my $PACKAGE = "intltool";
+
+## Loaded modules
+use strict;
+use Getopt::Long;
+use Cwd;
+use File::Copy;
+use File::Find;
+
+## Scalars used by the option stuff
+my $HELP_ARG      = 0;
+my $VERSION_ARG    = 0;
+my $DIST_ARG      = 0;
+my $POT_ARG       = 0;
+my $HEADERS_ARG    = 0;
+my $MAINTAIN_ARG   = 0;
+my $REPORT_ARG     = 0;
+my $VERBOSE       = 0;
+my $GETTEXT_PACKAGE = "";
+my $OUTPUT_FILE    = "";
+
+my @languages;
+my %varhash = ();
+my %po_files_by_lang = ();
+
+# Regular expressions to categorize file types.
+# FIXME: Please check if the following is correct
+
+my $xml_support =
+"xml(?:\\.in)*|".      # http://www.w3.org/XML/ (Note: .in is not required)
+"ui|".                 # Bonobo specific - User Interface desc. files
+"lang|".               # ?
+"glade2?(?:\\.in)*|".  # Glade specific - User Interface desc. files (Note: .in is not required)
+"scm(?:\\.in)*|".      # ? (Note: .in is not required)
+"oaf(?:\\.in)+|".      # DEPRECATED: Replaces by Bonobo .server files 
+"etspec|".             # ?
+"server(?:\\.in)+|".   # Bonobo specific
+"sheet(?:\\.in)+|".    # ?
+"schemas(?:\\.in)+|".  # GConf specific
+"pong(?:\\.in)+|".     # DEPRECATED: PONG is not used [by GNOME] any longer.
+"kbd(?:\\.in)+|".      # GOK specific. 
+"policy(?:\\.in)+";    # PolicyKit files
+
+my $ini_support =
+"icon(?:\\.in)+|".     # http://www.freedesktop.org/Standards/icon-theme-spec
+"desktop(?:\\.in)+|".  # http://www.freedesktop.org/Standards/menu-spec
+"caves(?:\\.in)+|".    # GNOME Games specific
+"directory(?:\\.in)+|".        # http://www.freedesktop.org/Standards/menu-spec
+"soundlist(?:\\.in)+|".        # GNOME specific
+"keys(?:\\.in)+|".     # GNOME Mime database specific
+"theme(?:\\.in)+|".    # http://www.freedesktop.org/Standards/icon-theme-spec
+"service(?:\\.in)+";    # DBus specific
+
+my $buildin_gettext_support = 
+"c|y|cs|cc|cpp|c\\+\\+|h|hh|gob|py";
+
+## Always flush buffer when printing
+$| = 1;
+
+## Sometimes the source tree will be rooted somewhere else.
+my $SRCDIR = $ENV{"srcdir"} || ".";
+my $POTFILES_in;
+
+$POTFILES_in = "<$SRCDIR/POTFILES.in";
+
+my $devnull = ($^O eq 'MSWin32' ? 'NUL:' : '/dev/null');
+
+## Handle options
+GetOptions 
+(
+ "help"               => \$HELP_ARG,
+ "version"            => \$VERSION_ARG,
+ "dist|d"             => \$DIST_ARG,
+ "pot|p"              => \$POT_ARG,
+ "headers|s"          => \$HEADERS_ARG,
+ "maintain|m"         => \$MAINTAIN_ARG,
+ "report|r"           => \$REPORT_ARG,
+ "verbose|x"          => \$VERBOSE,
+ "gettext-package|g=s" => \$GETTEXT_PACKAGE,
+ "output-file|o=s"     => \$OUTPUT_FILE,
+ ) or &Console_WriteError_InvalidOption;
+
+&Console_Write_IntltoolHelp if $HELP_ARG;
+&Console_Write_IntltoolVersion if $VERSION_ARG;
+
+my $arg_count = ($DIST_ARG > 0)
+    + ($POT_ARG > 0)
+    + ($HEADERS_ARG > 0)
+    + ($MAINTAIN_ARG > 0)
+    + ($REPORT_ARG > 0);
+
+&Console_Write_IntltoolHelp if $arg_count > 1;
+
+my $PKGNAME = FindPackageName ();
+
+# --version and --help don't require a module name
+my $MODULE = $GETTEXT_PACKAGE || $PKGNAME || "unknown";
+
+if ($POT_ARG)
+{
+    &GenerateHeaders;
+    &GeneratePOTemplate;
+}
+elsif ($HEADERS_ARG)
+{
+    &GenerateHeaders;
+}
+elsif ($MAINTAIN_ARG)
+{
+    &FindLeftoutFiles;
+}
+elsif ($REPORT_ARG)
+{
+    &GenerateHeaders;
+    &GeneratePOTemplate;
+    &Console_Write_CoverageReport;
+}
+elsif ((defined $ARGV[0]) && $ARGV[0] =~ /^[a-z]/)
+{
+    my $lang = $ARGV[0];
+
+    ## Report error if the language file supplied
+    ## to the command line is non-existent
+    &Console_WriteError_NotExisting("$SRCDIR/$lang.po")
+        if ! -s "$SRCDIR/$lang.po";
+
+    if (!$DIST_ARG)
+    {
+       print "Working, please wait..." if $VERBOSE;
+       &GenerateHeaders;
+       &GeneratePOTemplate;
+    }
+    &POFile_Update ($lang, $OUTPUT_FILE);
+    &Console_Write_TranslationStatus ($lang, $OUTPUT_FILE);
+} 
+else 
+{
+    &Console_Write_IntltoolHelp;
+}
+
+exit;
+
+#########
+
+sub Console_Write_IntltoolVersion
+{
+    print <<_EOF_;
+${PROGRAM} (${PACKAGE}) $VERSION
+Written by Kenneth Christiansen, Maciej Stachowiak, and Darin Adler.
+
+Copyright (C) 2000-2003 Free Software Foundation, Inc.
+This is free software; see the source for copying conditions.  There is NO
+warranty; not even for MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.
+_EOF_
+    exit;
+}
+
+sub Console_Write_IntltoolHelp
+{
+    print <<_EOF_;
+Usage: ${PROGRAM} [OPTION]... LANGCODE
+Updates PO template files and merge them with the translations.
+
+Mode of operation (only one is allowed):
+  -p, --pot                   generate the PO template only
+  -s, --headers               generate the header files in POTFILES.in
+  -m, --maintain              search for left out files from POTFILES.in
+  -r, --report                display a status report for the module
+  -d, --dist                  merge LANGCODE.po with existing PO template
+
+Extra options:
+  -g, --gettext-package=NAME  override PO template name, useful with --pot
+  -o, --output-file=FILE      write merged translation to FILE
+  -x, --verbose               display lots of feedback
+      --help                  display this help and exit
+      --version               output version information and exit
+
+Examples of use:
+${PROGRAM} --pot    just create a new PO template
+${PROGRAM} xy       create new PO template and merge xy.po with it
+
+Report bugs to http://bugzilla.gnome.org/ (product name "$PACKAGE")
+or send email to <xml-i18n-tools\@gnome.org>.
+_EOF_
+    exit;
+}
+
+sub echo_n
+{
+    my $str = shift;
+    my $ret = `echo "$str"`;
+
+    $ret =~ s/\n$//; # do we need the "s" flag?
+
+    return $ret;
+}
+
+sub POFile_DetermineType ($) 
+{
+   my $type = $_;
+   my $gettext_type;
+
+   my $xml_regex     = "(?:" . $xml_support . ")";
+   my $ini_regex     = "(?:" . $ini_support . ")";
+   my $buildin_regex = "(?:" . $buildin_gettext_support . ")";
+
+   if ($type =~ /\[type: gettext\/([^\]].*)]/) 
+   {
+       $gettext_type=$1;
+   }
+   elsif ($type =~ /schemas(\.in)+$/) 
+   {
+       $gettext_type="schemas";
+   }
+   elsif ($type =~ /glade2?(\.in)*$/) 
+   {
+       $gettext_type="glade";
+   }
+   elsif ($type =~ /scm(\.in)*$/) 
+   {
+       $gettext_type="scheme";
+   }
+   elsif ($type =~ /keys(\.in)+$/) 
+   {
+       $gettext_type="keys";
+   }
+
+   # bucket types
+
+   elsif ($type =~ /$xml_regex$/) 
+   {
+       $gettext_type="xml";
+   }
+   elsif ($type =~ /$ini_regex$/) 
+   { 
+       $gettext_type="ini";
+   }
+   elsif ($type =~ /$buildin_regex$/) 
+   {
+       $gettext_type="buildin";
+   }
+   else
+   { 
+       $gettext_type="unknown"; 
+   }
+
+   return "gettext\/$gettext_type";
+}
+
+sub TextFile_DetermineEncoding ($) 
+{
+    my $gettext_code="ASCII"; # All files are ASCII by default
+    my $filetype=`file $_ | cut -d ' ' -f 2`;
+
+    if ($? eq "0")
+    {
+       if ($filetype =~ /^(ISO|UTF)/)
+       {
+           chomp ($gettext_code = $filetype);
+       }
+       elsif ($filetype =~ /^XML/)
+       {
+           $gettext_code="UTF-8"; # We asume that .glade and other .xml files are UTF-8
+       }
+    }
+
+    return $gettext_code;
+}
+
+sub isNotValidMissing
+{
+    my ($file) = @_;
+
+    return if $file =~ /^\{arch\}\/.*$/;
+    return if $file =~ /^$varhash{"PACKAGE"}-$varhash{"VERSION"}\/.*$/;
+}
+
+sub FindLeftoutFiles
+{
+    my (@buf_i18n_plain,
+       @buf_i18n_xml,
+       @buf_i18n_xml_unmarked,
+       @buf_i18n_ini,
+       @buf_potfiles,
+       @buf_potfiles_ignore,
+       @buf_allfiles,
+       @buf_allfiles_sorted,
+       @buf_potfiles_sorted,
+        @buf_potfiles_ignore_sorted
+    );
+
+    ## Search and find all translatable files
+    find sub { 
+       push @buf_i18n_plain,        "$File::Find::name" if /\.($buildin_gettext_support)$/;
+       push @buf_i18n_xml,          "$File::Find::name" if /\.($xml_support)$/;
+       push @buf_i18n_ini,          "$File::Find::name" if /\.($ini_support)$/;
+       push @buf_i18n_xml_unmarked, "$File::Find::name" if /\.(schemas(\.in)+)$/;
+       }, "..";
+    find sub { 
+       push @buf_i18n_plain,        "$File::Find::name" if /\.($buildin_gettext_support)$/;
+       push @buf_i18n_xml,          "$File::Find::name" if /\.($xml_support)$/;
+       push @buf_i18n_ini,          "$File::Find::name" if /\.($ini_support)$/;
+       push @buf_i18n_xml_unmarked, "$File::Find::name" if /\.(schemas(\.in)+)$/;
+       }, "$SRCDIR/.." if "$SRCDIR" ne ".";
+
+    open POTFILES, $POTFILES_in or die "$PROGRAM:  there's no POTFILES.in!\n";
+    @buf_potfiles = grep !/^(#|\s*$)/, <POTFILES>;
+    close POTFILES;
+
+    foreach (@buf_potfiles) {
+       s/^\[.*]\s*//;
+    }
+
+    print "Searching for missing translatable files...\n" if $VERBOSE;
+
+    ## Check if we should ignore some found files, when
+    ## comparing with POTFILES.in
+    foreach my $ignore ("POTFILES.skip", "POTFILES.ignore")
+    {
+       (-s "$SRCDIR/$ignore") or next;
+
+       if ("$ignore" eq "POTFILES.ignore")
+       {
+           print "The usage of POTFILES.ignore is deprecated. Please consider moving the\n".
+                 "content of this file to POTFILES.skip.\n";
+       }
+
+       print "Found $ignore: Ignoring files...\n" if $VERBOSE;
+       open FILE, "<$SRCDIR/$ignore" or die "ERROR: Failed to open $SRCDIR/$ignore!\n";
+           
+       while (<FILE>)
+       {
+           push @buf_potfiles_ignore, $_ unless /^(#|\s*$)/;
+       }
+       close FILE;
+
+       @buf_potfiles_ignore_sorted = sort (@buf_potfiles_ignore);
+    }
+
+    foreach my $file (@buf_i18n_plain)
+    {
+       my $in_comment = 0;
+       my $in_macro = 0;
+
+       open FILE, "<$file";
+       while (<FILE>)
+       {
+           # Handle continued multi-line comment.
+           if ($in_comment)
+           {
+               next unless s-.*\*/--;
+               $in_comment = 0;
+           }
+
+           # Handle continued macro.
+           if ($in_macro)
+           {
+               $in_macro = 0 unless /\\$/;
+               next;
+           }
+
+           # Handle start of macro (or any preprocessor directive).
+           if (/^\s*\#/)
+           {
+               $in_macro = 1 if /^([^\\]|\\.)*\\$/;
+               next;
+           }
+
+           # Handle comments and quoted text.
+           while (m-(/\*|//|\'|\")-) # \' and \" keep emacs perl mode happy
+           {
+               my $match = $1;
+               if ($match eq "/*")
+               {
+                   if (!s-/\*.*?\*/--)
+                   {
+                       s-/\*.*--;
+                       $in_comment = 1;
+                   }
+               }
+               elsif ($match eq "//")
+               {
+                   s-//.*--;
+               }
+               else # ' or "
+               {
+                   if (!s-$match([^\\]|\\.)*?$match-QUOTEDTEXT-)
+                   {
+                       warn "mismatched quotes at line $. in $file\n";
+                       s-$match.*--;
+                   }
+               }
+           }       
+
+           if (/\w\.GetString *\(QUOTEDTEXT/)
+           {
+                if (defined isNotValidMissing (unpack("x3 A*", $file))) {
+                    ## Remove the first 3 chars and add newline
+                    push @buf_allfiles, unpack("x3 A*", $file) . "\n";
+                }
+               last;
+           }
+
+            ## C_ N_ Q_ and _ are the macros defined in gi8n.h
+           if (/[CNQ]?_ *\(QUOTEDTEXT/)
+           {
+                if (defined isNotValidMissing (unpack("x3 A*", $file))) {
+                    ## Remove the first 3 chars and add newline
+                    push @buf_allfiles, unpack("x3 A*", $file) . "\n";
+                }
+               last;
+           }
+       }
+       close FILE;
+    }
+
+    foreach my $file (@buf_i18n_xml) 
+    {
+       open FILE, "<$file";
+       
+       while (<FILE>) 
+       {
+           # FIXME: share the pattern matching code with intltool-extract
+           if (/\s_[-A-Za-z0-9._:]+\s*=\s*\"([^"]+)\"/ || /<_[^>]+>/ || /translatable=\"yes\"/)
+           {
+                if (defined isNotValidMissing (unpack("x3 A*", $file))) {
+                    push @buf_allfiles, unpack("x3 A*", $file) . "\n";
+                }
+               last;
+           }
+       }
+       close FILE;
+    }
+
+    foreach my $file (@buf_i18n_ini)
+    {
+       open FILE, "<$file";
+       while (<FILE>) 
+       {
+           if (/_(.*)=/)
+           {
+                if (defined isNotValidMissing (unpack("x3 A*", $file))) {
+                    push @buf_allfiles, unpack("x3 A*", $file) . "\n";
+                }
+               last;
+           }
+       }
+       close FILE;
+    }
+
+    foreach my $file (@buf_i18n_xml_unmarked)
+    {
+        if (defined isNotValidMissing (unpack("x3 A*", $file))) {
+            push @buf_allfiles, unpack("x3 A*", $file) . "\n";
+        }
+    }
+
+
+    @buf_allfiles_sorted = sort (@buf_allfiles);
+    @buf_potfiles_sorted = sort (@buf_potfiles);
+
+    my %in2;
+    foreach (@buf_potfiles_sorted) 
+    {
+        s#^$SRCDIR/../##;
+        s#^$SRCDIR/##;
+       $in2{$_} = 1;
+    }
+
+    foreach (@buf_potfiles_ignore_sorted) 
+    {
+        s#^$SRCDIR/../##;
+        s#^$SRCDIR/##;
+       $in2{$_} = 1;
+    }
+
+    my @result;
+
+    foreach (@buf_allfiles_sorted)
+    {
+        my $dummy = $_;
+        my $srcdir = $SRCDIR;
+
+        $srcdir =~ s#^../##;
+        $dummy =~ s#^$srcdir/../##;
+        $dummy =~ s#^$srcdir/##;
+        $dummy =~ s#_build/##;
+       if (!exists($in2{$dummy}))
+       {
+           push @result, $dummy
+       }
+    }
+
+    my @buf_potfiles_notexist;
+
+    foreach (@buf_potfiles_sorted)
+    {
+       chomp (my $dummy = $_);
+       if ("$dummy" ne "" and !(-f "$SRCDIR/../$dummy" or -f "../$dummy"))
+       {
+           push @buf_potfiles_notexist, $_;
+       }
+    }
+
+    ## Save file with information about the files missing
+    ## if any, and give information about this procedure.
+    if (@result + @buf_potfiles_notexist > 0)
+    {
+       if (@result) 
+       {
+           print "\n" if $VERBOSE;
+           unlink "missing";
+           open OUT, ">missing";
+           print OUT @result;
+           close OUT;
+           warn "\e[1mThe following files contain translations and are currently not in use. Please\e[0m\n".
+                "\e[1mconsider adding these to the POTFILES.in file, located in the po/ directory.\e[0m\n\n";
+           print STDERR @result, "\n";
+           warn "If some of these files are left out on purpose then please add them to\n".
+                "POTFILES.skip instead of POTFILES.in. A file \e[1m'missing'\e[0m containing this list\n".
+                "of left out files has been written in the current directory.\n";
+       }
+       if (@buf_potfiles_notexist)
+       {
+           unlink "notexist";
+           open OUT, ">notexist";
+           print OUT @buf_potfiles_notexist;
+           close OUT;
+           warn "\n" if ($VERBOSE or @result);
+           warn "\e[1mThe following files do not exist anymore:\e[0m\n\n";
+           warn @buf_potfiles_notexist, "\n";
+           warn "Please remove them from POTFILES.in. A file \e[1m'notexist'\e[0m\n".
+                "containing this list of absent files has been written in the current directory.\n";
+       }
+    }
+
+    ## If there is nothing to complain about, notify the user
+    else {
+       print "\nAll files containing translations are present in POTFILES.in.\n" if $VERBOSE;
+    }
+}
+
+sub Console_WriteError_InvalidOption
+{
+    ## Handle invalid arguments
+    print STDERR "Try `${PROGRAM} --help' for more information.\n";
+    exit 1;
+}
+
+sub isProgramInPath
+{
+    my ($file) = @_;
+    # If either a file exists, or when run it returns 0 exit status
+    return 1 if ((-x $file) or (system("$file --version >$devnull") == 0));
+    return 0;
+}
+
+sub isGNUGettextTool
+{
+    my ($file) = @_;
+    # Check that we are using GNU gettext tools
+    if (isProgramInPath ($file))
+    {
+        my $version = `$file --version`;
+        return 1 if ($version =~ m/.*\(GNU .*\).*/);
+    }
+    return 0;
+}
+
+sub GenerateHeaders
+{
+    my $EXTRACT = $ENV{"INTLTOOL_EXTRACT"} || "intltool-extract";
+
+    ## Generate the .h header files, so we can allow glade and
+    ## xml translation support
+    if (! isProgramInPath ("$EXTRACT"))
+    {
+       print STDERR "\n *** The intltool-extract script wasn't found!"
+            ."\n *** Without it, intltool-update can not generate files.\n";
+       exit;
+    }
+    else
+    {
+       open (FILE, $POTFILES_in) or die "$PROGRAM: POTFILES.in not found.\n";
+       
+       while (<FILE>) 
+       {
+          chomp;
+          next if /^\[\s*encoding/;
+
+          ## Find xml files in POTFILES.in and generate the
+          ## files with help from the extract script
+
+          my $gettext_type= &POFile_DetermineType ($1);
+
+          if (/\.($xml_support|$ini_support)$/ || /^\[/)
+          {
+              s/^\[[^\[].*]\s*//;
+
+              my $filename = "../$_";
+
+              if ($VERBOSE)
+              {
+                  system ($EXTRACT, "--update", "--srcdir=$SRCDIR",
+                          "--type=$gettext_type", $filename);
+              } 
+              else 
+              {
+                  system ($EXTRACT, "--update", "--type=$gettext_type", 
+                          "--srcdir=$SRCDIR", "--quiet", $filename);
+              }
+          }
+       }
+       close FILE;
+   }
+}
+
+#
+# Generate .pot file from POTFILES.in
+#
+sub GeneratePOTemplate
+{
+    my $XGETTEXT = $ENV{"XGETTEXT"} || "xgettext";
+    my $XGETTEXT_ARGS = $ENV{"XGETTEXT_ARGS"} || '';
+    chomp $XGETTEXT;
+
+    if (! isGNUGettextTool ("$XGETTEXT"))
+    {
+       print STDERR " *** GNU xgettext is not found on this system!\n".
+                    " *** Without it, intltool-update can not extract strings.\n";
+       exit;
+    }
+
+    print "Building $MODULE.pot...\n" if $VERBOSE;
+
+    open INFILE, $POTFILES_in;
+    unlink "POTFILES.in.temp";
+    open OUTFILE, ">POTFILES.in.temp" or die("Cannot open POTFILES.in.temp for writing");
+
+    my $gettext_support_nonascii = 0;
+
+    # checks for GNU gettext >= 0.12
+    my $dummy = `$XGETTEXT --version --from-code=UTF-8 >$devnull 2>$devnull`;
+    if ($? == 0)
+    {
+       $gettext_support_nonascii = 1;
+    }
+    else
+    {
+       # urge everybody to upgrade gettext
+       print STDERR "WARNING: This version of gettext does not support extracting non-ASCII\n".
+                    "         strings. That means you should install a version of gettext\n".
+                    "         that supports non-ASCII strings (such as GNU gettext >= 0.12),\n".
+                    "         or have to let non-ASCII strings untranslated. (If there is any)\n";
+    }
+
+    my $encoding = "ASCII";
+    my $forced_gettext_code;
+    my @temp_headers;
+    my $encoding_problem_is_reported = 0;
+
+    while (<INFILE>) 
+    {
+       next if (/^#/ or /^\s*$/);
+
+       chomp;
+
+       my $gettext_code;
+
+       if (/^\[\s*encoding:\s*(.*)\s*\]/)
+       {
+           $forced_gettext_code=$1;
+       }
+       elsif (/\.($xml_support|$ini_support)$/ || /^\[/)
+       {
+           s/^\[.*]\s*//;
+            print OUTFILE "../$_.h\n";
+           push @temp_headers, "../$_.h";
+           $gettext_code = &TextFile_DetermineEncoding ("../$_.h") if ($gettext_support_nonascii and not defined $forced_gettext_code);
+       } 
+       else 
+       {
+            print OUTFILE "$SRCDIR/../$_\n";
+           $gettext_code = &TextFile_DetermineEncoding ("$SRCDIR/../$_") if ($gettext_support_nonascii and not defined $forced_gettext_code);
+       }
+
+       next if (! $gettext_support_nonascii);
+
+       if (defined $forced_gettext_code)
+       {
+           $encoding=$forced_gettext_code;
+       }
+       elsif (defined $gettext_code and "$encoding" ne "$gettext_code")
+       {
+           if ($encoding eq "ASCII")
+           {
+               $encoding=$gettext_code;
+           }
+           elsif ($gettext_code ne "ASCII")
+           {
+               # Only report once because the message is quite long
+               if (! $encoding_problem_is_reported)
+               {
+                   print STDERR "WARNING: You should use the same file encoding for all your project files,\n".
+                                "         but $PROGRAM thinks that most of the source files are in\n".
+                                "         $encoding encoding, while \"$_\" is (likely) in\n".
+                                "         $gettext_code encoding. If you are sure that all translatable strings\n".
+                                "         are in same encoding (say UTF-8), please \e[1m*prepend*\e[0m the following\n".
+                                "         line to POTFILES.in:\n\n".
+                                "                 [encoding: UTF-8]\n\n".
+                                "         and make sure that configure.in/ac checks for $PACKAGE >= 0.27 .\n".
+                                "(such warning message will only be reported once.)\n";
+                   $encoding_problem_is_reported = 1;
+               }
+           }
+       }
+    }
+
+    close OUTFILE;
+    close INFILE;
+
+    unlink "$MODULE.pot";
+    my @xgettext_argument=("$XGETTEXT",
+                          "--add-comments",
+                          "--directory\=.",
+                           "--default-domain\=$MODULE",
+                           "--flag\=g_strdup_printf:1:c-format",
+                           "--flag\=g_string_printf:2:c-format",
+                           "--flag\=g_string_append_printf:2:c-format",
+                           "--flag\=g_error_new:3:c-format",
+                           "--flag\=g_set_error:4:c-format",
+                           "--flag\=g_markup_printf_escaped:1:c-format",
+                           "--flag\=g_log:3:c-format",
+                           "--flag\=g_print:1:c-format",
+                           "--flag\=g_printerr:1:c-format",
+                           "--flag\=g_printf:1:c-format",
+                           "--flag\=g_fprintf:2:c-format",
+                           "--flag\=g_sprintf:2:c-format",
+                           "--flag\=g_snprintf:3:c-format",
+                           "--flag\=g_scanner_error:2:c-format",
+                           "--flag\=g_scanner_warn:2:c-format",
+                          "--output\=$MODULE\.pot",
+                          "--files-from\=\.\/POTFILES\.in\.temp");
+    my $XGETTEXT_KEYWORDS = &FindPOTKeywords;
+    push @xgettext_argument, $XGETTEXT_KEYWORDS;
+    my $MSGID_BUGS_ADDRESS = &FindMakevarsBugAddress;
+    push @xgettext_argument, "--msgid-bugs-address\=\"$MSGID_BUGS_ADDRESS\"" if $MSGID_BUGS_ADDRESS;
+    push @xgettext_argument, "--from-code\=$encoding" if ($gettext_support_nonascii);
+    push @xgettext_argument, $XGETTEXT_ARGS if $XGETTEXT_ARGS;
+    my $xgettext_command = join ' ', @xgettext_argument;
+
+    # intercept xgettext error message
+    print "Running $xgettext_command\n" if $VERBOSE;
+    my $xgettext_error_msg = `$xgettext_command 2>\&1`;
+    my $command_failed = $?;
+
+    unlink "POTFILES.in.temp";
+
+    print "Removing generated header (.h) files..." if $VERBOSE;
+    unlink foreach (@temp_headers);
+    print "done.\n" if $VERBOSE;
+
+    if (! $command_failed)
+    {
+       if (! -e "$MODULE.pot")
+       {
+           print "None of the files in POTFILES.in contain strings marked for translation.\n" if $VERBOSE;
+       }
+       else
+       {
+           print "Wrote $MODULE.pot\n" if $VERBOSE;
+       }
+    }
+    else
+    {
+       if ($xgettext_error_msg =~ /--from-code/)
+       {
+           # replace non-ASCII error message with a more useful one.
+           print STDERR "ERROR: xgettext failed to generate PO template file because there is non-ASCII\n".
+                        "       string marked for translation. Please make sure that all strings marked\n".
+                        "       for translation are in uniform encoding (say UTF-8), then \e[1m*prepend*\e[0m the\n".
+                        "       following line to POTFILES.in and rerun $PROGRAM:\n\n".
+                        "           [encoding: UTF-8]\n\n";
+       }
+       else
+       {
+           print STDERR "$xgettext_error_msg";
+           if (-e "$MODULE.pot")
+           {
+               # is this possible?
+               print STDERR "ERROR: xgettext failed but still managed to generate PO template file.\n".
+                            "       Please consult error message above if there is any.\n";
+           }
+           else
+           {
+               print STDERR "ERROR: xgettext failed to generate PO template file. Please consult\n".
+                            "       error message above if there is any.\n";
+           }
+       }
+       exit (1);
+    }
+}
+
+sub POFile_Update
+{
+    -f "$MODULE.pot" or die "$PROGRAM: $MODULE.pot does not exist.\n";
+
+    my $MSGMERGE = $ENV{"MSGMERGE"} || "msgmerge";
+    my ($lang, $outfile) = @_;
+
+    if (! isGNUGettextTool ("$MSGMERGE"))
+    {
+       print STDERR " *** GNU msgmerge is not found on this system!\n".
+                    " *** Without it, intltool-update can not extract strings.\n";
+       exit;
+    }
+
+    print "Merging $SRCDIR/$lang.po with $MODULE.pot..." if $VERBOSE;
+
+    my $infile = "$SRCDIR/$lang.po";
+    $outfile = "$SRCDIR/$lang.po" if ($outfile eq "");
+
+    # I think msgmerge won't overwrite old file if merge is not successful
+    system ("$MSGMERGE", "-o", $outfile, $infile, "$MODULE.pot");
+}
+
+sub Console_WriteError_NotExisting
+{
+    my ($file) = @_;
+
+    ## Report error if supplied language file is non-existing
+    print STDERR "$PROGRAM: $file does not exist!\n";
+    print STDERR "Try '$PROGRAM --help' for more information.\n";
+    exit;
+}
+
+sub GatherPOFiles
+{
+    my @po_files = glob ("./*.po");
+
+    @languages = map (&POFile_GetLanguage, @po_files);
+
+    foreach my $lang (@languages) 
+    {
+       $po_files_by_lang{$lang} = shift (@po_files);
+    }
+}
+
+sub POFile_GetLanguage ($)
+{
+    s/^(.*\/)?(.+)\.po$/$2/;
+    return $_;
+}
+
+sub Console_Write_TranslationStatus
+{
+    my ($lang, $output_file) = @_;
+    my $MSGFMT = $ENV{"MSGFMT"} || "msgfmt";
+
+    if (! isGNUGettextTool ("$MSGFMT"))
+    {
+       print STDERR " *** GNU msgfmt is not found on this system!\n".
+                    " *** Without it, intltool-update can not extract strings.\n";
+       exit;
+    }
+
+    $output_file = "$SRCDIR/$lang.po" if ($output_file eq "");
+
+    system ("$MSGFMT", "-o", "$devnull", "--verbose", $output_file);
+}
+
+sub Console_Write_CoverageReport
+{
+    my $MSGFMT = $ENV{"MSGFMT"} || "msgfmt";
+
+    if (! isGNUGettextTool ("$MSGFMT"))
+    {
+       print STDERR " *** GNU msgfmt is not found on this system!\n".
+                    " *** Without it, intltool-update can not extract strings.\n";
+       exit;
+    }
+
+    &GatherPOFiles;
+
+    foreach my $lang (@languages) 
+    {
+       print STDERR "$lang: ";
+       &POFile_Update ($lang, "");
+    }
+
+    print STDERR "\n\n * Current translation support in $MODULE \n\n";
+
+    foreach my $lang (@languages)
+    {
+       print STDERR "$lang: ";
+       system ("$MSGFMT", "-o", "$devnull", "--verbose", "$SRCDIR/$lang.po");
+    }
+}
+
+sub SubstituteVariable
+{
+    my ($str) = @_;
+    
+    # always need to rewind file whenever it has been accessed
+    seek (CONF, 0, 0);
+
+    # cache each variable. varhash is global to we can add
+    # variables elsewhere.
+    while (<CONF>)
+    {
+       if (/^(\w+)=(.*)$/)
+       {
+           ($varhash{$1} = $2) =~  s/^["'](.*)["']$/$1/;
+       }
+    }
+    
+    if ($str =~ /^(.*)\${?([A-Z_]+)}?(.*)$/)
+    {
+       my $rest = $3;
+       my $untouched = $1;
+       my $sub = "";
+        # Ignore recursive definitions of variables
+        $sub = $varhash{$2} if defined $varhash{$2} and $varhash{$2} !~ /\${?$2}?/;
+
+       return SubstituteVariable ("$untouched$sub$rest");
+    }
+    
+    # We're using Perl backticks ` and "echo -n" here in order to 
+    # expand any shell escapes (such as backticks themselves) in every variable
+    return echo_n ($str);
+}
+
+sub CONF_Handle_Open
+{
+    my $base_dirname = getcwd();
+    $base_dirname =~ s@.*/@@;
+
+    my ($conf_in, $src_dir);
+
+    if ($base_dirname =~ /^po(-.+)?$/) 
+    {
+       if (-f "Makevars") 
+       {
+           my $makefile_source;
+
+           local (*IN);
+           open (IN, "<Makevars") || die "can't open Makevars: $!";
+
+           while (<IN>) 
+           {
+               if (/^top_builddir[ \t]*=/) 
+               {
+                   $src_dir = $_;
+                   $src_dir =~ s/^top_builddir[ \t]*=[ \t]*([^ \t\n\r]*)/$1/;
+
+                   chomp $src_dir;
+                    if (-f "$src_dir" . "/configure.ac") {
+                        $conf_in = "$src_dir" . "/configure.ac" . "\n";
+                    } else {
+                        $conf_in = "$src_dir" . "/configure.in" . "\n";
+                    }
+                   last;
+               }
+           }
+           close IN;
+
+           $conf_in || die "Cannot find top_builddir in Makevars.";
+       }
+       elsif (-f "$SRCDIR/../configure.ac") 
+       {
+           $conf_in = "$SRCDIR/../configure.ac";
+       } 
+       elsif (-f "$SRCDIR/../configure.in") 
+       {
+           $conf_in = "$SRCDIR/../configure.in";
+       } 
+       else 
+       {
+           my $makefile_source;
+
+           local (*IN);
+           open (IN, "<Makefile") || return;
+
+           while (<IN>) 
+           {
+               if (/^top_srcdir[ \t]*=/) 
+               {
+                   $src_dir = $_;                  
+                   $src_dir =~ s/^top_srcdir[ \t]*=[ \t]*([^ \t\n\r]*)/$1/;
+
+                   chomp $src_dir;
+                   $conf_in = "$src_dir" . "/configure.in" . "\n";
+
+                   last;
+               }
+           }
+           close IN;
+
+           $conf_in || die "Cannot find top_srcdir in Makefile.";
+       }
+
+       open (CONF, "<$conf_in");
+    }
+    else
+    {
+       print STDERR "$PROGRAM: Unable to proceed.\n" .
+                    "Make sure to run this script inside the po directory.\n";
+       exit;
+    }
+}
+
+sub FindPackageName
+{
+    my $version;
+    my $domain = &FindMakevarsDomain;
+    my $name = $domain || "untitled";
+
+    &CONF_Handle_Open;
+
+    my $conf_source; {
+       local (*IN);
+       open (IN, "<&CONF") || return $name;
+       seek (IN, 0, 0);
+       local $/; # slurp mode
+       $conf_source = <IN>;
+       close IN;
+    }
+
+    # priority for getting package name:
+    # 1. GETTEXT_PACKAGE
+    # 2. first argument of AC_INIT (with >= 2 arguments)
+    # 3. first argument of AM_INIT_AUTOMAKE (with >= 2 argument)
+
+    # /^AM_INIT_AUTOMAKE\([\s\[]*([^,\)\s\]]+)/m 
+    # the \s makes this not work, why?
+    if ($conf_source =~ /^AM_INIT_AUTOMAKE\(([^,\)]+),([^,\)]+)/m)
+    {
+       ($name, $version) = ($1, $2);
+       $name    =~ s/[\[\]\s]//g;
+       $version =~ s/[\[\]\s]//g;
+       $varhash{"PACKAGE_NAME"} = $name if (not $name =~ /\${?AC_PACKAGE_NAME}?/);
+       $varhash{"PACKAGE"} = $name if (not $name =~ /\${?PACKAGE}?/);
+       $varhash{"PACKAGE_VERSION"} = $version if (not $name =~ /\${?AC_PACKAGE_VERSION}?/);
+       $varhash{"VERSION"} = $version if (not $name =~ /\${?VERSION}?/);
+    }
+    
+    if ($conf_source =~ /^AC_INIT\(([^,\)]+),([^,\)]+)/m) 
+    {
+       ($name, $version) = ($1, $2);
+       $name    =~ s/[\[\]\s]//g;
+       $version =~ s/[\[\]\s]//g;
+       $varhash{"PACKAGE_NAME"} = $name if (not $name =~ /\${?AC_PACKAGE_NAME}?/);
+       $varhash{"PACKAGE"} = $name if (not $name =~ /\${?PACKAGE}?/);
+       $varhash{"PACKAGE_VERSION"} = $version if (not $name =~ /\${?AC_PACKAGE_VERSION}?/);
+       $varhash{"VERSION"} = $version if (not $name =~ /\${?VERSION}?/);
+    }
+
+    # \s makes this not work, why?
+    $name = $1 if $conf_source =~ /^GETTEXT_PACKAGE=\[?([^\n\]]+)/m;
+    
+    # m4 macros AC_PACKAGE_NAME, AC_PACKAGE_VERSION etc. have same value
+    # as corresponding $PACKAGE_NAME, $PACKAGE_VERSION etc. shell variables.
+    $name =~ s/\bAC_PACKAGE_/\$PACKAGE_/g;
+
+    $name = $domain if $domain;
+
+    $name = SubstituteVariable ($name);
+    $name =~ s/^["'](.*)["']$/$1/;
+
+    return $name if $name;
+}
+
+
+sub FindPOTKeywords
+{
+
+    my $keywords = "--keyword\=\_ --keyword\=N\_ --keyword\=U\_ --keyword\=Q\_";
+    my $varname = "XGETTEXT_OPTIONS";
+    my $make_source; {
+       local (*IN);
+       open (IN, "<Makevars") || (open(IN, "<Makefile.in.in") && ($varname = "XGETTEXT_KEYWORDS")) || return $keywords;
+       seek (IN, 0, 0);
+       local $/; # slurp mode
+       $make_source = <IN>;
+       close IN;
+    }
+
+    $keywords = $1 if $make_source =~ /^$varname[ ]*=\[?([^\n\]]+)/m;
+    
+    return $keywords;
+}
+
+sub FindMakevarsDomain
+{
+
+    my $domain = "";
+    my $makevars_source; { 
+       local (*IN);
+       open (IN, "<Makevars") || return $domain;
+       seek (IN, 0, 0);
+       local $/; # slurp mode
+       $makevars_source = <IN>;
+       close IN;
+    }
+
+    $domain = $1 if $makevars_source =~ /^DOMAIN[ ]*=\[?([^\n\]\$]+)/m;
+    $domain =~ s/^\s+//;
+    $domain =~ s/\s+$//;
+    
+    return $domain;
+}
+
+sub FindMakevarsBugAddress
+{
+
+    my $address = "";
+    my $makevars_source; { 
+       local (*IN);
+       open (IN, "<Makevars") || return undef;
+       seek (IN, 0, 0);
+       local $/; # slurp mode
+       $makevars_source = <IN>;
+       close IN;
+    }
+
+    $address = $1 if $makevars_source =~ /^MSGID_BUGS_ADDRESS[ ]*=\[?([^\n\]\$]+)/m;
+    $address =~ s/^\s+//;
+    $address =~ s/\s+$//;
+    
+    return $address;
+}
index e8d6a4730f6305865e6818bac49de5a436b30927..c138dfa0b06d81b0df263291aac83e25b0837e40 100644 (file)
@@ -42,11 +42,11 @@ endif
 # All library code is statically linked to avoid problems with other lib NLMs.
 # Edit the path below to point to your libpng sources or set environment var.
 ifndef LIBPNG
-LIBPNG = $(LIBBASE)/libpng-1.2.23
+LIBPNG = $(LIBBASE)/libpng-1.2.16
 endif
 # Edit the path below to point to your freetype sources or set environment var.
 ifndef LIBFT2
-LIBFT2 = $(LIBBASE)/freetype-2.3.5
+LIBFT2 = $(LIBBASE)/freetype-2.3.4
 endif
 # Edit the path below to point to your libart sources or set environment var.
 ifndef LIBART
@@ -61,17 +61,13 @@ endif
 ifndef DISTDIR
 DISTDIR        = rrdtool-$(RRD_VERSION_STR)-nw
 endif
-ifndef DISTARC
-DISTARC = $(DISTDIR).$(ARCEXT)
-endif
+DISTARC = $(DISTDIR).zip
 
 # Edit the path below to point to your distribution folder.
 ifndef DEVLDIR
 DEVLDIR        = rrdtool-$(RRD_VERSION_STR)-sdk-nw
 endif
-ifndef DEVLARC
-DEVLARC = $(DEVLDIR).$(ARCEXT)
-endif
+DEVLARC = $(DEVLDIR).zip
 
 # whatever...
 # NO_NULL_REALLOC = 1
@@ -102,14 +98,8 @@ FIXNLMN     = fixnlmname #-q
 # Here you can find a native Win32 binary of the original awk:
 # http://www.gknw.net/development/prgtools/awk.zip
 AWK    = awk
+ZIP    = zip -qzr9
 MV     = mv -fv
-ifndef ARCBIN
-ARCBIN = zip -qzr9
-ARCEXT = zip
-#ARCBIN        = 7za a
-#ARCEXT        = 7z
-endif
-
 
 # must be equal to DEBUG or NDEBUG
 DB     = NDEBUG
@@ -291,7 +281,7 @@ OBJS        := $(RRDLIBOBJS) $(XLIBOBJS) $(PNGLIBOBJS) $(ARTLIBOBJS) $(ZLIBOBJS)
 OBJCGI := $(OBJS) $(OBJDIR)/rrd_cgi.o
 OBJTOOL        := $(OBJS) $(OBJDIR)/rrd_tool.o
 
-LDLIBS += $(LIBFT2)/builds/netware/LIBC/libft2.$(LIBEXT)
+LDLIBS += $(LIBFT2)/builds/netware/libc/libft2.$(LIBEXT)
 
 
 all: rrdtool rrdcgi
@@ -312,7 +302,7 @@ dist: all $(DISTDIR) $(DISTDIR)/readme.txt
        @-$(CP) $(PROOT)/NEWS $(DISTDIR)
        @-$(CP) $(PROOT)/README $(DISTDIR)
        @echo Creating $(DISTARC)
-       @$(ARCBIN) $(DISTARC) $(DISTDIR)/* < $(DISTDIR)/readme.txt
+       @$(ZIP) $(DISTARC) $(DISTDIR)/* < $(DISTDIR)/readme.txt
 
 dev: librrd $(DEVLDIR) $(DEVLDIR)/readme.txt
        @-mkdir $(DEVLDIR)$(DS)include
@@ -328,7 +318,7 @@ dev: librrd $(DEVLDIR) $(DEVLDIR)/readme.txt
        @-$(CP) $(PROOT)/NEWS $(DEVLDIR)
        @-$(CP) $(PROOT)/README $(DEVLDIR)
        @echo Creating $(DEVLARC)
-       @$(ARCBIN) $(DEVLARC) $(DEVLDIR)/* < $(DEVLDIR)/readme.txt
+       @$(ZIP) $(DEVLARC) $(DEVLDIR)/* < $(DEVLDIR)/readme.txt
 
 clean:
        -$(RM) -r $(OBJDIR)
diff --git a/po/ChangeLog b/po/ChangeLog
new file mode 100644 (file)
index 0000000..8251db8
--- /dev/null
@@ -0,0 +1 @@
+# no change log yet
diff --git a/po/LINGUAS b/po/LINGUAS
new file mode 100644 (file)
index 0000000..46ae20d
--- /dev/null
@@ -0,0 +1,2 @@
+de
+
diff --git a/po/Makefile.in.in b/po/Makefile.in.in
new file mode 100644 (file)
index 0000000..b630d54
--- /dev/null
@@ -0,0 +1,218 @@
+# Makefile for program source directory in GNU NLS utilities package.
+# Copyright (C) 1995, 1996, 1997 by Ulrich Drepper <drepper@gnu.ai.mit.edu>
+#
+# This file file be copied and used freely without restrictions.  It can
+# be used in projects which are not available under the GNU Public License
+# but which still want to provide support for the GNU gettext functionality.
+# Please note that the actual code is *not* freely available.
+#
+# - Modified by Owen Taylor <otaylor@redhat.com> to use GETTEXT_PACKAGE
+#   instead of PACKAGE and to look for po2tbl in ./ not in intl/
+#
+# - Modified by jacob berkman <jacob@ximian.com> to install
+#   Makefile.in.in and po2tbl.sed.in for use with glib-gettextize
+#
+# - Modified by Rodney Dawes <dobey@novell.com> for use with intltool
+#
+# We have the following line for use by intltoolize:
+# INTLTOOL_MAKEFILE
+
+GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
+PACKAGE = @PACKAGE@
+VERSION = @VERSION@
+
+SHELL = /bin/sh
+
+srcdir = @srcdir@
+top_srcdir = @top_srcdir@
+top_builddir = @top_builddir@
+VPATH = @srcdir@
+
+prefix = @prefix@
+exec_prefix = @exec_prefix@
+datadir = @datadir@
+datarootdir = @datarootdir@
+libdir = @libdir@
+DATADIRNAME = @DATADIRNAME@
+itlocaledir = $(prefix)/$(DATADIRNAME)/locale
+subdir = po
+install_sh = @install_sh@
+# Automake >= 1.8 provides @mkdir_p@.
+# Until it can be supposed, use the safe fallback:
+mkdir_p = $(install_sh) -d
+
+INSTALL = @INSTALL@
+INSTALL_DATA = @INSTALL_DATA@
+
+GMSGFMT = @GMSGFMT@
+MSGFMT = @MSGFMT@
+XGETTEXT = @XGETTEXT@
+INTLTOOL_UPDATE = @INTLTOOL_UPDATE@
+INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@
+MSGMERGE = INTLTOOL_EXTRACT=$(INTLTOOL_EXTRACT) srcdir=$(srcdir) $(INTLTOOL_UPDATE) --gettext-package $(GETTEXT_PACKAGE) --dist
+GENPOT   = INTLTOOL_EXTRACT=$(INTLTOOL_EXTRACT) srcdir=$(srcdir) $(INTLTOOL_UPDATE) --gettext-package $(GETTEXT_PACKAGE) --pot
+
+ALL_LINGUAS = @ALL_LINGUAS@
+
+PO_LINGUAS=$(shell if test -r $(srcdir)/LINGUAS; then grep -v "^\#" $(srcdir)/LINGUAS; fi)
+
+USER_LINGUAS=$(shell if test -n "$(LINGUAS)"; then LLINGUAS="$(LINGUAS)"; ALINGUAS="$(ALL_LINGUAS)"; for lang in $$LLINGUAS; do if test -n "`grep ^$$lang$$ $(srcdir)/LINGUAS`" -o -n "`echo $$ALINGUAS|grep ' ?$$lang ?'`"; then printf "$$lang "; fi; done; fi)
+
+USE_LINGUAS=$(shell if test -n "$(USER_LINGUAS)"; then LLINGUAS="$(USER_LINGUAS)"; else if test -n "$(PO_LINGUAS)"; then LLINGUAS="$(PO_LINGUAS)"; else LLINGUAS="$(ALL_LINGUAS)"; fi; fi; for lang in $$LLINGUAS; do printf "$$lang "; done)
+
+POFILES=$(shell LINGUAS="$(USE_LINGUAS)"; for lang in $$LINGUAS; do printf "$$lang.po "; done)
+
+DISTFILES = ChangeLog Makefile.in.in POTFILES.in $(POFILES)
+EXTRA_DISTFILES = POTFILES.skip Makevars LINGUAS
+
+POTFILES = \
+# This comment gets stripped out
+
+CATALOGS=$(shell LINGUAS="$(USE_LINGUAS)"; for lang in $$LINGUAS; do printf "$$lang.gmo "; done)
+
+.SUFFIXES:
+.SUFFIXES: .po .pox .gmo .mo .msg .cat
+
+.po.pox:
+       $(MAKE) $(GETTEXT_PACKAGE).pot
+       $(MSGMERGE) $< $(GETTEXT_PACKAGE).pot -o $*.pox
+
+.po.mo:
+       $(MSGFMT) -o $@ $<
+
+.po.gmo:
+       file=`echo $* | sed 's,.*/,,'`.gmo \
+         && rm -f $$file && $(GMSGFMT) -o $$file $<
+
+.po.cat:
+       sed -f ../intl/po2msg.sed < $< > $*.msg \
+         && rm -f $@ && gencat $@ $*.msg
+
+
+all: all-@USE_NLS@
+
+all-yes: $(CATALOGS)
+all-no:
+
+$(GETTEXT_PACKAGE).pot: $(POTFILES)
+       $(GENPOT)
+
+install: install-data
+install-data: install-data-@USE_NLS@
+install-data-no: all
+install-data-yes: all
+       $(mkdir_p) $(DESTDIR)$(itlocaledir)
+       linguas="$(USE_LINGUAS)"; \
+       for lang in $$linguas; do \
+         dir=$(DESTDIR)$(itlocaledir)/$$lang/LC_MESSAGES; \
+         $(mkdir_p) $$dir; \
+         if test -r $$lang.gmo; then \
+           $(INSTALL_DATA) $$lang.gmo $$dir/$(GETTEXT_PACKAGE).mo; \
+           echo "installing $$lang.gmo as $$dir/$(GETTEXT_PACKAGE).mo"; \
+         else \
+           $(INSTALL_DATA) $(srcdir)/$$lang.gmo $$dir/$(GETTEXT_PACKAGE).mo; \
+           echo "installing $(srcdir)/$$lang.gmo as" \
+                "$$dir/$(GETTEXT_PACKAGE).mo"; \
+         fi; \
+         if test -r $$lang.gmo.m; then \
+           $(INSTALL_DATA) $$lang.gmo.m $$dir/$(GETTEXT_PACKAGE).mo.m; \
+           echo "installing $$lang.gmo.m as $$dir/$(GETTEXT_PACKAGE).mo.m"; \
+         else \
+           if test -r $(srcdir)/$$lang.gmo.m ; then \
+             $(INSTALL_DATA) $(srcdir)/$$lang.gmo.m \
+               $$dir/$(GETTEXT_PACKAGE).mo.m; \
+             echo "installing $(srcdir)/$$lang.gmo.m as" \
+                  "$$dir/$(GETTEXT_PACKAGE).mo.m"; \
+           else \
+             true; \
+           fi; \
+         fi; \
+       done
+
+# Empty stubs to satisfy archaic automake needs
+dvi info tags TAGS ID:
+
+# Define this as empty until I found a useful application.
+install-exec installcheck:
+
+uninstall:
+       linguas="$(USE_LINGUAS)"; \
+       for lang in $$linguas; do \
+         rm -f $(DESTDIR)$(itlocaledir)/$$lang/LC_MESSAGES/$(GETTEXT_PACKAGE).mo; \
+         rm -f $(DESTDIR)$(itlocaledir)/$$lang/LC_MESSAGES/$(GETTEXT_PACKAGE).mo.m; \
+       done
+
+check: all $(GETTEXT_PACKAGE).pot
+       rm -f missing notexist
+       srcdir=$(srcdir) $(INTLTOOL_UPDATE) -m
+       if [ -r missing -o -r notexist ]; then \
+         exit 1; \
+       fi
+
+mostlyclean:
+       rm -f *.pox $(GETTEXT_PACKAGE).pot *.old.po cat-id-tbl.tmp
+       rm -f .intltool-merge-cache
+
+clean: mostlyclean
+
+distclean: clean
+       rm -f Makefile Makefile.in POTFILES stamp-it
+       rm -f *.mo *.msg *.cat *.cat.m *.gmo
+
+maintainer-clean: distclean
+       @echo "This command is intended for maintainers to use;"
+       @echo "it deletes files that may require special tools to rebuild."
+       rm -f Makefile.in.in
+
+distdir = ../$(PACKAGE)-$(VERSION)/$(subdir)
+dist distdir: $(DISTFILES)
+       dists="$(DISTFILES)"; \
+       extra_dists="$(EXTRA_DISTFILES)"; \
+       for file in $$extra_dists; do \
+         test -f $(srcdir)/$$file && dists="$$dists $(srcdir)/$$file"; \
+       done; \
+       for file in $$dists; do \
+         test -f $$file || file="$(srcdir)/$$file"; \
+         ln $$file $(distdir) 2> /dev/null \
+           || cp -p $$file $(distdir); \
+       done
+
+update-po: Makefile
+       $(MAKE) $(GETTEXT_PACKAGE).pot
+       tmpdir=`pwd`; \
+       linguas="$(USE_LINGUAS)"; \
+       for lang in $$linguas; do \
+         echo "$$lang:"; \
+         result="`$(MSGMERGE) -o $$tmpdir/$$lang.new.po $$lang`"; \
+         if $$result; then \
+           if cmp $(srcdir)/$$lang.po $$tmpdir/$$lang.new.po >/dev/null 2>&1; then \
+             rm -f $$tmpdir/$$lang.new.po; \
+            else \
+             if mv -f $$tmpdir/$$lang.new.po $$lang.po; then \
+               :; \
+             else \
+               echo "msgmerge for $$lang.po failed: cannot move $$tmpdir/$$lang.new.po to $$lang.po" 1>&2; \
+               rm -f $$tmpdir/$$lang.new.po; \
+               exit 1; \
+             fi; \
+           fi; \
+         else \
+           echo "msgmerge for $$lang.gmo failed!"; \
+           rm -f $$tmpdir/$$lang.new.po; \
+         fi; \
+       done
+
+Makefile POTFILES: stamp-it
+       @if test ! -f $@; then \
+         rm -f stamp-it; \
+         $(MAKE) stamp-it; \
+       fi
+
+stamp-it: Makefile.in.in $(top_builddir)/config.status POTFILES.in
+       cd $(top_builddir) \
+         && CONFIG_FILES=$(subdir)/Makefile.in CONFIG_HEADERS= CONFIG_LINKS= \
+              $(SHELL) ./config.status
+
+# Tell versions [3.59,3.63) of GNU make not to export all variables.
+# Otherwise a system limit (for SysV at least) may be exceeded.
+.NOEXPORT:
diff --git a/po/POTFILES.in b/po/POTFILES.in
new file mode 100644 (file)
index 0000000..eeacfcb
--- /dev/null
@@ -0,0 +1,2 @@
+src/rrd_getopt.c
+src/rrd_tool.c
diff --git a/po/de.po b/po/de.po
new file mode 100644 (file)
index 0000000..4c556c7
--- /dev/null
+++ b/po/de.po
@@ -0,0 +1,334 @@
+#: ../src/rrd_getopt.c:615
+#, c-format
+msgid "%s: option `%s' is ambiguous\n"
+msgstr ""
+
+#: ../src/rrd_getopt.c:637
+#, c-format
+msgid "%s: option `--%s' doesn't allow an argument\n"
+msgstr ""
+
+#: ../src/rrd_getopt.c:643
+#, c-format
+msgid "%s: option `%c%s' doesn't allow an argument\n"
+msgstr ""
+
+#: ../src/rrd_getopt.c:658 ../src/rrd_getopt.c:811
+#, c-format
+msgid "%s: option `%s' requires an argument\n"
+msgstr ""
+
+#. --option
+#: ../src/rrd_getopt.c:684
+#, c-format
+msgid "%s: unrecognized option `--%s'\n"
+msgstr ""
+
+#. +option or -option
+#: ../src/rrd_getopt.c:688
+#, c-format
+msgid "%s: unrecognized option `%c%s'\n"
+msgstr ""
+
+#. 1003.2 specifies the format of this message.
+#: ../src/rrd_getopt.c:712
+#, c-format
+msgid "%s: illegal option -- %c\n"
+msgstr ""
+
+#: ../src/rrd_getopt.c:715
+#, c-format
+msgid "%s: invalid option -- %c\n"
+msgstr ""
+
+#: ../src/rrd_getopt.c:741 ../src/rrd_getopt.c:849
+#, c-format
+msgid "%s: option requires an argument -- %c\n"
+msgstr ""
+
+#: ../src/rrd_getopt.c:783
+#, c-format
+msgid "%s: option `-W %s' is ambiguous\n"
+msgstr ""
+
+#: ../src/rrd_getopt.c:798
+#, c-format
+msgid "%s: option `-W %s' doesn't allow an argument\n"
+msgstr ""
+
+#: ../src/rrd_tool.c:49
+#, c-format
+msgid ""
+"RRDtool %s  Copyright 1997-2007 by Tobias Oetiker <tobi@oetiker.ch>\n"
+"               Compiled %s %s\n"
+"\n"
+"Usage: rrdtool [options] command command_options\n"
+"\n"
+msgstr ""
+
+#: ../src/rrd_tool.c:55
+msgid ""
+"Valid commands: create, update, updatev, graph, dump, restore,\n"
+"\t\tlast, lastupdate, first, info, fetch, tune,\n"
+"\t\tresize, xport\n"
+"\n"
+msgstr ""
+
+#: ../src/rrd_tool.c:60
+msgid ""
+"Valid remote commands: quit, ls, cd, mkdir, pwd\n"
+"\n"
+msgstr ""
+
+#: ../src/rrd_tool.c:64
+msgid ""
+"* create - create a new RRD\n"
+"\n"
+"\trrdtool create filename [--start|-b start time]\n"
+"\t\t[--step|-s step]\n"
+"\t\t[DS:ds-name:DST:dst arguments]\n"
+"\t\t[RRA:CF:cf arguments]\n"
+"\n"
+msgstr ""
+
+#: ../src/rrd_tool.c:71
+msgid ""
+"* dump - dump an RRD to XML\n"
+"\n"
+"\trrdtool dump filename.rrd >filename.xml\n"
+"\n"
+msgstr ""
+
+#: ../src/rrd_tool.c:75
+msgid ""
+"* info - returns the configuration and status of the RRD\n"
+"\n"
+"\trrdtool info filename.rrd\n"
+"\n"
+msgstr ""
+
+#: ../src/rrd_tool.c:79
+msgid ""
+"* restore - restore an RRD file from its XML form\n"
+"\n"
+"\trrdtool restore [--range-check|-r] [--force-overwrite|-f] filename.xml "
+"filename.rrd\n"
+"\n"
+msgstr ""
+
+#: ../src/rrd_tool.c:83
+msgid ""
+"* last - show last update time for RRD\n"
+"\n"
+"\trrdtool last filename.rrd\n"
+"\n"
+msgstr ""
+
+#: ../src/rrd_tool.c:87
+msgid ""
+"* lastupdate - returns the most recent datum stored for\n"
+"  each DS in an RRD\n"
+"\n"
+"\trrdtool lastupdate filename.rrd\n"
+"\n"
+msgstr ""
+
+#: ../src/rrd_tool.c:91
+msgid ""
+"* first - show first update time for RRA within an RRD\n"
+"\n"
+"\trrdtool first filename.rrd [--rraindex number]\n"
+"\n"
+msgstr ""
+
+#: ../src/rrd_tool.c:95
+msgid ""
+"* update - update an RRD\n"
+"\n"
+"\trrdtool update filename\n"
+"\t\t--template|-t ds-name:ds-name:...\n"
+"\t\ttime|N:value[:value...]\n"
+"\n"
+"\t\tat-time@value[:value...]\n"
+"\n"
+"\t\t[ time:value[:value...] ..]\n"
+"\n"
+msgstr ""
+
+#: ../src/rrd_tool.c:103
+msgid ""
+"* updatev - a verbose version of update\n"
+"\treturns information about values, RRAs, and datasources updated\n"
+"\n"
+"\trrdtool updatev filename\n"
+"\t\t--template|-t ds-name:ds-name:...\n"
+"\t\ttime|N:value[:value...]\n"
+"\n"
+"\t\tat-time@value[:value...]\n"
+"\n"
+"\t\t[ time:value[:value...] ..]\n"
+"\n"
+msgstr ""
+
+#: ../src/rrd_tool.c:112
+msgid ""
+"* fetch - fetch data out of an RRD\n"
+"\n"
+"\trrdtool fetch filename.rrd CF\n"
+"\t\t[-r|--resolution resolution]\n"
+"\t\t[-s|--start start] [-e|--end end]\n"
+"\n"
+msgstr ""
+
+#: ../src/rrd_tool.c:120
+msgid ""
+"* graph - generate a graph from one or several RRD\n"
+"\n"
+"\trrdtool graph filename [-s|--start seconds] [-e|--end seconds]\n"
+"\t\t[-x|--x-grid x-axis grid and label]\n"
+"\t\t[-Y|--alt-y-grid]\n"
+"\t\t[-y|--y-grid y-axis grid and label]\n"
+"\t\t[-v|--vertical-label string] [-w|--width pixels]\n"
+"\t\t[-h|--height pixels] [-o|--logarithmic]\n"
+"\t\t[-u|--upper-limit value] [-z|--lazy]\n"
+"\t\t[-l|--lower-limit value] [-r|--rigid]\n"
+"\t\t[-g|--no-legend]\n"
+"\t\t[-F|--force-rules-legend]\n"
+"\t\t[-j|--only-graph]\n"
+msgstr ""
+
+#: ../src/rrd_tool.c:132
+msgid ""
+"\t\t[-n|--font FONTTAG:size:font]\n"
+"\t\t[-m|--zoom factor]\n"
+"\t\t[-A|--alt-autoscale]\n"
+"\t\t[-M|--alt-autoscale-max]\n"
+"\t\t[-R|--font-render-mode {normal,light,mono}]\n"
+"\t\t[-B|--font-smoothing-threshold size]\n"
+"\t\t[-E|--slope-mode]\n"
+"\t\t[-N|--no-gridfit]\n"
+"\t\t[-X|--units-exponent value]\n"
+"\t\t[-L|--units-length value]\n"
+"\t\t[-S|--step seconds]\n"
+"\t\t[-f|--imginfo printfstr]\n"
+"\t\t[-a|--imgformat PNG]\n"
+"\t\t[-c|--color COLORTAG#rrggbb[aa]] [-t|--title string]\n"
+"\t\t[-W|--watermark string]\n"
+"\t\t[DEF:vname=rrd:ds-name:CF]\n"
+msgstr ""
+
+#: ../src/rrd_tool.c:148
+msgid ""
+"\t\t[CDEF:vname=rpn-expression]\n"
+"\t\t[VDEF:vdefname=rpn-expression]\n"
+"\t\t[PRINT:vdefname:format]\n"
+"\t\t[GPRINT:vdefname:format]\n"
+"\t\t[COMMENT:text]\n"
+"\t\t[SHIFT:vname:offset]\n"
+"\t\t[TICK:vname#rrggbb[aa][:[fraction][:legend]]]\n"
+"\t\t[HRULE:value#rrggbb[aa][:legend]]\n"
+"\t\t[VRULE:value#rrggbb[aa][:legend]]\n"
+"\t\t[LINE[width]:vname[#rrggbb[aa][:[legend][:STACK]]]]\n"
+"\t\t[AREA:vname[#rrggbb[aa][:[legend][:STACK]]]]\n"
+"\t\t[PRINT:vname:CF:format] (deprecated)\n"
+"\t\t[GPRINT:vname:CF:format] (deprecated)\n"
+"\t\t[STACK:vname[#rrggbb[aa][:legend]]] (deprecated)\n"
+"\n"
+msgstr ""
+
+#: ../src/rrd_tool.c:164
+msgid ""
+" * tune -  Modify some basic properties of an RRD\n"
+"\n"
+"\trrdtool tune filename\n"
+"\t\t[--heartbeat|-h ds-name:heartbeat]\n"
+"\t\t[--data-source-type|-d ds-name:DST]\n"
+"\t\t[--data-source-rename|-r old-name:new-name]\n"
+"\t\t[--minimum|-i ds-name:min] [--maximum|-a ds-name:max]\n"
+"\t\t[--deltapos scale-value] [--deltaneg scale-value]\n"
+"\t\t[--failure-threshold integer]\n"
+"\t\t[--window-length integer]\n"
+"\t\t[--alpha adaptation-parameter]\n"
+msgstr ""
+
+#: ../src/rrd_tool.c:175
+msgid ""
+" * tune -  Modify some basic properties of an RRD\n"
+"\n"
+"\t\t[--beta adaptation-parameter]\n"
+"\t\t[--gamma adaptation-parameter]\n"
+"\t\t[--gamma-deviation adaptation-parameter]\n"
+"\t\t[--aberrant-reset ds-name]\n"
+"\n"
+msgstr ""
+
+#: ../src/rrd_tool.c:182
+msgid ""
+" * resize - alter the length of one of the RRAs in an RRD\n"
+"\n"
+"\trrdtool resize filename rranum GROW|SHRINK rows\n"
+"\n"
+msgstr ""
+
+#: ../src/rrd_tool.c:186
+msgid ""
+"* xport - generate XML dump from one or several RRD\n"
+"\n"
+"\trrdtool xport [-s|--start seconds] [-e|--end seconds]\n"
+"\t\t[-m|--maxrows rows]\n"
+"\t\t[--step seconds]\n"
+"\t\t[--enumds]\n"
+"\t\t[DEF:vname=rrd:ds-name:CF]\n"
+"\t\t[CDEF:vname=rpn-expression]\n"
+"\t\t[XPORT:vname:legend]\n"
+"\n"
+msgstr ""
+
+#: ../src/rrd_tool.c:195
+msgid ""
+" * quit - closing a session in remote mode\n"
+"\n"
+"\trrdtool quit\n"
+"\n"
+msgstr ""
+
+#: ../src/rrd_tool.c:198
+msgid ""
+" * ls - lists all *.rrd files in current directory\n"
+"\n"
+"\trrdtool ls\n"
+"\n"
+msgstr ""
+
+#: ../src/rrd_tool.c:202
+msgid ""
+" * cd - changes the current directory\n"
+"\n"
+"\trrdtool cd new directory\n"
+"\n"
+msgstr ""
+
+#: ../src/rrd_tool.c:206
+msgid ""
+" * mkdir - creates a new directory\n"
+"\n"
+"\trrdtool mkdir newdirectoryname\n"
+"\n"
+msgstr ""
+
+#: ../src/rrd_tool.c:210
+msgid ""
+" * pwd - returns the current working directory\n"
+"\n"
+"\trrdtool pwd\n"
+"\n"
+msgstr ""
+
+#: ../src/rrd_tool.c:214
+msgid ""
+"RRDtool is distributed under the Terms of the GNU General\n"
+"Public License Version 2. (www.gnu.org/copyleft/gpl.html)\n"
+"\n"
+"For more information read the RRD manpages\n"
+"\n"
+msgstr ""
index 303bac7f39dce8b59289ab5b2f3d2dd0f8bd7696..da08cac315a121057623fb8dbcd7cfc427751dd7 100644 (file)
@@ -14,7 +14,7 @@
 /* realloc does not support NULL as argument */
 #undef NO_NULL_REALLOC
 
-/* lets enable madvise defines in NetBSD */
+/* lets enable madvise defines in NetBSD */ 
 #if defined(__NetBSD__)
 # if !defined(_NETBSD_SOURCE)
 #  define _NETBSD_SOURCE
 
  
 
+/* Use this in code sections to mark them for libintl build */
+#undef BUILD_LIBINTL
+
+/* always defined to indicate that i18n is enabled */
+#undef ENABLE_NLS
+
+/* Gettext package */
+#undef GETTEXT_PACKAGE
+
+/* Define to 1 if you have the `bind_textdomain_codeset' function. */
+#undef HAVE_BIND_TEXTDOMAIN_CODESET
+
 /* Define to 1 if you have the `chdir' function. */
 #undef HAVE_CHDIR
 
 /* Define to 1 if you have the `class' function. */
 #undef HAVE_CLASS
 
-/* Define to 1 if you have the declaration of `fdatasync', and to 0 if you
-   don't. */
-#undef HAVE_DECL_FDATASYNC
+/* Define to 1 if you have the <ctype.h> header file. */
+#undef HAVE_CTYPE_H
+
+/* Define to 1 if you have the `dcgettext' function. */
+#undef HAVE_DCGETTEXT
 
 /* Define to 1 if you have the declaration of `madvise', and to 0 if you
    don't. */
 /* Define to 1 if you don't have `vprintf' but do have `_doprnt.' */
 #undef HAVE_DOPRNT
 
+/* Define to 1 if you have the <errno.h> header file. */
+#undef HAVE_ERRNO_H
+
 /* Define to 1 if you have the <fcntl.h> header file. */
 #undef HAVE_FCNTL_H
 
+/* Define to 1 if you have the `fdatasync' function. */
+#undef HAVE_FDATASYNC
+
 /* Define to 1 if you have the <features.h> header file. */
 #undef HAVE_FEATURES_H
 
 /* Define to 1 if you have the <fp_class.h> header file. */
 #undef HAVE_FP_CLASS_H
 
+/* Define to 1 if you have the `fsync' function. */
+#undef HAVE_FSYNC
+
 /* Define to 1 if you have the `getpagesize' function. */
 #undef HAVE_GETPAGESIZE
 
 /* Define to 1 if you have the `getrusage' function. */
 #undef HAVE_GETRUSAGE
 
+/* Define if the GNU gettext() function is already present or preinstalled. */
+#undef HAVE_GETTEXT
+
 /* Define to 1 if you have the `gettimeofday' function. */
 #undef HAVE_GETTIMEOFDAY
 
 /* Define to 1 if you have the `isnan' function. */
 #undef HAVE_ISNAN
 
+/* Define if your <locale.h> file defines LC_MESSAGES. */
+#undef HAVE_LC_MESSAGES
+
+/* Define to 1 if you have the <libintl.h> header file. */
+#undef HAVE_LIBINTL_H
+
 /* Define to 1 if you have the `m' library (-lm). */
 #undef HAVE_LIBM
 
 /* Define to 1 if you have the `mktime' function. */
 #undef HAVE_MKTIME
 
-/* Define to 1 if you have a working `mmap' system call. */
+/* Define to 1 if you have the `mmap' function. */
 #undef HAVE_MMAP
 
 /* Define to 1 if you have the `msync' function. */
 /* Define to 1 if you have the `setlocale' function. */
 #undef HAVE_SETLOCALE
 
+/* Define to 1 if you have the <signal.h> header file. */
+#undef HAVE_SIGNAL_H
+
 /* Define to 1 if you have the `snprintf' function. */
 #undef HAVE_SNPRINTF
 
 /* Define to 1 if you have the <stdint.h> header file. */
 #undef HAVE_STDINT_H
 
+/* Define to 1 if you have the <stdio.h> header file. */
+#undef HAVE_STDIO_H
+
 /* Define to 1 if you have the <stdlib.h> header file. */
 #undef HAVE_STDLIB_H
 
    your system. */
 #undef PTHREAD_CREATE_JOINABLE
 
-/* Vertical label angle: 90.0 (default) or 270.0 */
+/* Vertical label angle: -90.0 (default) or 90.0 */
 #undef RRDGRAPH_YLEGEND_ANGLE
 
 /* Define to 1 if you have the ANSI C header files. */
 #undef const
 
 
+/* make sure that we pickup the correct stuff from all headers */
 #ifdef HAVE_FEATURES_H
+#undef _XOPEN_SOURCE /* keep unmodified */
+#undef _BSD_SOURCE /* keep unmodified */
 #define _XOPEN_SOURCE 600
-#undef _BSD_SOURCE /* comment to prevent configure from modifying this line */   
 #define _BSD_SOURCE 1
 # include <features.h>
 #endif
 
-#ifdef HAVE_ERRNO_H
-# include <errno.h>
-#endif
-
-#if defined(HAVE_SYS_MMAN_H)
-#include <sys/mman.h>
+/* FreeBSD 4.8 wants this included BEFORE sys/types.h */
+#ifdef HAVE_SYS_MMAN_H
+# include <sys/mman.h>
 #endif
 
 #ifdef HAVE_SYS_TYPES_H
 # endif
 #endif
 
+#ifdef HAVE_ERRNO_H
+# include <errno.h>
+#endif
+
 #if !defined HAVE_MADVISE && defined HAVE_POSIX_MADVISE
 /* use posix_madvise family */
 # define madvise posix_madvise
 # define MADV_WILLNEED POSIX_MADV_WILLNEED
 # define MADV_DONTNEED POSIX_MADV_DONTNEED
 #endif
-
-#if defined POSIX_MADV_RANDOM && !defined MADV_RANDOM
-#define MADV_RANDOM POSIX_MADV_RANDOM
-#endif
-
-
-
 #if defined HAVE_MADVISE || defined HAVE_POSIX_MADVISE
 # define USE_MADVISE 1
 #endif
 #ifdef HAVE_SYS_RESOURCE_H
 # include <sys/resource.h>
 #if (defined(__svr4__) && defined(__sun__))
-/* Solaris headers (pre 2.6) don't have a getrusage prototype.
+/* Solaris headers (pre 2.6) do not have a getrusage prototype. 
    Use this instead. */
 extern int getrusage(int, struct rusage *);
 #endif /* __svr4__ && __sun__ */
 #endif
 
+
 /* define strrchr, strchr and memcpy, memmove in terms of bsd funcs
    make sure you are NOT using bcopy, index or rindex in the code */
       
@@ -389,20 +424,58 @@ char *strchr (), *strrchr ();
 #  include <malloc/malloc.h>
 #endif
 
+#ifdef HAVE_STDIO_H
+# include <stdio.h>
+#endif
+
+#ifdef HAVE_STDLIB_H
+# include <stdlib.h>
+#endif
+
+#ifdef HAVE_CTYPE_H
+# include <ctype.h>
+#endif
+
+#ifdef HAVE_DIRENT_H
+# include <dirent.h>
+# define NAMLEN(dirent) strlen((dirent)->d_name)
+#else
+# define dirent direct
+# define NAMLEN(dirent) (dirent)->d_namlen
+# ifdef HAVE_SYS_NDIR_H
+#  include <sys/ndir.h>
+# endif
+# ifdef HAVE_SYS_DIR_H
+#  include <sys/dir.h>
+# endif
+# ifdef HAVE_NDIR_H
+#  include <ndir.h>
+# endif
+#endif
+
+#ifdef MUST_DISABLE_SIGFPE
+# include <signal.h>
+#endif
+
+#ifdef MUST_DISABLE_FPMASK
+# include <floatingpoint.h>
+#endif
+
+
 #ifdef HAVE_MATH_H
-#  include <math.h>
+# include <math.h>
 #endif
 
 #ifdef HAVE_FLOAT_H
-#  include <float.h>
+# include <float.h>
 #endif
 
 #ifdef HAVE_IEEEFP_H
-#  include <ieeefp.h>
+# include <ieeefp.h>
 #endif
 
 #ifdef HAVE_FP_CLASS_H
-#  include <fp_class.h>
+# include <fp_class.h>
 #endif
 
 /* for Solaris */
@@ -416,7 +489,7 @@ char *strchr (), *strrchr ();
 
 /* solaris 10 it defines isnan such that only forte can compile it ... bad bad  */
 #if (defined(HAVE_ISNAN) && defined(isnan) && defined(HAVE_FPCLASS))
-#  undef isnan  /* confuse autoconf to NOT remove this */
+#  undef isnan /* confuse autoconf to NOT remove this */
 #  define isnan(a) (fpclass(a) == FP_SNAN || fpclass(a) == FP_QNAN)
 #endif
 
@@ -460,5 +533,13 @@ char *strchr (), *strrchr ();
 #error "Can't compile without isinf function"
 #endif
 
+#if (! defined(HAVE_FDATASYNC) && defined(HAVE_FSYNC))
+#define fdatasync fsync
+#endif
+
+#if (!defined(HAVE_FDATASYNC) && !defined(HAVE_FSYNC))
+#error "Can't compile with without fsync and fdatasync"
+#endif
+
 #endif /* RRD_CONFIG_H */
 
index 4db9ea9da09f9a7f0fec21e5feb084d6dd58bb61..09f22b30156dafef954cc77390e37d000d0bc82e 100644 (file)
@@ -7,17 +7,19 @@
 
 Summary: Round Robin Database Tool to store and display time-series data
 Name: rrdtool
-Version: 1.2.27
-Release: 5%{?dist}
+Version: 1.3rc4
+Release: 0.1%{?dist}
 License: GPL
 Group: Applications/Databases
 URL: http://oss.oetiker.ch/rrdtool/
-Source0: http://oss.oetiker.ch/%{name}/pub/%{name}-%{version}.tar.gz
+#Source0: http://oss.oetiker.ch/%{name}/pub/%{name}-%{version}.tar.gz
+Source0: http://oss.oetiker.ch/rrdtool/pub/beta/rrdtool-trunk-svn-snap.tar.gz
 Source1: php4-svn%{php_rrd_svn}.tar.gz
 Patch0: rrdtool-1.2.13-php.patch
 BuildRoot: %{_tmppath}/%{name}-%{version}-%{release}-root-%(%{__id_u} -n)
 BuildRequires: gcc-c++, openssl-devel, freetype-devel
-BuildRequires: libpng-devel, zlib-devel, libart_lgpl-devel >= 2.0
+BuildRequires: libpng-devel, zlib-devel, cairo-devel
+BuildRequires: perl-ExtUtils-MakeMaker
 %if "%{?fedora}" >= "7"
 BuildRequires: perl-devel
 %endif
@@ -128,7 +130,8 @@ The %{name}-ruby package includes RRDtool bindings for Ruby.
 %endif
 
 %prep
-%setup -q
+#setup -q
+%setup -q -n %{name}-%{version}
 %setup -q -T -D -a 1
 # Patch based on http://oss.oetiker.ch/rrdtool/pub/contrib/php_rrdtool.tgz
 %if %{with_php}
@@ -146,6 +149,11 @@ The %{name}-ruby package includes RRDtool bindings for Ruby.
     configure Makefile.in php4/configure php4/ltconfig*
 
 %build
+intltoolize --automake -c -f
+aclocal
+autoheader
+autoconf
+automake -a -c -f
 %configure \
     --with-perl-options='INSTALLDIRS="vendor"' \
 %if %{with_tcl}
@@ -303,6 +311,9 @@ find examples/ -type f -exec chmod 0644 {} \;
 %endif
 
 %changelog
+* Fri Jun 15 2007 Jarod Wilson <jwilson@redhat.com> 1.2.999050724000-0.1
+- Update for rrdtool pre-1.3 snapshot
+
 * Mon May 21 2007 Jarod Wilson <jwilson@redhat.com> 1.2.23-5
 - BR: ruby so %%ruby_sitearch gets set
 
diff --git a/src/DejaVuSansMono-Roman.ttf b/src/DejaVuSansMono-Roman.ttf
deleted file mode 100644 (file)
index 691c8d6..0000000
Binary files a/src/DejaVuSansMono-Roman.ttf and /dev/null differ
index 73f1113844c69c50fe45f08064bb5a6207aec9b2..daaacb6bee7d6ac1321bc5fd4b4b8030ec96053f 100644 (file)
@@ -4,11 +4,12 @@
 #
 #ACLOCAL_M4       = $(top_srcdir)/config/aclocal.m4
 #AUTOHEADER = @AUTOHEADER@ --localdir=$(top_srcdir)/config
-fontsdir =  $(datadir)/rrdtool/fonts
-fonts_DATA = DejaVuSansMono-Roman.ttf
 
-#INCLUDES = $(FREETYPE_INCLUDES) $(ART_INCLUDES) \
-#           $(PNG_INCLUDES) $(ZLIB_INCLUDES)
+if STATIC_PROGRAMS
+AM_LDFLAGS = -all-static
+endif
+
+INCLUDES = -DLOCALEDIR="\"$(datadir)/locale\""
 RRD_DEFAULT_FONT=@RRD_DEFAULT_FONT@
 AM_CPPFLAGS = -DRRD_DEFAULT_FONT=\"$(RRD_DEFAULT_FONT)\" -DNUMVERS=@NUMVERS@
 
@@ -17,6 +18,8 @@ UPD_C_FILES =         \
        rrd_getopt1.c   \
        parsetime.c     \
        rrd_hw.c        \
+       rrd_hw_math.c   \
+       rrd_hw_update.c \
        rrd_diff.c      \
        rrd_format.c    \
        rrd_info.c      \
@@ -30,30 +33,28 @@ RRD_C_FILES =               \
        hash_32.c       \
        pngsize.c       \
        rrd_create.c    \
-       rrd_dump.c      \
-       rrd_fetch.c     \
        rrd_graph.c     \
        rrd_graph_helper.c      \
+       rrd_version.c   \
        rrd_last.c      \
        rrd_lastupdate.c        \
        rrd_first.c     \
-       rrd_resize.c    \
        rrd_restore.c   \
-       rrd_tune.c      \
-       rrd_version.c   \
        rrd_xport.c     \
-        art_rgba_svp.c \
        rrd_gfx.c \
-       rrd_afm.c rrd_afm_data.c \
-       rrd_tool.c
+       rrd_dump.c      \
+       rrd_fetch.c     \
+       rrd_tool.c      \
+       rrd_resize.c \
+       rrd_tune.c
 
 noinst_HEADERS = \
-        art_rgba_svp.h \
        unused.h \
-       rrd_gfx.h \
        rrd_getopt.h parsetime.h \
-       rrd_format.h rrd_tool.h rrd_xport.h rrd.h rrd_hw.h rrd_rpncalc.h \
-       rrd_nan_inf.h fnv.h rrd_graph.h rrd_afm.h rrd_afm_data.h \
+       rrd_i18n.h \
+       rrd_format.h rrd_tool.h rrd_xport.h rrd.h rrd_rpncalc.h \
+       rrd_hw.h rrd_hw_math.h rrd_hw_update.h \
+       fnv.h rrd_graph.h \
        rrd_is_thread_safe.h
 
 noinst_LTLIBRARIES        = librrdupd.la
@@ -64,49 +65,18 @@ lib_LTLIBRARIES           += librrd_th.la
 endif
 
 librrdupd_la_SOURCES      = $(UPD_C_FILES) rrd_not_thread_safe.c
-librrdupd_la_LIBADD       = $(CORE_LIBS)
+librrdupd_la_LIBADD       = $(CORE_LIBS) @LIB_LIBINTL@
 
 librrd_la_SOURCES         = $(RRD_C_FILES)
 librrd_la_LIBADD          = librrdupd.la $(ALL_LIBS)
 
-# This flag accepts an argument of the form current[:revision[:age]]. So,
-# passing -version-info 3:12:1 sets current to 3, revision to 12, and age to 1.
-#
-# If either revision or age are omitted, they default to 0. Also note that
-# age must be less than or equal to the current interface number.
-#
-# Here are a set of rules to help you update your library version information:
-#
-#   1. Start with version information of 0:0:0 for each libtool library.
-#
-#   2. Update the version information only immediately before a public
-#   release of your software. More frequent updates are unnecessary, and
-#   only guarantee that the current interface number gets larger faster.
-#
-#   3. If the library source code has changed at all since the last update,
-#   then increment revision (c:r:a becomes c:r+1:a).
-#
-#   4. If any interfaces have been added, removed, or changed since the last
-#   update, increment current, and set revision to 0.
-#
-#   5. If any interfaces have been added since the last public release, then
-#   increment age.
-#
-#   6. If any interfaces have been removed since the last public release,
-#   then set age to 0.
-#
-# Never try to set the interface numbers so that they correspond to the
-# release number of your package. This is an abuse that only fosters
-# misunderstanding of the purpose of library versions. Instead, use the
-# -release flag (see Release numbers), but be warned that every release of
-# your package will not be binary compatible with any other release.
-#
-# see http://www.gnu.org/software/libtool/manual.html#SEC32 for explanation
-librrd_la_LDFLAGS         = -version-info 2:13:0
+# see http://sourceware.org/autobook/autobook/autobook_91.html
+
+librrd_la_LDFLAGS         = -version-info @LIBVERS@
 
 librrd_th_la_SOURCES         = $(UPD_C_FILES) $(RRD_C_FILES) rrd_thread_safe.c
 librrd_th_la_CFLAGS          = $(MULTITHREAD_CFLAGS)
-librrd_th_la_LDFLAGS         = $(MULTITHREAD_LDFLAGS) -version-info 2:13:0
+librrd_th_la_LDFLAGS         = $(MULTITHREAD_LDFLAGS) -version-info @LIBVERS@
 librrd_th_la_LIBADD          = $(ALL_LIBS)
 
 include_HEADERS        = rrd.h
@@ -129,6 +99,6 @@ rrdtool_LDADD        = librrd.la
 
 # strftime is here because we do not usually need it. unices have propper
 # iso date support
-EXTRA_DIST= strftime.c strftime.h $(fonts_DATA) \
+EXTRA_DIST= strftime.c strftime.h \
        win32comp.c  rrd_thread_safe_nt.c get_ver.awk
 
index f3489dfe472cb05fb51edce3cf9e97fff205e79d..52b533a7d39524ab20103cf4d3cd1258fbb324fb 100644 (file)
 
 @SET_MAKE@
 
+#AUTOMAKE_OPTIONS   = foreign
+#
+#ACLOCAL_M4       = $(top_srcdir)/config/aclocal.m4
+#AUTOHEADER = @AUTOHEADER@ --localdir=$(top_srcdir)/config
 
 
 
@@ -61,43 +65,44 @@ am__vpath_adj = case $$p in \
   esac;
 am__strip_dir = `echo $$p | sed -e 's|^.*/||'`;
 am__installdirs = "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" \
-       "$(DESTDIR)$(fontsdir)" "$(DESTDIR)$(includedir)"
+       "$(DESTDIR)$(includedir)"
 libLTLIBRARIES_INSTALL = $(INSTALL)
 LTLIBRARIES = $(lib_LTLIBRARIES) $(noinst_LTLIBRARIES)
 am__DEPENDENCIES_1 =
 librrd_la_DEPENDENCIES = librrdupd.la $(am__DEPENDENCIES_1)
-am__objects_1 = hash_32.lo pngsize.lo rrd_create.lo rrd_dump.lo \
-       rrd_fetch.lo rrd_graph.lo rrd_graph_helper.lo rrd_last.lo \
-       rrd_lastupdate.lo rrd_first.lo rrd_resize.lo rrd_restore.lo \
-       rrd_tune.lo rrd_version.lo rrd_xport.lo art_rgba_svp.lo \
-       rrd_gfx.lo rrd_afm.lo rrd_afm_data.lo rrd_tool.lo
+am__objects_1 = hash_32.lo pngsize.lo rrd_create.lo rrd_graph.lo \
+       rrd_graph_helper.lo rrd_version.lo rrd_last.lo \
+       rrd_lastupdate.lo rrd_first.lo rrd_restore.lo rrd_xport.lo \
+       rrd_gfx.lo rrd_dump.lo rrd_fetch.lo rrd_tool.lo rrd_resize.lo \
+       rrd_tune.lo
 am_librrd_la_OBJECTS = $(am__objects_1)
 librrd_la_OBJECTS = $(am_librrd_la_OBJECTS)
 librrd_th_la_DEPENDENCIES = $(am__DEPENDENCIES_1)
 am__objects_2 = librrd_th_la-rrd_getopt.lo librrd_th_la-rrd_getopt1.lo \
        librrd_th_la-parsetime.lo librrd_th_la-rrd_hw.lo \
+       librrd_th_la-rrd_hw_math.lo librrd_th_la-rrd_hw_update.lo \
        librrd_th_la-rrd_diff.lo librrd_th_la-rrd_format.lo \
        librrd_th_la-rrd_info.lo librrd_th_la-rrd_error.lo \
        librrd_th_la-rrd_open.lo librrd_th_la-rrd_nan_inf.lo \
        librrd_th_la-rrd_rpncalc.lo librrd_th_la-rrd_update.lo
 am__objects_3 = librrd_th_la-hash_32.lo librrd_th_la-pngsize.lo \
-       librrd_th_la-rrd_create.lo librrd_th_la-rrd_dump.lo \
-       librrd_th_la-rrd_fetch.lo librrd_th_la-rrd_graph.lo \
-       librrd_th_la-rrd_graph_helper.lo librrd_th_la-rrd_last.lo \
-       librrd_th_la-rrd_lastupdate.lo librrd_th_la-rrd_first.lo \
-       librrd_th_la-rrd_resize.lo librrd_th_la-rrd_restore.lo \
-       librrd_th_la-rrd_tune.lo librrd_th_la-rrd_version.lo \
-       librrd_th_la-rrd_xport.lo librrd_th_la-art_rgba_svp.lo \
-       librrd_th_la-rrd_gfx.lo librrd_th_la-rrd_afm.lo \
-       librrd_th_la-rrd_afm_data.lo librrd_th_la-rrd_tool.lo
+       librrd_th_la-rrd_create.lo librrd_th_la-rrd_graph.lo \
+       librrd_th_la-rrd_graph_helper.lo librrd_th_la-rrd_version.lo \
+       librrd_th_la-rrd_last.lo librrd_th_la-rrd_lastupdate.lo \
+       librrd_th_la-rrd_first.lo librrd_th_la-rrd_restore.lo \
+       librrd_th_la-rrd_xport.lo librrd_th_la-rrd_gfx.lo \
+       librrd_th_la-rrd_dump.lo librrd_th_la-rrd_fetch.lo \
+       librrd_th_la-rrd_tool.lo librrd_th_la-rrd_resize.lo \
+       librrd_th_la-rrd_tune.lo
 am_librrd_th_la_OBJECTS = $(am__objects_2) $(am__objects_3) \
        librrd_th_la-rrd_thread_safe.lo
 librrd_th_la_OBJECTS = $(am_librrd_th_la_OBJECTS)
 @BUILD_MULTITHREAD_TRUE@am_librrd_th_la_rpath = -rpath $(libdir)
 librrdupd_la_DEPENDENCIES = $(am__DEPENDENCIES_1)
 am__objects_4 = rrd_getopt.lo rrd_getopt1.lo parsetime.lo rrd_hw.lo \
-       rrd_diff.lo rrd_format.lo rrd_info.lo rrd_error.lo rrd_open.lo \
-       rrd_nan_inf.lo rrd_rpncalc.lo rrd_update.lo
+       rrd_hw_math.lo rrd_hw_update.lo rrd_diff.lo rrd_format.lo \
+       rrd_info.lo rrd_error.lo rrd_open.lo rrd_nan_inf.lo \
+       rrd_rpncalc.lo rrd_update.lo
 am_librrdupd_la_OBJECTS = $(am__objects_4) rrd_not_thread_safe.lo
 librrdupd_la_OBJECTS = $(am_librrdupd_la_OBJECTS)
 @BUILD_RRDCGI_TRUE@am__EXEEXT_1 = rrdcgi$(EXEEXT)
@@ -128,8 +133,6 @@ SOURCES = $(librrd_la_SOURCES) $(librrd_th_la_SOURCES) \
 DIST_SOURCES = $(librrd_la_SOURCES) $(librrd_th_la_SOURCES) \
        $(librrdupd_la_SOURCES) $(rrdcgi_SOURCES) $(rrdtool_SOURCES) \
        $(rrdupdate_SOURCES)
-fontsDATA_INSTALL = $(INSTALL_DATA)
-DATA = $(fonts_DATA)
 includeHEADERS_INSTALL = $(INSTALL_HEADER)
 HEADERS = $(include_HEADERS) $(noinst_HEADERS)
 ETAGS = etags
@@ -137,6 +140,7 @@ CTAGS = ctags
 DISTFILES = $(DIST_COMMON) $(DIST_SOURCES) $(TEXINFOS) $(EXTRA_DIST)
 ACLOCAL = @ACLOCAL@
 ALL_LIBS = @ALL_LIBS@
+ALL_LINGUAS = @ALL_LINGUAS@
 AMDEP_FALSE = @AMDEP_FALSE@
 AMDEP_TRUE = @AMDEP_TRUE@
 AMTAR = @AMTAR@
@@ -145,6 +149,8 @@ AUTOCONF = @AUTOCONF@
 AUTOHEADER = @AUTOHEADER@
 AUTOMAKE = @AUTOMAKE@
 AWK = @AWK@
+BUILD_LIBINTL_FALSE = @BUILD_LIBINTL_FALSE@
+BUILD_LIBINTL_TRUE = @BUILD_LIBINTL_TRUE@
 BUILD_MULTITHREAD_FALSE = @BUILD_MULTITHREAD_FALSE@
 BUILD_MULTITHREAD_TRUE = @BUILD_MULTITHREAD_TRUE@
 BUILD_RRDCGI_FALSE = @BUILD_RRDCGI_FALSE@
@@ -153,6 +159,8 @@ BUILD_TCL_FALSE = @BUILD_TCL_FALSE@
 BUILD_TCL_SITE_FALSE = @BUILD_TCL_SITE_FALSE@
 BUILD_TCL_SITE_TRUE = @BUILD_TCL_SITE_TRUE@
 BUILD_TCL_TRUE = @BUILD_TCL_TRUE@
+CATALOGS = @CATALOGS@
+CATOBJEXT = @CATOBJEXT@
 CC = @CC@
 CCDEPMODE = @CCDEPMODE@
 CFLAGS = @CFLAGS@
@@ -167,6 +175,7 @@ CXXCPP = @CXXCPP@
 CXXDEPMODE = @CXXDEPMODE@
 CXXFLAGS = @CXXFLAGS@
 CYGPATH_W = @CYGPATH_W@
+DATADIRNAME = @DATADIRNAME@
 DEFS = @DEFS@
 DEPDIR = @DEPDIR@
 ECHO = @ECHO@
@@ -177,18 +186,57 @@ EGREP = @EGREP@
 EXEEXT = @EXEEXT@
 F77 = @F77@
 FFLAGS = @FFLAGS@
+GETTEXT_PACKAGE = @GETTEXT_PACKAGE@
+GMOFILES = @GMOFILES@
+GMSGFMT = @GMSGFMT@
 GREP = @GREP@
 INSTALL_DATA = @INSTALL_DATA@
 INSTALL_PROGRAM = @INSTALL_PROGRAM@
 INSTALL_SCRIPT = @INSTALL_SCRIPT@
 INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@
+INSTOBJEXT = @INSTOBJEXT@
+INTLLIBS = @INTLLIBS@
+INTLTOOL_CAVES_RULE = @INTLTOOL_CAVES_RULE@
+INTLTOOL_DESKTOP_RULE = @INTLTOOL_DESKTOP_RULE@
+INTLTOOL_DIRECTORY_RULE = @INTLTOOL_DIRECTORY_RULE@
+INTLTOOL_EXTRACT = @INTLTOOL_EXTRACT@
+INTLTOOL_ICONV = @INTLTOOL_ICONV@
+INTLTOOL_KBD_RULE = @INTLTOOL_KBD_RULE@
+INTLTOOL_KEYS_RULE = @INTLTOOL_KEYS_RULE@
+INTLTOOL_MERGE = @INTLTOOL_MERGE@
+INTLTOOL_MSGFMT = @INTLTOOL_MSGFMT@
+INTLTOOL_MSGMERGE = @INTLTOOL_MSGMERGE@
+INTLTOOL_OAF_RULE = @INTLTOOL_OAF_RULE@
+INTLTOOL_PERL = @INTLTOOL_PERL@
+INTLTOOL_PONG_RULE = @INTLTOOL_PONG_RULE@
+INTLTOOL_PROP_RULE = @INTLTOOL_PROP_RULE@
+INTLTOOL_SCHEMAS_RULE = @INTLTOOL_SCHEMAS_RULE@
+INTLTOOL_SERVER_RULE = @INTLTOOL_SERVER_RULE@
+INTLTOOL_SERVICE_RULE = @INTLTOOL_SERVICE_RULE@
+INTLTOOL_SHEET_RULE = @INTLTOOL_SHEET_RULE@
+INTLTOOL_SOUNDLIST_RULE = @INTLTOOL_SOUNDLIST_RULE@
+INTLTOOL_THEME_RULE = @INTLTOOL_THEME_RULE@
+INTLTOOL_UI_RULE = @INTLTOOL_UI_RULE@
+INTLTOOL_UPDATE = @INTLTOOL_UPDATE@
+INTLTOOL_XAM_RULE = @INTLTOOL_XAM_RULE@
+INTLTOOL_XGETTEXT = @INTLTOOL_XGETTEXT@
+INTLTOOL_XML_NOMERGE_RULE = @INTLTOOL_XML_NOMERGE_RULE@
+INTLTOOL_XML_RULE = @INTLTOOL_XML_RULE@
 LDFLAGS = @LDFLAGS@
 LIBOBJS = @LIBOBJS@
 LIBS = @LIBS@
 LIBTOOL = @LIBTOOL@
+LIBVERS = @LIBVERS@
+LIB_LIBINTL = @LIB_LIBINTL@
 LN_S = @LN_S@
 LTLIBOBJS = @LTLIBOBJS@
+MAINT = @MAINT@
+MAINTAINER_MODE_FALSE = @MAINTAINER_MODE_FALSE@
+MAINTAINER_MODE_TRUE = @MAINTAINER_MODE_TRUE@
 MAKEINFO = @MAKEINFO@
+MKINSTALLDIRS = @MKINSTALLDIRS@
+MSGFMT = @MSGFMT@
+MSGFMT_OPTS = @MSGFMT_OPTS@
 MULTITHREAD_CFLAGS = @MULTITHREAD_CFLAGS@
 MULTITHREAD_LDFLAGS = @MULTITHREAD_LDFLAGS@
 NROFF = @NROFF@
@@ -211,6 +259,12 @@ PERL_CC = @PERL_CC@
 PERL_MAKE_OPTIONS = @PERL_MAKE_OPTIONS@
 PERL_VERSION = @PERL_VERSION@
 PKGCONFIG = @PKGCONFIG@
+POD2HTML = @POD2HTML@
+POD2MAN = @POD2MAN@
+POFILES = @POFILES@
+POSUB = @POSUB@
+PO_IN_DATADIR_FALSE = @PO_IN_DATADIR_FALSE@
+PO_IN_DATADIR_TRUE = @PO_IN_DATADIR_TRUE@
 PTHREAD_CC = @PTHREAD_CC@
 PTHREAD_CFLAGS = @PTHREAD_CFLAGS@
 PTHREAD_LIBS = @PTHREAD_LIBS@
@@ -223,15 +277,15 @@ PYTHON_VERSION = @PYTHON_VERSION@
 RANLIB = @RANLIB@
 RRDDOCDIR = @RRDDOCDIR@
 RRDGRAPH_YLEGEND_ANGLE = @RRDGRAPH_YLEGEND_ANGLE@
-
-#INCLUDES = $(FREETYPE_INCLUDES) $(ART_INCLUDES) \
-#           $(PNG_INCLUDES) $(ZLIB_INCLUDES)
 RRD_DEFAULT_FONT = @RRD_DEFAULT_FONT@
 RUBY = @RUBY@
 RUBY_MAKE_OPTIONS = @RUBY_MAKE_OPTIONS@
 SET_MAKE = @SET_MAKE@
 SHELL = @SHELL@
+STATIC_PROGRAMS_FALSE = @STATIC_PROGRAMS_FALSE@
+STATIC_PROGRAMS_TRUE = @STATIC_PROGRAMS_TRUE@
 STRIP = @STRIP@
+TCL_INC_DIR = @TCL_INC_DIR@
 TCL_LD_SEARCH_FLAGS = @TCL_LD_SEARCH_FLAGS@
 TCL_PACKAGE_DIR = @TCL_PACKAGE_DIR@
 TCL_PACKAGE_PATH = @TCL_PACKAGE_PATH@
@@ -242,7 +296,9 @@ TCL_SHLIB_SUFFIX = @TCL_SHLIB_SUFFIX@
 TCL_STUB_LIB_SPEC = @TCL_STUB_LIB_SPEC@
 TCL_VERSION = @TCL_VERSION@
 TROFF = @TROFF@
+USE_NLS = @USE_NLS@
 VERSION = @VERSION@
+XGETTEXT = @XGETTEXT@
 ac_ct_CC = @ac_ct_CC@
 ac_ct_CXX = @ac_ct_CXX@
 ac_ct_F77 = @ac_ct_F77@
@@ -299,19 +355,16 @@ target_alias = @target_alias@
 target_cpu = @target_cpu@
 target_os = @target_os@
 target_vendor = @target_vendor@
-
-#AUTOMAKE_OPTIONS   = foreign
-#
-#ACLOCAL_M4       = $(top_srcdir)/config/aclocal.m4
-#AUTOHEADER = @AUTOHEADER@ --localdir=$(top_srcdir)/config
-fontsdir = $(datadir)/rrdtool/fonts
-fonts_DATA = DejaVuSansMono-Roman.ttf
+@STATIC_PROGRAMS_TRUE@AM_LDFLAGS = -all-static
+INCLUDES = -DLOCALEDIR="\"$(datadir)/locale\""
 AM_CPPFLAGS = -DRRD_DEFAULT_FONT=\"$(RRD_DEFAULT_FONT)\" -DNUMVERS=@NUMVERS@
 UPD_C_FILES = \
        rrd_getopt.c    \
        rrd_getopt1.c   \
        parsetime.c     \
        rrd_hw.c        \
+       rrd_hw_math.c   \
+       rrd_hw_update.c \
        rrd_diff.c      \
        rrd_format.c    \
        rrd_info.c      \
@@ -325,76 +378,42 @@ RRD_C_FILES = \
        hash_32.c       \
        pngsize.c       \
        rrd_create.c    \
-       rrd_dump.c      \
-       rrd_fetch.c     \
        rrd_graph.c     \
        rrd_graph_helper.c      \
+       rrd_version.c   \
        rrd_last.c      \
        rrd_lastupdate.c        \
        rrd_first.c     \
-       rrd_resize.c    \
        rrd_restore.c   \
-       rrd_tune.c      \
-       rrd_version.c   \
        rrd_xport.c     \
-        art_rgba_svp.c \
        rrd_gfx.c \
-       rrd_afm.c rrd_afm_data.c \
-       rrd_tool.c
+       rrd_dump.c      \
+       rrd_fetch.c     \
+       rrd_tool.c      \
+       rrd_resize.c \
+       rrd_tune.c
 
 noinst_HEADERS = \
-        art_rgba_svp.h \
        unused.h \
-       rrd_gfx.h \
        rrd_getopt.h parsetime.h \
-       rrd_format.h rrd_tool.h rrd_xport.h rrd.h rrd_hw.h rrd_rpncalc.h \
-       rrd_nan_inf.h fnv.h rrd_graph.h rrd_afm.h rrd_afm_data.h \
+       rrd_i18n.h \
+       rrd_format.h rrd_tool.h rrd_xport.h rrd.h rrd_rpncalc.h \
+       rrd_hw.h rrd_hw_math.h rrd_hw_update.h \
+       fnv.h rrd_graph.h \
        rrd_is_thread_safe.h
 
 noinst_LTLIBRARIES = librrdupd.la
 lib_LTLIBRARIES = librrd.la $(am__append_1)
 librrdupd_la_SOURCES = $(UPD_C_FILES) rrd_not_thread_safe.c
-librrdupd_la_LIBADD = $(CORE_LIBS)
+librrdupd_la_LIBADD = $(CORE_LIBS) @LIB_LIBINTL@
 librrd_la_SOURCES = $(RRD_C_FILES)
 librrd_la_LIBADD = librrdupd.la $(ALL_LIBS)
 
-# This flag accepts an argument of the form current[:revision[:age]]. So,
-# passing -version-info 3:12:1 sets current to 3, revision to 12, and age to 1.
-#
-# If either revision or age are omitted, they default to 0. Also note that
-# age must be less than or equal to the current interface number.
-#
-# Here are a set of rules to help you update your library version information:
-#
-#   1. Start with version information of 0:0:0 for each libtool library.
-#
-#   2. Update the version information only immediately before a public
-#   release of your software. More frequent updates are unnecessary, and
-#   only guarantee that the current interface number gets larger faster.
-#
-#   3. If the library source code has changed at all since the last update,
-#   then increment revision (c:r:a becomes c:r+1:a).
-#
-#   4. If any interfaces have been added, removed, or changed since the last
-#   update, increment current, and set revision to 0.
-#
-#   5. If any interfaces have been added since the last public release, then
-#   increment age.
-#
-#   6. If any interfaces have been removed since the last public release,
-#   then set age to 0.
-#
-# Never try to set the interface numbers so that they correspond to the
-# release number of your package. This is an abuse that only fosters
-# misunderstanding of the purpose of library versions. Instead, use the
-# -release flag (see Release numbers), but be warned that every release of
-# your package will not be binary compatible with any other release.
-#
-# see http://www.gnu.org/software/libtool/manual.html#SEC32 for explanation
-librrd_la_LDFLAGS = -version-info 2:13:0
+# see http://sourceware.org/autobook/autobook/autobook_91.html
+librrd_la_LDFLAGS = -version-info @LIBVERS@
 librrd_th_la_SOURCES = $(UPD_C_FILES) $(RRD_C_FILES) rrd_thread_safe.c
 librrd_th_la_CFLAGS = $(MULTITHREAD_CFLAGS)
-librrd_th_la_LDFLAGS = $(MULTITHREAD_LDFLAGS) -version-info 2:13:0
+librrd_th_la_LDFLAGS = $(MULTITHREAD_LDFLAGS) -version-info @LIBVERS@
 librrd_th_la_LIBADD = $(ALL_LIBS)
 include_HEADERS = rrd.h
 rrdcgi_SOURCES = rrd_cgi.c
@@ -407,14 +426,14 @@ rrdtool_LDADD = librrd.la
 
 # strftime is here because we do not usually need it. unices have propper
 # iso date support
-EXTRA_DIST = strftime.c strftime.h $(fonts_DATA) \
+EXTRA_DIST = strftime.c strftime.h \
        win32comp.c  rrd_thread_safe_nt.c get_ver.awk
 
 all: all-am
 
 .SUFFIXES:
 .SUFFIXES: .c .lo .o .obj
-$(srcdir)/Makefile.in:  $(srcdir)/Makefile.am  $(am__configure_deps)
+$(srcdir)/Makefile.in: @MAINTAINER_MODE_TRUE@ $(srcdir)/Makefile.am  $(am__configure_deps)
        @for dep in $?; do \
          case '$(am__configure_deps)' in \
            *$$dep*) \
@@ -439,9 +458,9 @@ Makefile: $(srcdir)/Makefile.in $(top_builddir)/config.status
 $(top_builddir)/config.status: $(top_srcdir)/configure $(CONFIG_STATUS_DEPENDENCIES)
        cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
 
-$(top_srcdir)/configure:  $(am__configure_deps)
+$(top_srcdir)/configure: @MAINTAINER_MODE_TRUE@ $(am__configure_deps)
        cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
-$(ACLOCAL_M4):  $(am__aclocal_m4_deps)
+$(ACLOCAL_M4): @MAINTAINER_MODE_TRUE@ $(am__aclocal_m4_deps)
        cd $(top_builddir) && $(MAKE) $(AM_MAKEFLAGS) am--refresh
 install-libLTLIBRARIES: $(lib_LTLIBRARIES)
        @$(NORMAL_INSTALL)
@@ -529,14 +548,10 @@ mostlyclean-compile:
 distclean-compile:
        -rm -f *.tab.c
 
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/art_rgba_svp.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/hash_32.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/librrd_th_la-art_rgba_svp.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/librrd_th_la-hash_32.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/librrd_th_la-parsetime.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/librrd_th_la-pngsize.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/librrd_th_la-rrd_afm.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/librrd_th_la-rrd_afm_data.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/librrd_th_la-rrd_create.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/librrd_th_la-rrd_diff.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/librrd_th_la-rrd_dump.Plo@am__quote@
@@ -550,6 +565,8 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/librrd_th_la-rrd_graph.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/librrd_th_la-rrd_graph_helper.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/librrd_th_la-rrd_hw.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/librrd_th_la-rrd_hw_math.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/librrd_th_la-rrd_hw_update.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/librrd_th_la-rrd_info.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/librrd_th_la-rrd_last.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/librrd_th_la-rrd_lastupdate.Plo@am__quote@
@@ -566,8 +583,6 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/librrd_th_la-rrd_xport.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/parsetime.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/pngsize.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rrd_afm.Plo@am__quote@
-@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rrd_afm_data.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rrd_cgi.Po@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rrd_create.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rrd_diff.Plo@am__quote@
@@ -582,6 +597,8 @@ distclean-compile:
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rrd_graph.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rrd_graph_helper.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rrd_hw.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rrd_hw_math.Plo@am__quote@
+@AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rrd_hw_update.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rrd_info.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rrd_last.Plo@am__quote@
 @AMDEP_TRUE@@am__include@ @am__quote@./$(DEPDIR)/rrd_lastupdate.Plo@am__quote@
@@ -647,6 +664,20 @@ librrd_th_la-rrd_hw.lo: rrd_hw.c
 @AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@  $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librrd_th_la_CFLAGS) $(CFLAGS) -c -o librrd_th_la-rrd_hw.lo `test -f 'rrd_hw.c' || echo '$(srcdir)/'`rrd_hw.c
 
+librrd_th_la-rrd_hw_math.lo: rrd_hw_math.c
+@am__fastdepCC_TRUE@   if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librrd_th_la_CFLAGS) $(CFLAGS) -MT librrd_th_la-rrd_hw_math.lo -MD -MP -MF "$(DEPDIR)/librrd_th_la-rrd_hw_math.Tpo" -c -o librrd_th_la-rrd_hw_math.lo `test -f 'rrd_hw_math.c' || echo '$(srcdir)/'`rrd_hw_math.c; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/librrd_th_la-rrd_hw_math.Tpo" "$(DEPDIR)/librrd_th_la-rrd_hw_math.Plo"; else rm -f "$(DEPDIR)/librrd_th_la-rrd_hw_math.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='rrd_hw_math.c' object='librrd_th_la-rrd_hw_math.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librrd_th_la_CFLAGS) $(CFLAGS) -c -o librrd_th_la-rrd_hw_math.lo `test -f 'rrd_hw_math.c' || echo '$(srcdir)/'`rrd_hw_math.c
+
+librrd_th_la-rrd_hw_update.lo: rrd_hw_update.c
+@am__fastdepCC_TRUE@   if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librrd_th_la_CFLAGS) $(CFLAGS) -MT librrd_th_la-rrd_hw_update.lo -MD -MP -MF "$(DEPDIR)/librrd_th_la-rrd_hw_update.Tpo" -c -o librrd_th_la-rrd_hw_update.lo `test -f 'rrd_hw_update.c' || echo '$(srcdir)/'`rrd_hw_update.c; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/librrd_th_la-rrd_hw_update.Tpo" "$(DEPDIR)/librrd_th_la-rrd_hw_update.Plo"; else rm -f "$(DEPDIR)/librrd_th_la-rrd_hw_update.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='rrd_hw_update.c' object='librrd_th_la-rrd_hw_update.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librrd_th_la_CFLAGS) $(CFLAGS) -c -o librrd_th_la-rrd_hw_update.lo `test -f 'rrd_hw_update.c' || echo '$(srcdir)/'`rrd_hw_update.c
+
 librrd_th_la-rrd_diff.lo: rrd_diff.c
 @am__fastdepCC_TRUE@   if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librrd_th_la_CFLAGS) $(CFLAGS) -MT librrd_th_la-rrd_diff.lo -MD -MP -MF "$(DEPDIR)/librrd_th_la-rrd_diff.Tpo" -c -o librrd_th_la-rrd_diff.lo `test -f 'rrd_diff.c' || echo '$(srcdir)/'`rrd_diff.c; \
 @am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/librrd_th_la-rrd_diff.Tpo" "$(DEPDIR)/librrd_th_la-rrd_diff.Plo"; else rm -f "$(DEPDIR)/librrd_th_la-rrd_diff.Tpo"; exit 1; fi
@@ -724,20 +755,6 @@ librrd_th_la-rrd_create.lo: rrd_create.c
 @AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@  $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librrd_th_la_CFLAGS) $(CFLAGS) -c -o librrd_th_la-rrd_create.lo `test -f 'rrd_create.c' || echo '$(srcdir)/'`rrd_create.c
 
-librrd_th_la-rrd_dump.lo: rrd_dump.c
-@am__fastdepCC_TRUE@   if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librrd_th_la_CFLAGS) $(CFLAGS) -MT librrd_th_la-rrd_dump.lo -MD -MP -MF "$(DEPDIR)/librrd_th_la-rrd_dump.Tpo" -c -o librrd_th_la-rrd_dump.lo `test -f 'rrd_dump.c' || echo '$(srcdir)/'`rrd_dump.c; \
-@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/librrd_th_la-rrd_dump.Tpo" "$(DEPDIR)/librrd_th_la-rrd_dump.Plo"; else rm -f "$(DEPDIR)/librrd_th_la-rrd_dump.Tpo"; exit 1; fi
-@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='rrd_dump.c' object='librrd_th_la-rrd_dump.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@  $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librrd_th_la_CFLAGS) $(CFLAGS) -c -o librrd_th_la-rrd_dump.lo `test -f 'rrd_dump.c' || echo '$(srcdir)/'`rrd_dump.c
-
-librrd_th_la-rrd_fetch.lo: rrd_fetch.c
-@am__fastdepCC_TRUE@   if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librrd_th_la_CFLAGS) $(CFLAGS) -MT librrd_th_la-rrd_fetch.lo -MD -MP -MF "$(DEPDIR)/librrd_th_la-rrd_fetch.Tpo" -c -o librrd_th_la-rrd_fetch.lo `test -f 'rrd_fetch.c' || echo '$(srcdir)/'`rrd_fetch.c; \
-@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/librrd_th_la-rrd_fetch.Tpo" "$(DEPDIR)/librrd_th_la-rrd_fetch.Plo"; else rm -f "$(DEPDIR)/librrd_th_la-rrd_fetch.Tpo"; exit 1; fi
-@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='rrd_fetch.c' object='librrd_th_la-rrd_fetch.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@  $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librrd_th_la_CFLAGS) $(CFLAGS) -c -o librrd_th_la-rrd_fetch.lo `test -f 'rrd_fetch.c' || echo '$(srcdir)/'`rrd_fetch.c
-
 librrd_th_la-rrd_graph.lo: rrd_graph.c
 @am__fastdepCC_TRUE@   if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librrd_th_la_CFLAGS) $(CFLAGS) -MT librrd_th_la-rrd_graph.lo -MD -MP -MF "$(DEPDIR)/librrd_th_la-rrd_graph.Tpo" -c -o librrd_th_la-rrd_graph.lo `test -f 'rrd_graph.c' || echo '$(srcdir)/'`rrd_graph.c; \
 @am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/librrd_th_la-rrd_graph.Tpo" "$(DEPDIR)/librrd_th_la-rrd_graph.Plo"; else rm -f "$(DEPDIR)/librrd_th_la-rrd_graph.Tpo"; exit 1; fi
@@ -752,6 +769,13 @@ librrd_th_la-rrd_graph_helper.lo: rrd_graph_helper.c
 @AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@  $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librrd_th_la_CFLAGS) $(CFLAGS) -c -o librrd_th_la-rrd_graph_helper.lo `test -f 'rrd_graph_helper.c' || echo '$(srcdir)/'`rrd_graph_helper.c
 
+librrd_th_la-rrd_version.lo: rrd_version.c
+@am__fastdepCC_TRUE@   if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librrd_th_la_CFLAGS) $(CFLAGS) -MT librrd_th_la-rrd_version.lo -MD -MP -MF "$(DEPDIR)/librrd_th_la-rrd_version.Tpo" -c -o librrd_th_la-rrd_version.lo `test -f 'rrd_version.c' || echo '$(srcdir)/'`rrd_version.c; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/librrd_th_la-rrd_version.Tpo" "$(DEPDIR)/librrd_th_la-rrd_version.Plo"; else rm -f "$(DEPDIR)/librrd_th_la-rrd_version.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='rrd_version.c' object='librrd_th_la-rrd_version.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librrd_th_la_CFLAGS) $(CFLAGS) -c -o librrd_th_la-rrd_version.lo `test -f 'rrd_version.c' || echo '$(srcdir)/'`rrd_version.c
+
 librrd_th_la-rrd_last.lo: rrd_last.c
 @am__fastdepCC_TRUE@   if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librrd_th_la_CFLAGS) $(CFLAGS) -MT librrd_th_la-rrd_last.lo -MD -MP -MF "$(DEPDIR)/librrd_th_la-rrd_last.Tpo" -c -o librrd_th_la-rrd_last.lo `test -f 'rrd_last.c' || echo '$(srcdir)/'`rrd_last.c; \
 @am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/librrd_th_la-rrd_last.Tpo" "$(DEPDIR)/librrd_th_la-rrd_last.Plo"; else rm -f "$(DEPDIR)/librrd_th_la-rrd_last.Tpo"; exit 1; fi
@@ -773,13 +797,6 @@ librrd_th_la-rrd_first.lo: rrd_first.c
 @AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@  $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librrd_th_la_CFLAGS) $(CFLAGS) -c -o librrd_th_la-rrd_first.lo `test -f 'rrd_first.c' || echo '$(srcdir)/'`rrd_first.c
 
-librrd_th_la-rrd_resize.lo: rrd_resize.c
-@am__fastdepCC_TRUE@   if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librrd_th_la_CFLAGS) $(CFLAGS) -MT librrd_th_la-rrd_resize.lo -MD -MP -MF "$(DEPDIR)/librrd_th_la-rrd_resize.Tpo" -c -o librrd_th_la-rrd_resize.lo `test -f 'rrd_resize.c' || echo '$(srcdir)/'`rrd_resize.c; \
-@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/librrd_th_la-rrd_resize.Tpo" "$(DEPDIR)/librrd_th_la-rrd_resize.Plo"; else rm -f "$(DEPDIR)/librrd_th_la-rrd_resize.Tpo"; exit 1; fi
-@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='rrd_resize.c' object='librrd_th_la-rrd_resize.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@  $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librrd_th_la_CFLAGS) $(CFLAGS) -c -o librrd_th_la-rrd_resize.lo `test -f 'rrd_resize.c' || echo '$(srcdir)/'`rrd_resize.c
-
 librrd_th_la-rrd_restore.lo: rrd_restore.c
 @am__fastdepCC_TRUE@   if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librrd_th_la_CFLAGS) $(CFLAGS) -MT librrd_th_la-rrd_restore.lo -MD -MP -MF "$(DEPDIR)/librrd_th_la-rrd_restore.Tpo" -c -o librrd_th_la-rrd_restore.lo `test -f 'rrd_restore.c' || echo '$(srcdir)/'`rrd_restore.c; \
 @am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/librrd_th_la-rrd_restore.Tpo" "$(DEPDIR)/librrd_th_la-rrd_restore.Plo"; else rm -f "$(DEPDIR)/librrd_th_la-rrd_restore.Tpo"; exit 1; fi
@@ -787,20 +804,6 @@ librrd_th_la-rrd_restore.lo: rrd_restore.c
 @AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@  $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librrd_th_la_CFLAGS) $(CFLAGS) -c -o librrd_th_la-rrd_restore.lo `test -f 'rrd_restore.c' || echo '$(srcdir)/'`rrd_restore.c
 
-librrd_th_la-rrd_tune.lo: rrd_tune.c
-@am__fastdepCC_TRUE@   if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librrd_th_la_CFLAGS) $(CFLAGS) -MT librrd_th_la-rrd_tune.lo -MD -MP -MF "$(DEPDIR)/librrd_th_la-rrd_tune.Tpo" -c -o librrd_th_la-rrd_tune.lo `test -f 'rrd_tune.c' || echo '$(srcdir)/'`rrd_tune.c; \
-@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/librrd_th_la-rrd_tune.Tpo" "$(DEPDIR)/librrd_th_la-rrd_tune.Plo"; else rm -f "$(DEPDIR)/librrd_th_la-rrd_tune.Tpo"; exit 1; fi
-@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='rrd_tune.c' object='librrd_th_la-rrd_tune.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@  $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librrd_th_la_CFLAGS) $(CFLAGS) -c -o librrd_th_la-rrd_tune.lo `test -f 'rrd_tune.c' || echo '$(srcdir)/'`rrd_tune.c
-
-librrd_th_la-rrd_version.lo: rrd_version.c
-@am__fastdepCC_TRUE@   if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librrd_th_la_CFLAGS) $(CFLAGS) -MT librrd_th_la-rrd_version.lo -MD -MP -MF "$(DEPDIR)/librrd_th_la-rrd_version.Tpo" -c -o librrd_th_la-rrd_version.lo `test -f 'rrd_version.c' || echo '$(srcdir)/'`rrd_version.c; \
-@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/librrd_th_la-rrd_version.Tpo" "$(DEPDIR)/librrd_th_la-rrd_version.Plo"; else rm -f "$(DEPDIR)/librrd_th_la-rrd_version.Tpo"; exit 1; fi
-@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='rrd_version.c' object='librrd_th_la-rrd_version.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@  $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librrd_th_la_CFLAGS) $(CFLAGS) -c -o librrd_th_la-rrd_version.lo `test -f 'rrd_version.c' || echo '$(srcdir)/'`rrd_version.c
-
 librrd_th_la-rrd_xport.lo: rrd_xport.c
 @am__fastdepCC_TRUE@   if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librrd_th_la_CFLAGS) $(CFLAGS) -MT librrd_th_la-rrd_xport.lo -MD -MP -MF "$(DEPDIR)/librrd_th_la-rrd_xport.Tpo" -c -o librrd_th_la-rrd_xport.lo `test -f 'rrd_xport.c' || echo '$(srcdir)/'`rrd_xport.c; \
 @am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/librrd_th_la-rrd_xport.Tpo" "$(DEPDIR)/librrd_th_la-rrd_xport.Plo"; else rm -f "$(DEPDIR)/librrd_th_la-rrd_xport.Tpo"; exit 1; fi
@@ -808,13 +811,6 @@ librrd_th_la-rrd_xport.lo: rrd_xport.c
 @AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@  $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librrd_th_la_CFLAGS) $(CFLAGS) -c -o librrd_th_la-rrd_xport.lo `test -f 'rrd_xport.c' || echo '$(srcdir)/'`rrd_xport.c
 
-librrd_th_la-art_rgba_svp.lo: art_rgba_svp.c
-@am__fastdepCC_TRUE@   if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librrd_th_la_CFLAGS) $(CFLAGS) -MT librrd_th_la-art_rgba_svp.lo -MD -MP -MF "$(DEPDIR)/librrd_th_la-art_rgba_svp.Tpo" -c -o librrd_th_la-art_rgba_svp.lo `test -f 'art_rgba_svp.c' || echo '$(srcdir)/'`art_rgba_svp.c; \
-@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/librrd_th_la-art_rgba_svp.Tpo" "$(DEPDIR)/librrd_th_la-art_rgba_svp.Plo"; else rm -f "$(DEPDIR)/librrd_th_la-art_rgba_svp.Tpo"; exit 1; fi
-@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='art_rgba_svp.c' object='librrd_th_la-art_rgba_svp.lo' libtool=yes @AMDEPBACKSLASH@
-@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@  $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librrd_th_la_CFLAGS) $(CFLAGS) -c -o librrd_th_la-art_rgba_svp.lo `test -f 'art_rgba_svp.c' || echo '$(srcdir)/'`art_rgba_svp.c
-
 librrd_th_la-rrd_gfx.lo: rrd_gfx.c
 @am__fastdepCC_TRUE@   if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librrd_th_la_CFLAGS) $(CFLAGS) -MT librrd_th_la-rrd_gfx.lo -MD -MP -MF "$(DEPDIR)/librrd_th_la-rrd_gfx.Tpo" -c -o librrd_th_la-rrd_gfx.lo `test -f 'rrd_gfx.c' || echo '$(srcdir)/'`rrd_gfx.c; \
 @am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/librrd_th_la-rrd_gfx.Tpo" "$(DEPDIR)/librrd_th_la-rrd_gfx.Plo"; else rm -f "$(DEPDIR)/librrd_th_la-rrd_gfx.Tpo"; exit 1; fi
@@ -822,19 +818,19 @@ librrd_th_la-rrd_gfx.lo: rrd_gfx.c
 @AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@  $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librrd_th_la_CFLAGS) $(CFLAGS) -c -o librrd_th_la-rrd_gfx.lo `test -f 'rrd_gfx.c' || echo '$(srcdir)/'`rrd_gfx.c
 
-librrd_th_la-rrd_afm.lo: rrd_afm.c
-@am__fastdepCC_TRUE@   if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librrd_th_la_CFLAGS) $(CFLAGS) -MT librrd_th_la-rrd_afm.lo -MD -MP -MF "$(DEPDIR)/librrd_th_la-rrd_afm.Tpo" -c -o librrd_th_la-rrd_afm.lo `test -f 'rrd_afm.c' || echo '$(srcdir)/'`rrd_afm.c; \
-@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/librrd_th_la-rrd_afm.Tpo" "$(DEPDIR)/librrd_th_la-rrd_afm.Plo"; else rm -f "$(DEPDIR)/librrd_th_la-rrd_afm.Tpo"; exit 1; fi
-@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='rrd_afm.c' object='librrd_th_la-rrd_afm.lo' libtool=yes @AMDEPBACKSLASH@
+librrd_th_la-rrd_dump.lo: rrd_dump.c
+@am__fastdepCC_TRUE@   if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librrd_th_la_CFLAGS) $(CFLAGS) -MT librrd_th_la-rrd_dump.lo -MD -MP -MF "$(DEPDIR)/librrd_th_la-rrd_dump.Tpo" -c -o librrd_th_la-rrd_dump.lo `test -f 'rrd_dump.c' || echo '$(srcdir)/'`rrd_dump.c; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/librrd_th_la-rrd_dump.Tpo" "$(DEPDIR)/librrd_th_la-rrd_dump.Plo"; else rm -f "$(DEPDIR)/librrd_th_la-rrd_dump.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='rrd_dump.c' object='librrd_th_la-rrd_dump.lo' libtool=yes @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@  $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librrd_th_la_CFLAGS) $(CFLAGS) -c -o librrd_th_la-rrd_afm.lo `test -f 'rrd_afm.c' || echo '$(srcdir)/'`rrd_afm.c
+@am__fastdepCC_FALSE@  $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librrd_th_la_CFLAGS) $(CFLAGS) -c -o librrd_th_la-rrd_dump.lo `test -f 'rrd_dump.c' || echo '$(srcdir)/'`rrd_dump.c
 
-librrd_th_la-rrd_afm_data.lo: rrd_afm_data.c
-@am__fastdepCC_TRUE@   if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librrd_th_la_CFLAGS) $(CFLAGS) -MT librrd_th_la-rrd_afm_data.lo -MD -MP -MF "$(DEPDIR)/librrd_th_la-rrd_afm_data.Tpo" -c -o librrd_th_la-rrd_afm_data.lo `test -f 'rrd_afm_data.c' || echo '$(srcdir)/'`rrd_afm_data.c; \
-@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/librrd_th_la-rrd_afm_data.Tpo" "$(DEPDIR)/librrd_th_la-rrd_afm_data.Plo"; else rm -f "$(DEPDIR)/librrd_th_la-rrd_afm_data.Tpo"; exit 1; fi
-@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='rrd_afm_data.c' object='librrd_th_la-rrd_afm_data.lo' libtool=yes @AMDEPBACKSLASH@
+librrd_th_la-rrd_fetch.lo: rrd_fetch.c
+@am__fastdepCC_TRUE@   if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librrd_th_la_CFLAGS) $(CFLAGS) -MT librrd_th_la-rrd_fetch.lo -MD -MP -MF "$(DEPDIR)/librrd_th_la-rrd_fetch.Tpo" -c -o librrd_th_la-rrd_fetch.lo `test -f 'rrd_fetch.c' || echo '$(srcdir)/'`rrd_fetch.c; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/librrd_th_la-rrd_fetch.Tpo" "$(DEPDIR)/librrd_th_la-rrd_fetch.Plo"; else rm -f "$(DEPDIR)/librrd_th_la-rrd_fetch.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='rrd_fetch.c' object='librrd_th_la-rrd_fetch.lo' libtool=yes @AMDEPBACKSLASH@
 @AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
-@am__fastdepCC_FALSE@  $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librrd_th_la_CFLAGS) $(CFLAGS) -c -o librrd_th_la-rrd_afm_data.lo `test -f 'rrd_afm_data.c' || echo '$(srcdir)/'`rrd_afm_data.c
+@am__fastdepCC_FALSE@  $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librrd_th_la_CFLAGS) $(CFLAGS) -c -o librrd_th_la-rrd_fetch.lo `test -f 'rrd_fetch.c' || echo '$(srcdir)/'`rrd_fetch.c
 
 librrd_th_la-rrd_tool.lo: rrd_tool.c
 @am__fastdepCC_TRUE@   if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librrd_th_la_CFLAGS) $(CFLAGS) -MT librrd_th_la-rrd_tool.lo -MD -MP -MF "$(DEPDIR)/librrd_th_la-rrd_tool.Tpo" -c -o librrd_th_la-rrd_tool.lo `test -f 'rrd_tool.c' || echo '$(srcdir)/'`rrd_tool.c; \
@@ -843,6 +839,20 @@ librrd_th_la-rrd_tool.lo: rrd_tool.c
 @AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
 @am__fastdepCC_FALSE@  $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librrd_th_la_CFLAGS) $(CFLAGS) -c -o librrd_th_la-rrd_tool.lo `test -f 'rrd_tool.c' || echo '$(srcdir)/'`rrd_tool.c
 
+librrd_th_la-rrd_resize.lo: rrd_resize.c
+@am__fastdepCC_TRUE@   if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librrd_th_la_CFLAGS) $(CFLAGS) -MT librrd_th_la-rrd_resize.lo -MD -MP -MF "$(DEPDIR)/librrd_th_la-rrd_resize.Tpo" -c -o librrd_th_la-rrd_resize.lo `test -f 'rrd_resize.c' || echo '$(srcdir)/'`rrd_resize.c; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/librrd_th_la-rrd_resize.Tpo" "$(DEPDIR)/librrd_th_la-rrd_resize.Plo"; else rm -f "$(DEPDIR)/librrd_th_la-rrd_resize.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='rrd_resize.c' object='librrd_th_la-rrd_resize.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librrd_th_la_CFLAGS) $(CFLAGS) -c -o librrd_th_la-rrd_resize.lo `test -f 'rrd_resize.c' || echo '$(srcdir)/'`rrd_resize.c
+
+librrd_th_la-rrd_tune.lo: rrd_tune.c
+@am__fastdepCC_TRUE@   if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librrd_th_la_CFLAGS) $(CFLAGS) -MT librrd_th_la-rrd_tune.lo -MD -MP -MF "$(DEPDIR)/librrd_th_la-rrd_tune.Tpo" -c -o librrd_th_la-rrd_tune.lo `test -f 'rrd_tune.c' || echo '$(srcdir)/'`rrd_tune.c; \
+@am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/librrd_th_la-rrd_tune.Tpo" "$(DEPDIR)/librrd_th_la-rrd_tune.Plo"; else rm -f "$(DEPDIR)/librrd_th_la-rrd_tune.Tpo"; exit 1; fi
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      source='rrd_tune.c' object='librrd_th_la-rrd_tune.lo' libtool=yes @AMDEPBACKSLASH@
+@AMDEP_TRUE@@am__fastdepCC_FALSE@      DEPDIR=$(DEPDIR) $(CCDEPMODE) $(depcomp) @AMDEPBACKSLASH@
+@am__fastdepCC_FALSE@  $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librrd_th_la_CFLAGS) $(CFLAGS) -c -o librrd_th_la-rrd_tune.lo `test -f 'rrd_tune.c' || echo '$(srcdir)/'`rrd_tune.c
+
 librrd_th_la-rrd_thread_safe.lo: rrd_thread_safe.c
 @am__fastdepCC_TRUE@   if $(LIBTOOL) --tag=CC --mode=compile $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(librrd_th_la_CFLAGS) $(CFLAGS) -MT librrd_th_la-rrd_thread_safe.lo -MD -MP -MF "$(DEPDIR)/librrd_th_la-rrd_thread_safe.Tpo" -c -o librrd_th_la-rrd_thread_safe.lo `test -f 'rrd_thread_safe.c' || echo '$(srcdir)/'`rrd_thread_safe.c; \
 @am__fastdepCC_TRUE@   then mv -f "$(DEPDIR)/librrd_th_la-rrd_thread_safe.Tpo" "$(DEPDIR)/librrd_th_la-rrd_thread_safe.Plo"; else rm -f "$(DEPDIR)/librrd_th_la-rrd_thread_safe.Tpo"; exit 1; fi
@@ -859,23 +869,6 @@ clean-libtool:
 distclean-libtool:
        -rm -f libtool
 uninstall-info-am:
-install-fontsDATA: $(fonts_DATA)
-       @$(NORMAL_INSTALL)
-       test -z "$(fontsdir)" || $(mkdir_p) "$(DESTDIR)$(fontsdir)"
-       @list='$(fonts_DATA)'; for p in $$list; do \
-         if test -f "$$p"; then d=; else d="$(srcdir)/"; fi; \
-         f=$(am__strip_dir) \
-         echo " $(fontsDATA_INSTALL) '$$d$$p' '$(DESTDIR)$(fontsdir)/$$f'"; \
-         $(fontsDATA_INSTALL) "$$d$$p" "$(DESTDIR)$(fontsdir)/$$f"; \
-       done
-
-uninstall-fontsDATA:
-       @$(NORMAL_UNINSTALL)
-       @list='$(fonts_DATA)'; for p in $$list; do \
-         f=$(am__strip_dir) \
-         echo " rm -f '$(DESTDIR)$(fontsdir)/$$f'"; \
-         rm -f "$(DESTDIR)$(fontsdir)/$$f"; \
-       done
 install-includeHEADERS: $(include_HEADERS)
        @$(NORMAL_INSTALL)
        test -z "$(includedir)" || $(mkdir_p) "$(DESTDIR)$(includedir)"
@@ -971,11 +964,11 @@ distdir: $(DISTFILES)
        done
 check-am: all-am
 check: check-am
-all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(DATA) $(HEADERS)
+all-am: Makefile $(LTLIBRARIES) $(PROGRAMS) $(HEADERS)
 install-binPROGRAMS: install-libLTLIBRARIES
 
 installdirs:
-       for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(fontsdir)" "$(DESTDIR)$(includedir)"; do \
+       for dir in "$(DESTDIR)$(libdir)" "$(DESTDIR)$(bindir)" "$(DESTDIR)$(includedir)"; do \
          test -z "$$dir" || $(mkdir_p) "$$dir"; \
        done
 install: install-am
@@ -1023,7 +1016,7 @@ info: info-am
 
 info-am:
 
-install-data-am: install-fontsDATA install-includeHEADERS
+install-data-am: install-includeHEADERS
 
 install-exec-am: install-binPROGRAMS install-libLTLIBRARIES
 
@@ -1051,9 +1044,8 @@ ps: ps-am
 
 ps-am:
 
-uninstall-am: uninstall-binPROGRAMS uninstall-fontsDATA \
-       uninstall-includeHEADERS uninstall-info-am \
-       uninstall-libLTLIBRARIES
+uninstall-am: uninstall-binPROGRAMS uninstall-includeHEADERS \
+       uninstall-info-am uninstall-libLTLIBRARIES
 
 .PHONY: CTAGS GTAGS all all-am check check-am clean clean-binPROGRAMS \
        clean-generic clean-libLTLIBRARIES clean-libtool \
@@ -1061,15 +1053,14 @@ uninstall-am: uninstall-binPROGRAMS uninstall-fontsDATA \
        distclean-generic distclean-libtool distclean-tags distdir dvi \
        dvi-am html html-am info info-am install install-am \
        install-binPROGRAMS install-data install-data-am install-exec \
-       install-exec-am install-fontsDATA install-includeHEADERS \
-       install-info install-info-am install-libLTLIBRARIES \
-       install-man install-strip installcheck installcheck-am \
-       installdirs maintainer-clean maintainer-clean-generic \
-       mostlyclean mostlyclean-compile mostlyclean-generic \
-       mostlyclean-libtool pdf pdf-am ps ps-am tags uninstall \
-       uninstall-am uninstall-binPROGRAMS uninstall-fontsDATA \
-       uninstall-includeHEADERS uninstall-info-am \
-       uninstall-libLTLIBRARIES
+       install-exec-am install-includeHEADERS install-info \
+       install-info-am install-libLTLIBRARIES install-man \
+       install-strip installcheck installcheck-am installdirs \
+       maintainer-clean maintainer-clean-generic mostlyclean \
+       mostlyclean-compile mostlyclean-generic mostlyclean-libtool \
+       pdf pdf-am ps ps-am tags uninstall uninstall-am \
+       uninstall-binPROGRAMS uninstall-includeHEADERS \
+       uninstall-info-am uninstall-libLTLIBRARIES
 
 # Tell versions [3.59,3.63) of GNU make to not export all variables.
 # Otherwise a system limit (for SysV at least) may be exceeded.
diff --git a/src/art_rgba_svp.c b/src/art_rgba_svp.c
deleted file mode 100644 (file)
index 25083d7..0000000
+++ /dev/null
@@ -1,333 +0,0 @@
-/* -*- Mode: C; tab-width: 8; indent-tabs-mode: t; c-basic-offset: 8 -*- */
-/*
- *  art_rgba_svp.c: A slightly modified version of art_rgb_svp to render into rgba buffer
- *
- *  This program is free software; you can redistribute it and/or
- *  modify it under the terms of the GNU Library General Public License
- *  as published by the Free Software Foundation; either version 2 of
- *  the License, or (at your option) any later version.
- *
- *  This program is distributed in the hope that it will be useful,
- *  but WITHOUT ANY WARRANTY; without even the implied warranty of
- *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
- *  GNU Library General Public License for more details.
- *
- *  You should have received a copy of the GNU Library General Public
- *  License along with this program; if not, write to the Free Software
- *  Foundation, Inc., 675 Mass Ave, Cambridge, MA 02139, USA.
- *
- *  Authors:
- *    Raph Levien <raph@acm.org>
- *    Lauris Kaplinski <lauris@ariman.ee>
- *
- *  Copyright (C) 1998 Raph Levien
- *
- */
-
-#define SP_ART_RGBA_SVP_C
-
-/* Render a sorted vector path into an RGBA buffer. */
-
-#include <libart_lgpl/art_misc.h>
-#include <libart_lgpl/art_svp.h>
-#include <libart_lgpl/art_svp_render_aa.h>
-#include <libart_lgpl/art_rgb.h>
-
-#include "art_rgba_svp.h"
-#include "unused.h"
-
-static void art_rgba_fill_run (art_u8 * linebuf, art_u8 r, art_u8 g, art_u8 b, int n);
-static void art_rgba_run_alpha (art_u8 * linebuf, art_u8 r, art_u8 g, art_u8 b, int alpha, int n);
-
-typedef struct _ArtRgbaSVPAlphaData ArtRgbaSVPAlphaData;
-
-struct _ArtRgbaSVPAlphaData {
-  int alphatab[256];
-  art_u8 r, g, b, alpha;
-  art_u8 *buf;
-  int rowstride;
-  int libart_x0, libart_x1;
-};
-
-static void
-art_rgba_svp_alpha_callback (void *callback_data, int UNUSED(y),
-                           int start, ArtSVPRenderAAStep *steps, int n_steps)
-{
-  ArtRgbaSVPAlphaData *data = callback_data;
-  art_u8 *linebuf;
-  int run_x0, run_x1;
-  art_u32 running_sum = start;
-  int libart_x0, libart_x1;
-  int k;
-  art_u8 r, g, b;
-  int *alphatab;
-  int alpha;
-
-  linebuf = data->buf;
-  libart_x0 = data->libart_x0;
-  libart_x1 = data->libart_x1;
-
-  r = data->r;
-  g = data->g;
-  b = data->b;
-  alphatab = data->alphatab;
-
-  if (n_steps > 0)
-    {
-      run_x1 = steps[0].x;
-      if (run_x1 > libart_x0)
-       {
-         alpha = (running_sum >> 16) & 0xff;
-         if (alpha)
-           art_rgba_run_alpha (linebuf,
-                              r, g, b, alphatab[alpha],
-                              run_x1 - libart_x0);
-       }
-
-      /* render the steps into tmpbuf */
-      for (k = 0; k < n_steps - 1; k++)
-       {
-         running_sum += steps[k].delta;
-         run_x0 = run_x1;
-         run_x1 = steps[k + 1].x;
-         if (run_x1 > run_x0)
-           {
-             alpha = (running_sum >> 16) & 0xff;
-             if (alpha)
-               art_rgba_run_alpha (linebuf + (run_x0 - libart_x0) * 4,
-                                  r, g, b, alphatab[alpha],
-                                  run_x1 - run_x0);
-           }
-       }
-      running_sum += steps[k].delta;
-      if (libart_x1 > run_x1)
-       {
-         alpha = (running_sum >> 16) & 0xff;
-         if (alpha)
-           art_rgba_run_alpha (linebuf + (run_x1 - libart_x0) * 4,
-                              r, g, b, alphatab[alpha],
-                              libart_x1 - run_x1);
-       }
-    }
-  else
-    {
-      alpha = (running_sum >> 16) & 0xff;
-      if (alpha)
-       art_rgba_run_alpha (linebuf,
-                          r, g, b, alphatab[alpha],
-                          libart_x1 - libart_x0);
-    }
-
-  data->buf += data->rowstride;
-}
-
-static void
-art_rgba_svp_alpha_opaque_callback (void *callback_data, int UNUSED(y),
-                                  int start,
-                                  ArtSVPRenderAAStep *steps, int n_steps)
-{
-  ArtRgbaSVPAlphaData *data = callback_data;
-  art_u8 *linebuf;
-  int run_x0, run_x1;
-  art_u32 running_sum = start;
-  int libart_x0, libart_x1;
-  int k;
-  art_u8 r, g, b;
-  int *alphatab;
-  int alpha;
-
-  linebuf = data->buf;
-  libart_x0 = data->libart_x0;
-  libart_x1 = data->libart_x1;
-
-  r = data->r;
-  g = data->g;
-  b = data->b;
-  alphatab = data->alphatab;
-
-  if (n_steps > 0)
-    {
-      run_x1 = steps[0].x;
-      if (run_x1 > libart_x0)
-       {
-         alpha = running_sum >> 16;
-         if (alpha)
-           {
-             if (alpha >= 255)
-               art_rgba_fill_run (linebuf,
-                                 r, g, b,
-                                 run_x1 - libart_x0);
-             else
-               art_rgba_run_alpha (linebuf,
-                                  r, g, b, alphatab[alpha],
-                                  run_x1 - libart_x0);
-           }
-       }
-
-      /* render the steps into tmpbuf */
-      for (k = 0; k < n_steps - 1; k++)
-       {
-         running_sum += steps[k].delta;
-         run_x0 = run_x1;
-         run_x1 = steps[k + 1].x;
-         if (run_x1 > run_x0)
-           {
-             alpha = running_sum >> 16;
-             if (alpha)
-               {
-                 if (alpha >= 255)
-                   art_rgba_fill_run (linebuf + (run_x0 - libart_x0) * 4,
-                                     r, g, b,
-                                     run_x1 - run_x0);
-                 else
-                   art_rgba_run_alpha (linebuf + (run_x0 - libart_x0) * 4,
-                                      r, g, b, alphatab[alpha],
-                                      run_x1 - run_x0);
-               }
-           }
-       }
-      running_sum += steps[k].delta;
-      if (libart_x1 > run_x1)
-       {
-         alpha = running_sum >> 16;
-         if (alpha)
-           {
-             if (alpha >= 255)
-               art_rgba_fill_run (linebuf + (run_x1 - libart_x0) * 4,
-                                 r, g, b,
-                                 libart_x1 - run_x1);
-             else
-               art_rgba_run_alpha (linebuf + (run_x1 - libart_x0) * 4,
-                                  r, g, b, alphatab[alpha],
-                                  libart_x1 - run_x1);
-           }
-       }
-    }
-  else
-    {
-      alpha = running_sum >> 16;
-      if (alpha)
-       {
-         if (alpha >= 255)
-           art_rgba_fill_run (linebuf,
-                             r, g, b,
-                             libart_x1 - libart_x0);
-         else
-           art_rgba_run_alpha (linebuf,
-                              r, g, b, alphatab[alpha],
-                              libart_x1 - libart_x0);
-       }
-    }
-
-  data->buf += data->rowstride;
-}
-
-/**
- * gnome_print_art_rgba_svp_alpha: Alpha-composite sorted vector path over RGBA buffer.
- * @svp: The source sorted vector path.
- * @libart_x0: Left coordinate of destination rectangle.
- * @libart_y0: Top coordinate of destination rectangle.
- * @libart_x1: Right coordinate of destination rectangle.
- * @libart_y1: Bottom coordinate of destination rectangle.
- * @rgba: Color in 0xRRGGBBAA format.
- * @buf: Destination RGB buffer.
- * @rowstride: Rowstride of @buf buffer.
- * @alphagamma: #ArtAlphaGamma for gamma-correcting the compositing.
- *
- * Renders the shape specified with @svp over the @buf RGB buffer.
- * @libart_x1 - @x0 specifies the width, and @libart_y1 - @libart_y0 specifies the height,
- * of the rectangle rendered. The new pixels are stored starting at
- * the first byte of @buf. Thus, the @x0 and @libart_y0 parameters specify
- * an offset within @svp, and may be tweaked as a way of doing
- * integer-pixel translations without fiddling with @svp itself.
- *
- * The @rgba argument specifies the color for the rendering. Pixels of
- * entirely 0 winding number are left untouched. Pixels of entirely
- * 1 winding number have the color @rgba composited over them (ie,
- * are replaced by the red, green, blue components of @rgba if the alpha
- * component is 0xff). Pixels of intermediate coverage are interpolated
- * according to the rule in @alphagamma, or default to linear if
- * @alphagamma is NULL.
- **/
-void
-gnome_print_art_rgba_svp_alpha (const ArtSVP *svp,
-                               int libart_x0, int libart_y0, int libart_x1, int libart_y1,
-                               art_u32 rgba,
-                               art_u8 *buf, int rowstride,
-                               ArtAlphaGamma UNUSED(*alphagamma))
-{
-  ArtRgbaSVPAlphaData data;
-  int r, g, b, alpha;
-  int i;
-  int a, da;
-
-  r = rgba >> 24;
-  g = (rgba >> 16) & 0xff;
-  b = (rgba >> 8) & 0xff;
-  alpha = rgba & 0xff;
-
-  data.r = r;
-  data.g = g;
-  data.b = b;
-  data.alpha = alpha;
-
-  a = 0x8000;
-  da = (alpha * 66051 + 0x80) >> 8; /* 66051 equals 2 ^ 32 / (255 * 255) */
-
-  for (i = 0; i < 256; i++)
-    {
-      data.alphatab[i] = a >> 16;
-      a += da;
-    }
-
-  data.buf = buf;
-  data.rowstride = rowstride;
-  data.libart_x0 = libart_x0;
-  data.libart_x1 = libart_x1;
-  if (alpha == 255)
-    art_svp_render_aa (svp, libart_x0, libart_y0, libart_x1, libart_y1, art_rgba_svp_alpha_opaque_callback,
-                      &data);
-  else
-    art_svp_render_aa (svp, libart_x0, libart_y0, libart_x1, libart_y1, art_rgba_svp_alpha_callback, &data);
-}
-
-static void
-art_rgba_fill_run (art_u8 * buf, art_u8 r, art_u8 g, art_u8 b, int n)
-{
-       int i;
-
-       for (i = 0; i < n; i++) {
-               * buf++ = r;
-               * buf++ = g;
-               * buf++ = b;
-               * buf++ = 255;
-       }
-}
-
-/* fixme: this */
-
-static void
-art_rgba_run_alpha (art_u8 * buf, art_u8 r, art_u8 g, art_u8 b, int alpha, int n)
-{
-       int i;
-       int br, bg, bb, ba;
-       int cr, cg, cb;
-
-       for (i = 0; i < n; i++) {
-               br = * (buf + 0);
-               bg = * (buf + 1);
-               bb = * (buf + 2);
-               ba = * (buf + 3);
-
-               cr = (br * ba + 0x80) >> 8;
-               cg = (bg * ba + 0x80) >> 8;
-               cb = (bb * ba + 0x80) >> 8;
-
-               * buf++ = cr + (((r - cr) * alpha + 0x80) >> 8);
-               * buf++ = cg + (((g - cg) * alpha + 0x80) >> 8);
-               * buf++ = cb + (((b - cb) * alpha + 0x80) >> 8);
-               * buf++ = ba + (((255 - ba) * alpha + 0x80) >> 8);
-       }
-}
-
-
diff --git a/src/art_rgba_svp.h b/src/art_rgba_svp.h
deleted file mode 100644 (file)
index 4cac175..0000000
+++ /dev/null
@@ -1,17 +0,0 @@
-#ifndef SP_ART_RGBA_SVP_H
-#define SP_ART_RGBA_SVP_H
-
-#include <libart_lgpl/art_misc.h>
-#include <libart_lgpl/art_alphagamma.h>
-#include <libart_lgpl/art_affine.h>
-#include <libart_lgpl/art_svp.h>
-#include <libart_lgpl/art_uta.h>
-
-void
-gnome_print_art_rgba_svp_alpha (const ArtSVP *svp,
-                               int x0, int y0, int x1, int y1,
-                               art_u32 rgba,
-                               art_u8 *buf, int rowstride,
-                               ArtAlphaGamma *alphagamma);
-
-#endif /* SP_ART_RGBA_SVP_H */
index 75004ad0a63c45e045642c0f70a36a4ab17018f1..f7d3bcca7df25d62d84215fba20b661416d40900 100644 (file)
--- a/src/fnv.h
+++ b/src/fnv.h
@@ -1,8 +1,8 @@
 /*
  * fnv - Fowler/Noll/Vo- hash code
  *
- * @(#) $Revision: 1028 $
- * @(#) $Id: fnv.h 1028 2007-04-02 06:21:19Z oetiker $
+ * @(#) $Revision: 1306 $
+ * @(#) $Id: fnv.h 1306 2008-03-15 10:39:48Z oetiker $
  * @(#) $Source$
  *
  ***
@@ -99,10 +99,16 @@ typedef unsigned long Fnv32_t;
  */
 #define FNV1_32_INIT ((Fnv32_t)0x811c9dc5)
 
-Fnv32_t fnv_32_buf(const void *, size_t, Fnv32_t);
+Fnv32_t   fnv_32_buf(
+    const void *,
+    size_t,
+    Fnv32_t);
 
-Fnv32_t fnv_32_str(const char *, Fnv32_t );
+Fnv32_t   fnv_32_str(
+    const char *,
+    Fnv32_t);
 
-unsigned long FnvHash(const char *);
+unsigned long FnvHash(
+    const char *);
 
-#endif /* __FNV_H__ */
+#endif                          /* __FNV_H__ */
index d7edbee753327a079846b8199eb8deede5195a5e..7885c3ed2d1863dedc1eb7ba88e25759d269735a 100644 (file)
@@ -65,7 +65,7 @@
 /* 
  * 32 bit magic FNV-0 and FNV-1 prime 
  */
-#define FNV_32_PRIME ((Fnv32_t)0x01000193)     
+#define FNV_32_PRIME ((Fnv32_t)0x01000193)
 
 
 /*
  * NOTE: To use the recommended 32 bit FNV-1 hash, use FNV1_32_INIT as the hval
  *      argument on the first call to either fnv_32_buf() or fnv_32_str().
  */
-Fnv32_t
-fnv_32_buf(const void *buf, size_t len, Fnv32_t hval)
+Fnv32_t fnv_32_buf(
+    const void *buf,
+    size_t len,
+    Fnv32_t hval)
 {
-    const unsigned char *bp = (const unsigned char *)buf;      /* start of buffer */
-    const unsigned char *be = bp + len;                /* beyond end of buffer */
+    const unsigned char *bp = (const unsigned char *) buf;  /* start of buffer */
+    const unsigned char *be = bp + len; /* beyond end of buffer */
 
     /*
      * FNV-1 hash each octet in the buffer
      */
     while (bp < be) {
 
-       /* multiply by the 32 bit FNV magic prime mod 2^64 */
-       hval *= FNV_32_PRIME;
+        /* multiply by the 32 bit FNV magic prime mod 2^64 */
+        hval *= FNV_32_PRIME;
 
-       /* xor the bottom with the current octet */
-       hval ^= (Fnv32_t)*bp++;
+        /* xor the bottom with the current octet */
+        hval ^= (Fnv32_t) *bp++;
     }
 
     /* return our new hash value */
@@ -124,21 +126,22 @@ fnv_32_buf(const void *buf, size_t len, Fnv32_t hval)
  * NOTE: To use the recommended 32 bit FNV-1 hash, use FNV1_32_INIT as the hval
  *      argument on the first call to either fnv_32_buf() or fnv_32_str().
  */
-Fnv32_t
-fnv_32_str(const char *str, Fnv32_t hval)
+Fnv32_t fnv_32_str(
+    const char *str,
+    Fnv32_t hval)
 {
-    const unsigned char *s = (const unsigned char *)str;       /* unsigned string */
+    const unsigned char *s = (const unsigned char *) str;   /* unsigned string */
 
     /*
      * FNV-1 hash each octet in the buffer
      */
     while (*s) {
 
-       /* multiply by the 32 bit FNV magic prime mod 2^64 */
-       hval *= FNV_32_PRIME;
+        /* multiply by the 32 bit FNV magic prime mod 2^64 */
+        hval *= FNV_32_PRIME;
 
-       /* xor the bottom with the current octet */
-       hval ^= (Fnv32_t)*s++;
+        /* xor the bottom with the current octet */
+        hval ^= (Fnv32_t) *s++;
     }
 
     /* return our new hash value */
@@ -146,7 +149,8 @@ fnv_32_str(const char *str, Fnv32_t hval)
 }
 
 /* a wrapper function for fnv_32_str */
-unsigned long FnvHash(const char *str)
+unsigned long FnvHash(
+    const char *str)
 {
-  return fnv_32_str(str,FNV1_32_INIT);
+    return fnv_32_str(str, FNV1_32_INIT);
 }
index 919dd50b340d74ed8806c59af2e9ae88b0082aaf..8818f1cbe2cb8732d6476f6040bd9c41bbb3cd7d 100644 (file)
 
 /* Structures and unions */
 
-enum { /* symbols */
+enum {                  /* symbols */
     MIDNIGHT, NOON, TEATIME,
     PM, AM, YESTERDAY, TODAY, TOMORROW, NOW, START, END,
     SECONDS, MINUTES, HOURS, DAYS, WEEKS, MONTHS, YEARS,
@@ -128,7 +128,7 @@ enum {      /* symbols */
     JAN, FEB, MAR, APR, MAY, JUN,
     JUL, AUG, SEP, OCT, NOV, DEC,
     SUN, MON, TUE, WED, THU, FRI, SAT
-    };
+};
 
 /* the below is for plus_minus() */
 #define PREVIOUS_OP    (-1)
@@ -136,94 +136,94 @@ enum {    /* symbols */
 /* parse translation table - table driven parsers can be your FRIEND!
  */
 struct SpecialToken {
-    char *name;        /* token name */
-    int value; /* token id */
+    char     *name;     /* token name */
+    int       value;    /* token id */
 };
-static struct SpecialToken VariousWords[] = {
-    { "midnight", MIDNIGHT },  /* 00:00:00 of today or tomorrow */
-    { "noon", NOON },          /* 12:00:00 of today or tomorrow */
-    { "teatime", TEATIME },    /* 16:00:00 of today or tomorrow */
-    { "am", AM },              /* morning times for 0-12 clock */
-    { "pm", PM },              /* evening times for 0-12 clock */
-    { "tomorrow", TOMORROW },
-    { "yesterday", YESTERDAY },
-    { "today", TODAY },
-    { "now", NOW },
-    { "n", NOW },
-    { "start", START },
-    { "s", START },    
-    { "end", END },
-    { "e", END },
-
-    { "jan", JAN },
-    { "feb", FEB },
-    { "mar", MAR },
-    { "apr", APR },
-    { "may", MAY },
-    { "jun", JUN },
-    { "jul", JUL },
-    { "aug", AUG },
-    { "sep", SEP },
-    { "oct", OCT },
-    { "nov", NOV },
-    { "dec", DEC },
-    { "january", JAN },
-    { "february", FEB },
-    { "march", MAR },
-    { "april", APR },
-    { "may", MAY },
-    { "june", JUN },
-    { "july", JUL },
-    { "august", AUG },
-    { "september", SEP },
-    { "october", OCT },
-    { "november", NOV },
-    { "december", DEC },
-    { "sunday", SUN },
-    { "sun", SUN },
-    { "monday", MON },
-    { "mon", MON },
-    { "tuesday", TUE },
-    { "tue", TUE },
-    { "wednesday", WED },
-    { "wed", WED },
-    { "thursday", THU },
-    { "thu", THU },
-    { "friday", FRI },
-    { "fri", FRI },
-    { "saturday", SAT },
-    { "sat", SAT },
-    { NULL, 0 }                        /*** SENTINEL ***/
+static const struct SpecialToken VariousWords[] = {
+    {"midnight", MIDNIGHT}, /* 00:00:00 of today or tomorrow */
+    {"noon", NOON},     /* 12:00:00 of today or tomorrow */
+    {"teatime", TEATIME},   /* 16:00:00 of today or tomorrow */
+    {"am", AM},         /* morning times for 0-12 clock */
+    {"pm", PM},         /* evening times for 0-12 clock */
+    {"tomorrow", TOMORROW},
+    {"yesterday", YESTERDAY},
+    {"today", TODAY},
+    {"now", NOW},
+    {"n", NOW},
+    {"start", START},
+    {"s", START},
+    {"end", END},
+    {"e", END},
+
+    {"jan", JAN},
+    {"feb", FEB},
+    {"mar", MAR},
+    {"apr", APR},
+    {"may", MAY},
+    {"jun", JUN},
+    {"jul", JUL},
+    {"aug", AUG},
+    {"sep", SEP},
+    {"oct", OCT},
+    {"nov", NOV},
+    {"dec", DEC},
+    {"january", JAN},
+    {"february", FEB},
+    {"march", MAR},
+    {"april", APR},
+    {"may", MAY},
+    {"june", JUN},
+    {"july", JUL},
+    {"august", AUG},
+    {"september", SEP},
+    {"october", OCT},
+    {"november", NOV},
+    {"december", DEC},
+    {"sunday", SUN},
+    {"sun", SUN},
+    {"monday", MON},
+    {"mon", MON},
+    {"tuesday", TUE},
+    {"tue", TUE},
+    {"wednesday", WED},
+    {"wed", WED},
+    {"thursday", THU},
+    {"thu", THU},
+    {"friday", FRI},
+    {"fri", FRI},
+    {"saturday", SAT},
+    {"sat", SAT},
+    {NULL, 0}           /*** SENTINEL ***/
 };
 
-static struct SpecialToken TimeMultipliers[] = {
-    { "second", SECONDS },     /* seconds multiplier */
-    { "seconds", SECONDS },    /* (pluralized) */
-    { "sec", SECONDS },                /* (generic) */
-    { "s", SECONDS },          /* (short generic) */
-    { "minute", MINUTES },     /* minutes multiplier */
-    { "minutes", MINUTES },    /* (pluralized) */
-    { "min", MINUTES },                /* (generic) */
-    { "m", MONTHS_MINUTES },   /* (short generic) */
-    { "hour", HOURS },         /* hours ... */
-    { "hours", HOURS },                /* (pluralized) */
-    { "hr", HOURS },           /* (generic) */
-    { "h", HOURS },            /* (short generic) */
-    { "day", DAYS },           /* days ... */
-    { "days", DAYS },          /* (pluralized) */
-    { "d", DAYS },             /* (short generic) */
-    { "week", WEEKS },         /* week ... */
-    { "weeks", WEEKS },                /* (pluralized) */
-    { "wk", WEEKS },           /* (generic) */
-    { "w", WEEKS },            /* (short generic) */
-    { "month", MONTHS },       /* week ... */
-    { "months", MONTHS },      /* (pluralized) */
-    { "mon", MONTHS },         /* (generic) */
-    { "year", YEARS },         /* year ... */
-    { "years", YEARS },                /* (pluralized) */
-    { "yr", YEARS },           /* (generic) */
-    { "y", YEARS },            /* (short generic) */
-    { NULL, 0 }                        /*** SENTINEL ***/
+static const struct SpecialToken TimeMultipliers[] = {
+    {"second", SECONDS},    /* seconds multiplier */
+    {"seconds", SECONDS},   /* (pluralized) */
+    {"sec", SECONDS},   /* (generic) */
+    {"s", SECONDS},     /* (short generic) */
+    {"minute", MINUTES},    /* minutes multiplier */
+    {"minutes", MINUTES},   /* (pluralized) */
+    {"min", MINUTES},   /* (generic) */
+    {"m", MONTHS_MINUTES},  /* (short generic) */
+    {"hour", HOURS},    /* hours ... */
+    {"hours", HOURS},   /* (pluralized) */
+    {"hr", HOURS},      /* (generic) */
+    {"h", HOURS},       /* (short generic) */
+    {"day", DAYS},      /* days ... */
+    {"days", DAYS},     /* (pluralized) */
+    {"d", DAYS},        /* (short generic) */
+    {"week", WEEKS},    /* week ... */
+    {"weeks", WEEKS},   /* (pluralized) */
+    {"wk", WEEKS},      /* (generic) */
+    {"w", WEEKS},       /* (short generic) */
+    {"month", MONTHS},  /* week ... */
+    {"months", MONTHS}, /* (pluralized) */
+    {"mon", MONTHS},    /* (generic) */
+    {"year", YEARS},    /* year ... */
+    {"years", YEARS},   /* (pluralized) */
+    {"yr", YEARS},      /* (generic) */
+    {"y", YEARS},       /* (short generic) */
+    {NULL, 0}           /*** SENTINEL ***/
 };
 
 /* File scope variables */
@@ -232,26 +232,27 @@ static struct SpecialToken TimeMultipliers[] = {
  * required for us to be able distinguish between 'mon' as 'month'
  * and 'mon' as 'monday'
  */
-static struct SpecialToken *Specials;
+static const struct SpecialToken *Specials;
 
-static const char **scp;       /* scanner - pointer at arglist */
-static char scc;       /* scanner - count of remaining arguments */
-static const char *sct;        /* scanner - next char pointer in current argument */
-static int need;       /* scanner - need to advance to next argument */
+static const char **scp;    /* scanner - pointer at arglist */
+static char scc;        /* scanner - count of remaining arguments */
+static const char *sct; /* scanner - next char pointer in current argument */
+static int need;        /* scanner - need to advance to next argument */
 
-static char *sc_token=NULL;    /* scanner - token buffer */
+static char *sc_token = NULL;   /* scanner - token buffer */
 static size_t sc_len;   /* scanner - length of token buffer */
-static int sc_tokid;   /* scanner - token id */
+static int sc_tokid;    /* scanner - token id */
 
 /* Local functions */
-static void EnsureMemFree (void);
+static void EnsureMemFree(
+    void);
 
-static void EnsureMemFree (void)
+static void EnsureMemFree(
+    void)
 {
-  if( sc_token )
-    {
-    free(sc_token);
-    sc_token = NULL;
+    if (sc_token) {
+        free(sc_token);
+        sc_token = NULL;
     }
 }
 
@@ -293,178 +294,187 @@ static void EnsureMemFree (void)
  * the most appropriate use for these is inside panic(...) 
  */
 #define MAX_ERR_MSG_LEN        1024
-static char errmsg[ MAX_ERR_MSG_LEN ];
+static char errmsg[MAX_ERR_MSG_LEN];
 
-static char *
-ve ( char *fmt, va_list ap )
+static char *ve(
+    char *fmt,
+    va_list ap)
 {
 #ifdef HAVE_VSNPRINTF
-  vsnprintf( errmsg, MAX_ERR_MSG_LEN, fmt, ap );
+    vsnprintf(errmsg, MAX_ERR_MSG_LEN, fmt, ap);
 #else
-  vsprintf( errmsg, fmt, ap );
+    vsprintf(errmsg, fmt, ap);
 #endif
-  EnsureMemFree();
-  return( errmsg );
+    EnsureMemFree();
+    return (errmsg);
 }
 
-static char *
-e ( char *fmt, ... )
+static char *e(
+    char *fmt,
+    ...)
 {
-  char *err;
-  va_list ap;
-  va_start( ap, fmt );
-  err = ve( fmt, ap );
-  va_end( ap );
-  return( err );
+    char     *err;
+    va_list   ap;
+
+    va_start(ap, fmt);
+    err = ve(fmt, ap);
+    va_end(ap);
+    return (err);
 }
 
 /* Compare S1 and S2, ignoring case, returning less than, equal to or
    greater than zero if S1 is lexicographically less than,
    equal to or greater than S2.  -- copied from GNU libc*/
-static int
-mystrcasecmp (s1, s2)
-     const char *s1;
-     const char *s2;
+static int mystrcasecmp(
+    const char *s1,
+    const char *s2)
 {
-  const unsigned char *p1 = (const unsigned char *) s1;
-  const unsigned char *p2 = (const unsigned char *) s2;
-  unsigned char c1, c2;
+    const unsigned char *p1 = (const unsigned char *) s1;
+    const unsigned char *p2 = (const unsigned char *) s2;
+    unsigned char c1, c2;
 
-  if (p1 == p2)
-    return 0;
+    if (p1 == p2)
+        return 0;
 
-  do
-    {
-      c1 = tolower (*p1++);
-      c2 = tolower (*p2++);
-      if (c1 == '\0')
-       break;
+    do {
+        c1 = tolower(*p1++);
+        c2 = tolower(*p2++);
+        if (c1 == '\0')
+            break;
     }
-  while (c1 == c2);
+    while (c1 == c2);
 
-  return c1 - c2;
+    return c1 - c2;
 }
 
 /*
  * parse a token, checking if it's something special to us
  */
-static int
-parse_token(char *arg)
+static int parse_token(
+    char *arg)
 {
-    int i;
+    int       i;
 
-    for (i=0; Specials[i].name != NULL; i++)
-       if (mystrcasecmp(Specials[i].name, arg) == 0)
-           return sc_tokid = Specials[i].value;
+    for (i = 0; Specials[i].name != NULL; i++)
+        if (mystrcasecmp(Specials[i].name, arg) == 0)
+            return sc_tokid = Specials[i].value;
 
     /* not special - must be some random id */
     return sc_tokid = ID;
-} /* parse_token */
+}                       /* parse_token */
 
 
 
 /*
  * init_scanner() sets up the scanner to eat arguments
  */
-static char *
-init_scanner(int argc, const char **argv)
+static char *init_scanner(
+    int argc,
+    const char **argv)
 {
     scp = argv;
     scc = argc;
     need = 1;
     sc_len = 1;
     while (argc-- > 0)
-       sc_len += strlen(*argv++);
+        sc_len += strlen(*argv++);
 
-    sc_token = (char *) malloc(sc_len*sizeof(char));
-    if( sc_token == NULL )
-      return "Failed to allocate memory";
+    sc_token = (char *) malloc(sc_len * sizeof(char));
+    if (sc_token == NULL)
+        return "Failed to allocate memory";
     return TIME_OK;
-} /* init_scanner */
+}                       /* init_scanner */
 
 /*
  * token() fetches a token from the input stream
  */
-static int
-token()
+static int token(
+    void)
 {
-    int idx;
+    int       idx;
 
     while (1) {
-       memset(sc_token, '\0', sc_len);
-       sc_tokid = EOF;
-       idx = 0;
-
-       /* if we need to read another argument, walk along the argument list;
-        * when we fall off the arglist, we'll just return EOF forever
-        */
-       if (need) {
-           if (scc < 1)
-               return sc_tokid;
-           sct = *scp;
-           scp++;
-           scc--;
-           need = 0;
-       }
-       /* eat whitespace now - if we walk off the end of the argument,
-        * we'll continue, which puts us up at the top of the while loop
-        * to fetch the next argument in
-        */
-       while (isspace((unsigned char)*sct) || *sct == '_' || *sct == ',' )
-           ++sct;
-       if (!*sct) {
-           need = 1;
-           continue;
-       }
-
-       /* preserve the first character of the new token
-        */
-       sc_token[0] = *sct++;
-
-       /* then see what it is
-        */
-       if (isdigit((unsigned char)(sc_token[0]))) {
-           while (isdigit((unsigned char)(*sct)))
-               sc_token[++idx] = *sct++;
-           sc_token[++idx] = '\0';
-           return sc_tokid = NUMBER;
-       }
-       else if (isalpha((unsigned char)(sc_token[0]))) {
-           while (isalpha((unsigned char)(*sct)))
-               sc_token[++idx] = *sct++;
-           sc_token[++idx] = '\0';
-           return parse_token(sc_token);
-       }
-       else switch(sc_token[0]) {
-           case ':': return sc_tokid = COLON;
-           case '.': return sc_tokid = DOT;
-           case '+': return sc_tokid = PLUS;
-           case '-': return sc_tokid = MINUS;
-           case '/': return sc_tokid = SLASH;
-       default:
-        /*OK, we did not make it ... */
-           sct--;
-           return sc_tokid = EOF;
-       }
-    } /* while (1) */
-} /* token */
+        memset(sc_token, '\0', sc_len);
+        sc_tokid = EOF;
+        idx = 0;
+
+        /* if we need to read another argument, walk along the argument list;
+         * when we fall off the arglist, we'll just return EOF forever
+         */
+        if (need) {
+            if (scc < 1)
+                return sc_tokid;
+            sct = *scp;
+            scp++;
+            scc--;
+            need = 0;
+        }
+        /* eat whitespace now - if we walk off the end of the argument,
+         * we'll continue, which puts us up at the top of the while loop
+         * to fetch the next argument in
+         */
+        while (isspace((unsigned char) *sct) || *sct == '_' || *sct == ',')
+            ++sct;
+        if (!*sct) {
+            need = 1;
+            continue;
+        }
+
+        /* preserve the first character of the new token
+         */
+        sc_token[0] = *sct++;
+
+        /* then see what it is
+         */
+        if (isdigit((unsigned char) (sc_token[0]))) {
+            while (isdigit((unsigned char) (*sct)))
+                sc_token[++idx] = *sct++;
+            sc_token[++idx] = '\0';
+            return sc_tokid = NUMBER;
+        } else if (isalpha((unsigned char) (sc_token[0]))) {
+            while (isalpha((unsigned char) (*sct)))
+                sc_token[++idx] = *sct++;
+            sc_token[++idx] = '\0';
+            return parse_token(sc_token);
+        } else
+            switch (sc_token[0]) {
+            case ':':
+                return sc_tokid = COLON;
+            case '.':
+                return sc_tokid = DOT;
+            case '+':
+                return sc_tokid = PLUS;
+            case '-':
+                return sc_tokid = MINUS;
+            case '/':
+                return sc_tokid = SLASH;
+            default:
+                /*OK, we did not make it ... */
+                sct--;
+                return sc_tokid = EOF;
+            }
+    }                   /* while (1) */
+}                       /* token */
 
 
 /* 
  * expect2() gets a token and complains if it's not the token we want
  */
-static char *
-expect2(int desired, char *complain_fmt, ...)
+static char *expect2(
+    int desired,
+    char *complain_fmt,
+    ...)
 {
-    va_list ap;
-    va_start( ap, complain_fmt );
+    va_list   ap;
+
+    va_start(ap, complain_fmt);
     if (token() != desired) {
-       panic(ve( complain_fmt, ap ));
+        panic(ve(complain_fmt, ap));
     }
-    va_end( ap );
+    va_end(ap);
     return TIME_OK;
-    
-} /* expect2 */
+
+}                       /* expect2 */
 
 
 /*
@@ -472,303 +482,341 @@ expect2(int desired, char *complain_fmt, ...)
  *              for the OFFSET-SPEC.
  *              It also applies those m-guessing heuristics.
  */
-static char *
-plus_minus(struct rrd_time_value *ptv, int doop)
+static char *plus_minus(
+    struct rrd_time_value *ptv,
+    int doop)
 {
     static int op = PLUS;
     static int prev_multiplier = -1;
-    int delta;
-
-    if( doop >= 0 ) 
-      {
-      op = doop;
-      try(expect2(NUMBER,"There should be number after '%c'", op == PLUS ? '+' : '-'));
-      prev_multiplier = -1; /* reset months-minutes guessing mechanics */
-      }
+    int       delta;
+
+    if (doop >= 0) {
+        op = doop;
+        try(expect2
+            (NUMBER, "There should be number after '%c'",
+             op == PLUS ? '+' : '-'));
+        prev_multiplier = -1;   /* reset months-minutes guessing mechanics */
+    }
     /* if doop is < 0 then we repeat the previous op
      * with the prefetched number */
 
     delta = atoi(sc_token);
 
-    if( token() == MONTHS_MINUTES )
-      {
-      /* hard job to guess what does that -5m means: -5mon or -5min? */
-      switch(prev_multiplier)
-       {
+    if (token() == MONTHS_MINUTES) {
+        /* hard job to guess what does that -5m means: -5mon or -5min? */
+        switch (prev_multiplier) {
         case DAYS:
         case WEEKS:
         case MONTHS:
         case YEARS:
-             sc_tokid = MONTHS;
-            break;
+            sc_tokid = MONTHS;
+            break;
 
         case SECONDS:
         case MINUTES:
         case HOURS:
-            sc_tokid = MINUTES;
-            break;
+            sc_tokid = MINUTES;
+            break;
 
         default:
-             if( delta < 6 ) /* it may be some other value but in the context
-                              * of RRD who needs less than 6 min deltas? */
-               sc_tokid = MONTHS;
-             else
-              sc_tokid = MINUTES;
+            if (delta < 6)  /* it may be some other value but in the context
+                             * of RRD who needs less than 6 min deltas? */
+                sc_tokid = MONTHS;
+            else
+                sc_tokid = MINUTES;
         }
-      }
+    }
     prev_multiplier = sc_tokid;
     switch (sc_tokid) {
     case YEARS:
-           ptv->tm.tm_year += (op == PLUS) ? delta : -delta;
-           return TIME_OK;
+        ptv->tm.  tm_year += (
+    op == PLUS) ? delta : -delta;
+
+        return TIME_OK;
     case MONTHS:
-           ptv->tm.tm_mon += (op == PLUS) ? delta : -delta;
-           return TIME_OK;
+        ptv->tm.  tm_mon += (
+    op == PLUS) ? delta : -delta;
+
+        return TIME_OK;
     case WEEKS:
-           delta *= 7;
-           /* FALLTHRU */
+        delta *= 7;
+        /* FALLTHRU */
     case DAYS:
-           ptv->tm.tm_mday += (op == PLUS) ? delta : -delta;
-           return TIME_OK;
+        ptv->tm.  tm_mday += (
+    op == PLUS) ? delta : -delta;
+
+        return TIME_OK;
     case HOURS:
-           ptv->offset += (op == PLUS) ? delta*60*60 : -delta*60*60;
-           return TIME_OK;
+        ptv->offset += (op == PLUS) ? delta * 60 * 60 : -delta * 60 * 60;
+        return TIME_OK;
     case MINUTES:
-           ptv->offset += (op == PLUS) ? delta*60 : -delta*60;
-           return TIME_OK;
+        ptv->offset += (op == PLUS) ? delta * 60 : -delta * 60;
+        return TIME_OK;
     case SECONDS:
-           ptv->offset += (op == PLUS) ? delta : -delta;
-           return TIME_OK;
-    default: /*default unit is seconds */
-       ptv->offset += (op == PLUS) ? delta : -delta;
-       return TIME_OK;
+        ptv->offset += (op == PLUS) ? delta : -delta;
+        return TIME_OK;
+    default:           /*default unit is seconds */
+        ptv->offset += (op == PLUS) ? delta : -delta;
+        return TIME_OK;
     }
     panic(e("well-known time unit expected after %d", delta));
     /* NORETURN */
-    return TIME_OK; /* to make compiler happy :) */
-} /* plus_minus */
+    return TIME_OK;     /* to make compiler happy :) */
+}                       /* plus_minus */
 
 
 /*
  * tod() computes the time of day (TIME-OF-DAY-SPEC)
  */
-static char *
-tod(struct rrd_time_value *ptv)
+static char *tod(
+    struct rrd_time_value *ptv)
 {
-    int hour, minute = 0;
-    int tlen;
+    int       hour, minute = 0;
+    int       tlen;
+
     /* save token status in  case we must abort */
-    int scc_sv = scc; 
-    const char *sct_sv = sct; 
-    int sc_tokid_sv = sc_tokid;
+    int       scc_sv = scc;
+    const char *sct_sv = sct;
+    int       sc_tokid_sv = sc_tokid;
 
     tlen = strlen(sc_token);
-    
+
     /* first pick out the time of day - we assume a HH (COLON|DOT) MM time
-     */    
+     */
     if (tlen > 2) {
-      return TIME_OK;
+        return TIME_OK;
     }
-    
+
     hour = atoi(sc_token);
 
     token();
     if (sc_tokid == SLASH || sc_tokid == DOT) {
-      /* guess we are looking at a date */
-      scc = scc_sv;
-      sct = sct_sv;
-      sc_tokid = sc_tokid_sv;
-      sprintf (sc_token,"%d", hour);
-      return TIME_OK;
+        /* guess we are looking at a date */
+        scc = scc_sv;
+        sct = sct_sv;
+        sc_tokid = sc_tokid_sv;
+        sprintf(sc_token, "%d", hour);
+        return TIME_OK;
     }
-    if (sc_tokid == COLON ) {
-       try(expect2(NUMBER,
-            "Parsing HH:MM syntax, expecting MM as number, got none"));
-       minute = atoi(sc_token);
-       if (minute > 59) {
-           panic(e("parsing HH:MM syntax, got MM = %d (>59!)", minute ));
-       }
-       token();
+    if (sc_tokid == COLON) {
+        try(expect2(NUMBER,
+                    "Parsing HH:MM syntax, expecting MM as number, got none"));
+        minute = atoi(sc_token);
+        if (minute > 59) {
+            panic(e("parsing HH:MM syntax, got MM = %d (>59!)", minute));
+        }
+        token();
     }
 
     /* check if an AM or PM specifier was given
      */
     if (sc_tokid == AM || sc_tokid == PM) {
-       if (hour > 12) {
-           panic(e("there cannot be more than 12 AM or PM hours"));
-       }
-       if (sc_tokid == PM) {
-           if (hour != 12)     /* 12:xx PM is 12:xx, not 24:xx */
-                       hour += 12;
-       } else {
-           if (hour == 12)     /* 12:xx AM is 00:xx, not 12:xx */
-                       hour = 0;
-       }
-       token();
-    } 
-    else if (hour > 23) {
-      /* guess it was not a time then ... */
-      scc = scc_sv;
-      sct = sct_sv;
-      sc_tokid = sc_tokid_sv;
-      sprintf (sc_token,"%d", hour);
-      return TIME_OK;
+        if (hour > 12) {
+            panic(e("there cannot be more than 12 AM or PM hours"));
+        }
+        if (sc_tokid == PM) {
+            if (hour != 12) /* 12:xx PM is 12:xx, not 24:xx */
+                hour += 12;
+        } else {
+            if (hour == 12) /* 12:xx AM is 00:xx, not 12:xx */
+                hour = 0;
+        }
+        token();
+    } else if (hour > 23) {
+        /* guess it was not a time then ... */
+        scc = scc_sv;
+        sct = sct_sv;
+        sc_tokid = sc_tokid_sv;
+        sprintf(sc_token, "%d", hour);
+        return TIME_OK;
     }
-    ptv->tm.tm_hour = hour;
-    ptv->tm.tm_min = minute;
-    ptv->tm.tm_sec = 0;
+    ptv->tm.  tm_hour = hour;
+    ptv->tm.  tm_min = minute;
+    ptv->tm.  tm_sec = 0;
+
     if (ptv->tm.tm_hour == 24) {
-       ptv->tm.tm_hour = 0;
-       ptv->tm.tm_mday++;
+        ptv->tm.  tm_hour = 0;
+        ptv->tm.  tm_mday++;
     }
-  return TIME_OK;
-} /* tod */
+    return TIME_OK;
+}                       /* tod */
 
 
 /*
  * assign_date() assigns a date, adjusting year as appropriate
  */
-static char *
-assign_date(struct rrd_time_value *ptv, long mday, long mon, long year)
+static char *assign_date(
+    struct rrd_time_value *ptv,
+    long mday,
+    long mon,
+    long year)
 {
     if (year > 138) {
-       if (year > 1970)
-           year -= 1900;
-       else {
-           panic(e("invalid year %d (should be either 00-99 or >1900)",
+        if (year > 1970)
+            year -= 1900;
+        else {
+            panic(e("invalid year %d (should be either 00-99 or >1900)",
                     year));
-       }
-    } else if( year >= 0 && year < 38 ) {
-       year += 100;         /* Allow year 2000-2037 to be specified as   */
-    }                       /* 00-37 until the problem of 2038 year will */
-                            /* arise for unices with 32-bit time_t :)    */
+        }
+    } else if (year >= 0 && year < 38) {
+        year += 100;    /* Allow year 2000-2037 to be specified as   */
+    }
+    /* 00-37 until the problem of 2038 year will */
+    /* arise for unices with 32-bit time_t :)    */
     if (year < 70) {
-      panic(e("won't handle dates before epoch (01/01/1970), sorry"));
+        panic(e("won't handle dates before epoch (01/01/1970), sorry"));
     }
 
-    ptv->tm.tm_mday = mday;
-    ptv->tm.tm_mon = mon;
-    ptv->tm.tm_year = year;
-  return TIME_OK;
-} /* assign_date */
+    ptv->tm.  tm_mday = mday;
+    ptv->tm.  tm_mon = mon;
+    ptv->tm.  tm_year = year;
+
+    return TIME_OK;
+}                       /* assign_date */
 
 
 /* 
  * day() picks apart DAY-SPEC-[12]
  */
-static char *
-day(struct rrd_time_value *ptv)
+static char *day(
+    struct rrd_time_value *ptv)
 {
-    /* using time_t seems to help portability with 64bit oses */    
-    time_t mday=0, wday, mon, year = ptv->tm.tm_year;
-    int tlen;
+    /* using time_t seems to help portability with 64bit oses */
+    time_t    mday = 0, wday, mon, year = ptv->tm.tm_year;
+    int       tlen;
 
     switch (sc_tokid) {
     case YESTERDAY:
-           ptv->tm.tm_mday--;
-           /* FALLTRHU */
-    case TODAY:        /* force ourselves to stay in today - no further processing */
-           token();
-           break;
+        ptv->tm.  tm_mday--;
+
+        /* FALLTRHU */
+    case TODAY:        /* force ourselves to stay in today - no further processing */
+        token();
+        break;
     case TOMORROW:
-           ptv->tm.tm_mday++;
-           token();
-           break;
-
-    case JAN: case FEB: case MAR: case APR: case MAY: case JUN:
-    case JUL: case AUG: case SEP: case OCT: case NOV: case DEC:
-           /* do month mday [year]
-            */
-           mon = (sc_tokid-JAN);
-           try(expect2(NUMBER,
-               "the day of the month should follow month name"));
-           mday = atol(sc_token);
-           if (token() == NUMBER) {
-               year = atol(sc_token);
-               token();
-           }
-           else
-               year = ptv->tm.tm_year;
-           try(assign_date(ptv, mday, mon, year));
-           break;
-
-    case SUN: case MON: case TUE:
-    case WED: case THU: case FRI:
+        ptv->tm.  tm_mday++;
+
+        token();
+        break;
+
+    case JAN:
+    case FEB:
+    case MAR:
+    case APR:
+    case MAY:
+    case JUN:
+    case JUL:
+    case AUG:
+    case SEP:
+    case OCT:
+    case NOV:
+    case DEC:
+        /* do month mday [year]
+         */
+        mon = (sc_tokid - JAN);
+        try(expect2(NUMBER, "the day of the month should follow month name"));
+        mday = atol(sc_token);
+        if (token() == NUMBER) {
+            year = atol(sc_token);
+            token();
+        } else
+            year = ptv->tm.tm_year;
+
+        try(assign_date(ptv, mday, mon, year));
+        break;
+
+    case SUN:
+    case MON:
+    case TUE:
+    case WED:
+    case THU:
+    case FRI:
     case SAT:
-           /* do a particular day of the week
-            */
-           wday = (sc_tokid-SUN);
-           ptv->tm.tm_mday += (wday - ptv->tm.tm_wday);
+        /* do a particular day of the week
+         */
+        wday = (sc_tokid - SUN);
+        ptv->tm.  tm_mday += (
+    wday - ptv->tm.tm_wday);
+
+        token();
+        break;
+        /*
+           mday = ptv->tm.tm_mday;
+           mday += (wday - ptv->tm.tm_wday);
+           ptv->tm.tm_wday = wday;
+
+           try(assign_date(ptv, mday, ptv->tm.tm_mon, ptv->tm.tm_year));
+           break;
+         */
+
+    case NUMBER:
+        /* get numeric <sec since 1970>, MM/DD/[YY]YY, or DD.MM.[YY]YY
+         */
+        tlen = strlen(sc_token);
+        mon = atol(sc_token);
+        if (mon > 10 * 365 * 24 * 60 * 60) {
+            ptv->tm = *localtime(&mon);
+
+            token();
+            break;
+        }
+
+        if (mon > 19700101 && mon < 24000101) { /*works between 1900 and 2400 */
+            char      cmon[3], cmday[3], cyear[5];
+
+            strncpy(cyear, sc_token, 4);
+            cyear[4] = '\0';
+            year = atol(cyear);
+            strncpy(cmon, &(sc_token[4]), 2);
+            cmon[2] = '\0';
+            mon = atol(cmon);
+            strncpy(cmday, &(sc_token[6]), 2);
+            cmday[2] = '\0';
+            mday = atol(cmday);
+            token();
+        } else {
             token();
-           break;
-           /*
-           mday = ptv->tm.tm_mday;
-           mday += (wday - ptv->tm.tm_wday);
-           ptv->tm.tm_wday = wday;
 
-           try(assign_date(ptv, mday, ptv->tm.tm_mon, ptv->tm.tm_year));
-           break;
-           */
+            if (mon <= 31 && (sc_tokid == SLASH || sc_tokid == DOT)) {
+                int       sep;
+
+                sep = sc_tokid;
+                try(expect2(NUMBER, "there should be %s number after '%c'",
+                            sep == DOT ? "month" : "day",
+                            sep == DOT ? '.' : '/'));
+                mday = atol(sc_token);
+                if (token() == sep) {
+                    try(expect2
+                        (NUMBER, "there should be year number after '%c'",
+                         sep == DOT ? '.' : '/'));
+                    year = atol(sc_token);
+                    token();
+                }
+
+                /* flip months and days for European timing
+                 */
+                if (sep == DOT) {
+                    long      x = mday;
+
+                    mday = mon;
+                    mon = x;
+                }
+            }
+        }
 
-    case NUMBER:
-           /* get numeric <sec since 1970>, MM/DD/[YY]YY, or DD.MM.[YY]YY
-            */
-           tlen = strlen(sc_token);
-           mon = atol(sc_token);
-            if (mon > 10*365*24*60*60) {
-               ptv->tm=*localtime(&mon);
-               token();
-               break;
-           }
-
-           if (mon > 19700101 && mon < 24000101){ /*works between 1900 and 2400 */
-               char  cmon[3],cmday[3],cyear[5];
-               strncpy(cyear,sc_token,4);cyear[4]='\0';              
-               year = atol(cyear);           
-               strncpy(cmon,&(sc_token[4]),2);cmon[2]='\0';
-               mon = atol(cmon);
-               strncpy(cmday,&(sc_token[6]),2);cmday[2]='\0';
-               mday = atol(cmday);
-               token();
-           } else { 
-             token();
-             
-             if (mon <= 31 && (sc_tokid == SLASH || sc_tokid == DOT)) {
-               int sep;                    
-               sep = sc_tokid;
-               try(expect2(NUMBER,"there should be %s number after '%c'",
-                          sep == DOT ? "month" : "day", sep == DOT ? '.' : '/'));
-               mday = atol(sc_token);
-               if (token() == sep) {
-                 try(expect2(NUMBER,"there should be year number after '%c'",
-                            sep == DOT ? '.' : '/'));
-                 year = atol(sc_token);
-                 token();
-               }
-               
-               /* flip months and days for European timing
-                */
-               if (sep == DOT) {
-                 long x = mday;
-                 mday = mon;
-                 mon = x;
-               }
-             }
-           }
-
-           mon--;
-           if(mon < 0 || mon > 11 ) {
-               panic(e("did you really mean month %d?", mon+1));
-           }
-           if(mday < 1 || mday > 31) {
-               panic(e("I'm afraid that %d is not a valid day of the month",
-                       mday));
-           }      
-           try(assign_date(ptv, mday, mon, year));
-           break;
-    } /* case */
+        mon--;
+        if (mon < 0 || mon > 11) {
+            panic(e("did you really mean month %d?", mon + 1));
+        }
+        if (mday < 1 || mday > 31) {
+            panic(e("I'm afraid that %d is not a valid day of the month",
+                    mday));
+        }
+        try(assign_date(ptv, mday, mon, year));
+        break;
+    }                   /* case */
     return TIME_OK;
-} /* month */
+}                       /* month */
 
 
 /* Global functions */
@@ -783,199 +831,213 @@ day(struct rrd_time_value *ptv)
  * mktime() The return value is either TIME_OK (aka NULL) or
  * the pointer to the error message in the case of problems
  */
-char *
-parsetime(const char *tspec, struct rrd_time_value *ptv)
+char     *parsetime(
+    const char *tspec,
+    struct rrd_time_value *ptv)
 {
-    time_t now = time(NULL);
-    int hr = 0;
+    time_t    now = time(NULL);
+    int       hr = 0;
+
     /* this MUST be initialized to zero for midnight/noon/teatime */
 
-    Specials = VariousWords; /* initialize special words context */
+    Specials = VariousWords;    /* initialize special words context */
 
-    try(init_scanner( 1, &tspec ));
+    try(init_scanner(1, &tspec));
 
     /* establish the default time reference */
     ptv->type = ABSOLUTE_TIME;
     ptv->offset = 0;
     ptv->tm = *localtime(&now);
-    ptv->tm.tm_isdst = -1; /* mk time can figure this out for us ... */
+    ptv->tm.  tm_isdst = -1;    /* mk time can figure dst by default ... */
 
     token();
     switch (sc_tokid) {
     case PLUS:
     case MINUS:
-           break; /* jump to OFFSET-SPEC part */
+        break;          /* jump to OFFSET-SPEC part */
 
     case START:
-           ptv->type = RELATIVE_TO_START_TIME;
-           goto KeepItRelative;
+        ptv->type = RELATIVE_TO_START_TIME;
+        goto KeepItRelative;
     case END:
-           ptv->type = RELATIVE_TO_END_TIME;
-        KeepItRelative:
-           ptv->tm.tm_sec  = 0;
-           ptv->tm.tm_min  = 0;
-           ptv->tm.tm_hour = 0;
-           ptv->tm.tm_mday = 0;
-           ptv->tm.tm_mon  = 0;
-           ptv->tm.tm_year = 0;
-           /* FALLTHRU */
+        ptv->type = RELATIVE_TO_END_TIME;
+      KeepItRelative:
+        ptv->tm.  tm_sec = 0;
+        ptv->tm.  tm_min = 0;
+        ptv->tm.  tm_hour = 0;
+        ptv->tm.  tm_mday = 0;
+        ptv->tm.  tm_mon = 0;
+        ptv->tm.  tm_year = 0;
+
+        /* FALLTHRU */
     case NOW:
-           {
-           int time_reference = sc_tokid;
-           token();
-           if( sc_tokid == PLUS || sc_tokid == MINUS )
-             break;
-           if( time_reference != NOW ) {
-             panic(e("'start' or 'end' MUST be followed by +|- offset"));
-           }
-           else
-             if( sc_tokid != EOF ) {
-               panic(e("if 'now' is followed by a token it must be +|- offset"));      
-             }
-           };
-           break;
-
-    /* Only absolute time specifications below */
+    {
+        int       time_reference = sc_tokid;
+
+        token();
+        if (sc_tokid == PLUS || sc_tokid == MINUS)
+            break;
+        if (time_reference != NOW) {
+            panic(e("'start' or 'end' MUST be followed by +|- offset"));
+        } else if (sc_tokid != EOF) {
+            panic(e("if 'now' is followed by a token it must be +|- offset"));
+        }
+    };
+        break;
+
+        /* Only absolute time specifications below */
     case NUMBER:
-           {
-             long hour_sv = ptv->tm.tm_hour;
-             long year_sv = ptv->tm.tm_year;
-              ptv->tm.tm_hour = 30;
-              ptv->tm.tm_year = 30000;
-             try(tod(ptv))
-             try(day(ptv))
-             if ( ptv->tm.tm_hour == 30 &&  ptv->tm.tm_year != 30000 ){
-               try(tod(ptv))
-              }
-             if ( ptv->tm.tm_hour == 30 ){
-               ptv->tm.tm_hour = hour_sv;
-              }
-             if ( ptv->tm.tm_year == 30000 ){
-               ptv->tm.tm_year = year_sv;
-              }
-           };      
+    {
+        long      hour_sv = ptv->tm.tm_hour;
+        long      year_sv = ptv->tm.tm_year;
+
+        ptv->tm.  tm_hour = 30;
+        ptv->tm.  tm_year = 30000;
+
+        try(tod(ptv))
+            try(day(ptv))
+            if (ptv->tm.tm_hour == 30 && ptv->tm.tm_year != 30000) {
+            try(tod(ptv))
+        }
+        if (ptv->tm.tm_hour == 30) {
+            ptv->tm.  tm_hour = hour_sv;
+        }
+        if (ptv->tm.tm_year == 30000) {
+            ptv->tm.  tm_year = year_sv;
+        }
+    };
+        break;
+        /* fix month parsing */
+    case JAN:
+    case FEB:
+    case MAR:
+    case APR:
+    case MAY:
+    case JUN:
+    case JUL:
+    case AUG:
+    case SEP:
+    case OCT:
+    case NOV:
+    case DEC:
+        try(day(ptv));
+        if (sc_tokid != NUMBER)
+            break;
+        try(tod(ptv))
             break;
-    /* fix month parsing */
-    case JAN: case FEB: case MAR: case APR: case MAY: case JUN:
-    case JUL: case AUG: case SEP: case OCT: case NOV: case DEC:
-            try(day(ptv));
-           if (sc_tokid != NUMBER) break;
-           try(tod(ptv))
-           break;
-
-           /* evil coding for TEATIME|NOON|MIDNIGHT - we've initialized
-            * hr to zero up above, then fall into this case in such a
-            * way so we add +12 +4 hours to it for teatime, +12 hours
-            * to it for noon, and nothing at all for midnight, then
-            * set our rettime to that hour before leaping into the
-            * month scanner
-            */
+
+        /* evil coding for TEATIME|NOON|MIDNIGHT - we've initialized
+         * hr to zero up above, then fall into this case in such a
+         * way so we add +12 +4 hours to it for teatime, +12 hours
+         * to it for noon, and nothing at all for midnight, then
+         * set our rettime to that hour before leaping into the
+         * month scanner
+         */
     case TEATIME:
-           hr += 4;
-           /* FALLTHRU */
+        hr += 4;
+        /* FALLTHRU */
     case NOON:
-           hr += 12;
-           /* FALLTHRU */
+        hr += 12;
+        /* FALLTHRU */
     case MIDNIGHT:
-            /* if (ptv->tm.tm_hour >= hr) {
-               ptv->tm.tm_mday++;
-               ptv->tm.tm_wday++;
-           } */ /* shifting does not makes sense here ... noon is noon */ 
-           ptv->tm.tm_hour = hr;
-           ptv->tm.tm_min = 0;
-           ptv->tm.tm_sec = 0;
-           token();
-           try(day(ptv));
-           break;
+        /* if (ptv->tm.tm_hour >= hr) {
+           ptv->tm.tm_mday++;
+           ptv->tm.tm_wday++;
+           } *//* shifting does not makes sense here ... noon is noon */
+        ptv->tm.  tm_hour = hr;
+        ptv->tm.  tm_min = 0;
+        ptv->tm.  tm_sec = 0;
+
+        token();
+        try(day(ptv));
+        break;
     default:
-           panic(e("unparsable time: %s%s",sc_token,sct));
-           break;
-    } /* ugly case statement */
+        panic(e("unparsable time: %s%s", sc_token, sct));
+        break;
+    }                   /* ugly case statement */
 
     /*
      * the OFFSET-SPEC part
      *
      * (NOTE, the sc_tokid was prefetched for us by the previous code)
      */
-    if( sc_tokid == PLUS || sc_tokid == MINUS ) {
-       Specials = TimeMultipliers; /* switch special words context */
-       while( sc_tokid == PLUS || sc_tokid == MINUS ||
-                              sc_tokid == NUMBER ) {
-           if( sc_tokid == NUMBER ) {
-               try(plus_minus(ptv, PREVIOUS_OP ));
-           } else
-               try(plus_minus(ptv, sc_tokid));
-           token(); /* We will get EOF eventually but that's OK, since
-                           token() will return us as many EOFs as needed */
-       }
+    if (sc_tokid == PLUS || sc_tokid == MINUS) {
+        Specials = TimeMultipliers; /* switch special words context */
+        while (sc_tokid == PLUS || sc_tokid == MINUS || sc_tokid == NUMBER) {
+            if (sc_tokid == NUMBER) {
+                try(plus_minus(ptv, PREVIOUS_OP));
+            } else
+                try(plus_minus(ptv, sc_tokid));
+            token();    /* We will get EOF eventually but that's OK, since
+                           token() will return us as many EOFs as needed */
+        }
     }
 
     /* now we should be at EOF */
-    if( sc_tokid != EOF ) {
-      panic(e("unparsable trailing text: '...%s%s'", sc_token, sct));
+    if (sc_tokid != EOF) {
+        panic(e("unparsable trailing text: '...%s%s'", sc_token, sct));
     }
 
-    ptv->tm.tm_isdst = -1; /* for mktime to guess DST status */
-    if( ptv->type == ABSOLUTE_TIME )
-      if( mktime( &ptv->tm ) == -1 ) { /* normalize & check */
-        /* can happen for "nonexistent" times, e.g. around 3am */
-       /* when winter -> summer time correction eats a hour */
-        panic(e("the specified time is incorrect (out of range?)"));
-      }
+    if (ptv->type == ABSOLUTE_TIME)
+        if (mktime(&ptv->tm) == -1) {   /* normalize & check */
+            /* can happen for "nonexistent" times, e.g. around 3am */
+            /* when winter -> summer time correction eats a hour */
+            panic(e("the specified time is incorrect (out of range?)"));
+        }
     EnsureMemFree();
     return TIME_OK;
-} /* parsetime */
-
-
-int proc_start_end (struct rrd_time_value *start_tv, 
-                   struct rrd_time_value *end_tv, 
-                   time_t *start, 
-                   time_t *end){
-    if (start_tv->type == RELATIVE_TO_END_TIME  && /* same as the line above */
-       end_tv->type == RELATIVE_TO_START_TIME) {
-       rrd_set_error("the start and end times cannot be specified "
-                     "relative to each other");
-       return -1;
+}                       /* parsetime */
+
+
+int proc_start_end(
+    struct rrd_time_value *start_tv,
+    struct rrd_time_value *end_tv,
+    time_t *start,
+    time_t *end)
+{
+    if (start_tv->type == RELATIVE_TO_END_TIME &&   /* same as the line above */
+        end_tv->type == RELATIVE_TO_START_TIME) {
+        rrd_set_error("the start and end times cannot be specified "
+                      "relative to each other");
+        return -1;
     }
 
     if (start_tv->type == RELATIVE_TO_START_TIME) {
-       rrd_set_error("the start time cannot be specified relative to itself");
-       return -1;
+        rrd_set_error
+            ("the start time cannot be specified relative to itself");
+        return -1;
     }
 
     if (end_tv->type == RELATIVE_TO_END_TIME) {
-       rrd_set_error("the end time cannot be specified relative to itself");
-       return -1;
+        rrd_set_error("the end time cannot be specified relative to itself");
+        return -1;
     }
 
-    if( start_tv->type == RELATIVE_TO_END_TIME) {
-       struct tm tmtmp;
-       *end = mktime(&(end_tv->tm)) + end_tv->offset;    
-       tmtmp = *localtime(end); /* reinit end including offset */
-       tmtmp.tm_mday += start_tv->tm.tm_mday;
-       tmtmp.tm_mon += start_tv->tm.tm_mon;
-       tmtmp.tm_year += start_tv->tm.tm_year;  
-       *start = mktime(&tmtmp) + start_tv->offset;
+    if (start_tv->type == RELATIVE_TO_END_TIME) {
+        struct tm tmtmp;
+
+        *end = mktime(&(end_tv->tm)) + end_tv->offset;
+        tmtmp = *localtime(end);    /* reinit end including offset */
+        tmtmp.tm_mday += start_tv->tm.tm_mday;
+        tmtmp.tm_mon += start_tv->tm.tm_mon;
+        tmtmp.tm_year += start_tv->tm.tm_year;
+
+        *start = mktime(&tmtmp) + start_tv->offset;
     } else {
-       *start = mktime(&(start_tv->tm)) + start_tv->offset;
+        *start = mktime(&(start_tv->tm)) + start_tv->offset;
     }
     if (end_tv->type == RELATIVE_TO_START_TIME) {
-       struct tm tmtmp;
-       *start = mktime(&(start_tv->tm)) + start_tv->offset;
-       tmtmp = *localtime(start);
-       tmtmp.tm_mday += end_tv->tm.tm_mday;
-       tmtmp.tm_mon += end_tv->tm.tm_mon;
-       tmtmp.tm_year += end_tv->tm.tm_year;    
-       *end = mktime(&tmtmp) + end_tv->offset;
-    } else {
-       *end = mktime(&(end_tv->tm)) + end_tv->offset;
-    }    
-    return 0;
-} /* proc_start_end */
-
-
-
-
-
+        struct tm tmtmp;
 
+        *start = mktime(&(start_tv->tm)) + start_tv->offset;
+        tmtmp = *localtime(start);
+        tmtmp.tm_mday += end_tv->tm.tm_mday;
+        tmtmp.tm_mon += end_tv->tm.tm_mon;
+        tmtmp.tm_year += end_tv->tm.tm_year;
 
+        *end = mktime(&tmtmp) + end_tv->offset;
+    } else {
+        *end = mktime(&(end_tv->tm)) + end_tv->offset;
+    }
+    return 0;
+}                       /* proc_start_end */
index c9254d48f65f915ed315848df78939effd9f1dc6..1c695350625ab354c1289770123e14337331d8a1 100644 (file)
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * RRDtool 1.2.27  Copyright by Tobi Oetiker, 1997-2008
+ * RRDtool 1.3rc4  Copyright by Tobi Oetiker, 1997-2008
  *****************************************************************************
  * pngsize.c  determine the size of a PNG image
  *****************************************************************************/
@@ -7,20 +7,22 @@
 #include <png.h>
 #include "rrd_tool.h"
 
-int
-PngSize(FILE *fd, long *width, long *height)
+int PngSize(
+    FILE * fd,
+    long *width,
+    long *height)
 {
-  png_structp png_read_ptr = 
-    png_create_read_struct(PNG_LIBPNG_VER_STRING, 
-                          (png_voidp)NULL,
-                               /* we would need to point to error handlers
-                                  here to do it properly */
-                          (png_error_ptr)NULL, (png_error_ptr)NULL);
-    
-  png_infop info_ptr = png_create_info_struct(png_read_ptr);
-
-  (*width)=0;
-  (*height)=0;
+    png_structp png_read_ptr = png_create_read_struct(PNG_LIBPNG_VER_STRING,
+                                                      (png_voidp) NULL,
+                                                      /* we would need to point to error handlers
+                                                         here to do it properly */
+                                                      (png_error_ptr) NULL,
+                                                      (png_error_ptr) NULL);
+
+    png_infop info_ptr = png_create_info_struct(png_read_ptr);
+
+    (*width) = 0;
+    (*height) = 0;
 
 /* this is to make compile on aix work since they seem to define jmpbuf
    to be _jmpbuf which breaks compilation */
@@ -33,22 +35,19 @@ PngSize(FILE *fd, long *width, long *height)
 #  define png_jmpbuf(png_ptr)   ((png_ptr)->jmpbuf)
 #endif
 
-  if (setjmp(png_jmpbuf(png_read_ptr))){
-    png_destroy_read_struct(&png_read_ptr, &info_ptr, (png_infopp)NULL);
-    return 0;
-  }
-
-  png_init_io(png_read_ptr,fd);
-  png_read_info(png_read_ptr, info_ptr);
-  (*width)=png_get_image_width(png_read_ptr, info_ptr);
-  (*height)=png_get_image_height(png_read_ptr, info_ptr);
-  
-  png_destroy_read_struct(&png_read_ptr, &info_ptr, NULL);
-  if (*width >0 && *height >0) 
-    return 1;
-  else
-    return 0;
+    if (setjmp(png_jmpbuf(png_read_ptr))) {
+        png_destroy_read_struct(&png_read_ptr, &info_ptr, (png_infopp) NULL);
+        return 0;
+    }
+
+    png_init_io(png_read_ptr, fd);
+    png_read_info(png_read_ptr, info_ptr);
+    (*width) = png_get_image_width(png_read_ptr, info_ptr);
+    (*height) = png_get_image_height(png_read_ptr, info_ptr);
+
+    png_destroy_read_struct(&png_read_ptr, &info_ptr, NULL);
+    if (*width > 0 && *height > 0)
+        return 1;
+    else
+        return 0;
 }
-
-
-
index d58662f7c9e5bc1d9cd110530b59506b629c4004..6b475d88095c512df76386ec86aa6302854fbcee 100644 (file)
--- a/src/rrd.h
+++ b/src/rrd.h
@@ -1,9 +1,9 @@
 /*****************************************************************************
- * RRDtool 1.2.27  Copyright by Tobi Oetiker, 1997-2008
+ * RRDtool 1.3rc4  Copyright by Tobi Oetiker, 1997-2008
  *****************************************************************************
  * rrdlib.h   Public header file for librrd
  *****************************************************************************
- * $Id: rrd.h 1286 2008-02-17 10:08:10Z oetiker $
+ * $Id: rrd.h 1366 2008-05-18 13:06:44Z oetiker $
  * $Log$
  * Revision 1.9  2005/02/13 16:13:33  oetiker
  * let rrd_graph return the actual value range it picked ...
  *
  *****************************************************************************/
 #ifdef  __cplusplus
-extern "C" {
+extern    "C" {
 #endif
 
 #ifndef _RRDLIB_H
 #define _RRDLIB_H
 
+#include <sys/types.h>  /* for off_t */
+#include <unistd.h>     /* for off_t */
 #include <time.h>
-#include <stdio.h> /* for FILE */
+#include <stdio.h>      /* for FILE */
+
+
+/* Formerly rrd_nan_inf.h */
+#ifndef DNAN
+# define DNAN set_to_DNAN()
+#endif
+
+#ifndef DINF
+# define DINF set_to_DINF()
+#endif
+    double    set_to_DNAN(
+    void);
+    double    set_to_DINF(
+    void);
+/* end of rrd_nan_inf.h */
 
 /* Transplanted from rrd_format.h */
-typedef double       rrd_value_t;         /* the data storage type is
-                                           * double */
+    typedef double rrd_value_t; /* the data storage type is
+                                 * double */
 /* END rrd_format.h */
 
+/* information about an rrd file */
+    typedef struct rrd_file_t {
+        int       fd;   /* file descriptor if this rrd file */
+        char     *file_start;   /* start address of an open rrd file */
+        off_t     header_len;   /* length of the header of this rrd file */
+        off_t     file_len; /* total size of the rrd file */
+        off_t     pos;  /* current pos in file */
+    } rrd_file_t;
+
+/* rrd info interface */
+    typedef struct rrd_blob_t {
+        unsigned long size; /* size of the blob */
+        unsigned char *ptr; /* pointer */
+    } rrd_blob_t;
+
+    enum info_type { RD_I_VAL = 0,
+        RD_I_CNT,
+        RD_I_STR,
+        RD_I_INT,
+        RD_I_BLO
+    };
+
+    typedef union infoval {
+        unsigned long u_cnt;
+        rrd_value_t u_val;
+        char     *u_str;
+        int       u_int;
+        struct rrd_blob_t u_blo;
+    } infoval;
+
+    typedef struct info_t {
+        char     *key;
+        enum info_type type;
+        union infoval value;
+        struct info_t *next;
+    } info_t;
+
+
 /* main function blocks */
-int    rrd_create(int, char **);
-int    rrd_update(int, char **);
-int    rrd_graph(int, char **, char ***, int *, int *, FILE *, double *, double *);
-int    rrd_fetch(int, char **, time_t *, time_t *, unsigned long *,
-                unsigned long *, char ***, rrd_value_t **);
-int    rrd_restore(int, char **);
-int    rrd_dump(int, char **);
-int    rrd_tune(int, char **);
-time_t rrd_last(int, char **);
-time_t rrd_first(int, char **);
-int    rrd_resize(int, char **);
-char * rrd_strversion(void);
-double rrd_version(void);
-int    rrd_xport(int, char **, int *, time_t *, time_t *,
-                unsigned long *, unsigned long *,
-                char ***, rrd_value_t **);
+    int       rrd_create(
+    int,
+    char **);
+    int       rrd_update(
+    int,
+    char **);
+    int       rrd_graph(
+    int,
+    char **,
+    char ***,
+    int *,
+    int *,
+    FILE *,
+    double *,
+    double *);
+    info_t   *rrd_graph_v(
+    int,
+    char **);
+
+    int       rrd_fetch(
+    int,
+    char **,
+    time_t *,
+    time_t *,
+    unsigned long *,
+    unsigned long *,
+    char ***,
+    rrd_value_t **);
+    int       rrd_restore(
+    int,
+    char **);
+    int       rrd_dump(
+    int,
+    char **);
+    int       rrd_tune(
+    int,
+    char **);
+    time_t    rrd_last(
+    int,
+    char **);
+    time_t    rrd_first(
+    int,
+    char **);
+    int       rrd_resize(
+    int,
+    char **);
+    char     *rrd_strversion(
+    void);
+    double    rrd_version(
+    void);
+    int       rrd_xport(
+    int,
+    char **,
+    int *,
+    time_t *,
+    time_t *,
+    unsigned long *,
+    unsigned long *,
+    char ***,
+    rrd_value_t **);
 
 /* thread-safe (hopefully) */
-int    rrd_create_r(const char *filename,
-                   unsigned long pdp_step, time_t last_up,
-                   int argc, const char **argv);
+    int       rrd_create_r(
+    const char *filename,
+    unsigned long pdp_step,
+    time_t last_up,
+    int argc,
+    const char **argv);
 /* NOTE: rrd_update_r are only thread-safe if no at-style time
    specifications get used!!! */
 
-int    rrd_update_r(const char *filename, const char *_template,
-                   int argc, const char **argv);
-int    rrd_fetch_r(const char *filename, const char* cf,
-                   time_t *start, time_t *end,
-                   unsigned long *step,
-                   unsigned long *ds_cnt,
-                   char        ***ds_namv,
-                   rrd_value_t **data);
-int    rrd_dump_r(const char *filename, char *outname);
-time_t rrd_last_r(const char *filename);
-time_t rrd_first_r(const char *filename, int rraindex);
+    int       rrd_update_r(
+    const char *filename,
+    const char *_template,
+    int argc,
+    const char **argv);
+    int       rrd_fetch_r(
+    const char *filename,
+    const char *cf,
+    time_t *start,
+    time_t *end,
+    unsigned long *step,
+    unsigned long *ds_cnt,
+    char ***ds_namv,
+    rrd_value_t **data);
+    int       rrd_dump_r(
+    const char *filename,
+    char *outname);
+    time_t    rrd_last_r(
+    const char *filename);
+    time_t    rrd_first_r(
+    const char *filename,
+    int rraindex);
 
 /* Transplanted from parsetime.h */
-typedef enum {
+    typedef enum {
         ABSOLUTE_TIME,
-        RELATIVE_TO_START_TIME, 
+        RELATIVE_TO_START_TIME,
         RELATIVE_TO_END_TIME
-} timetype;
+    } timetype;
 
 #define TIME_OK NULL
 
-struct rrd_time_value {
-  timetype type;
-  long offset;
-  struct tm tm;
-};
+    struct rrd_time_value {
+        timetype  type;
+        long      offset;
+        struct tm tm;
+    };
 
-char *parsetime(const char *spec, struct rrd_time_value *ptv);
+    char     *parsetime(
+    const char *spec,
+    struct rrd_time_value *ptv);
 /* END parsetime.h */
 
-struct rrd_context {
-    int len;
-    int errlen;
-    char *lib_errstr;
-    char *rrd_error;
-};
+    struct rrd_context {
+        int       len;
+        int       errlen;
+        char     *lib_errstr;
+        char     *rrd_error;
+    };
 
 /* returns the current per-thread rrd_context */
-struct rrd_context *rrd_get_context(void);
+    struct rrd_context *rrd_get_context(
+    void);
 
 
-int proc_start_end (struct rrd_time_value *,  struct rrd_time_value *, time_t *, time_t *);
+    int       proc_start_end(
+    struct rrd_time_value *,
+    struct rrd_time_value *,
+    time_t *,
+    time_t *);
 
 /* HELPER FUNCTIONS */
-void rrd_set_error(char *,...);
-void rrd_clear_error(void);
-int  rrd_test_error(void);
-char *rrd_get_error(void);
+    void      rrd_set_error(
+    char *,
+    ...);
+    void      rrd_clear_error(
+    void);
+    int       rrd_test_error(
+    void);
+    char     *rrd_get_error(
+    void);
 
 /** MULTITHREADED HELPER FUNCTIONS */
-struct rrd_context *rrd_new_context(void);
-void   rrd_free_context (struct rrd_context *buf);
+    struct rrd_context *rrd_new_context(
+    void);
+    void      rrd_free_context(
+    struct rrd_context *buf);
 
 /* void   rrd_set_error_r  (struct rrd_context *, char *, ...); */
 /* void   rrd_clear_error_r(struct rrd_context *); */
 /* int    rrd_test_error_r (struct rrd_context *); */
 /* char  *rrd_get_error_r  (struct rrd_context *); */
 
-int  LockRRD(FILE *);
+    int       LockRRD(
+    int in_file);
 
-#endif /* _RRDLIB_H */
+#endif                  /* _RRDLIB_H */
 
 #ifdef  __cplusplus
 }
diff --git a/src/rrd_afm.c b/src/rrd_afm.c
deleted file mode 100644 (file)
index 59ead88..0000000
+++ /dev/null
@@ -1,287 +0,0 @@
-/****************************************************************************
- * RRDtool 1.2.27  Copyright by Tobi Oetiker, 1997-2008
- ****************************************************************************
- * rrd_afm.h  Parsing afm tables to find width of strings.
- ****************************************************************************
- * $Id: rrd_afm.c 1286 2008-02-17 10:08:10Z oetiker $
-*/
-
-#if defined(_WIN32) && !defined(__CYGWIN__) && !defined(__CYGWIN32__) && !defined(HAVE_CONFIG_H)
-#include "../win32/config.h"
-#else
-#ifdef HAVE_CONFIG_H
-#include "../rrd_config.h"
-#endif
-#endif
-
-#include "rrd_afm.h"
-#include "rrd_afm_data.h"
-
-#include <stdio.h>
-
-#ifdef HAVE_STRING_H
-#include <string.h>
-#endif
-
-#include "unused.h"
-
-#if 0
-# define DEBUG 1
-# define DLOG(x) fprintf x
-#else
-# define DEBUG 0
-# define DLOG(x) 
-#endif
-
-/* Adobe SVG View and Batik 1.1.1 can't handle ligatures.
-   So disable it as we just waste speed.
-   Besides, it doesn't matter much in normal text.
-*/
-#define ENABLE_LIGATURES 0
-
-static const afm_fontinfo *afm_last_used_font = NULL;
-static const char *last_unknown_font = NULL;
-
-#define is_font(p, name) \
-  (!strcmp(p->postscript_name, name) || !strcmp(p->fullname, name))
-
-static const afm_fontinfo *afm_searchfont(const char *name)
-{
-  int i;
-  const afm_fontinfo *p = afm_last_used_font;
-  if (p && is_font(p, name))
-    return p;
-  p = afm_fontinfolist;
-  for (i = 0; i < afm_fontinfo_count; i++, p++) {
-    if (is_font(p, name)) {
-      afm_last_used_font = p;
-      return p;
-    }
-  }
-  return NULL;
-}
-
-
-/* returns always a font, never NULL.
-   The rest of the code depends on the result never being NULL.
-   See rrd_afm.h */
-static const afm_fontinfo *afm_findfont(const char *name)
-{
-  const afm_fontinfo *p = afm_searchfont(name);
-  if (p)
-    return p;
-  if (!last_unknown_font || strcmp(name, last_unknown_font)) {
-         fprintf(stderr, "Can't find font '%s'\n", name);
-         last_unknown_font = name;
-  }
-  p = afm_searchfont(RRD_AFM_DEFAULT_FONT);
-  if (p)
-    return p;
-  return afm_fontinfolist; /* anything, just anything. */
-}
-
-const char *afm_get_font_postscript_name(const char* font)
-{
-  const afm_fontinfo *p = afm_findfont(font);
-  return p->postscript_name;
-}
-
-const char *afm_get_font_name(const char* font)
-{
-  const afm_fontinfo *p = afm_findfont(font);
-  return p->fullname;
-}
-
-double afm_get_ascender(const char* font, double size)
-{
-  const afm_fontinfo *p = afm_findfont(font);
-  return size * p->ascender / 1000.0;
-}
-
-double afm_get_descender(const char* font, double size)
-{
-  const afm_fontinfo *p = afm_findfont(font);
-  return size * p->descender / 1000.0;
-}
-
-static int afm_find_char_index(const afm_fontinfo *fontinfo,
-    afm_cunicode ch1)
-{
-  int idx = ch1 - 32;
-  afm_cuint16 *indexP;
-  int numIndexChars, i;
-  if (idx <= 0)
-    return 0;
-  if (idx <= 126 - 32)
-    return idx;
-  indexP = fontinfo->highchars_index;
-  if (indexP == 0)
-    return 0;
-  numIndexChars = fontinfo->highchars_count;
-  DLOG((stderr, " find highbit, num = %d\n", numIndexChars));
-  if (ch1 >= 161 && ch1 <= 255) {
-    idx = ch1 - 161;
-    DLOG((stderr, "  161, idx = %d -> %d\n", idx, indexP[idx]));
-    if (idx < numIndexChars && indexP[idx] == ch1) {
-      idx += 127 - 32;
-      DLOG((stderr, "  161-guessed ok to %d\n", idx));
-      return idx;
-    }
-  }
-  for (i = 0; i < numIndexChars; i++) {
-    DLOG((stderr, "    compares to %d -> %d\n", indexP[i], i));
-    if (indexP[i] == ch1)
-      return i + 127 - 32;
-  }
-  DLOG((stderr, "Did not find %d in highchars_index ??\n", ch1));
-  return 0;
-}
-
-#if ENABLE_LIGATURES
-static afm_cunicode afm_find_combined_ligature(const afm_fontinfo *fontinfo,
-    afm_cunicode ch1, afm_cunicode ch2)
-{
-  afm_cunicode *p = fontinfo->ligatures;
-  int num = fontinfo->ligatures_count;
-  int i;
-  if (!num)
-    return 0;
-  DLOG((stderr, " find-lig, num = %d\n", num));
-  for (i = 0; i < num; i++, p += 3) {
-    DLOG((stderr, "    lig: %d + %d -> %d (%c %c %c)\n",
-        p[0], p[1], p[2], p[0], p[1], p[2]));
-    if (ch1 == *p && ch2 == p[1]) {
-      DLOG((stderr, "   matches.\n"));
-      return p[2];
-    }
-  }
-  return 0;
-}
-#endif
-
-#define READ_ESCAPED(p, val) \
-  if ((val = *p++) == 0) { \
-    val = 254 + *p++; \
-  } else if (!--val) { \
-    val = *p++ << 8; \
-    val |= *p++; \
-  }
-
-
-static long afm_find_kern(const afm_fontinfo *fontinfo,
-    int kern_idx, afm_cunicode ch2)
-{
-  afm_cuint8 *p8 = fontinfo->kerning_data + kern_idx;
-  int num;
-  READ_ESCAPED(p8, num);
-  DLOG((stderr, " find kern, num pairs = %d\n", num));
-  while (num > 0) {
-    afm_unicode ch;
-    READ_ESCAPED(p8, ch);
-    DLOG((stderr, "     pair-char = %d\n", ch));
-    if (ch == ch2) {
-      DLOG((stderr, " got kern = %d\n", *(afm_csint8*)p8));
-      return *(afm_csint8*)p8;
-    }
-    p8++;
-    num--;
-  }
-  return 0;
-}
-
-/* measure width of a text string */
-double afm_get_text_width( double start, const char* font, double size,
-          double tabwidth, const char* text)
-{
-#ifdef HAVE_MBSTOWCS     
-    size_t clen = strlen(text) + 1;
-    wchar_t *cstr = malloc(sizeof(wchar_t) * clen); /* yes we are allocating probably too much here, I know */
-    int text_count = mbstowcs(cstr, text, clen);
-    double w;
-    if (text_count == -1)
-           text_count = mbstowcs(cstr, "Enc-Err", 6);
-#ifdef __APPLE__
-       while (text_count > 0) {
-               text_count--;
-               cstr[text_count] = afm_fix_osx_charset(cstr[text_count]); /* unsafe macro */
-       }
-#endif
-    w = afm_get_text_width_wide(start, font, size, tabwidth, cstr);
-    free(cstr);
-    return w;
-#else
-    return afm_get_text_width_wide(start, font, size, tabwidth, text);
-#endif
-}
-
-double afm_get_text_width_wide( double UNUSED(start), const char* font, double size,
-          double UNUSED(tabwidth), const afm_char* text)
-{
-  const afm_fontinfo *fontinfo = afm_findfont(font);
-  long width = 0;
-  double widthf;
-  const afm_char *up = text;
-  DLOG((stderr, "================= %s\n", text));
-  if (fontinfo == NULL) {
-      while (*up)
-         up++;
-    return size * (up - text);
-  }
-  while (1) {
-    afm_unicode ch1, ch2;
-    int idx1, kern_idx;
-    if ((ch1 = *up) == 0)
-        break;
-    ch2 = *++up;
-    DLOG((stderr, "------------- Loop: %d + %d (%c%c)   at %d\n",
-          ch1, ch2, ch1, ch2 ? ch2 : ' ',
-         (up - (const unsigned char*)text) - 1));
-    idx1 = afm_find_char_index(fontinfo, ch1);
-    DLOG((stderr, "  idx1 = %d\n", idx1));
-#if ENABLE_LIGATURES
-    if (ch2) {
-      int ch1_new = afm_find_combined_ligature(fontinfo, ch1, ch2);
-      DLOG((stderr, "  lig-ch = %d\n", ch1_new));
-      if (ch1_new) {
-        ch1 = ch1_new;
-        idx1 = afm_find_char_index(fontinfo, ch1);
-        ch2 = *++up;
-        DLOG((stderr, "  -> idx1 = %d, ch2 = %d (%c)\n", 
-            idx1, ch2, ch2 ? ch2 : ' '));
-      }
-    }
-#endif
-    width += fontinfo->widths[idx1];
-    DLOG((stderr, "Plain width of %d = %d\n", ch1, fontinfo->widths[idx1]));
-    if (fontinfo->kerning_index && ch2) {
-      kern_idx = fontinfo->kerning_index[idx1];
-      DLOG((stderr, "    kern_idx = %d\n", kern_idx));
-      if (kern_idx > 0)
-        width += afm_find_kern(fontinfo, kern_idx, ch2);
-    }
-  }
-  widthf = (width * 6 / 1000.0) * size;
-  DLOG((stderr, "Returns %ld (%ld) -> %f\n", width, width * 6, widthf));
-  return widthf;
-}
-
-#ifdef __APPLE__
-const unsigned char afm_mac2iso[128] = {
-  '\xC4', '\xC5', '\xC7', '\xC9', '\xD1', '\xD6', '\xDC', '\xE1', /* 80 */
-  '\xE0', '\xE2', '\xE4', '\xE3', '\xE5', '\xE7', '\xE9', '\xE8', /* 88 */
-  '\xEA', '\xEB', '\xED', '\xEC', '\xEE', '\xEF', '\xF1', '\xF3', /* 90 */
-  '\xF2', '\xF4', '\xF6', '\xF5', '\xFA', '\xF9', '\xFB', '\xFC', /* 98 */
-  '\xDD', '\xB0', '\xA2', '\xA3', '\xA7', ' ',    '\xB6', '\xDF', /* A0 */
-  '\xAE', '\xA9', ' ',    '\xB4', '\xA8', ' ',    '\xC6', '\xD8', /* A8 */
-  ' ',    '\xB1', '\xBE', ' ',    '\xA5', '\xB5', ' ',    ' ',    /* B0 */
-  '\xBD', '\xBC', ' ',    '\xAA', '\xBA', ' ',    '\xE6', '\xF8', /* B8 */
-  '\xBF', '\xA1', '\xAC', ' ',    ' ',    ' ',    ' ',    '\xAB', /* C0 */
-  '\xBB', ' ',    '\xA0', '\xC0', '\xC3', '\xD5', ' ',    '\xA6', /* C8 */
-  '\xAD', ' ',    '"',    '"',    '\'',   '\'',   '\xF7', '\xD7', /* D0 */
-  '\xFF', ' ',    ' ',    '\xA4', '\xD0', '\xF0', '\xDE', '\xFE', /* D8 */
-  '\xFD', '\xB7', ' ',    ' ',    ' ',    '\xC2', '\xCA', '\xC1', /* E0 */
-  '\xCB', '\xC8', '\xCD', '\xCE', '\xCF', '\xCC', '\xD3', '\xD4', /* E8 */
-  ' ',    '\xD2', '\xDA', '\xDB', '\xD9', ' ',    ' ',    ' ',    /* F0 */
-  '\xAF', ' ',    ' ',    ' ',    '\xB8', ' ',    ' ',    ' ',    /* F8 */
-};
-#endif
diff --git a/src/rrd_afm.h b/src/rrd_afm.h
deleted file mode 100644 (file)
index 94d93eb..0000000
+++ /dev/null
@@ -1,54 +0,0 @@
-/****************************************************************************
- * RRDtool 1.2.27  Copyright by Tobi Oetiker, 1997-2008
- ****************************************************************************
- * rrd_afm.h  Parsing afm tables to find width of strings.
- ****************************************************************************/
-
-#ifndef  RRD_AFM_H
-#define RRD_AFM_H
-
-#include <stdlib.h>
-#ifdef HAVE_MBSTOWCS
-#define afm_char wchar_t
-#else
-#define afm_char unsigned char
-#endif
-/*
-   If the font specified by the name parameter in the routes below
-   is not found
-   (because it is not compiled into rrd_afm_data.c by compile_afm.pl)
-   the font specified by RRD_AFM_DEFAULT_FONT will be used.
-   If it is not installed, it uses the first font compiled
-   into rrd_afm_data.c
-   So they will always use some font.
-*/
-
-#define RRD_AFM_DEFAULT_FONT "Courier"
-
-/* measure width of a text string */
-/* fontname can be full name or postscript name */
-double afm_get_text_width( double start, const char* font, double size,
-                           double tabwidth, const char* text);
-double afm_get_text_width_wide( double start, const char* font, double size,
-                           double tabwidth, const afm_char* text);
-
-double afm_get_ascender(const char* font, double size);
-double afm_get_descender(const char* font, double size);
-
-/* get postscript name from fullname or postscript name */
-const char *afm_get_font_postscript_name ( const char* font);
-const char *afm_get_font_name(const char* font);
-
-/* cc -E -dM /dev/null */
-#ifdef __APPLE__
-/* need charset conversion from macintosh to unicode. */
-extern const unsigned char afm_mac2iso[128];
-#define afm_fix_osx_charset(c) \
-       ( (c) >= 128 && (c) <= 255 ? afm_mac2iso[(c) - 128] : (c))
-#else
-/* UNSAFE macro */
-#define afm_fix_osx_charset(x) (x)
-#endif
-
-#endif
diff --git a/src/rrd_afm_data.c b/src/rrd_afm_data.c
deleted file mode 100644 (file)
index 2c7ab44..0000000
+++ /dev/null
@@ -1,3338 +0,0 @@
-/****************************************************************************
- * RRDtool 1.2.27  Copyright by Tobi Oetiker, 1997-2008
- ****************************************************************************
- * rrd_afm_data.c  Encoded afm (Adobe Font Metrics) for selected fonts.
- ****************************************************************************
- *
- * THIS FILE IS AUTOGENERATED BY PERL. DO NOT EDIT.
- *
- ****************************************************************************/
-
-#include "rrd_afm_data.h"
-#include <stdlib.h>
-
-
-
-/* ------------------------------------------------------------------*/
-/* FontName: Courier */
-/* FullName: Courier */
-/* FamilyName: Courier */
-static afm_cuint8 afm_Courier_widths[] = { /* 315 */
-  100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
-  100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
-  100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
-  100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
-  100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
-  100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
-  100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
-  100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
-  100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
-  100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
-  100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
-  100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
-  100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
-  100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
-  100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
-  100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
-  100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
-  100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
-  100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
-  100,100,100,100,100,100,100,100,100,100,100
-};
-static afm_cuint16 afm_Courier_highchars_index[] = { /* 220 */
-  161,162,163,164,165,166,167,168,169,170,171,172,174,175,176,177,
-  178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,
-  194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,
-  210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,
-  226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,
-  242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,
-  258,259,260,261,262,263,268,269,270,271,272,273,274,275,278,279,
-  280,281,282,283,286,287,290,291,298,299,302,303,304,305,310,311,
-  313,314,315,316,317,318,321,322,323,324,325,326,327,328,332,333,
-  336,337,338,339,340,341,342,343,344,345,346,347,350,351,352,353,
-  354,355,356,357,362,363,366,367,368,369,370,371,376,377,378,379,
-  380,381,382,402,536,537,710,711,728,729,730,731,732,733,8211,8212,
-  8216,8217,8218,8220,8221,8222,8224,8225,8226,8230,8240,8249,8250,
-  8260,8364,8482,8706,8710,8721,8722,8730,8800,8804,8805,9674,63171,
-  64257,64258
-};
-static afm_cunicode afm_Courier_ligatures[] = { /* 3 */
-  102,105,64257
-};
-
-
-/* ------------------------------------------------------------------*/
-/* FontName: Courier-Bold */
-/* FullName: Courier Bold */
-/* FamilyName: Courier */
-static afm_cuint8 afm_Courier_Bold_widths[] = { /* 315 */
-  100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
-  100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
-  100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
-  100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
-  100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
-  100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
-  100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
-  100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
-  100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
-  100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
-  100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
-  100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
-  100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
-  100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
-  100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
-  100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
-  100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
-  100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
-  100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
-  100,100,100,100,100,100,100,100,100,100,100
-};
-static afm_cuint16 afm_Courier_Bold_highchars_index[] = { /* 220 */
-  161,162,163,164,165,166,167,168,169,170,171,172,174,175,176,177,
-  178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,
-  194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,
-  210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,
-  226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,
-  242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,
-  258,259,260,261,262,263,268,269,270,271,272,273,274,275,278,279,
-  280,281,282,283,286,287,290,291,298,299,302,303,304,305,310,311,
-  313,314,315,316,317,318,321,322,323,324,325,326,327,328,332,333,
-  336,337,338,339,340,341,342,343,344,345,346,347,350,351,352,353,
-  354,355,356,357,362,363,366,367,368,369,370,371,376,377,378,379,
-  380,381,382,402,536,537,710,711,728,729,730,731,732,733,8211,8212,
-  8216,8217,8218,8220,8221,8222,8224,8225,8226,8230,8240,8249,8250,
-  8260,8364,8482,8706,8710,8721,8722,8730,8800,8804,8805,9674,63171,
-  64257,64258
-};
-static afm_cunicode afm_Courier_Bold_ligatures[] = { /* 3 */
-  102,105,64257
-};
-
-
-/* ------------------------------------------------------------------*/
-/* FontName: Courier-BoldOblique */
-/* FullName: Courier Bold Oblique */
-/* FamilyName: Courier */
-static afm_cuint8 afm_Courier_BoldOblique_widths[] = { /* 315 */
-  100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
-  100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
-  100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
-  100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
-  100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
-  100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
-  100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
-  100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
-  100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
-  100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
-  100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
-  100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
-  100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
-  100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
-  100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
-  100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
-  100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
-  100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
-  100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
-  100,100,100,100,100,100,100,100,100,100,100
-};
-static afm_cuint16 afm_Courier_BoldOblique_highchars_index[] = { /* 220 */
-  161,162,163,164,165,166,167,168,169,170,171,172,174,175,176,177,
-  178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,
-  194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,
-  210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,
-  226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,
-  242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,
-  258,259,260,261,262,263,268,269,270,271,272,273,274,275,278,279,
-  280,281,282,283,286,287,290,291,298,299,302,303,304,305,310,311,
-  313,314,315,316,317,318,321,322,323,324,325,326,327,328,332,333,
-  336,337,338,339,340,341,342,343,344,345,346,347,350,351,352,353,
-  354,355,356,357,362,363,366,367,368,369,370,371,376,377,378,379,
-  380,381,382,402,536,537,710,711,728,729,730,731,732,733,8211,8212,
-  8216,8217,8218,8220,8221,8222,8224,8225,8226,8230,8240,8249,8250,
-  8260,8364,8482,8706,8710,8721,8722,8730,8800,8804,8805,9674,63171,
-  64257,64258
-};
-static afm_cunicode afm_Courier_BoldOblique_ligatures[] = { /* 3 */
-  102,105,64257
-};
-
-
-/* ------------------------------------------------------------------*/
-/* FontName: Courier-Oblique */
-/* FullName: Courier Oblique */
-/* FamilyName: Courier */
-static afm_cuint8 afm_Courier_Oblique_widths[] = { /* 315 */
-  100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
-  100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
-  100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
-  100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
-  100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
-  100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
-  100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
-  100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
-  100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
-  100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
-  100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
-  100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
-  100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
-  100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
-  100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
-  100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
-  100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
-  100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
-  100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,100,
-  100,100,100,100,100,100,100,100,100,100,100
-};
-static afm_cuint16 afm_Courier_Oblique_highchars_index[] = { /* 220 */
-  161,162,163,164,165,166,167,168,169,170,171,172,174,175,176,177,
-  178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,
-  194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,
-  210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,
-  226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,
-  242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,
-  258,259,260,261,262,263,268,269,270,271,272,273,274,275,278,279,
-  280,281,282,283,286,287,290,291,298,299,302,303,304,305,310,311,
-  313,314,315,316,317,318,321,322,323,324,325,326,327,328,332,333,
-  336,337,338,339,340,341,342,343,344,345,346,347,350,351,352,353,
-  354,355,356,357,362,363,366,367,368,369,370,371,376,377,378,379,
-  380,381,382,402,536,537,710,711,728,729,730,731,732,733,8211,8212,
-  8216,8217,8218,8220,8221,8222,8224,8225,8226,8230,8240,8249,8250,
-  8260,8364,8482,8706,8710,8721,8722,8730,8800,8804,8805,9674,63171,
-  64257,64258
-};
-static afm_cunicode afm_Courier_Oblique_ligatures[] = { /* 3 */
-  102,105,64257
-};
-
-
-/* ------------------------------------------------------------------*/
-/* FontName: Helvetica */
-/* FullName: Helvetica */
-/* FamilyName: Helvetica */
-static afm_cuint8 afm_Helvetica_widths[] = { /* 315 */
-  46,46,59,93,93,148,111,32,56,56,65,97,46,56,46,46,93,93,93,93,93,
-  93,93,93,93,93,46,46,97,97,97,93,169,111,111,120,120,111,102,130,
-  120,46,83,111,93,139,120,130,111,130,120,111,102,120,111,157,111,
-  111,102,46,46,46,78,93,56,93,93,83,93,93,46,93,93,37,37,83,37,139,
-  93,93,93,93,56,83,46,93,83,120,83,83,83,56,43,56,97,56,93,93,93,
-  93,43,93,56,123,62,93,97,123,56,67,97,56,56,56,93,90,46,56,56,61,
-  93,139,139,139,102,111,111,111,111,111,111,167,120,111,111,111,111,
-  46,46,46,46,120,120,130,130,130,130,130,97,130,120,120,120,120,111,
-  111,102,93,93,93,93,93,93,148,83,93,93,93,93,46,46,46,46,93,93,93,
-  93,93,93,93,97,102,93,93,93,93,83,93,83,111,93,111,93,111,93,120,
-  83,120,83,120,107,120,93,111,93,111,93,111,93,111,93,130,93,130,
-  93,46,46,46,37,46,46,111,83,93,37,93,37,93,50,93,37,120,93,120,93,
-  120,93,130,93,130,93,167,157,120,56,120,56,120,56,111,83,111,83,
-  111,83,102,46,102,53,120,93,120,93,120,93,120,93,111,102,83,102,
-  83,102,83,93,111,83,56,56,56,56,56,56,56,56,93,167,37,37,37,56,56,
-  56,93,93,58,167,167,56,56,28,93,167,79,102,100,97,76,92,92,92,79,
-  42,83,83
-};
-static afm_sint16 afm_Helvetica_kerning_index[] = { /* 315 */
-  1,0,0,0,0,0,0,0,0,0,0,0,29,0,38,0,0,0,0,0,0,0,0,0,0,0,49,52,0,0,
-  0,0,0,55,170,197,202,0,241,0,0,0,345,418,510,0,0,545,594,687,710,
-  772,777,938,966,1115,0,1259,0,0,0,0,0,0,0,1407,1419,1468,0,1476,
-  1494,1575,1587,0,0,1595,0,1638,1668,1700,1718,0,1730,1847,0,0,1854,
-  1924,1994,2017,2087,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-  0,0,0,0,0,0,0,0,0,0,0,0,2130,2245,2360,2475,2590,2705,0,2820,0,0,
-  0,0,0,0,0,0,0,0,2825,2874,2923,2972,3021,0,3070,3119,3147,3175,3203,
-  3231,0,0,3379,3391,3403,3415,3427,3439,0,3451,3459,3477,3495,3513,
-  0,0,0,0,0,3531,3563,3581,3599,3617,3635,0,3653,0,0,0,0,3882,0,3952,
-  4022,4137,4149,4264,4276,4391,4403,4408,4416,4421,4429,0,4468,0,
-  0,4507,0,4525,0,4543,0,4561,0,4579,0,4591,0,0,0,0,0,0,4603,4695,
-  4738,0,4773,0,4808,0,4843,0,0,4878,0,4910,0,4942,4974,5023,5041,
-  5090,0,0,5108,5170,5287,5349,5466,5528,5645,5650,5657,5662,5669,
-  5674,5681,0,5842,0,6003,0,6031,0,6059,0,6087,0,6115,0,6263,0,6306,
-  0,6349,0,6392,6397,0,0,0,0,0,0,0,0,0,0,6404,6409,0,0,6447,0,0,0,
-  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
-};
-static afm_cuint8 afm_Helvetica_kerning_data[] = { /* 6450 */
-  42,11,85,249,87,249,88,250,90,242,222,242,0,100,249,0,102,249,0,
-  122,242,1,32,24,247,1,32,28,252,3,1,32,25,240,1,32,29,240,4,33,247,
-  1,32,25,240,1,32,29,240,2,33,249,2,33,249,49,68,252,72,252,80,252,
-  82,252,85,237,86,249,87,245,88,249,90,240,118,252,119,250,120,250,
-  122,250,200,252,211,252,212,252,213,252,214,252,215,252,217,252,
-  218,249,219,249,220,249,221,249,222,240,250,252,251,252,252,252,
-  253,252,254,250,0,1,250,0,8,252,0,14,252,0,32,252,0,36,252,0,78,
-  252,0,82,252,0,100,237,0,102,237,0,108,249,0,109,252,0,112,249,0,
-  113,252,0,114,249,0,115,252,0,116,249,0,117,252,0,122,240,12,45,
-  254,47,254,86,255,218,255,219,255,220,255,221,255,0,108,255,0,112,
-  255,0,114,255,0,116,255,3,45,252,47,252,18,45,245,47,245,66,250,
-  87,245,88,250,90,242,193,250,194,250,195,250,196,250,197,250,198,
-  250,222,242,0,2,250,0,4,250,0,6,250,0,122,242,45,45,232,47,232,66,
-  244,98,249,102,252,112,252,115,249,193,244,194,244,195,244,196,244,
-  197,244,198,244,225,249,226,249,227,249,228,249,229,249,230,249,
-  233,252,234,252,235,252,236,252,243,252,244,252,245,252,246,252,
-  247,252,249,252,0,2,244,0,3,249,0,4,244,0,5,249,0,6,244,0,7,249,
-  0,21,252,0,25,252,0,27,252,0,29,252,0,79,252,0,83,252,0,87,249,0,
-  89,249,0,91,249,32,45,252,47,252,66,254,98,254,118,254,193,254,194,
-  254,195,254,196,254,197,254,198,254,225,254,226,254,227,254,228,
-  254,229,254,230,254,250,254,251,254,252,254,253,254,0,2,254,0,3,
-  254,0,4,254,0,5,254,0,6,254,0,7,254,0,109,254,0,113,254,0,115,254,
-  0,117,254,40,80,249,102,250,112,250,118,252,122,249,211,249,212,
-  249,213,249,214,249,215,249,217,249,233,250,234,250,235,250,236,
-  250,243,250,244,250,245,250,246,250,247,250,249,250,250,252,251,
-  252,252,252,253,252,254,249,0,1,249,0,21,250,0,25,250,0,27,250,0,
-  29,250,0,78,249,0,79,250,0,82,249,0,83,250,0,109,252,0,113,252,0,
-  115,252,0,117,252,14,85,239,87,239,88,245,90,234,122,252,222,234,
-  254,252,0,1,252,0,100,239,0,102,239,0,122,234,1,32,25,230,1,32,29,
-  234,22,45,250,47,250,66,254,85,250,87,249,88,252,89,247,90,245,193,
-  254,194,254,195,254,196,254,197,254,198,254,222,245,0,2,254,0,4,
-  254,0,6,254,0,100,250,0,102,250,0,122,245,41,45,227,47,227,66,237,
-  98,250,102,249,112,249,193,237,194,237,195,237,196,237,197,237,198,
-  237,225,250,226,250,227,250,228,250,229,250,230,250,233,249,234,
-  249,235,249,236,249,243,249,244,249,245,249,246,249,247,249,249,
-  249,0,2,237,0,3,250,0,4,237,0,5,250,0,6,237,0,7,250,0,21,249,0,25,
-  249,0,27,249,0,29,249,0,79,249,0,83,249,10,86,255,218,255,219,255,
-  220,255,221,255,0,108,255,0,112,255,0,114,255,0,116,255,27,80,254,
-  85,252,86,250,87,249,88,252,90,249,211,254,212,254,213,254,214,254,
-  215,254,217,254,218,250,219,250,220,250,221,250,222,249,0,78,254,
-  0,82,254,0,100,252,0,102,252,0,108,250,0,112,250,0,114,250,0,116,
-  250,0,122,249,3,45,254,47,254,70,45,237,46,234,47,237,59,254,60,
-  254,66,237,80,250,98,237,102,237,112,237,115,237,118,237,120,237,
-  122,237,193,237,194,237,195,237,196,237,197,237,198,237,211,250,
-  212,250,213,250,214,250,215,250,217,250,225,237,226,237,227,237,
-  228,247,229,237,230,237,233,247,234,237,235,237,236,237,243,237,
-  244,237,245,237,246,247,247,237,249,237,250,237,251,237,252,237,
-  253,237,254,237,0,1,247,0,2,237,0,3,247,0,4,237,0,5,247,0,6,237,
-  0,7,237,0,21,247,0,25,237,0,27,237,0,29,237,0,78,250,0,79,247,0,
-  82,250,0,83,237,0,87,237,0,89,237,0,91,237,0,109,247,0,113,237,0,
-  115,237,0,117,237,13,45,250,47,250,66,250,193,250,194,250,195,250,
-  196,250,197,250,198,250,0,2,250,0,4,250,0,6,250,65,45,236,46,244,
-  47,236,59,250,60,250,66,244,72,250,80,250,98,245,102,244,112,244,
-  118,245,193,244,194,244,195,244,196,244,197,244,198,244,211,250,
-  212,250,213,250,214,250,215,250,217,250,225,245,226,245,227,245,
-  228,245,229,245,230,245,233,244,234,244,235,244,236,244,243,244,
-  244,244,245,244,246,244,247,244,249,244,250,245,251,245,252,245,
-  253,245,0,2,244,0,3,245,0,4,244,0,5,245,0,6,244,0,7,245,0,21,244,
-  0,25,244,0,27,244,0,29,244,0,32,250,0,36,250,0,78,250,0,79,244,0,
-  82,250,0,83,244,0,109,245,0,113,245,0,115,245,0,117,245,63,45,244,
-  46,250,47,244,66,249,80,254,98,250,102,252,112,252,118,252,122,254,
-  193,249,194,249,195,249,196,249,197,249,198,249,211,254,212,254,
-  213,254,214,254,215,254,217,254,225,250,226,250,227,250,228,250,
-  229,250,230,250,233,252,234,252,235,252,236,252,243,252,244,252,
-  245,252,246,252,247,252,249,252,250,252,251,252,252,252,253,252,
-  254,254,0,1,254,0,2,249,0,3,250,0,4,249,0,5,250,0,6,249,0,7,250,
-  0,21,252,0,25,252,0,27,252,0,29,252,0,78,254,0,79,252,0,82,254,0,
-  83,252,0,109,252,0,113,252,0,115,252,0,117,252,65,45,234,46,234,
-  47,234,59,247,60,247,66,239,80,243,98,234,102,234,106,254,112,234,
-  118,239,193,239,194,239,195,239,196,239,197,239,198,239,211,243,
-  212,243,213,243,214,243,215,243,217,243,225,234,226,234,227,234,
-  228,234,229,234,230,234,233,234,234,234,235,234,236,234,238,254,
-  243,234,244,234,245,234,246,234,247,234,249,234,250,239,251,239,
-  252,239,253,239,0,2,239,0,3,245,0,4,239,0,5,245,0,6,239,0,7,234,
-  0,21,245,0,25,234,0,27,234,0,29,234,0,49,254,0,78,243,0,79,234,0,
-  82,243,0,83,234,0,109,239,0,113,239,0,115,239,0,117,239,6,119,254,
-  120,254,122,252,254,252,0,1,252,21,45,250,47,250,99,255,109,254,
-  118,254,119,254,122,254,250,254,251,254,252,254,253,254,254,254,
-  0,1,254,0,60,254,0,62,254,0,68,254,0,109,254,0,113,254,0,115,254,
-  0,117,254,4,45,254,108,254,0,57,254,9,45,254,47,254,119,252,120,
-  254,121,252,122,254,254,254,0,1,254,34,45,252,47,252,98,252,102,
-  252,112,252,225,252,226,252,227,252,228,252,229,252,230,252,233,
-  252,234,252,235,252,236,252,243,252,244,252,245,252,246,252,247,
-  252,249,252,0,3,252,0,5,252,0,7,252,0,21,252,0,25,252,0,27,252,0,
-  29,252,0,51,252,0,79,252,0,83,252,1,32,25,8,1,32,29,10,5,115,255,
-  0,87,255,0,89,255,0,91,255,4,122,252,254,252,0,1,252,19,102,254,
-  112,254,233,254,234,254,235,254,236,254,243,254,244,254,245,254,
-  246,254,247,254,249,254,0,21,254,0,25,254,0,27,254,0,29,254,0,79,
-  254,0,83,254,13,118,255,122,254,250,255,251,255,252,255,253,255,
-  254,254,0,1,254,0,109,255,0,113,255,0,115,255,0,117,255,14,118,255,
-  119,254,122,254,250,255,251,255,252,255,253,255,254,254,0,1,254,
-  0,109,255,0,113,255,0,115,255,0,117,255,9,45,250,47,250,119,254,
-  120,254,121,252,122,252,254,252,0,1,252,6,45,251,47,251,122,252,
-  254,252,0,1,252,50,45,249,47,249,59,5,60,5,98,255,106,3,108,3,109,
-  3,110,4,111,4,113,5,117,7,118,3,119,5,122,5,225,255,226,255,227,
-  255,228,255,229,255,230,255,237,3,238,3,239,3,240,3,242,4,250,3,
-  251,3,252,3,253,3,254,5,0,1,5,0,3,255,0,5,255,0,7,255,0,45,3,0,49,
-  3,0,57,3,0,60,3,0,62,3,0,68,3,0,70,4,0,72,4,0,74,4,0,101,7,0,109,
-  3,0,113,3,0,115,3,0,117,3,4,45,254,47,254,120,252,31,45,244,47,244,
-  98,253,102,253,112,253,225,253,226,253,227,253,228,253,229,253,230,
-  253,233,253,234,253,235,253,236,253,243,253,244,253,245,253,246,
-  253,247,253,249,253,0,3,253,0,5,253,0,7,253,0,21,253,0,25,253,0,
-  27,253,0,29,253,0,79,253,0,83,253,31,45,247,47,247,98,254,102,255,
-  112,255,225,254,226,254,227,254,228,254,229,254,230,254,233,255,
-  234,255,235,255,236,255,243,255,244,255,245,255,246,255,247,255,
-  249,255,0,3,254,0,5,254,0,7,254,0,21,255,0,25,255,0,27,255,0,29,
-  255,0,79,255,0,83,255,10,102,252,233,252,234,252,235,252,236,252,
-  0,21,252,0,25,252,0,27,252,0,29,252,31,45,240,47,240,98,254,102,
-  254,112,254,225,254,226,254,227,254,228,254,229,254,230,254,233,
-  254,234,254,235,254,236,254,243,254,244,254,245,254,246,254,247,
-  254,249,254,0,3,254,0,5,254,0,7,254,0,21,254,0,25,254,0,27,254,0,
-  29,254,0,79,254,0,83,254,19,102,254,112,254,233,254,234,254,235,
-  254,236,254,243,254,244,254,245,254,246,254,247,254,249,254,0,21,
-  254,0,25,254,0,27,254,0,29,254,0,79,254,0,83,254,49,68,252,72,252,
-  80,252,82,252,85,237,86,249,87,245,88,249,90,240,118,252,119,250,
-  120,250,122,250,200,252,211,252,212,252,213,252,214,252,215,252,
-  217,252,218,249,219,249,220,249,221,249,222,240,250,252,251,252,
-  252,252,253,252,254,250,0,1,250,0,8,252,0,14,252,0,32,252,0,36,252,
-  0,78,252,0,82,252,0,100,237,0,102,237,0,108,249,0,109,252,0,112,
-  249,0,113,252,0,114,249,0,115,252,0,116,249,0,117,252,0,122,240,
-  49,68,252,72,252,80,252,82,252,85,237,86,249,87,245,88,249,90,240,
-  118,252,119,250,120,250,122,250,200,252,211,252,212,252,213,252,
-  214,252,215,252,217,252,218,249,219,249,220,249,221,249,222,240,
-  250,252,251,252,252,252,253,252,254,250,0,1,250,0,8,252,0,14,252,
-  0,32,252,0,36,252,0,78,252,0,82,252,0,100,237,0,102,237,0,108,249,
-  0,109,252,0,112,249,0,113,252,0,114,249,0,115,252,0,116,249,0,117,
-  252,0,122,240,49,68,252,72,252,80,252,82,252,85,237,86,249,87,245,
-  88,249,90,240,118,252,119,250,120,250,122,250,200,252,211,252,212,
-  252,213,252,214,252,215,252,217,252,218,249,219,249,220,249,221,
-  249,222,240,250,252,251,252,252,252,253,252,254,250,0,1,250,0,8,
-  252,0,14,252,0,32,252,0,36,252,0,78,252,0,82,252,0,100,237,0,102,
-  237,0,108,249,0,109,252,0,112,249,0,113,252,0,114,249,0,115,252,
-  0,116,249,0,117,252,0,122,240,49,68,252,72,252,80,252,82,252,85,
-  237,86,249,87,245,88,249,90,240,118,252,119,250,120,250,122,250,
-  200,252,211,252,212,252,213,252,214,252,215,252,217,252,218,249,
-  219,249,220,249,221,249,222,240,250,252,251,252,252,252,253,252,
-  254,250,0,1,250,0,8,252,0,14,252,0,32,252,0,36,252,0,78,252,0,82,
-  252,0,100,237,0,102,237,0,108,249,0,109,252,0,112,249,0,113,252,
-  0,114,249,0,115,252,0,116,249,0,117,252,0,122,240,49,68,252,72,252,
-  80,252,82,252,85,237,86,249,87,245,88,249,90,240,118,252,119,250,
-  120,250,122,250,200,252,211,252,212,252,213,252,214,252,215,252,
-  217,252,218,249,219,249,220,249,221,249,222,240,250,252,251,252,
-  252,252,253,252,254,250,0,1,250,0,8,252,0,14,252,0,32,252,0,36,252,
-  0,78,252,0,82,252,0,100,237,0,102,237,0,108,249,0,109,252,0,112,
-  249,0,113,252,0,114,249,0,115,252,0,116,249,0,117,252,0,122,240,
-  49,68,252,72,252,80,252,82,252,85,237,86,249,87,245,88,249,90,240,
-  118,252,119,250,120,250,122,250,200,252,211,252,212,252,213,252,
-  214,252,215,252,217,252,218,249,219,249,220,249,221,249,222,240,
-  250,252,251,252,252,252,253,252,254,250,0,1,250,0,8,252,0,14,252,
-  0,32,252,0,36,252,0,78,252,0,82,252,0,100,237,0,102,237,0,108,249,
-  0,109,252,0,112,249,0,113,252,0,114,249,0,115,252,0,116,249,0,117,
-  252,0,122,240,3,45,252,47,252,22,45,250,47,250,66,254,85,250,87,
-  249,88,252,89,247,90,245,193,254,194,254,195,254,196,254,197,254,
-  198,254,222,245,0,2,254,0,4,254,0,6,254,0,100,250,0,102,250,0,122,
-  245,22,45,250,47,250,66,254,85,250,87,249,88,252,89,247,90,245,193,
-  254,194,254,195,254,196,254,197,254,198,254,222,245,0,2,254,0,4,
-  254,0,6,254,0,100,250,0,102,250,0,122,245,22,45,250,47,250,66,254,
-  85,250,87,249,88,252,89,247,90,245,193,254,194,254,195,254,196,254,
-  197,254,198,254,222,245,0,2,254,0,4,254,0,6,254,0,100,250,0,102,
-  250,0,122,245,22,45,250,47,250,66,254,85,250,87,249,88,252,89,247,
-  90,245,193,254,194,254,195,254,196,254,197,254,198,254,222,245,0,
-  2,254,0,4,254,0,6,254,0,100,250,0,102,250,0,122,245,22,45,250,47,
-  250,66,254,85,250,87,249,88,252,89,247,90,245,193,254,194,254,195,
-  254,196,254,197,254,198,254,222,245,0,2,254,0,4,254,0,6,254,0,100,
-  250,0,102,250,0,122,245,22,45,250,47,250,66,254,85,250,87,249,88,
-  252,89,247,90,245,193,254,194,254,195,254,196,254,197,254,198,254,
-  222,245,0,2,254,0,4,254,0,6,254,0,100,250,0,102,250,0,122,245,13,
-  45,250,47,250,66,250,193,250,194,250,195,250,196,250,197,250,198,
-  250,0,2,250,0,4,250,0,6,250,13,45,250,47,250,66,250,193,250,194,
-  250,195,250,196,250,197,250,198,250,0,2,250,0,4,250,0,6,250,13,45,
-  250,47,250,66,250,193,250,194,250,195,250,196,250,197,250,198,250,
-  0,2,250,0,4,250,0,6,250,13,45,250,47,250,66,250,193,250,194,250,
-  195,250,196,250,197,250,198,250,0,2,250,0,4,250,0,6,250,65,45,234,
-  46,234,47,234,59,247,60,247,66,239,80,243,98,234,102,234,106,254,
-  112,234,118,239,193,239,194,239,195,239,196,239,197,239,198,239,
-  211,243,212,243,213,243,214,243,215,243,217,243,225,234,226,234,
-  227,234,228,245,229,234,230,234,233,234,234,234,235,234,236,234,
-  238,254,243,234,244,234,245,234,246,234,247,234,249,234,250,239,
-  251,239,252,239,253,239,0,2,239,0,3,245,0,4,239,0,5,245,0,6,239,
-  0,7,234,0,21,245,0,25,234,0,27,234,0,29,234,0,49,254,0,78,243,0,
-  79,245,0,82,243,0,83,234,0,109,239,0,113,239,0,115,239,0,117,239,
-  6,119,254,120,254,122,252,254,252,0,1,252,6,119,254,120,254,122,
-  252,254,252,0,1,252,6,119,254,120,254,122,252,254,252,0,1,252,6,
-  119,254,120,254,122,252,254,252,0,1,252,6,119,254,120,254,122,252,
-  254,252,0,1,252,6,119,254,120,254,122,252,254,252,0,1,252,4,45,254,
-  108,254,0,57,254,9,45,254,47,254,119,252,120,254,121,252,122,254,
-  254,254,0,1,254,9,45,254,47,254,119,252,120,254,121,252,122,254,
-  254,254,0,1,254,9,45,254,47,254,119,252,120,254,121,252,122,254,
-  254,254,0,1,254,9,45,254,47,254,119,252,120,254,121,252,122,254,
-  254,254,0,1,254,14,118,255,119,254,122,254,250,255,251,255,252,255,
-  253,255,254,254,0,1,254,0,109,255,0,113,255,0,115,255,0,117,255,
-  9,45,250,47,250,119,254,120,254,121,252,122,252,254,252,0,1,252,
-  9,45,250,47,250,119,254,120,254,121,252,122,252,254,252,0,1,252,
-  9,45,250,47,250,119,254,120,254,121,252,122,252,254,252,0,1,252,
-  9,45,250,47,250,119,254,120,254,121,252,122,252,254,252,0,1,252,
-  9,45,250,47,250,119,254,120,254,121,252,122,252,254,252,0,1,252,
-  95,45,241,47,241,98,248,99,248,100,248,101,248,102,248,103,248,104,
-  248,105,248,106,248,107,248,108,248,109,248,110,248,111,248,112,
-  248,113,248,114,248,115,248,116,248,117,248,118,248,119,245,120,
-  245,121,243,122,245,123,248,225,248,226,248,227,248,228,248,229,
-  248,230,248,232,248,233,248,234,248,235,248,236,248,237,248,238,
-  248,239,248,240,248,242,248,243,248,244,248,245,248,246,248,247,
-  248,249,248,250,248,251,248,252,248,253,248,254,245,0,1,245,0,3,
-  248,0,5,248,0,7,248,0,9,248,0,15,248,0,19,248,0,21,248,0,25,248,
-  0,27,248,0,29,248,0,33,248,0,37,248,0,45,248,0,49,248,0,57,248,0,
-  60,248,0,62,248,0,68,248,0,70,248,0,72,248,0,74,248,0,79,248,0,83,
-  248,0,87,248,0,89,248,0,91,248,0,93,248,0,97,248,0,99,248,0,101,
-  248,0,109,248,0,113,248,0,115,248,0,117,248,0,124,248,0,126,248,
-  0,128,248,1,2,25,248,31,45,240,47,240,98,254,102,254,112,254,225,
-  254,226,254,227,254,228,254,229,254,230,254,233,254,234,254,235,
-  254,236,254,243,254,244,254,245,254,246,254,247,254,249,254,0,3,
-  254,0,5,254,0,7,254,0,21,254,0,25,254,0,27,254,0,29,254,0,79,254,
-  0,83,254,31,45,240,47,240,98,254,102,254,112,254,225,254,226,254,
-  227,254,228,254,229,254,230,254,233,254,234,254,235,254,236,254,
-  243,254,244,254,245,254,246,254,247,254,249,254,0,3,254,0,5,254,
-  0,7,254,0,21,254,0,25,254,0,27,254,0,29,254,0,79,254,0,83,254,49,
-  68,252,72,252,80,252,82,252,85,237,86,249,87,245,88,249,90,240,118,
-  252,119,250,120,250,122,250,200,252,211,252,212,252,213,252,214,
-  252,215,252,217,252,218,249,219,249,220,249,221,249,222,240,250,
-  252,251,252,252,252,253,252,254,250,0,1,250,0,8,252,0,14,252,0,32,
-  252,0,36,252,0,78,252,0,82,252,0,100,237,0,102,237,0,108,249,0,109,
-  252,0,112,249,0,113,252,0,114,249,0,115,252,0,116,249,0,117,252,
-  0,122,240,6,119,254,120,254,122,252,254,252,0,1,252,49,68,252,72,
-  252,80,252,82,252,85,237,86,249,87,245,88,249,90,240,118,252,119,
-  250,120,250,122,250,200,252,211,252,212,252,213,252,214,252,215,
-  252,217,252,218,249,219,249,220,249,221,249,222,240,250,252,251,
-  252,252,252,253,252,254,250,0,1,250,0,8,252,0,14,252,0,32,252,0,
-  36,252,0,78,252,0,82,252,0,100,237,0,102,237,0,108,249,0,109,252,
-  0,112,249,0,113,252,0,114,249,0,115,252,0,116,249,0,117,252,0,122,
-  240,6,119,254,120,254,122,252,254,252,0,1,252,49,68,252,72,252,80,
-  252,82,252,85,237,86,249,87,245,88,249,90,240,118,252,119,250,120,
-  250,122,250,200,252,211,252,212,252,213,252,214,252,215,252,217,
-  252,218,249,219,249,220,249,221,249,222,240,250,252,251,252,252,
-  252,253,252,254,250,0,1,250,0,8,252,0,14,252,0,32,252,0,36,252,0,
-  78,252,0,82,252,0,100,237,0,102,237,0,108,249,0,109,252,0,112,249,
-  0,113,252,0,114,249,0,115,252,0,116,249,0,117,252,0,122,240,6,119,
-  254,120,254,122,252,254,252,0,1,252,3,45,252,47,252,4,45,254,108,
-  254,0,57,254,3,45,252,47,252,4,45,254,108,254,0,57,254,18,45,245,
-  47,245,66,250,87,245,88,250,90,242,193,250,194,250,195,250,196,250,
-  197,250,198,250,222,242,0,2,250,0,4,250,0,6,250,0,122,242,18,45,
-  245,47,245,66,250,87,245,88,250,90,242,193,250,194,250,195,250,196,
-  250,197,250,198,250,222,242,0,2,250,0,4,250,0,6,250,0,122,242,9,
-  45,254,47,254,119,252,120,254,121,252,122,254,254,254,0,1,254,9,
-  45,254,47,254,119,252,120,254,121,252,122,254,254,254,0,1,254,9,
-  45,254,47,254,119,252,120,254,121,252,122,254,254,254,0,1,254,9,
-  45,254,47,254,119,252,120,254,121,252,122,254,254,254,0,1,254,5,
-  115,255,0,87,255,0,89,255,0,91,255,5,115,255,0,87,255,0,89,255,0,
-  91,255,40,80,249,102,250,112,250,118,252,122,249,211,249,212,249,
-  213,249,214,249,215,249,217,249,233,250,234,250,235,250,236,250,
-  243,250,244,250,245,250,246,250,247,250,249,250,250,252,251,252,
-  252,252,253,252,254,249,0,1,249,0,21,250,0,25,250,0,27,250,0,29,
-  250,0,78,249,0,79,250,0,82,249,0,83,250,0,109,252,0,113,252,0,115,
-  252,0,117,252,19,102,254,112,254,233,254,234,254,235,254,236,254,
-  243,254,244,254,245,254,246,254,247,254,249,254,0,21,254,0,25,254,
-  0,27,254,0,29,254,0,79,254,0,83,254,14,85,239,87,239,88,245,90,234,
-  122,252,222,234,254,252,0,1,252,0,100,239,0,102,239,0,122,234,1,
-  32,25,230,1,32,29,234,14,85,239,87,239,88,245,90,234,122,252,222,
-  234,254,252,0,1,252,0,100,239,0,102,239,0,122,234,1,32,25,230,1,
-  32,29,234,14,85,239,87,239,88,245,90,234,122,252,222,234,254,252,
-  0,1,252,0,100,239,0,102,239,0,122,234,1,32,25,230,1,32,29,234,14,
-  85,239,87,239,88,245,90,234,122,252,222,234,254,252,0,1,252,0,100,
-  239,0,102,239,0,122,234,1,32,25,230,1,32,29,234,14,118,255,119,254,
-  122,254,250,255,251,255,252,255,253,255,254,254,0,1,254,0,109,255,
-  0,113,255,0,115,255,0,117,255,14,118,255,119,254,122,254,250,255,
-  251,255,252,255,253,255,254,254,0,1,254,0,109,255,0,113,255,0,115,
-  255,0,117,255,14,118,255,119,254,122,254,250,255,251,255,252,255,
-  253,255,254,254,0,1,254,0,109,255,0,113,255,0,115,255,0,117,255,
-  22,45,250,47,250,66,254,85,250,87,249,88,252,89,247,90,245,193,254,
-  194,254,195,254,196,254,197,254,198,254,222,245,0,2,254,0,4,254,
-  0,6,254,0,100,250,0,102,250,0,122,245,9,45,250,47,250,119,254,120,
-  254,121,252,122,252,254,252,0,1,252,22,45,250,47,250,66,254,85,250,
-  87,249,88,252,89,247,90,245,193,254,194,254,195,254,196,254,197,
-  254,198,254,222,245,0,2,254,0,4,254,0,6,254,0,100,250,0,102,250,
-  0,122,245,9,45,250,47,250,119,254,120,254,121,252,122,252,254,252,
-  0,1,252,27,80,254,85,252,86,250,87,249,88,252,90,249,211,254,212,
-  254,213,254,214,254,215,254,217,254,218,250,219,250,220,250,221,
-  250,222,249,0,78,254,0,82,254,0,100,252,0,102,252,0,108,250,0,112,
-  250,0,114,250,0,116,250,0,122,249,50,45,249,47,249,59,5,60,5,98,
-  255,106,3,108,3,109,3,110,4,111,4,113,5,117,7,118,3,119,5,122,5,
-  225,255,226,255,227,255,228,255,229,255,230,255,237,3,238,3,239,
-  3,240,3,242,4,250,3,251,3,252,3,253,3,254,5,0,1,5,0,3,255,0,5,255,
-  0,7,255,0,45,3,0,49,3,0,57,3,0,60,3,0,62,3,0,68,3,0,70,4,0,72,4,
-  0,74,4,0,101,7,0,109,3,0,113,3,0,115,3,0,117,3,27,80,254,85,252,
-  86,250,87,249,88,252,90,249,211,254,212,254,213,254,214,254,215,
-  254,217,254,218,250,219,250,220,250,221,250,222,249,0,78,254,0,82,
-  254,0,100,252,0,102,252,0,108,250,0,112,250,0,114,250,0,116,250,
-  0,122,249,50,45,249,47,249,59,5,60,5,98,255,106,3,108,3,109,3,110,
-  4,111,4,113,5,117,7,118,3,119,5,122,5,225,255,226,255,227,255,228,
-  255,229,255,230,255,237,3,238,3,239,3,240,3,242,4,250,3,251,3,252,
-  3,253,3,254,5,0,1,5,0,3,255,0,5,255,0,7,255,0,45,3,0,49,3,0,57,3,
-  0,60,3,0,62,3,0,68,3,0,70,4,0,72,4,0,74,4,0,101,7,0,109,3,0,113,
-  3,0,115,3,0,117,3,27,80,254,85,252,86,250,87,249,88,252,90,249,211,
-  254,212,254,213,254,214,254,215,254,217,254,218,250,219,250,220,
-  250,221,250,222,249,0,78,254,0,82,254,0,100,252,0,102,252,0,108,
-  250,0,112,250,0,114,250,0,116,250,0,122,249,50,45,249,47,249,59,
-  5,60,5,98,255,106,3,108,3,109,3,110,4,111,4,113,5,117,7,118,3,119,
-  5,122,5,225,255,226,255,227,255,228,255,229,255,230,255,237,3,238,
-  3,239,3,240,3,242,4,250,3,251,3,252,3,253,3,254,5,0,1,5,0,3,255,
-  0,5,255,0,7,255,0,45,3,0,49,3,0,57,3,0,60,3,0,62,3,0,68,3,0,70,4,
-  0,72,4,0,74,4,0,101,7,0,109,3,0,113,3,0,115,3,0,117,3,3,45,254,47,
-  254,4,45,254,47,254,120,252,3,45,254,47,254,4,45,254,47,254,120,
-  252,3,45,254,47,254,4,45,254,47,254,120,252,70,45,237,46,234,47,
-  237,59,254,60,254,66,237,80,250,98,237,102,237,112,237,115,237,118,
-  237,120,237,122,237,193,237,194,237,195,237,196,237,197,237,198,
-  237,211,250,212,250,213,250,214,250,215,250,217,250,225,237,226,
-  237,227,237,228,247,229,237,230,237,233,247,234,237,235,237,236,
-  237,243,237,244,237,245,237,246,247,247,237,249,237,250,237,251,
-  237,252,237,253,237,254,237,0,1,247,0,2,237,0,3,247,0,4,237,0,5,
-  247,0,6,237,0,7,237,0,21,247,0,25,237,0,27,237,0,29,237,0,78,250,
-  0,79,247,0,82,250,0,83,237,0,87,237,0,89,237,0,91,237,0,109,247,
-  0,113,237,0,115,237,0,117,237,70,45,237,46,234,47,237,59,254,60,
-  254,66,237,80,250,98,237,102,237,112,237,115,237,118,237,120,237,
-  122,237,193,237,194,237,195,237,196,237,197,237,198,237,211,250,
-  212,250,213,250,214,250,215,250,217,250,225,237,226,237,227,237,
-  228,247,229,237,230,237,233,247,234,237,235,237,236,237,243,237,
-  244,237,245,237,246,247,247,237,249,237,250,237,251,237,252,237,
-  253,237,254,237,0,1,247,0,2,237,0,3,247,0,4,237,0,5,247,0,6,237,
-  0,7,237,0,21,247,0,25,237,0,27,237,0,29,237,0,78,250,0,79,247,0,
-  82,250,0,83,237,0,87,237,0,89,237,0,91,237,0,109,247,0,113,237,0,
-  115,237,0,117,237,13,45,250,47,250,66,250,193,250,194,250,195,250,
-  196,250,197,250,198,250,0,2,250,0,4,250,0,6,250,13,45,250,47,250,
-  66,250,193,250,194,250,195,250,196,250,197,250,198,250,0,2,250,0,
-  4,250,0,6,250,13,45,250,47,250,66,250,193,250,194,250,195,250,196,
-  250,197,250,198,250,0,2,250,0,4,250,0,6,250,13,45,250,47,250,66,
-  250,193,250,194,250,195,250,196,250,197,250,198,250,0,2,250,0,4,
-  250,0,6,250,65,45,234,46,234,47,234,59,247,60,247,66,239,80,243,
-  98,234,102,234,106,254,112,234,118,239,193,239,194,239,195,239,196,
-  239,197,239,198,239,211,243,212,243,213,243,214,243,215,243,217,
-  243,225,234,226,234,227,234,228,245,229,234,230,234,233,234,234,
-  234,235,234,236,234,238,254,243,234,244,234,245,234,246,234,247,
-  234,249,234,250,239,251,239,252,239,253,239,0,2,239,0,3,245,0,4,
-  239,0,5,245,0,6,239,0,7,234,0,21,245,0,25,234,0,27,234,0,29,234,
-  0,49,254,0,78,243,0,79,234,0,82,243,0,83,234,0,109,239,0,113,239,
-  0,115,239,0,117,239,19,102,254,112,254,233,254,234,254,235,254,236,
-  254,243,254,244,254,245,254,246,254,247,254,249,254,0,21,254,0,25,
-  254,0,27,254,0,29,254,0,79,254,0,83,254,19,102,254,112,254,233,254,
-  234,254,235,254,236,254,243,254,244,254,245,254,246,254,247,254,
-  249,254,0,21,254,0,25,254,0,27,254,0,29,254,0,79,254,0,83,254,19,
-  102,254,112,254,233,254,234,254,235,254,236,254,243,254,244,254,
-  245,254,246,254,247,254,249,254,0,21,254,0,25,254,0,27,254,0,29,
-  254,0,79,254,0,83,254,3,45,254,47,254,4,45,254,47,254,120,252,2,
-  1,32,24,247,14,33,245,101,249,115,249,116,249,0,19,249,0,87,249,
-  0,89,249,0,91,249,0,93,249,0,97,249,0,99,249,1,2,25,249,1,32,25,
-  247,2,33,250
-};
-static afm_cuint16 afm_Helvetica_highchars_index[] = { /* 220 */
-  161,162,163,164,165,166,167,168,169,170,171,172,174,175,176,177,
-  178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,
-  194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,
-  210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,
-  226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,
-  242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,
-  258,259,260,261,262,263,268,269,270,271,272,273,274,275,278,279,
-  280,281,282,283,286,287,290,291,298,299,302,303,304,305,310,311,
-  313,314,315,316,317,318,321,322,323,324,325,326,327,328,332,333,
-  336,337,338,339,340,341,342,343,344,345,346,347,350,351,352,353,
-  354,355,356,357,362,363,366,367,368,369,370,371,376,377,378,379,
-  380,381,382,402,536,537,710,711,728,729,730,731,732,733,8211,8212,
-  8216,8217,8218,8220,8221,8222,8224,8225,8226,8230,8240,8249,8250,
-  8260,8364,8482,8706,8710,8721,8722,8730,8800,8804,8805,9674,63171,
-  64257,64258
-};
-static afm_cunicode afm_Helvetica_ligatures[] = { /* 3 */
-  102,105,64257
-};
-
-
-/* ------------------------------------------------------------------*/
-/* FontName: Helvetica-Bold */
-/* FullName: Helvetica Bold */
-/* FamilyName: Helvetica */
-static afm_cuint8 afm_Helvetica_Bold_widths[] = { /* 315 */
-  46,56,79,93,93,148,120,40,56,56,65,97,46,56,46,46,93,93,93,93,93,
-  93,93,93,93,93,56,56,97,97,97,102,163,120,120,120,120,111,102,130,
-  120,46,93,120,102,139,120,130,111,130,120,111,102,120,111,157,111,
-  111,102,56,46,56,97,93,56,93,102,93,102,93,56,102,102,46,46,93,46,
-  148,102,102,102,102,65,93,56,102,93,130,93,93,83,65,47,65,97,56,
-  93,93,93,93,47,93,56,123,62,93,97,123,56,67,97,56,56,56,102,93,46,
-  56,56,61,93,139,139,139,102,120,120,120,120,120,120,167,120,111,
-  111,111,111,46,46,46,46,120,120,130,130,130,130,130,97,130,120,120,
-  120,120,111,111,102,93,93,93,93,93,93,148,93,93,93,93,93,46,46,46,
-  46,102,102,102,102,102,102,102,97,102,102,102,102,102,93,102,93,
-  120,93,120,93,120,93,120,93,120,93,120,124,120,102,111,93,111,93,
-  111,93,111,93,130,102,130,102,46,46,46,46,46,46,120,93,102,46,102,
-  46,102,67,102,46,120,102,120,102,120,102,130,102,130,102,167,157,
-  120,65,120,65,120,65,111,93,111,93,111,93,102,56,102,65,120,102,
-  120,102,120,102,120,102,111,102,83,102,83,102,83,93,111,93,56,56,
-  56,56,56,56,56,56,93,167,46,46,46,83,83,83,93,93,58,167,167,56,56,
-  28,93,167,82,102,100,97,92,92,92,92,82,42,102,102
-};
-static afm_sint16 afm_Helvetica_Bold_kerning_index[] = { /* 315 */
-  1,0,0,0,0,0,0,0,0,0,0,0,29,0,40,0,0,0,0,0,0,0,0,0,0,0,51,54,0,0,
-  0,0,0,57,172,0,218,0,257,0,0,0,308,358,450,0,0,485,534,627,654,0,
-  716,874,902,1051,0,1199,0,0,0,0,0,0,0,1338,1358,1401,1427,1444,1462,
-  1517,1548,0,0,1556,1577,1587,1617,1649,1663,0,1671,1752,0,0,1755,
-  1803,1828,1851,1921,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-  0,0,0,0,0,0,0,0,0,0,0,0,1944,2059,2174,2289,2404,2519,0,0,0,0,0,
-  0,0,0,0,0,0,0,2634,2683,2732,2781,2830,0,2879,2928,2956,2984,3012,
-  3040,0,0,3179,3199,3219,3239,3259,3279,0,3299,3325,3343,3361,3379,
-  0,0,0,0,0,3397,3429,3443,3457,3471,3485,0,3499,0,0,0,0,3513,0,3583,
-  3653,3768,3788,3903,3923,4038,0,4058,0,4084,4110,0,4149,4188,0,4205,
-  0,4223,0,4241,0,4259,0,4277,0,4308,0,0,0,0,0,0,4339,4431,4452,4487,
-  4497,4532,0,0,4542,4577,0,4587,0,4619,0,4651,4683,4732,4746,4795,
-  0,0,4809,4871,4952,5014,5095,5157,0,5238,0,5241,0,5244,5247,0,5405,
-  0,5563,0,5591,0,5619,0,5647,0,5675,0,5814,0,5837,0,5860,0,0,5883,
-  0,0,0,0,0,0,0,0,0,0,5886,5891,0,0,5942,0,0,0,0,0,0,0,0,0,0,0,0,0,
-  0,0,0,0,0,0,0,0,0,0
-};
-static afm_cuint8 afm_Helvetica_Bold_kerning_data[] = { /* 5945 */
-  42,11,85,240,87,244,88,244,90,237,222,237,0,100,240,0,102,240,0,
-  122,237,1,32,24,247,1,32,28,244,4,33,250,1,32,25,237,1,32,29,237,
-  4,33,250,1,32,25,237,1,32,29,237,2,33,250,2,33,250,49,68,250,72,
-  249,80,250,82,250,85,242,86,249,87,244,88,247,90,239,118,252,119,
-  250,120,252,122,252,200,250,211,250,212,250,213,250,214,250,215,
-  250,217,250,218,249,219,249,220,249,221,249,222,239,250,252,251,
-  252,252,252,253,252,254,252,0,1,252,0,8,250,0,14,250,0,32,249,0,
-  36,249,0,78,250,0,82,250,0,100,242,0,102,242,0,108,249,0,109,252,
-  0,112,249,0,113,252,0,114,249,0,115,252,0,116,249,0,117,252,0,122,
-  239,20,66,252,86,255,193,252,194,252,195,252,196,252,197,252,198,
-  252,218,255,219,255,220,255,221,255,0,2,252,0,4,252,0,6,252,0,108,
-  255,0,112,255,0,114,255,0,116,255,18,45,252,47,252,66,250,87,250,
-  88,250,90,245,193,250,194,250,195,250,196,250,197,250,198,250,222,
-  245,0,2,250,0,4,250,0,6,250,0,122,245,23,45,240,47,240,66,244,98,
-  254,193,244,194,244,195,244,196,244,197,244,198,244,225,254,226,
-  254,227,254,228,254,229,254,230,254,0,2,244,0,3,254,0,4,244,0,5,
-  254,0,6,244,0,7,254,22,45,254,47,254,66,254,118,254,193,254,194,
-  254,195,254,196,254,197,254,198,254,250,254,251,254,252,254,253,
-  254,0,2,254,0,4,254,0,6,254,0,109,254,0,113,254,0,115,254,0,117,
-  254,40,80,252,102,254,112,251,118,252,122,250,211,252,212,252,213,
-  252,214,252,215,252,217,252,233,254,234,254,235,254,236,254,243,
-  251,244,251,245,251,246,251,247,251,249,251,250,252,251,252,252,
-  252,253,252,254,250,0,1,250,0,21,254,0,25,254,0,27,254,0,29,254,
-  0,78,252,0,79,251,0,82,252,0,83,251,0,109,252,0,113,252,0,115,252,
-  0,117,252,14,85,242,87,239,88,244,90,237,122,252,222,237,254,252,
-  0,1,252,0,100,242,0,102,242,0,122,237,1,32,25,234,1,32,29,234,22,
-  45,250,47,250,66,249,85,250,87,249,88,249,89,249,90,245,193,249,
-  194,249,195,249,196,249,197,249,198,249,222,245,0,2,249,0,4,249,
-  0,6,249,0,100,250,0,102,250,0,122,245,41,45,237,47,237,66,240,98,
-  252,102,252,112,250,193,240,194,240,195,240,196,240,197,240,198,
-  240,225,252,226,252,227,252,228,252,229,252,230,252,233,252,234,
-  252,235,252,236,252,243,250,244,250,245,250,246,250,247,250,249,
-  250,0,2,240,0,3,252,0,4,240,0,5,252,0,6,240,0,7,252,0,21,252,0,25,
-  252,0,27,252,0,29,252,0,79,250,0,83,250,12,45,3,47,3,86,255,218,
-  255,219,255,220,255,221,255,0,108,255,0,112,255,0,114,255,0,116,
-  255,27,80,254,85,254,86,254,87,249,88,250,90,249,211,254,212,254,
-  213,254,214,254,215,254,217,254,218,254,219,254,220,254,221,254,
-  222,249,0,78,254,0,82,254,0,100,254,0,102,254,0,108,254,0,112,254,
-  0,114,254,0,116,254,0,122,249,69,45,244,46,237,47,244,59,250,60,
-  250,66,242,80,250,98,244,102,247,112,244,115,244,118,242,120,247,
-  122,247,193,242,194,242,195,242,196,242,197,242,198,242,211,250,
-  212,250,213,250,214,250,215,250,217,250,225,244,226,244,227,244,
-  228,244,229,244,230,244,233,247,234,247,235,247,236,247,243,244,
-  244,244,245,244,246,244,247,244,249,244,250,242,251,242,252,242,
-  253,242,254,247,0,1,247,0,2,242,0,3,244,0,4,242,0,5,244,0,6,242,
-  0,7,244,0,21,247,0,25,247,0,27,247,0,29,247,0,78,250,0,79,244,0,
-  82,250,0,83,244,0,87,244,0,89,244,0,109,242,0,113,242,0,115,242,
-  0,117,242,13,45,252,47,252,66,249,193,249,194,249,195,249,196,249,
-  197,249,198,249,0,2,249,0,4,249,0,6,249,65,45,237,46,244,47,237,
-  59,250,60,250,66,244,72,249,80,249,98,247,102,249,112,242,118,247,
-  193,244,194,244,195,244,196,244,197,244,198,244,211,249,212,249,
-  213,249,214,249,215,249,217,249,225,247,226,247,227,247,228,247,
-  229,247,230,247,233,249,234,249,235,249,236,249,243,242,244,242,
-  245,242,246,242,247,242,249,242,250,247,251,247,252,247,253,247,
-  0,2,244,0,3,247,0,4,244,0,5,247,0,6,244,0,7,247,0,21,249,0,25,249,
-  0,27,249,0,29,249,0,32,249,0,36,249,0,78,249,0,79,242,0,82,249,0,
-  83,242,0,109,247,0,113,247,0,115,247,0,117,247,65,45,244,46,250,
-  47,244,59,255,60,255,66,247,80,254,98,250,102,251,112,247,118,249,
-  122,254,193,247,194,247,195,247,196,247,197,247,198,247,211,254,
-  212,254,213,254,214,254,215,254,217,254,225,250,226,250,227,250,
-  228,250,229,250,230,250,233,251,234,251,235,251,236,251,243,247,
-  244,247,245,247,246,247,247,247,249,247,250,249,251,249,252,249,
-  253,249,254,254,0,1,254,0,2,247,0,3,250,0,4,247,0,5,250,0,6,247,
-  0,7,250,0,21,251,0,25,251,0,27,251,0,29,251,0,78,254,0,79,247,0,
-  82,254,0,83,247,0,109,249,0,113,249,0,115,249,0,117,249,61,45,240,
-  47,240,59,249,60,249,66,239,80,245,98,242,102,244,112,240,118,240,
-  193,239,194,239,195,239,196,239,197,239,198,239,211,245,212,245,
-  213,245,214,245,215,245,217,245,225,242,226,242,227,242,228,242,
-  229,242,230,242,233,244,234,244,235,244,236,244,243,240,244,240,
-  245,240,246,240,247,240,249,240,250,240,251,240,252,240,253,240,
-  0,2,239,0,3,242,0,4,239,0,5,242,0,6,239,0,7,242,0,21,244,0,25,244,
-  0,27,244,0,29,244,0,78,245,0,79,240,0,82,245,0,83,240,0,109,240,
-  0,113,240,0,115,240,0,117,240,9,104,255,119,254,120,254,122,254,
-  254,254,0,1,254,0,33,255,0,37,255,18,109,255,118,254,119,254,122,
-  254,250,254,251,254,252,254,253,254,254,254,0,1,254,0,60,255,0,62,
-  255,0,68,255,0,109,254,0,113,254,0,115,254,0,117,254,11,105,255,
-  108,254,109,254,122,255,254,255,0,1,255,0,57,254,0,60,254,0,62,254,
-  0,68,254,8,101,255,119,254,120,254,122,254,254,254,0,1,254,0,19,
-  255,9,45,2,47,3,119,254,120,254,121,254,122,254,254,254,0,1,254,
-  23,45,255,47,255,102,255,112,254,233,255,234,255,235,255,236,255,
-  243,254,244,254,245,254,246,254,247,254,249,254,0,21,255,0,25,255,
-  0,27,255,0,29,255,0,79,254,0,83,254,1,32,25,5,1,32,29,5,13,102,2,
-  104,255,233,2,234,2,235,2,236,2,0,21,2,0,25,2,0,27,2,0,29,2,0,33,
-  255,0,37,255,4,122,254,254,254,0,1,254,10,112,254,243,254,244,254,
-  245,254,246,254,247,254,249,254,0,79,254,0,83,254,5,120,254,122,
-  254,254,254,0,1,254,13,118,254,122,252,250,254,251,254,252,254,253,
-  254,254,252,0,1,252,0,109,254,0,113,254,0,115,254,0,117,254,14,118,
-  255,119,250,122,254,250,255,251,255,252,255,253,255,254,254,0,1,
-  254,0,109,255,0,113,255,0,115,255,0,117,255,7,119,254,120,254,121,
-  252,122,254,254,254,0,1,254,4,122,254,254,254,0,1,254,34,45,247,
-  46,254,47,247,100,254,101,254,104,254,112,254,114,254,116,254,117,
-  3,119,2,122,2,232,254,243,254,244,254,245,254,246,254,247,254,249,
-  254,254,2,0,1,2,0,9,254,0,15,254,0,19,254,0,33,254,0,37,254,0,79,
-  254,0,83,254,0,93,254,0,97,254,0,99,254,0,101,3,1,2,25,254,2,120,
-  254,22,45,244,47,244,98,254,112,252,225,254,226,254,227,254,228,
-  254,229,254,230,254,243,252,244,252,245,252,246,252,247,252,249,
-  252,0,3,254,0,5,254,0,7,254,0,79,252,0,83,252,12,45,250,47,250,112,
-  254,243,254,244,254,245,254,246,254,247,254,249,254,0,79,254,0,83,
-  254,10,102,255,233,255,234,255,235,255,236,255,0,21,255,0,25,255,
-  0,27,255,0,29,255,31,45,244,47,244,98,252,102,255,112,253,225,252,
-  226,252,227,252,228,252,229,252,230,252,233,255,234,255,235,255,
-  236,255,243,253,244,253,245,253,246,253,247,253,249,253,0,3,252,
-  0,5,252,0,7,252,0,21,255,0,25,255,0,27,255,0,29,255,0,79,253,0,83,
-  253,10,102,2,233,2,234,2,235,2,236,2,0,21,2,0,25,2,0,27,2,0,29,2,
-  49,68,250,72,249,80,250,82,250,85,242,86,249,87,244,88,247,90,239,
-  118,252,119,250,120,252,122,252,200,250,211,250,212,250,213,250,
-  214,250,215,250,217,250,218,249,219,249,220,249,221,249,222,239,
-  250,252,251,252,252,252,253,252,254,252,0,1,252,0,8,250,0,14,250,
-  0,32,249,0,36,249,0,78,250,0,82,250,0,100,242,0,102,242,0,108,249,
-  0,109,252,0,112,249,0,113,252,0,114,249,0,115,252,0,116,249,0,117,
-  252,0,122,239,49,68,250,72,249,80,250,82,250,85,242,86,249,87,244,
-  88,247,90,239,118,252,119,250,120,252,122,252,200,250,211,250,212,
-  250,213,250,214,250,215,250,217,250,218,249,219,249,220,249,221,
-  249,222,239,250,252,251,252,252,252,253,252,254,252,0,1,252,0,8,
-  250,0,14,250,0,32,249,0,36,249,0,78,250,0,82,250,0,100,242,0,102,
-  242,0,108,249,0,109,252,0,112,249,0,113,252,0,114,249,0,115,252,
-  0,116,249,0,117,252,0,122,239,49,68,250,72,249,80,250,82,250,85,
-  242,86,249,87,244,88,247,90,239,118,252,119,250,120,252,122,252,
-  200,250,211,250,212,250,213,250,214,250,215,250,217,250,218,249,
-  219,249,220,249,221,249,222,239,250,252,251,252,252,252,253,252,
-  254,252,0,1,252,0,8,250,0,14,250,0,32,249,0,36,249,0,78,250,0,82,
-  250,0,100,242,0,102,242,0,108,249,0,109,252,0,112,249,0,113,252,
-  0,114,249,0,115,252,0,116,249,0,117,252,0,122,239,49,68,250,72,249,
-  80,250,82,250,85,242,86,249,87,244,88,247,90,239,118,252,119,250,
-  120,252,122,252,200,250,211,250,212,250,213,250,214,250,215,250,
-  217,250,218,249,219,249,220,249,221,249,222,239,250,252,251,252,
-  252,252,253,252,254,252,0,1,252,0,8,250,0,14,250,0,32,249,0,36,249,
-  0,78,250,0,82,250,0,100,242,0,102,242,0,108,249,0,109,252,0,112,
-  249,0,113,252,0,114,249,0,115,252,0,116,249,0,117,252,0,122,239,
-  49,68,250,72,249,80,250,82,250,85,242,86,249,87,244,88,247,90,239,
-  118,252,119,250,120,252,122,252,200,250,211,250,212,250,213,250,
-  214,250,215,250,217,250,218,249,219,249,220,249,221,249,222,239,
-  250,252,251,252,252,252,253,252,254,252,0,1,252,0,8,250,0,14,250,
-  0,32,249,0,36,249,0,78,250,0,82,250,0,100,242,0,102,242,0,108,249,
-  0,109,252,0,112,249,0,113,252,0,114,249,0,115,252,0,116,249,0,117,
-  252,0,122,239,49,68,250,72,249,80,250,82,250,85,242,86,249,87,244,
-  88,247,90,239,118,252,119,250,120,252,122,252,200,250,211,250,212,
-  250,213,250,214,250,215,250,217,250,218,249,219,249,220,249,221,
-  249,222,239,250,252,251,252,252,252,253,252,254,252,0,1,252,0,8,
-  250,0,14,250,0,32,249,0,36,249,0,78,250,0,82,250,0,100,242,0,102,
-  242,0,108,249,0,109,252,0,112,249,0,113,252,0,114,249,0,115,252,
-  0,116,249,0,117,252,0,122,239,22,45,250,47,250,66,249,85,250,87,
-  249,88,249,89,249,90,245,193,249,194,249,195,249,196,249,197,249,
-  198,249,222,245,0,2,249,0,4,249,0,6,249,0,100,250,0,102,250,0,122,
-  245,22,45,250,47,250,66,249,85,250,87,249,88,249,89,249,90,245,193,
-  249,194,249,195,249,196,249,197,249,198,249,222,245,0,2,249,0,4,
-  249,0,6,249,0,100,250,0,102,250,0,122,245,22,45,250,47,250,66,249,
-  85,250,87,249,88,249,89,249,90,245,193,249,194,249,195,249,196,249,
-  197,249,198,249,222,245,0,2,249,0,4,249,0,6,249,0,100,250,0,102,
-  250,0,122,245,22,45,250,47,250,66,249,85,250,87,249,88,249,89,249,
-  90,245,193,249,194,249,195,249,196,249,197,249,198,249,222,245,0,
-  2,249,0,4,249,0,6,249,0,100,250,0,102,250,0,122,245,22,45,250,47,
-  250,66,249,85,250,87,249,88,249,89,249,90,245,193,249,194,249,195,
-  249,196,249,197,249,198,249,222,245,0,2,249,0,4,249,0,6,249,0,100,
-  250,0,102,250,0,122,245,22,45,250,47,250,66,249,85,250,87,249,88,
-  249,89,249,90,245,193,249,194,249,195,249,196,249,197,249,198,249,
-  222,245,0,2,249,0,4,249,0,6,249,0,100,250,0,102,250,0,122,245,13,
-  45,252,47,252,66,249,193,249,194,249,195,249,196,249,197,249,198,
-  249,0,2,249,0,4,249,0,6,249,13,45,252,47,252,66,249,193,249,194,
-  249,195,249,196,249,197,249,198,249,0,2,249,0,4,249,0,6,249,13,45,
-  252,47,252,66,249,193,249,194,249,195,249,196,249,197,249,198,249,
-  0,2,249,0,4,249,0,6,249,13,45,252,47,252,66,249,193,249,194,249,
-  195,249,196,249,197,249,198,249,0,2,249,0,4,249,0,6,249,61,45,240,
-  47,240,59,249,60,249,66,239,80,245,98,242,102,244,112,240,118,240,
-  193,239,194,239,195,239,196,239,197,239,198,239,211,245,212,245,
-  213,245,214,245,215,245,217,245,225,242,226,242,227,242,228,242,
-  229,242,230,242,233,244,234,244,235,244,236,244,243,240,244,240,
-  245,240,246,240,247,240,249,240,250,240,251,240,252,240,253,240,
-  0,2,239,0,3,242,0,4,239,0,5,242,0,6,239,0,7,242,0,21,244,0,25,244,
-  0,27,244,0,29,244,0,78,245,0,79,240,0,82,245,0,83,240,0,109,240,
-  0,113,240,0,115,240,0,117,240,9,104,255,119,254,120,254,122,254,
-  254,254,0,1,254,0,33,255,0,37,255,9,104,255,119,254,120,254,122,
-  254,254,254,0,1,254,0,33,255,0,37,255,9,104,255,119,254,120,254,
-  122,254,254,254,0,1,254,0,33,255,0,37,255,9,104,255,119,254,120,
-  254,122,254,254,254,0,1,254,0,33,255,0,37,255,9,104,255,119,254,
-  120,254,122,254,254,254,0,1,254,0,33,255,0,37,255,9,104,255,119,
-  254,120,254,122,254,254,254,0,1,254,0,33,255,0,37,255,11,105,255,
-  108,254,109,254,122,255,254,255,0,1,255,0,57,254,0,60,254,0,62,254,
-  0,68,254,9,45,2,47,3,119,254,120,254,121,254,122,254,254,254,0,1,
-  254,9,45,2,47,3,119,254,120,254,121,254,122,254,254,254,0,1,254,
-  9,45,2,47,3,119,254,120,254,121,254,122,254,254,254,0,1,254,9,45,
-  2,47,3,119,254,120,254,121,254,122,254,254,254,0,1,254,14,118,255,
-  119,250,122,254,250,255,251,255,252,255,253,255,254,254,0,1,254,
-  0,109,255,0,113,255,0,115,255,0,117,255,7,119,254,120,254,121,252,
-  122,254,254,254,0,1,254,7,119,254,120,254,121,252,122,254,254,254,
-  0,1,254,7,119,254,120,254,121,252,122,254,254,254,0,1,254,7,119,
-  254,120,254,121,252,122,254,254,254,0,1,254,7,119,254,120,254,121,
-  252,122,254,254,254,0,1,254,7,119,254,120,254,121,252,122,254,254,
-  254,0,1,254,31,45,244,47,244,98,252,102,255,112,253,225,252,226,
-  252,227,252,228,252,229,252,230,252,233,255,234,255,235,255,236,
-  255,243,253,244,253,245,253,246,253,247,253,249,253,0,3,252,0,5,
-  252,0,7,252,0,21,255,0,25,255,0,27,255,0,29,255,0,79,253,0,83,253,
-  31,45,244,47,244,98,252,102,255,112,253,225,252,226,252,227,252,
-  228,252,229,252,230,252,233,255,234,255,235,255,236,255,243,253,
-  244,253,245,253,246,253,247,253,249,253,0,3,252,0,5,252,0,7,252,
-  0,21,255,0,25,255,0,27,255,0,29,255,0,79,253,0,83,253,49,68,250,
-  72,249,80,250,82,250,85,242,86,249,87,244,88,247,90,239,118,252,
-  119,250,120,252,122,252,200,250,211,250,212,250,213,250,214,250,
-  215,250,217,250,218,249,219,249,220,249,221,249,222,239,250,252,
-  251,252,252,252,253,252,254,252,0,1,252,0,8,250,0,14,250,0,32,249,
-  0,36,249,0,78,250,0,82,250,0,100,242,0,102,242,0,108,249,0,109,252,
-  0,112,249,0,113,252,0,114,249,0,115,252,0,116,249,0,117,252,0,122,
-  239,9,104,255,119,254,120,254,122,254,254,254,0,1,254,0,33,255,0,
-  37,255,49,68,250,72,249,80,250,82,250,85,242,86,249,87,244,88,247,
-  90,239,118,252,119,250,120,252,122,252,200,250,211,250,212,250,213,
-  250,214,250,215,250,217,250,218,249,219,249,220,249,221,249,222,
-  239,250,252,251,252,252,252,253,252,254,252,0,1,252,0,8,250,0,14,
-  250,0,32,249,0,36,249,0,78,250,0,82,250,0,100,242,0,102,242,0,108,
-  249,0,109,252,0,112,249,0,113,252,0,114,249,0,115,252,0,116,249,
-  0,117,252,0,122,239,9,104,255,119,254,120,254,122,254,254,254,0,
-  1,254,0,33,255,0,37,255,49,68,250,72,249,80,250,82,250,85,242,86,
-  249,87,244,88,247,90,239,118,252,119,250,120,252,122,252,200,250,
-  211,250,212,250,213,250,214,250,215,250,217,250,218,249,219,249,
-  220,249,221,249,222,239,250,252,251,252,252,252,253,252,254,252,
-  0,1,252,0,8,250,0,14,250,0,32,249,0,36,249,0,78,250,0,82,250,0,100,
-  242,0,102,242,0,108,249,0,109,252,0,112,249,0,113,252,0,114,249,
-  0,115,252,0,116,249,0,117,252,0,122,239,9,104,255,119,254,120,254,
-  122,254,254,254,0,1,254,0,33,255,0,37,255,11,105,255,108,254,109,
-  254,122,255,254,255,0,1,255,0,57,254,0,60,254,0,62,254,0,68,254,
-  11,105,255,108,254,109,254,122,255,254,255,0,1,255,0,57,254,0,60,
-  254,0,62,254,0,68,254,18,45,252,47,252,66,250,87,250,88,250,90,245,
-  193,250,194,250,195,250,196,250,197,250,198,250,222,245,0,2,250,
-  0,4,250,0,6,250,0,122,245,18,45,252,47,252,66,250,87,250,88,250,
-  90,245,193,250,194,250,195,250,196,250,197,250,198,250,222,245,0,
-  2,250,0,4,250,0,6,250,0,122,245,8,101,255,119,254,120,254,122,254,
-  254,254,0,1,254,0,19,255,9,45,2,47,3,119,254,120,254,121,254,122,
-  254,254,254,0,1,254,9,45,2,47,3,119,254,120,254,121,254,122,254,
-  254,254,0,1,254,9,45,2,47,3,119,254,120,254,121,254,122,254,254,
-  254,0,1,254,9,45,2,47,3,119,254,120,254,121,254,122,254,254,254,
-  0,1,254,13,102,2,104,255,233,2,234,2,235,2,236,2,0,21,2,0,25,2,0,
-  27,2,0,29,2,0,33,255,0,37,255,13,102,2,104,255,233,2,234,2,235,2,
-  236,2,0,21,2,0,25,2,0,27,2,0,29,2,0,33,255,0,37,255,40,80,252,102,
-  254,112,251,118,252,122,250,211,252,212,252,213,252,214,252,215,
-  252,217,252,233,254,234,254,235,254,236,254,243,251,244,251,245,
-  251,246,251,247,251,249,251,250,252,251,252,252,252,253,252,254,
-  250,0,1,250,0,21,254,0,25,254,0,27,254,0,29,254,0,78,252,0,79,251,
-  0,82,252,0,83,251,0,109,252,0,113,252,0,115,252,0,117,252,10,112,
-  254,243,254,244,254,245,254,246,254,247,254,249,254,0,79,254,0,83,
-  254,14,85,242,87,239,88,244,90,237,122,252,222,237,254,252,0,1,252,
-  0,100,242,0,102,242,0,122,237,1,32,25,234,1,32,29,234,5,120,254,
-  122,254,254,254,0,1,254,14,85,242,87,239,88,244,90,237,122,252,222,
-  237,254,252,0,1,252,0,100,242,0,102,242,0,122,237,1,32,25,234,1,
-  32,29,234,5,120,254,122,254,254,254,0,1,254,14,85,242,87,239,88,
-  244,90,237,122,252,222,237,254,252,0,1,252,0,100,242,0,102,242,0,
-  122,237,1,32,25,234,1,32,29,234,5,120,254,122,254,254,254,0,1,254,
-  14,118,255,119,250,122,254,250,255,251,255,252,255,253,255,254,254,
-  0,1,254,0,109,255,0,113,255,0,115,255,0,117,255,14,118,255,119,250,
-  122,254,250,255,251,255,252,255,253,255,254,254,0,1,254,0,109,255,
-  0,113,255,0,115,255,0,117,255,14,118,255,119,250,122,254,250,255,
-  251,255,252,255,253,255,254,254,0,1,254,0,109,255,0,113,255,0,115,
-  255,0,117,255,22,45,250,47,250,66,249,85,250,87,249,88,249,89,249,
-  90,245,193,249,194,249,195,249,196,249,197,249,198,249,222,245,0,
-  2,249,0,4,249,0,6,249,0,100,250,0,102,250,0,122,245,7,119,254,120,
-  254,121,252,122,254,254,254,0,1,254,22,45,250,47,250,66,249,85,250,
-  87,249,88,249,89,249,90,245,193,249,194,249,195,249,196,249,197,
-  249,198,249,222,245,0,2,249,0,4,249,0,6,249,0,100,250,0,102,250,
-  0,122,245,7,119,254,120,254,121,252,122,254,254,254,0,1,254,27,80,
-  254,85,254,86,254,87,249,88,250,90,249,211,254,212,254,213,254,214,
-  254,215,254,217,254,218,254,219,254,220,254,221,254,222,249,0,78,
-  254,0,82,254,0,100,254,0,102,254,0,108,254,0,112,254,0,114,254,0,
-  116,254,0,122,249,34,45,247,46,254,47,247,100,254,101,254,104,254,
-  112,254,114,254,116,254,117,3,119,2,122,2,232,254,243,254,244,254,
-  245,254,246,254,247,254,249,254,254,2,0,1,2,0,9,254,0,15,254,0,19,
-  254,0,33,254,0,37,254,0,79,254,0,83,254,0,93,254,0,97,254,0,99,254,
-  0,101,3,1,2,25,254,27,80,254,85,254,86,254,87,249,88,250,90,249,
-  211,254,212,254,213,254,214,254,215,254,217,254,218,254,219,254,
-  220,254,221,254,222,249,0,78,254,0,82,254,0,100,254,0,102,254,0,
-  108,254,0,112,254,0,114,254,0,116,254,0,122,249,34,45,247,46,254,
-  47,247,100,254,101,254,104,254,112,254,114,254,116,254,117,3,119,
-  2,122,2,232,254,243,254,244,254,245,254,246,254,247,254,249,254,
-  254,2,0,1,2,0,9,254,0,15,254,0,19,254,0,33,254,0,37,254,0,79,254,
-  0,83,254,0,93,254,0,97,254,0,99,254,0,101,3,1,2,25,254,27,80,254,
-  85,254,86,254,87,249,88,250,90,249,211,254,212,254,213,254,214,254,
-  215,254,217,254,218,254,219,254,220,254,221,254,222,249,0,78,254,
-  0,82,254,0,100,254,0,102,254,0,108,254,0,112,254,0,114,254,0,116,
-  254,0,122,249,34,45,247,46,254,47,247,100,254,101,254,104,254,112,
-  254,114,254,116,254,117,3,119,2,122,2,232,254,243,254,244,254,245,
-  254,246,254,247,254,249,254,254,2,0,1,2,0,9,254,0,15,254,0,19,254,
-  0,33,254,0,37,254,0,79,254,0,83,254,0,93,254,0,97,254,0,99,254,0,
-  101,3,1,2,25,254,2,120,254,2,120,254,2,120,254,69,45,244,46,237,
-  47,244,59,250,60,250,66,242,80,250,98,244,102,247,112,244,115,244,
-  118,242,120,247,122,247,193,242,194,242,195,242,196,242,197,242,
-  198,242,211,250,212,250,213,250,214,250,215,250,217,250,225,244,
-  226,244,227,244,228,244,229,244,230,244,233,247,234,247,235,247,
-  236,247,243,244,244,244,245,244,246,244,247,244,249,244,250,242,
-  251,242,252,242,253,242,254,247,0,1,247,0,2,242,0,3,244,0,4,242,
-  0,5,244,0,6,242,0,7,244,0,21,247,0,25,247,0,27,247,0,29,247,0,78,
-  250,0,79,244,0,82,250,0,83,244,0,87,244,0,89,244,0,109,242,0,113,
-  242,0,115,242,0,117,242,69,45,244,46,237,47,244,59,250,60,250,66,
-  242,80,250,98,244,102,247,112,244,115,244,118,242,120,247,122,247,
-  193,242,194,242,195,242,196,242,197,242,198,242,211,250,212,250,
-  213,250,214,250,215,250,217,250,225,244,226,244,227,244,228,244,
-  229,244,230,244,233,247,234,247,235,247,236,247,243,244,244,244,
-  245,244,246,244,247,244,249,244,250,242,251,242,252,242,253,242,
-  254,247,0,1,247,0,2,242,0,3,244,0,4,242,0,5,244,0,6,242,0,7,244,
-  0,21,247,0,25,247,0,27,247,0,29,247,0,78,250,0,79,244,0,82,250,0,
-  83,244,0,87,244,0,89,244,0,109,242,0,113,242,0,115,242,0,117,242,
-  13,45,252,47,252,66,249,193,249,194,249,195,249,196,249,197,249,
-  198,249,0,2,249,0,4,249,0,6,249,13,45,252,47,252,66,249,193,249,
-  194,249,195,249,196,249,197,249,198,249,0,2,249,0,4,249,0,6,249,
-  13,45,252,47,252,66,249,193,249,194,249,195,249,196,249,197,249,
-  198,249,0,2,249,0,4,249,0,6,249,13,45,252,47,252,66,249,193,249,
-  194,249,195,249,196,249,197,249,198,249,0,2,249,0,4,249,0,6,249,
-  61,45,240,47,240,59,249,60,249,66,239,80,245,98,242,102,244,112,
-  240,118,240,193,239,194,239,195,239,196,239,197,239,198,239,211,
-  245,212,245,213,245,214,245,215,245,217,245,225,242,226,242,227,
-  242,228,242,229,242,230,242,233,244,234,244,235,244,236,244,243,
-  240,244,240,245,240,246,240,247,240,249,240,250,240,251,240,252,
-  240,253,240,0,2,239,0,3,242,0,4,239,0,5,242,0,6,239,0,7,242,0,21,
-  244,0,25,244,0,27,244,0,29,244,0,78,245,0,79,240,0,82,245,0,83,240,
-  0,109,240,0,113,240,0,115,240,0,117,240,10,102,2,233,2,234,2,235,
-  2,236,2,0,21,2,0,25,2,0,27,2,0,29,2,10,102,2,233,2,234,2,235,2,236,
-  2,0,21,2,0,25,2,0,27,2,0,29,2,10,102,2,233,2,234,2,235,2,236,2,0,
-  21,2,0,25,2,0,27,2,0,29,2,2,120,254,2,1,32,24,249,19,33,244,101,
-  244,109,254,115,250,116,247,119,254,0,19,244,0,60,254,0,62,254,0,
-  68,254,0,87,250,0,89,250,0,91,250,0,93,247,0,97,247,0,99,247,1,2,
-  25,247,1,32,25,249,2,33,244
-};
-static afm_cuint16 afm_Helvetica_Bold_highchars_index[] = { /* 220 */
-  161,162,163,164,165,166,167,168,169,170,171,172,174,175,176,177,
-  178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,
-  194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,
-  210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,
-  226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,
-  242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,
-  258,259,260,261,262,263,268,269,270,271,272,273,274,275,278,279,
-  280,281,282,283,286,287,290,291,298,299,302,303,304,305,310,311,
-  313,314,315,316,317,318,321,322,323,324,325,326,327,328,332,333,
-  336,337,338,339,340,341,342,343,344,345,346,347,350,351,352,353,
-  354,355,356,357,362,363,366,367,368,369,370,371,376,377,378,379,
-  380,381,382,402,536,537,710,711,728,729,730,731,732,733,8211,8212,
-  8216,8217,8218,8220,8221,8222,8224,8225,8226,8230,8240,8249,8250,
-  8260,8364,8482,8706,8710,8721,8722,8730,8800,8804,8805,9674,63171,
-  64257,64258
-};
-static afm_cunicode afm_Helvetica_Bold_ligatures[] = { /* 3 */
-  102,105,64257
-};
-
-
-/* ------------------------------------------------------------------*/
-/* FontName: Helvetica-BoldOblique */
-/* FullName: Helvetica Bold Oblique */
-/* FamilyName: Helvetica */
-static afm_cuint8 afm_Helvetica_BoldOblique_widths[] = { /* 315 */
-  46,56,79,93,93,148,120,40,56,56,65,97,46,56,46,46,93,93,93,93,93,
-  93,93,93,93,93,56,56,97,97,97,102,163,120,120,120,120,111,102,130,
-  120,46,93,120,102,139,120,130,111,130,120,111,102,120,111,157,111,
-  111,102,56,46,56,97,93,56,93,102,93,102,93,56,102,102,46,46,93,46,
-  148,102,102,102,102,65,93,56,102,93,130,93,93,83,65,47,65,97,56,
-  93,93,93,93,47,93,56,123,62,93,97,123,56,67,97,56,56,56,102,93,46,
-  56,56,61,93,139,139,139,102,120,120,120,120,120,120,167,120,111,
-  111,111,111,46,46,46,46,120,120,130,130,130,130,130,97,130,120,120,
-  120,120,111,111,102,93,93,93,93,93,93,148,93,93,93,93,93,46,46,46,
-  46,102,102,102,102,102,102,102,97,102,102,102,102,102,93,102,93,
-  120,93,120,93,120,93,120,93,120,93,120,124,120,102,111,93,111,93,
-  111,93,111,93,130,102,130,102,46,46,46,46,46,46,120,93,102,46,102,
-  46,102,67,102,46,120,102,120,102,120,102,130,102,130,102,167,157,
-  120,65,120,65,120,65,111,93,111,93,111,93,102,56,102,65,120,102,
-  120,102,120,102,120,102,111,102,83,102,83,102,83,93,111,93,56,56,
-  56,56,56,56,56,56,93,167,46,46,46,83,83,83,93,93,58,167,167,56,56,
-  28,93,167,82,102,100,97,92,92,92,92,82,42,102,102
-};
-static afm_sint16 afm_Helvetica_BoldOblique_kerning_index[] = { /* 315 */
-  1,0,0,0,0,0,0,0,0,0,0,0,29,0,40,0,0,0,0,0,0,0,0,0,0,0,51,54,0,0,
-  0,0,0,57,172,0,218,0,257,0,0,0,308,358,450,0,0,485,534,627,654,0,
-  716,874,902,1051,0,1199,0,0,0,0,0,0,0,1338,1358,1401,1427,1444,1462,
-  1517,1548,0,0,1556,1577,1587,1617,1649,1663,0,1671,1752,0,0,1755,
-  1803,1828,1851,1921,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-  0,0,0,0,0,0,0,0,0,0,0,0,1944,2059,2174,2289,2404,2519,0,0,0,0,0,
-  0,0,0,0,0,0,0,2634,2683,2732,2781,2830,0,2879,2928,2956,2984,3012,
-  3040,0,0,3179,3199,3219,3239,3259,3279,0,3299,3325,3343,3361,3379,
-  0,0,0,0,0,3397,3429,3443,3457,3471,3485,0,3499,0,0,0,0,3513,0,3583,
-  3653,3768,3788,3903,3923,4038,0,4058,0,4084,4110,0,4149,4188,0,4205,
-  0,4223,0,4241,0,4259,0,4277,0,4308,0,0,0,0,0,0,4339,4431,4452,4487,
-  4497,4532,0,0,4542,4577,0,4587,0,4619,0,4651,4683,4732,4746,4795,
-  0,0,4809,4871,4952,5014,5095,5157,0,5238,0,5241,0,5244,5247,0,5405,
-  0,5563,0,5591,0,5619,0,5647,0,5675,0,5814,0,5837,0,5860,0,0,5883,
-  0,0,0,0,0,0,0,0,0,0,5886,5891,0,0,5942,0,0,0,0,0,0,0,0,0,0,0,0,0,
-  0,0,0,0,0,0,0,0,0,0
-};
-static afm_cuint8 afm_Helvetica_BoldOblique_kerning_data[] = { /* 5945 */
-  42,11,85,240,87,244,88,244,90,237,222,237,0,100,240,0,102,240,0,
-  122,237,1,32,24,247,1,32,28,244,4,33,250,1,32,25,237,1,32,29,237,
-  4,33,250,1,32,25,237,1,32,29,237,2,33,250,2,33,250,49,68,250,72,
-  249,80,250,82,250,85,242,86,249,87,244,88,247,90,239,118,252,119,
-  250,120,252,122,252,200,250,211,250,212,250,213,250,214,250,215,
-  250,217,250,218,249,219,249,220,249,221,249,222,239,250,252,251,
-  252,252,252,253,252,254,252,0,1,252,0,8,250,0,14,250,0,32,249,0,
-  36,249,0,78,250,0,82,250,0,100,242,0,102,242,0,108,249,0,109,252,
-  0,112,249,0,113,252,0,114,249,0,115,252,0,116,249,0,117,252,0,122,
-  239,20,66,252,86,255,193,252,194,252,195,252,196,252,197,252,198,
-  252,218,255,219,255,220,255,221,255,0,2,252,0,4,252,0,6,252,0,108,
-  255,0,112,255,0,114,255,0,116,255,18,45,252,47,252,66,250,87,250,
-  88,250,90,245,193,250,194,250,195,250,196,250,197,250,198,250,222,
-  245,0,2,250,0,4,250,0,6,250,0,122,245,23,45,240,47,240,66,244,98,
-  254,193,244,194,244,195,244,196,244,197,244,198,244,225,254,226,
-  254,227,254,228,254,229,254,230,254,0,2,244,0,3,254,0,4,244,0,5,
-  254,0,6,244,0,7,254,22,45,254,47,254,66,254,118,254,193,254,194,
-  254,195,254,196,254,197,254,198,254,250,254,251,254,252,254,253,
-  254,0,2,254,0,4,254,0,6,254,0,109,254,0,113,254,0,115,254,0,117,
-  254,40,80,252,102,254,112,251,118,252,122,250,211,252,212,252,213,
-  252,214,252,215,252,217,252,233,254,234,254,235,254,236,254,243,
-  251,244,251,245,251,246,251,247,251,249,251,250,252,251,252,252,
-  252,253,252,254,250,0,1,250,0,21,254,0,25,254,0,27,254,0,29,254,
-  0,78,252,0,79,251,0,82,252,0,83,251,0,109,252,0,113,252,0,115,252,
-  0,117,252,14,85,242,87,239,88,244,90,237,122,252,222,237,254,252,
-  0,1,252,0,100,242,0,102,242,0,122,237,1,32,25,234,1,32,29,234,22,
-  45,250,47,250,66,249,85,250,87,249,88,249,89,249,90,245,193,249,
-  194,249,195,249,196,249,197,249,198,249,222,245,0,2,249,0,4,249,
-  0,6,249,0,100,250,0,102,250,0,122,245,41,45,237,47,237,66,240,98,
-  252,102,252,112,250,193,240,194,240,195,240,196,240,197,240,198,
-  240,225,252,226,252,227,252,228,252,229,252,230,252,233,252,234,
-  252,235,252,236,252,243,250,244,250,245,250,246,250,247,250,249,
-  250,0,2,240,0,3,252,0,4,240,0,5,252,0,6,240,0,7,252,0,21,252,0,25,
-  252,0,27,252,0,29,252,0,79,250,0,83,250,12,45,3,47,3,86,255,218,
-  255,219,255,220,255,221,255,0,108,255,0,112,255,0,114,255,0,116,
-  255,27,80,254,85,254,86,254,87,249,88,250,90,249,211,254,212,254,
-  213,254,214,254,215,254,217,254,218,254,219,254,220,254,221,254,
-  222,249,0,78,254,0,82,254,0,100,254,0,102,254,0,108,254,0,112,254,
-  0,114,254,0,116,254,0,122,249,69,45,244,46,237,47,244,59,250,60,
-  250,66,242,80,250,98,244,102,247,112,244,115,244,118,242,120,247,
-  122,247,193,242,194,242,195,242,196,242,197,242,198,242,211,250,
-  212,250,213,250,214,250,215,250,217,250,225,244,226,244,227,244,
-  228,244,229,244,230,244,233,247,234,247,235,247,236,247,243,244,
-  244,244,245,244,246,244,247,244,249,244,250,242,251,242,252,242,
-  253,242,254,247,0,1,247,0,2,242,0,3,244,0,4,242,0,5,244,0,6,242,
-  0,7,244,0,21,247,0,25,247,0,27,247,0,29,247,0,78,250,0,79,244,0,
-  82,250,0,83,244,0,87,244,0,89,244,0,109,242,0,113,242,0,115,242,
-  0,117,242,13,45,252,47,252,66,249,193,249,194,249,195,249,196,249,
-  197,249,198,249,0,2,249,0,4,249,0,6,249,65,45,237,46,244,47,237,
-  59,250,60,250,66,244,72,249,80,249,98,247,102,249,112,242,118,247,
-  193,244,194,244,195,244,196,244,197,244,198,244,211,249,212,249,
-  213,249,214,249,215,249,217,249,225,247,226,247,227,247,228,247,
-  229,247,230,247,233,249,234,249,235,249,236,249,243,242,244,242,
-  245,242,246,242,247,242,249,242,250,247,251,247,252,247,253,247,
-  0,2,244,0,3,247,0,4,244,0,5,247,0,6,244,0,7,247,0,21,249,0,25,249,
-  0,27,249,0,29,249,0,32,249,0,36,249,0,78,249,0,79,242,0,82,249,0,
-  83,242,0,109,247,0,113,247,0,115,247,0,117,247,65,45,244,46,250,
-  47,244,59,255,60,255,66,247,80,254,98,250,102,251,112,247,118,249,
-  122,254,193,247,194,247,195,247,196,247,197,247,198,247,211,254,
-  212,254,213,254,214,254,215,254,217,254,225,250,226,250,227,250,
-  228,250,229,250,230,250,233,251,234,251,235,251,236,251,243,247,
-  244,247,245,247,246,247,247,247,249,247,250,249,251,249,252,249,
-  253,249,254,254,0,1,254,0,2,247,0,3,250,0,4,247,0,5,250,0,6,247,
-  0,7,250,0,21,251,0,25,251,0,27,251,0,29,251,0,78,254,0,79,247,0,
-  82,254,0,83,247,0,109,249,0,113,249,0,115,249,0,117,249,61,45,240,
-  47,240,59,249,60,249,66,239,80,245,98,242,102,244,112,240,118,240,
-  193,239,194,239,195,239,196,239,197,239,198,239,211,245,212,245,
-  213,245,214,245,215,245,217,245,225,242,226,242,227,242,228,242,
-  229,242,230,242,233,244,234,244,235,244,236,244,243,240,244,240,
-  245,240,246,240,247,240,249,240,250,240,251,240,252,240,253,240,
-  0,2,239,0,3,242,0,4,239,0,5,242,0,6,239,0,7,242,0,21,244,0,25,244,
-  0,27,244,0,29,244,0,78,245,0,79,240,0,82,245,0,83,240,0,109,240,
-  0,113,240,0,115,240,0,117,240,9,104,255,119,254,120,254,122,254,
-  254,254,0,1,254,0,33,255,0,37,255,18,109,255,118,254,119,254,122,
-  254,250,254,251,254,252,254,253,254,254,254,0,1,254,0,60,255,0,62,
-  255,0,68,255,0,109,254,0,113,254,0,115,254,0,117,254,11,105,255,
-  108,254,109,254,122,255,254,255,0,1,255,0,57,254,0,60,254,0,62,254,
-  0,68,254,8,101,255,119,254,120,254,122,254,254,254,0,1,254,0,19,
-  255,9,45,2,47,3,119,254,120,254,121,254,122,254,254,254,0,1,254,
-  23,45,255,47,255,102,255,112,254,233,255,234,255,235,255,236,255,
-  243,254,244,254,245,254,246,254,247,254,249,254,0,21,255,0,25,255,
-  0,27,255,0,29,255,0,79,254,0,83,254,1,32,25,5,1,32,29,5,13,102,2,
-  104,255,233,2,234,2,235,2,236,2,0,21,2,0,25,2,0,27,2,0,29,2,0,33,
-  255,0,37,255,4,122,254,254,254,0,1,254,10,112,254,243,254,244,254,
-  245,254,246,254,247,254,249,254,0,79,254,0,83,254,5,120,254,122,
-  254,254,254,0,1,254,13,118,254,122,252,250,254,251,254,252,254,253,
-  254,254,252,0,1,252,0,109,254,0,113,254,0,115,254,0,117,254,14,118,
-  255,119,250,122,254,250,255,251,255,252,255,253,255,254,254,0,1,
-  254,0,109,255,0,113,255,0,115,255,0,117,255,7,119,254,120,254,121,
-  252,122,254,254,254,0,1,254,4,122,254,254,254,0,1,254,34,45,247,
-  46,254,47,247,100,254,101,254,104,254,112,254,114,254,116,254,117,
-  3,119,2,122,2,232,254,243,254,244,254,245,254,246,254,247,254,249,
-  254,254,2,0,1,2,0,9,254,0,15,254,0,19,254,0,33,254,0,37,254,0,79,
-  254,0,83,254,0,93,254,0,97,254,0,99,254,0,101,3,1,2,25,254,2,120,
-  254,22,45,244,47,244,98,254,112,252,225,254,226,254,227,254,228,
-  254,229,254,230,254,243,252,244,252,245,252,246,252,247,252,249,
-  252,0,3,254,0,5,254,0,7,254,0,79,252,0,83,252,12,45,250,47,250,112,
-  254,243,254,244,254,245,254,246,254,247,254,249,254,0,79,254,0,83,
-  254,10,102,255,233,255,234,255,235,255,236,255,0,21,255,0,25,255,
-  0,27,255,0,29,255,31,45,244,47,244,98,252,102,255,112,253,225,252,
-  226,252,227,252,228,252,229,252,230,252,233,255,234,255,235,255,
-  236,255,243,253,244,253,245,253,246,253,247,253,249,253,0,3,252,
-  0,5,252,0,7,252,0,21,255,0,25,255,0,27,255,0,29,255,0,79,253,0,83,
-  253,10,102,2,233,2,234,2,235,2,236,2,0,21,2,0,25,2,0,27,2,0,29,2,
-  49,68,250,72,249,80,250,82,250,85,242,86,249,87,244,88,247,90,239,
-  118,252,119,250,120,252,122,252,200,250,211,250,212,250,213,250,
-  214,250,215,250,217,250,218,249,219,249,220,249,221,249,222,239,
-  250,252,251,252,252,252,253,252,254,252,0,1,252,0,8,250,0,14,250,
-  0,32,249,0,36,249,0,78,250,0,82,250,0,100,242,0,102,242,0,108,249,
-  0,109,252,0,112,249,0,113,252,0,114,249,0,115,252,0,116,249,0,117,
-  252,0,122,239,49,68,250,72,249,80,250,82,250,85,242,86,249,87,244,
-  88,247,90,239,118,252,119,250,120,252,122,252,200,250,211,250,212,
-  250,213,250,214,250,215,250,217,250,218,249,219,249,220,249,221,
-  249,222,239,250,252,251,252,252,252,253,252,254,252,0,1,252,0,8,
-  250,0,14,250,0,32,249,0,36,249,0,78,250,0,82,250,0,100,242,0,102,
-  242,0,108,249,0,109,252,0,112,249,0,113,252,0,114,249,0,115,252,
-  0,116,249,0,117,252,0,122,239,49,68,250,72,249,80,250,82,250,85,
-  242,86,249,87,244,88,247,90,239,118,252,119,250,120,252,122,252,
-  200,250,211,250,212,250,213,250,214,250,215,250,217,250,218,249,
-  219,249,220,249,221,249,222,239,250,252,251,252,252,252,253,252,
-  254,252,0,1,252,0,8,250,0,14,250,0,32,249,0,36,249,0,78,250,0,82,
-  250,0,100,242,0,102,242,0,108,249,0,109,252,0,112,249,0,113,252,
-  0,114,249,0,115,252,0,116,249,0,117,252,0,122,239,49,68,250,72,249,
-  80,250,82,250,85,242,86,249,87,244,88,247,90,239,118,252,119,250,
-  120,252,122,252,200,250,211,250,212,250,213,250,214,250,215,250,
-  217,250,218,249,219,249,220,249,221,249,222,239,250,252,251,252,
-  252,252,253,252,254,252,0,1,252,0,8,250,0,14,250,0,32,249,0,36,249,
-  0,78,250,0,82,250,0,100,242,0,102,242,0,108,249,0,109,252,0,112,
-  249,0,113,252,0,114,249,0,115,252,0,116,249,0,117,252,0,122,239,
-  49,68,250,72,249,80,250,82,250,85,242,86,249,87,244,88,247,90,239,
-  118,252,119,250,120,252,122,252,200,250,211,250,212,250,213,250,
-  214,250,215,250,217,250,218,249,219,249,220,249,221,249,222,239,
-  250,252,251,252,252,252,253,252,254,252,0,1,252,0,8,250,0,14,250,
-  0,32,249,0,36,249,0,78,250,0,82,250,0,100,242,0,102,242,0,108,249,
-  0,109,252,0,112,249,0,113,252,0,114,249,0,115,252,0,116,249,0,117,
-  252,0,122,239,49,68,250,72,249,80,250,82,250,85,242,86,249,87,244,
-  88,247,90,239,118,252,119,250,120,252,122,252,200,250,211,250,212,
-  250,213,250,214,250,215,250,217,250,218,249,219,249,220,249,221,
-  249,222,239,250,252,251,252,252,252,253,252,254,252,0,1,252,0,8,
-  250,0,14,250,0,32,249,0,36,249,0,78,250,0,82,250,0,100,242,0,102,
-  242,0,108,249,0,109,252,0,112,249,0,113,252,0,114,249,0,115,252,
-  0,116,249,0,117,252,0,122,239,22,45,250,47,250,66,249,85,250,87,
-  249,88,249,89,249,90,245,193,249,194,249,195,249,196,249,197,249,
-  198,249,222,245,0,2,249,0,4,249,0,6,249,0,100,250,0,102,250,0,122,
-  245,22,45,250,47,250,66,249,85,250,87,249,88,249,89,249,90,245,193,
-  249,194,249,195,249,196,249,197,249,198,249,222,245,0,2,249,0,4,
-  249,0,6,249,0,100,250,0,102,250,0,122,245,22,45,250,47,250,66,249,
-  85,250,87,249,88,249,89,249,90,245,193,249,194,249,195,249,196,249,
-  197,249,198,249,222,245,0,2,249,0,4,249,0,6,249,0,100,250,0,102,
-  250,0,122,245,22,45,250,47,250,66,249,85,250,87,249,88,249,89,249,
-  90,245,193,249,194,249,195,249,196,249,197,249,198,249,222,245,0,
-  2,249,0,4,249,0,6,249,0,100,250,0,102,250,0,122,245,22,45,250,47,
-  250,66,249,85,250,87,249,88,249,89,249,90,245,193,249,194,249,195,
-  249,196,249,197,249,198,249,222,245,0,2,249,0,4,249,0,6,249,0,100,
-  250,0,102,250,0,122,245,22,45,250,47,250,66,249,85,250,87,249,88,
-  249,89,249,90,245,193,249,194,249,195,249,196,249,197,249,198,249,
-  222,245,0,2,249,0,4,249,0,6,249,0,100,250,0,102,250,0,122,245,13,
-  45,252,47,252,66,249,193,249,194,249,195,249,196,249,197,249,198,
-  249,0,2,249,0,4,249,0,6,249,13,45,252,47,252,66,249,193,249,194,
-  249,195,249,196,249,197,249,198,249,0,2,249,0,4,249,0,6,249,13,45,
-  252,47,252,66,249,193,249,194,249,195,249,196,249,197,249,198,249,
-  0,2,249,0,4,249,0,6,249,13,45,252,47,252,66,249,193,249,194,249,
-  195,249,196,249,197,249,198,249,0,2,249,0,4,249,0,6,249,61,45,240,
-  47,240,59,249,60,249,66,239,80,245,98,242,102,244,112,240,118,240,
-  193,239,194,239,195,239,196,239,197,239,198,239,211,245,212,245,
-  213,245,214,245,215,245,217,245,225,242,226,242,227,242,228,242,
-  229,242,230,242,233,244,234,244,235,244,236,244,243,240,244,240,
-  245,240,246,240,247,240,249,240,250,240,251,240,252,240,253,240,
-  0,2,239,0,3,242,0,4,239,0,5,242,0,6,239,0,7,242,0,21,244,0,25,244,
-  0,27,244,0,29,244,0,78,245,0,79,240,0,82,245,0,83,240,0,109,240,
-  0,113,240,0,115,240,0,117,240,9,104,255,119,254,120,254,122,254,
-  254,254,0,1,254,0,33,255,0,37,255,9,104,255,119,254,120,254,122,
-  254,254,254,0,1,254,0,33,255,0,37,255,9,104,255,119,254,120,254,
-  122,254,254,254,0,1,254,0,33,255,0,37,255,9,104,255,119,254,120,
-  254,122,254,254,254,0,1,254,0,33,255,0,37,255,9,104,255,119,254,
-  120,254,122,254,254,254,0,1,254,0,33,255,0,37,255,9,104,255,119,
-  254,120,254,122,254,254,254,0,1,254,0,33,255,0,37,255,11,105,255,
-  108,254,109,254,122,255,254,255,0,1,255,0,57,254,0,60,254,0,62,254,
-  0,68,254,9,45,2,47,3,119,254,120,254,121,254,122,254,254,254,0,1,
-  254,9,45,2,47,3,119,254,120,254,121,254,122,254,254,254,0,1,254,
-  9,45,2,47,3,119,254,120,254,121,254,122,254,254,254,0,1,254,9,45,
-  2,47,3,119,254,120,254,121,254,122,254,254,254,0,1,254,14,118,255,
-  119,250,122,254,250,255,251,255,252,255,253,255,254,254,0,1,254,
-  0,109,255,0,113,255,0,115,255,0,117,255,7,119,254,120,254,121,252,
-  122,254,254,254,0,1,254,7,119,254,120,254,121,252,122,254,254,254,
-  0,1,254,7,119,254,120,254,121,252,122,254,254,254,0,1,254,7,119,
-  254,120,254,121,252,122,254,254,254,0,1,254,7,119,254,120,254,121,
-  252,122,254,254,254,0,1,254,7,119,254,120,254,121,252,122,254,254,
-  254,0,1,254,31,45,244,47,244,98,252,102,255,112,253,225,252,226,
-  252,227,252,228,252,229,252,230,252,233,255,234,255,235,255,236,
-  255,243,253,244,253,245,253,246,253,247,253,249,253,0,3,252,0,5,
-  252,0,7,252,0,21,255,0,25,255,0,27,255,0,29,255,0,79,253,0,83,253,
-  31,45,244,47,244,98,252,102,255,112,253,225,252,226,252,227,252,
-  228,252,229,252,230,252,233,255,234,255,235,255,236,255,243,253,
-  244,253,245,253,246,253,247,253,249,253,0,3,252,0,5,252,0,7,252,
-  0,21,255,0,25,255,0,27,255,0,29,255,0,79,253,0,83,253,49,68,250,
-  72,249,80,250,82,250,85,242,86,249,87,244,88,247,90,239,118,252,
-  119,250,120,252,122,252,200,250,211,250,212,250,213,250,214,250,
-  215,250,217,250,218,249,219,249,220,249,221,249,222,239,250,252,
-  251,252,252,252,253,252,254,252,0,1,252,0,8,250,0,14,250,0,32,249,
-  0,36,249,0,78,250,0,82,250,0,100,242,0,102,242,0,108,249,0,109,252,
-  0,112,249,0,113,252,0,114,249,0,115,252,0,116,249,0,117,252,0,122,
-  239,9,104,255,119,254,120,254,122,254,254,254,0,1,254,0,33,255,0,
-  37,255,49,68,250,72,249,80,250,82,250,85,242,86,249,87,244,88,247,
-  90,239,118,252,119,250,120,252,122,252,200,250,211,250,212,250,213,
-  250,214,250,215,250,217,250,218,249,219,249,220,249,221,249,222,
-  239,250,252,251,252,252,252,253,252,254,252,0,1,252,0,8,250,0,14,
-  250,0,32,249,0,36,249,0,78,250,0,82,250,0,100,242,0,102,242,0,108,
-  249,0,109,252,0,112,249,0,113,252,0,114,249,0,115,252,0,116,249,
-  0,117,252,0,122,239,9,104,255,119,254,120,254,122,254,254,254,0,
-  1,254,0,33,255,0,37,255,49,68,250,72,249,80,250,82,250,85,242,86,
-  249,87,244,88,247,90,239,118,252,119,250,120,252,122,252,200,250,
-  211,250,212,250,213,250,214,250,215,250,217,250,218,249,219,249,
-  220,249,221,249,222,239,250,252,251,252,252,252,253,252,254,252,
-  0,1,252,0,8,250,0,14,250,0,32,249,0,36,249,0,78,250,0,82,250,0,100,
-  242,0,102,242,0,108,249,0,109,252,0,112,249,0,113,252,0,114,249,
-  0,115,252,0,116,249,0,117,252,0,122,239,9,104,255,119,254,120,254,
-  122,254,254,254,0,1,254,0,33,255,0,37,255,11,105,255,108,254,109,
-  254,122,255,254,255,0,1,255,0,57,254,0,60,254,0,62,254,0,68,254,
-  11,105,255,108,254,109,254,122,255,254,255,0,1,255,0,57,254,0,60,
-  254,0,62,254,0,68,254,18,45,252,47,252,66,250,87,250,88,250,90,245,
-  193,250,194,250,195,250,196,250,197,250,198,250,222,245,0,2,250,
-  0,4,250,0,6,250,0,122,245,18,45,252,47,252,66,250,87,250,88,250,
-  90,245,193,250,194,250,195,250,196,250,197,250,198,250,222,245,0,
-  2,250,0,4,250,0,6,250,0,122,245,8,101,255,119,254,120,254,122,254,
-  254,254,0,1,254,0,19,255,9,45,2,47,3,119,254,120,254,121,254,122,
-  254,254,254,0,1,254,9,45,2,47,3,119,254,120,254,121,254,122,254,
-  254,254,0,1,254,9,45,2,47,3,119,254,120,254,121,254,122,254,254,
-  254,0,1,254,9,45,2,47,3,119,254,120,254,121,254,122,254,254,254,
-  0,1,254,13,102,2,104,255,233,2,234,2,235,2,236,2,0,21,2,0,25,2,0,
-  27,2,0,29,2,0,33,255,0,37,255,13,102,2,104,255,233,2,234,2,235,2,
-  236,2,0,21,2,0,25,2,0,27,2,0,29,2,0,33,255,0,37,255,40,80,252,102,
-  254,112,251,118,252,122,250,211,252,212,252,213,252,214,252,215,
-  252,217,252,233,254,234,254,235,254,236,254,243,251,244,251,245,
-  251,246,251,247,251,249,251,250,252,251,252,252,252,253,252,254,
-  250,0,1,250,0,21,254,0,25,254,0,27,254,0,29,254,0,78,252,0,79,251,
-  0,82,252,0,83,251,0,109,252,0,113,252,0,115,252,0,117,252,10,112,
-  254,243,254,244,254,245,254,246,254,247,254,249,254,0,79,254,0,83,
-  254,14,85,242,87,239,88,244,90,237,122,252,222,237,254,252,0,1,252,
-  0,100,242,0,102,242,0,122,237,1,32,25,234,1,32,29,234,5,120,254,
-  122,254,254,254,0,1,254,14,85,242,87,239,88,244,90,237,122,252,222,
-  237,254,252,0,1,252,0,100,242,0,102,242,0,122,237,1,32,25,234,1,
-  32,29,234,5,120,254,122,254,254,254,0,1,254,14,85,242,87,239,88,
-  244,90,237,122,252,222,237,254,252,0,1,252,0,100,242,0,102,242,0,
-  122,237,1,32,25,234,1,32,29,234,5,120,254,122,254,254,254,0,1,254,
-  14,118,255,119,250,122,254,250,255,251,255,252,255,253,255,254,254,
-  0,1,254,0,109,255,0,113,255,0,115,255,0,117,255,14,118,255,119,250,
-  122,254,250,255,251,255,252,255,253,255,254,254,0,1,254,0,109,255,
-  0,113,255,0,115,255,0,117,255,14,118,255,119,250,122,254,250,255,
-  251,255,252,255,253,255,254,254,0,1,254,0,109,255,0,113,255,0,115,
-  255,0,117,255,22,45,250,47,250,66,249,85,250,87,249,88,249,89,249,
-  90,245,193,249,194,249,195,249,196,249,197,249,198,249,222,245,0,
-  2,249,0,4,249,0,6,249,0,100,250,0,102,250,0,122,245,7,119,254,120,
-  254,121,252,122,254,254,254,0,1,254,22,45,250,47,250,66,249,85,250,
-  87,249,88,249,89,249,90,245,193,249,194,249,195,249,196,249,197,
-  249,198,249,222,245,0,2,249,0,4,249,0,6,249,0,100,250,0,102,250,
-  0,122,245,7,119,254,120,254,121,252,122,254,254,254,0,1,254,27,80,
-  254,85,254,86,254,87,249,88,250,90,249,211,254,212,254,213,254,214,
-  254,215,254,217,254,218,254,219,254,220,254,221,254,222,249,0,78,
-  254,0,82,254,0,100,254,0,102,254,0,108,254,0,112,254,0,114,254,0,
-  116,254,0,122,249,34,45,247,46,254,47,247,100,254,101,254,104,254,
-  112,254,114,254,116,254,117,3,119,2,122,2,232,254,243,254,244,254,
-  245,254,246,254,247,254,249,254,254,2,0,1,2,0,9,254,0,15,254,0,19,
-  254,0,33,254,0,37,254,0,79,254,0,83,254,0,93,254,0,97,254,0,99,254,
-  0,101,3,1,2,25,254,27,80,254,85,254,86,254,87,249,88,250,90,249,
-  211,254,212,254,213,254,214,254,215,254,217,254,218,254,219,254,
-  220,254,221,254,222,249,0,78,254,0,82,254,0,100,254,0,102,254,0,
-  108,254,0,112,254,0,114,254,0,116,254,0,122,249,34,45,247,46,254,
-  47,247,100,254,101,254,104,254,112,254,114,254,116,254,117,3,119,
-  2,122,2,232,254,243,254,244,254,245,254,246,254,247,254,249,254,
-  254,2,0,1,2,0,9,254,0,15,254,0,19,254,0,33,254,0,37,254,0,79,254,
-  0,83,254,0,93,254,0,97,254,0,99,254,0,101,3,1,2,25,254,27,80,254,
-  85,254,86,254,87,249,88,250,90,249,211,254,212,254,213,254,214,254,
-  215,254,217,254,218,254,219,254,220,254,221,254,222,249,0,78,254,
-  0,82,254,0,100,254,0,102,254,0,108,254,0,112,254,0,114,254,0,116,
-  254,0,122,249,34,45,247,46,254,47,247,100,254,101,254,104,254,112,
-  254,114,254,116,254,117,3,119,2,122,2,232,254,243,254,244,254,245,
-  254,246,254,247,254,249,254,254,2,0,1,2,0,9,254,0,15,254,0,19,254,
-  0,33,254,0,37,254,0,79,254,0,83,254,0,93,254,0,97,254,0,99,254,0,
-  101,3,1,2,25,254,2,120,254,2,120,254,2,120,254,69,45,244,46,237,
-  47,244,59,250,60,250,66,242,80,250,98,244,102,247,112,244,115,244,
-  118,242,120,247,122,247,193,242,194,242,195,242,196,242,197,242,
-  198,242,211,250,212,250,213,250,214,250,215,250,217,250,225,244,
-  226,244,227,244,228,244,229,244,230,244,233,247,234,247,235,247,
-  236,247,243,244,244,244,245,244,246,244,247,244,249,244,250,242,
-  251,242,252,242,253,242,254,247,0,1,247,0,2,242,0,3,244,0,4,242,
-  0,5,244,0,6,242,0,7,244,0,21,247,0,25,247,0,27,247,0,29,247,0,78,
-  250,0,79,244,0,82,250,0,83,244,0,87,244,0,89,244,0,109,242,0,113,
-  242,0,115,242,0,117,242,69,45,244,46,237,47,244,59,250,60,250,66,
-  242,80,250,98,244,102,247,112,244,115,244,118,242,120,247,122,247,
-  193,242,194,242,195,242,196,242,197,242,198,242,211,250,212,250,
-  213,250,214,250,215,250,217,250,225,244,226,244,227,244,228,244,
-  229,244,230,244,233,247,234,247,235,247,236,247,243,244,244,244,
-  245,244,246,244,247,244,249,244,250,242,251,242,252,242,253,242,
-  254,247,0,1,247,0,2,242,0,3,244,0,4,242,0,5,244,0,6,242,0,7,244,
-  0,21,247,0,25,247,0,27,247,0,29,247,0,78,250,0,79,244,0,82,250,0,
-  83,244,0,87,244,0,89,244,0,109,242,0,113,242,0,115,242,0,117,242,
-  13,45,252,47,252,66,249,193,249,194,249,195,249,196,249,197,249,
-  198,249,0,2,249,0,4,249,0,6,249,13,45,252,47,252,66,249,193,249,
-  194,249,195,249,196,249,197,249,198,249,0,2,249,0,4,249,0,6,249,
-  13,45,252,47,252,66,249,193,249,194,249,195,249,196,249,197,249,
-  198,249,0,2,249,0,4,249,0,6,249,13,45,252,47,252,66,249,193,249,
-  194,249,195,249,196,249,197,249,198,249,0,2,249,0,4,249,0,6,249,
-  61,45,240,47,240,59,249,60,249,66,239,80,245,98,242,102,244,112,
-  240,118,240,193,239,194,239,195,239,196,239,197,239,198,239,211,
-  245,212,245,213,245,214,245,215,245,217,245,225,242,226,242,227,
-  242,228,242,229,242,230,242,233,244,234,244,235,244,236,244,243,
-  240,244,240,245,240,246,240,247,240,249,240,250,240,251,240,252,
-  240,253,240,0,2,239,0,3,242,0,4,239,0,5,242,0,6,239,0,7,242,0,21,
-  244,0,25,244,0,27,244,0,29,244,0,78,245,0,79,240,0,82,245,0,83,240,
-  0,109,240,0,113,240,0,115,240,0,117,240,10,102,2,233,2,234,2,235,
-  2,236,2,0,21,2,0,25,2,0,27,2,0,29,2,10,102,2,233,2,234,2,235,2,236,
-  2,0,21,2,0,25,2,0,27,2,0,29,2,10,102,2,233,2,234,2,235,2,236,2,0,
-  21,2,0,25,2,0,27,2,0,29,2,2,120,254,2,1,32,24,249,19,33,244,101,
-  244,109,254,115,250,116,247,119,254,0,19,244,0,60,254,0,62,254,0,
-  68,254,0,87,250,0,89,250,0,91,250,0,93,247,0,97,247,0,99,247,1,2,
-  25,247,1,32,25,249,2,33,244
-};
-static afm_cuint16 afm_Helvetica_BoldOblique_highchars_index[] = { /* 220 */
-  161,162,163,164,165,166,167,168,169,170,171,172,174,175,176,177,
-  178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,
-  194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,
-  210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,
-  226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,
-  242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,
-  258,259,260,261,262,263,268,269,270,271,272,273,274,275,278,279,
-  280,281,282,283,286,287,290,291,298,299,302,303,304,305,310,311,
-  313,314,315,316,317,318,321,322,323,324,325,326,327,328,332,333,
-  336,337,338,339,340,341,342,343,344,345,346,347,350,351,352,353,
-  354,355,356,357,362,363,366,367,368,369,370,371,376,377,378,379,
-  380,381,382,402,536,537,710,711,728,729,730,731,732,733,8211,8212,
-  8216,8217,8218,8220,8221,8222,8224,8225,8226,8230,8240,8249,8250,
-  8260,8364,8482,8706,8710,8721,8722,8730,8800,8804,8805,9674,63171,
-  64257,64258
-};
-static afm_cunicode afm_Helvetica_BoldOblique_ligatures[] = { /* 3 */
-  102,105,64257
-};
-
-
-/* ------------------------------------------------------------------*/
-/* FontName: Helvetica-Oblique */
-/* FullName: Helvetica Oblique */
-/* FamilyName: Helvetica */
-static afm_cuint8 afm_Helvetica_Oblique_widths[] = { /* 315 */
-  46,46,59,93,93,148,111,32,56,56,65,97,46,56,46,46,93,93,93,93,93,
-  93,93,93,93,93,46,46,97,97,97,93,169,111,111,120,120,111,102,130,
-  120,46,83,111,93,139,120,130,111,130,120,111,102,120,111,157,111,
-  111,102,46,46,46,78,93,56,93,93,83,93,93,46,93,93,37,37,83,37,139,
-  93,93,93,93,56,83,46,93,83,120,83,83,83,56,43,56,97,56,93,93,93,
-  93,43,93,56,123,62,93,97,123,56,67,97,56,56,56,93,90,46,56,56,61,
-  93,139,139,139,102,111,111,111,111,111,111,167,120,111,111,111,111,
-  46,46,46,46,120,120,130,130,130,130,130,97,130,120,120,120,120,111,
-  111,102,93,93,93,93,93,93,148,83,93,93,93,93,46,46,46,46,93,93,93,
-  93,93,93,93,97,102,93,93,93,93,83,93,83,111,93,111,93,111,93,120,
-  83,120,83,120,107,120,93,111,93,111,93,111,93,111,93,130,93,130,
-  93,46,46,46,37,46,46,111,83,93,37,93,37,93,50,93,37,120,93,120,93,
-  120,93,130,93,130,93,167,157,120,56,120,56,120,56,111,83,111,83,
-  111,83,102,46,102,53,120,93,120,93,120,93,120,93,111,102,83,102,
-  83,102,83,93,111,83,56,56,56,56,56,56,56,56,93,167,37,37,37,56,56,
-  56,93,93,58,167,167,56,56,28,93,167,79,102,100,97,76,92,92,92,79,
-  42,83,83
-};
-static afm_sint16 afm_Helvetica_Oblique_kerning_index[] = { /* 315 */
-  1,0,0,0,0,0,0,0,0,0,0,0,29,0,38,0,0,0,0,0,0,0,0,0,0,0,49,52,0,0,
-  0,0,0,55,170,197,202,0,241,0,0,0,345,418,510,0,0,545,594,687,710,
-  772,777,938,966,1115,0,1259,0,0,0,0,0,0,0,1407,1419,1468,0,1476,
-  1494,1575,1587,0,0,1595,0,1638,1668,1700,1718,0,1730,1847,0,0,1854,
-  1924,1994,2017,2087,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-  0,0,0,0,0,0,0,0,0,0,0,0,2130,2245,2360,2475,2590,2705,0,2820,0,0,
-  0,0,0,0,0,0,0,0,2825,2874,2923,2972,3021,0,3070,3119,3147,3175,3203,
-  3231,0,0,3379,3391,3403,3415,3427,3439,0,3451,3459,3477,3495,3513,
-  0,0,0,0,0,3531,3563,3581,3599,3617,3635,0,3653,0,0,0,0,3882,0,3952,
-  4022,4137,4149,4264,4276,4391,4403,4408,4416,4421,4429,0,4468,0,
-  0,4507,0,4525,0,4543,0,4561,0,4579,0,4591,0,0,0,0,0,0,4603,4695,
-  4738,0,4773,0,4808,0,4843,0,0,4878,0,4910,0,4942,4974,5023,5041,
-  5090,0,0,5108,5170,5287,5349,5466,5528,5645,5650,5657,5662,5669,
-  5674,5681,0,5842,0,6003,0,6031,0,6059,0,6087,0,6115,0,6263,0,6306,
-  0,6349,0,6392,6397,0,0,0,0,0,0,0,0,0,0,6404,6409,0,0,6447,0,0,0,
-  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
-};
-static afm_cuint8 afm_Helvetica_Oblique_kerning_data[] = { /* 6450 */
-  42,11,85,249,87,249,88,250,90,242,222,242,0,100,249,0,102,249,0,
-  122,242,1,32,24,247,1,32,28,252,3,1,32,25,240,1,32,29,240,4,33,247,
-  1,32,25,240,1,32,29,240,2,33,249,2,33,249,49,68,252,72,252,80,252,
-  82,252,85,237,86,249,87,245,88,249,90,240,118,252,119,250,120,250,
-  122,250,200,252,211,252,212,252,213,252,214,252,215,252,217,252,
-  218,249,219,249,220,249,221,249,222,240,250,252,251,252,252,252,
-  253,252,254,250,0,1,250,0,8,252,0,14,252,0,32,252,0,36,252,0,78,
-  252,0,82,252,0,100,237,0,102,237,0,108,249,0,109,252,0,112,249,0,
-  113,252,0,114,249,0,115,252,0,116,249,0,117,252,0,122,240,12,45,
-  254,47,254,86,255,218,255,219,255,220,255,221,255,0,108,255,0,112,
-  255,0,114,255,0,116,255,3,45,252,47,252,18,45,245,47,245,66,250,
-  87,245,88,250,90,242,193,250,194,250,195,250,196,250,197,250,198,
-  250,222,242,0,2,250,0,4,250,0,6,250,0,122,242,45,45,232,47,232,66,
-  244,98,249,102,252,112,252,115,249,193,244,194,244,195,244,196,244,
-  197,244,198,244,225,249,226,249,227,249,228,249,229,249,230,249,
-  233,252,234,252,235,252,236,252,243,252,244,252,245,252,246,252,
-  247,252,249,252,0,2,244,0,3,249,0,4,244,0,5,249,0,6,244,0,7,249,
-  0,21,252,0,25,252,0,27,252,0,29,252,0,79,252,0,83,252,0,87,249,0,
-  89,249,0,91,249,32,45,252,47,252,66,254,98,254,118,254,193,254,194,
-  254,195,254,196,254,197,254,198,254,225,254,226,254,227,254,228,
-  254,229,254,230,254,250,254,251,254,252,254,253,254,0,2,254,0,3,
-  254,0,4,254,0,5,254,0,6,254,0,7,254,0,109,254,0,113,254,0,115,254,
-  0,117,254,40,80,249,102,250,112,250,118,252,122,249,211,249,212,
-  249,213,249,214,249,215,249,217,249,233,250,234,250,235,250,236,
-  250,243,250,244,250,245,250,246,250,247,250,249,250,250,252,251,
-  252,252,252,253,252,254,249,0,1,249,0,21,250,0,25,250,0,27,250,0,
-  29,250,0,78,249,0,79,250,0,82,249,0,83,250,0,109,252,0,113,252,0,
-  115,252,0,117,252,14,85,239,87,239,88,245,90,234,122,252,222,234,
-  254,252,0,1,252,0,100,239,0,102,239,0,122,234,1,32,25,230,1,32,29,
-  234,22,45,250,47,250,66,254,85,250,87,249,88,252,89,247,90,245,193,
-  254,194,254,195,254,196,254,197,254,198,254,222,245,0,2,254,0,4,
-  254,0,6,254,0,100,250,0,102,250,0,122,245,41,45,227,47,227,66,237,
-  98,250,102,249,112,249,193,237,194,237,195,237,196,237,197,237,198,
-  237,225,250,226,250,227,250,228,250,229,250,230,250,233,249,234,
-  249,235,249,236,249,243,249,244,249,245,249,246,249,247,249,249,
-  249,0,2,237,0,3,250,0,4,237,0,5,250,0,6,237,0,7,250,0,21,249,0,25,
-  249,0,27,249,0,29,249,0,79,249,0,83,249,10,86,255,218,255,219,255,
-  220,255,221,255,0,108,255,0,112,255,0,114,255,0,116,255,27,80,254,
-  85,252,86,250,87,249,88,252,90,249,211,254,212,254,213,254,214,254,
-  215,254,217,254,218,250,219,250,220,250,221,250,222,249,0,78,254,
-  0,82,254,0,100,252,0,102,252,0,108,250,0,112,250,0,114,250,0,116,
-  250,0,122,249,3,45,254,47,254,70,45,237,46,234,47,237,59,254,60,
-  254,66,237,80,250,98,237,102,237,112,237,115,237,118,237,120,237,
-  122,237,193,237,194,237,195,237,196,237,197,237,198,237,211,250,
-  212,250,213,250,214,250,215,250,217,250,225,237,226,237,227,237,
-  228,247,229,237,230,237,233,247,234,237,235,237,236,237,243,237,
-  244,237,245,237,246,247,247,237,249,237,250,237,251,237,252,237,
-  253,237,254,237,0,1,247,0,2,237,0,3,247,0,4,237,0,5,247,0,6,237,
-  0,7,237,0,21,247,0,25,237,0,27,237,0,29,237,0,78,250,0,79,247,0,
-  82,250,0,83,237,0,87,237,0,89,237,0,91,237,0,109,247,0,113,237,0,
-  115,237,0,117,237,13,45,250,47,250,66,250,193,250,194,250,195,250,
-  196,250,197,250,198,250,0,2,250,0,4,250,0,6,250,65,45,236,46,244,
-  47,236,59,250,60,250,66,244,72,250,80,250,98,245,102,244,112,244,
-  118,245,193,244,194,244,195,244,196,244,197,244,198,244,211,250,
-  212,250,213,250,214,250,215,250,217,250,225,245,226,245,227,245,
-  228,245,229,245,230,245,233,244,234,244,235,244,236,244,243,244,
-  244,244,245,244,246,244,247,244,249,244,250,245,251,245,252,245,
-  253,245,0,2,244,0,3,245,0,4,244,0,5,245,0,6,244,0,7,245,0,21,244,
-  0,25,244,0,27,244,0,29,244,0,32,250,0,36,250,0,78,250,0,79,244,0,
-  82,250,0,83,244,0,109,245,0,113,245,0,115,245,0,117,245,63,45,244,
-  46,250,47,244,66,249,80,254,98,250,102,252,112,252,118,252,122,254,
-  193,249,194,249,195,249,196,249,197,249,198,249,211,254,212,254,
-  213,254,214,254,215,254,217,254,225,250,226,250,227,250,228,250,
-  229,250,230,250,233,252,234,252,235,252,236,252,243,252,244,252,
-  245,252,246,252,247,252,249,252,250,252,251,252,252,252,253,252,
-  254,254,0,1,254,0,2,249,0,3,250,0,4,249,0,5,250,0,6,249,0,7,250,
-  0,21,252,0,25,252,0,27,252,0,29,252,0,78,254,0,79,252,0,82,254,0,
-  83,252,0,109,252,0,113,252,0,115,252,0,117,252,65,45,234,46,234,
-  47,234,59,247,60,247,66,239,80,243,98,234,102,234,106,254,112,234,
-  118,239,193,239,194,239,195,239,196,239,197,239,198,239,211,243,
-  212,243,213,243,214,243,215,243,217,243,225,234,226,234,227,234,
-  228,234,229,234,230,234,233,234,234,234,235,234,236,234,238,254,
-  243,234,244,234,245,234,246,234,247,234,249,234,250,239,251,239,
-  252,239,253,239,0,2,239,0,3,245,0,4,239,0,5,245,0,6,239,0,7,234,
-  0,21,245,0,25,234,0,27,234,0,29,234,0,49,254,0,78,243,0,79,234,0,
-  82,243,0,83,234,0,109,239,0,113,239,0,115,239,0,117,239,6,119,254,
-  120,254,122,252,254,252,0,1,252,21,45,250,47,250,99,255,109,254,
-  118,254,119,254,122,254,250,254,251,254,252,254,253,254,254,254,
-  0,1,254,0,60,254,0,62,254,0,68,254,0,109,254,0,113,254,0,115,254,
-  0,117,254,4,45,254,108,254,0,57,254,9,45,254,47,254,119,252,120,
-  254,121,252,122,254,254,254,0,1,254,34,45,252,47,252,98,252,102,
-  252,112,252,225,252,226,252,227,252,228,252,229,252,230,252,233,
-  252,234,252,235,252,236,252,243,252,244,252,245,252,246,252,247,
-  252,249,252,0,3,252,0,5,252,0,7,252,0,21,252,0,25,252,0,27,252,0,
-  29,252,0,51,252,0,79,252,0,83,252,1,32,25,8,1,32,29,10,5,115,255,
-  0,87,255,0,89,255,0,91,255,4,122,252,254,252,0,1,252,19,102,254,
-  112,254,233,254,234,254,235,254,236,254,243,254,244,254,245,254,
-  246,254,247,254,249,254,0,21,254,0,25,254,0,27,254,0,29,254,0,79,
-  254,0,83,254,13,118,255,122,254,250,255,251,255,252,255,253,255,
-  254,254,0,1,254,0,109,255,0,113,255,0,115,255,0,117,255,14,118,255,
-  119,254,122,254,250,255,251,255,252,255,253,255,254,254,0,1,254,
-  0,109,255,0,113,255,0,115,255,0,117,255,9,45,250,47,250,119,254,
-  120,254,121,252,122,252,254,252,0,1,252,6,45,251,47,251,122,252,
-  254,252,0,1,252,50,45,249,47,249,59,5,60,5,98,255,106,3,108,3,109,
-  3,110,4,111,4,113,5,117,7,118,3,119,5,122,5,225,255,226,255,227,
-  255,228,255,229,255,230,255,237,3,238,3,239,3,240,3,242,4,250,3,
-  251,3,252,3,253,3,254,5,0,1,5,0,3,255,0,5,255,0,7,255,0,45,3,0,49,
-  3,0,57,3,0,60,3,0,62,3,0,68,3,0,70,4,0,72,4,0,74,4,0,101,7,0,109,
-  3,0,113,3,0,115,3,0,117,3,4,45,254,47,254,120,252,31,45,244,47,244,
-  98,253,102,253,112,253,225,253,226,253,227,253,228,253,229,253,230,
-  253,233,253,234,253,235,253,236,253,243,253,244,253,245,253,246,
-  253,247,253,249,253,0,3,253,0,5,253,0,7,253,0,21,253,0,25,253,0,
-  27,253,0,29,253,0,79,253,0,83,253,31,45,247,47,247,98,254,102,255,
-  112,255,225,254,226,254,227,254,228,254,229,254,230,254,233,255,
-  234,255,235,255,236,255,243,255,244,255,245,255,246,255,247,255,
-  249,255,0,3,254,0,5,254,0,7,254,0,21,255,0,25,255,0,27,255,0,29,
-  255,0,79,255,0,83,255,10,102,252,233,252,234,252,235,252,236,252,
-  0,21,252,0,25,252,0,27,252,0,29,252,31,45,240,47,240,98,254,102,
-  254,112,254,225,254,226,254,227,254,228,254,229,254,230,254,233,
-  254,234,254,235,254,236,254,243,254,244,254,245,254,246,254,247,
-  254,249,254,0,3,254,0,5,254,0,7,254,0,21,254,0,25,254,0,27,254,0,
-  29,254,0,79,254,0,83,254,19,102,254,112,254,233,254,234,254,235,
-  254,236,254,243,254,244,254,245,254,246,254,247,254,249,254,0,21,
-  254,0,25,254,0,27,254,0,29,254,0,79,254,0,83,254,49,68,252,72,252,
-  80,252,82,252,85,237,86,249,87,245,88,249,90,240,118,252,119,250,
-  120,250,122,250,200,252,211,252,212,252,213,252,214,252,215,252,
-  217,252,218,249,219,249,220,249,221,249,222,240,250,252,251,252,
-  252,252,253,252,254,250,0,1,250,0,8,252,0,14,252,0,32,252,0,36,252,
-  0,78,252,0,82,252,0,100,237,0,102,237,0,108,249,0,109,252,0,112,
-  249,0,113,252,0,114,249,0,115,252,0,116,249,0,117,252,0,122,240,
-  49,68,252,72,252,80,252,82,252,85,237,86,249,87,245,88,249,90,240,
-  118,252,119,250,120,250,122,250,200,252,211,252,212,252,213,252,
-  214,252,215,252,217,252,218,249,219,249,220,249,221,249,222,240,
-  250,252,251,252,252,252,253,252,254,250,0,1,250,0,8,252,0,14,252,
-  0,32,252,0,36,252,0,78,252,0,82,252,0,100,237,0,102,237,0,108,249,
-  0,109,252,0,112,249,0,113,252,0,114,249,0,115,252,0,116,249,0,117,
-  252,0,122,240,49,68,252,72,252,80,252,82,252,85,237,86,249,87,245,
-  88,249,90,240,118,252,119,250,120,250,122,250,200,252,211,252,212,
-  252,213,252,214,252,215,252,217,252,218,249,219,249,220,249,221,
-  249,222,240,250,252,251,252,252,252,253,252,254,250,0,1,250,0,8,
-  252,0,14,252,0,32,252,0,36,252,0,78,252,0,82,252,0,100,237,0,102,
-  237,0,108,249,0,109,252,0,112,249,0,113,252,0,114,249,0,115,252,
-  0,116,249,0,117,252,0,122,240,49,68,252,72,252,80,252,82,252,85,
-  237,86,249,87,245,88,249,90,240,118,252,119,250,120,250,122,250,
-  200,252,211,252,212,252,213,252,214,252,215,252,217,252,218,249,
-  219,249,220,249,221,249,222,240,250,252,251,252,252,252,253,252,
-  254,250,0,1,250,0,8,252,0,14,252,0,32,252,0,36,252,0,78,252,0,82,
-  252,0,100,237,0,102,237,0,108,249,0,109,252,0,112,249,0,113,252,
-  0,114,249,0,115,252,0,116,249,0,117,252,0,122,240,49,68,252,72,252,
-  80,252,82,252,85,237,86,249,87,245,88,249,90,240,118,252,119,250,
-  120,250,122,250,200,252,211,252,212,252,213,252,214,252,215,252,
-  217,252,218,249,219,249,220,249,221,249,222,240,250,252,251,252,
-  252,252,253,252,254,250,0,1,250,0,8,252,0,14,252,0,32,252,0,36,252,
-  0,78,252,0,82,252,0,100,237,0,102,237,0,108,249,0,109,252,0,112,
-  249,0,113,252,0,114,249,0,115,252,0,116,249,0,117,252,0,122,240,
-  49,68,252,72,252,80,252,82,252,85,237,86,249,87,245,88,249,90,240,
-  118,252,119,250,120,250,122,250,200,252,211,252,212,252,213,252,
-  214,252,215,252,217,252,218,249,219,249,220,249,221,249,222,240,
-  250,252,251,252,252,252,253,252,254,250,0,1,250,0,8,252,0,14,252,
-  0,32,252,0,36,252,0,78,252,0,82,252,0,100,237,0,102,237,0,108,249,
-  0,109,252,0,112,249,0,113,252,0,114,249,0,115,252,0,116,249,0,117,
-  252,0,122,240,3,45,252,47,252,22,45,250,47,250,66,254,85,250,87,
-  249,88,252,89,247,90,245,193,254,194,254,195,254,196,254,197,254,
-  198,254,222,245,0,2,254,0,4,254,0,6,254,0,100,250,0,102,250,0,122,
-  245,22,45,250,47,250,66,254,85,250,87,249,88,252,89,247,90,245,193,
-  254,194,254,195,254,196,254,197,254,198,254,222,245,0,2,254,0,4,
-  254,0,6,254,0,100,250,0,102,250,0,122,245,22,45,250,47,250,66,254,
-  85,250,87,249,88,252,89,247,90,245,193,254,194,254,195,254,196,254,
-  197,254,198,254,222,245,0,2,254,0,4,254,0,6,254,0,100,250,0,102,
-  250,0,122,245,22,45,250,47,250,66,254,85,250,87,249,88,252,89,247,
-  90,245,193,254,194,254,195,254,196,254,197,254,198,254,222,245,0,
-  2,254,0,4,254,0,6,254,0,100,250,0,102,250,0,122,245,22,45,250,47,
-  250,66,254,85,250,87,249,88,252,89,247,90,245,193,254,194,254,195,
-  254,196,254,197,254,198,254,222,245,0,2,254,0,4,254,0,6,254,0,100,
-  250,0,102,250,0,122,245,22,45,250,47,250,66,254,85,250,87,249,88,
-  252,89,247,90,245,193,254,194,254,195,254,196,254,197,254,198,254,
-  222,245,0,2,254,0,4,254,0,6,254,0,100,250,0,102,250,0,122,245,13,
-  45,250,47,250,66,250,193,250,194,250,195,250,196,250,197,250,198,
-  250,0,2,250,0,4,250,0,6,250,13,45,250,47,250,66,250,193,250,194,
-  250,195,250,196,250,197,250,198,250,0,2,250,0,4,250,0,6,250,13,45,
-  250,47,250,66,250,193,250,194,250,195,250,196,250,197,250,198,250,
-  0,2,250,0,4,250,0,6,250,13,45,250,47,250,66,250,193,250,194,250,
-  195,250,196,250,197,250,198,250,0,2,250,0,4,250,0,6,250,65,45,234,
-  46,234,47,234,59,247,60,247,66,239,80,243,98,234,102,234,106,254,
-  112,234,118,239,193,239,194,239,195,239,196,239,197,239,198,239,
-  211,243,212,243,213,243,214,243,215,243,217,243,225,234,226,234,
-  227,234,228,245,229,234,230,234,233,234,234,234,235,234,236,234,
-  238,254,243,234,244,234,245,234,246,234,247,234,249,234,250,239,
-  251,239,252,239,253,239,0,2,239,0,3,245,0,4,239,0,5,245,0,6,239,
-  0,7,234,0,21,245,0,25,234,0,27,234,0,29,234,0,49,254,0,78,243,0,
-  79,245,0,82,243,0,83,234,0,109,239,0,113,239,0,115,239,0,117,239,
-  6,119,254,120,254,122,252,254,252,0,1,252,6,119,254,120,254,122,
-  252,254,252,0,1,252,6,119,254,120,254,122,252,254,252,0,1,252,6,
-  119,254,120,254,122,252,254,252,0,1,252,6,119,254,120,254,122,252,
-  254,252,0,1,252,6,119,254,120,254,122,252,254,252,0,1,252,4,45,254,
-  108,254,0,57,254,9,45,254,47,254,119,252,120,254,121,252,122,254,
-  254,254,0,1,254,9,45,254,47,254,119,252,120,254,121,252,122,254,
-  254,254,0,1,254,9,45,254,47,254,119,252,120,254,121,252,122,254,
-  254,254,0,1,254,9,45,254,47,254,119,252,120,254,121,252,122,254,
-  254,254,0,1,254,14,118,255,119,254,122,254,250,255,251,255,252,255,
-  253,255,254,254,0,1,254,0,109,255,0,113,255,0,115,255,0,117,255,
-  9,45,250,47,250,119,254,120,254,121,252,122,252,254,252,0,1,252,
-  9,45,250,47,250,119,254,120,254,121,252,122,252,254,252,0,1,252,
-  9,45,250,47,250,119,254,120,254,121,252,122,252,254,252,0,1,252,
-  9,45,250,47,250,119,254,120,254,121,252,122,252,254,252,0,1,252,
-  9,45,250,47,250,119,254,120,254,121,252,122,252,254,252,0,1,252,
-  95,45,241,47,241,98,248,99,248,100,248,101,248,102,248,103,248,104,
-  248,105,248,106,248,107,248,108,248,109,248,110,248,111,248,112,
-  248,113,248,114,248,115,248,116,248,117,248,118,248,119,245,120,
-  245,121,243,122,245,123,248,225,248,226,248,227,248,228,248,229,
-  248,230,248,232,248,233,248,234,248,235,248,236,248,237,248,238,
-  248,239,248,240,248,242,248,243,248,244,248,245,248,246,248,247,
-  248,249,248,250,248,251,248,252,248,253,248,254,245,0,1,245,0,3,
-  248,0,5,248,0,7,248,0,9,248,0,15,248,0,19,248,0,21,248,0,25,248,
-  0,27,248,0,29,248,0,33,248,0,37,248,0,45,248,0,49,248,0,57,248,0,
-  60,248,0,62,248,0,68,248,0,70,248,0,72,248,0,74,248,0,79,248,0,83,
-  248,0,87,248,0,89,248,0,91,248,0,93,248,0,97,248,0,99,248,0,101,
-  248,0,109,248,0,113,248,0,115,248,0,117,248,0,124,248,0,126,248,
-  0,128,248,1,2,25,248,31,45,240,47,240,98,254,102,254,112,254,225,
-  254,226,254,227,254,228,254,229,254,230,254,233,254,234,254,235,
-  254,236,254,243,254,244,254,245,254,246,254,247,254,249,254,0,3,
-  254,0,5,254,0,7,254,0,21,254,0,25,254,0,27,254,0,29,254,0,79,254,
-  0,83,254,31,45,240,47,240,98,254,102,254,112,254,225,254,226,254,
-  227,254,228,254,229,254,230,254,233,254,234,254,235,254,236,254,
-  243,254,244,254,245,254,246,254,247,254,249,254,0,3,254,0,5,254,
-  0,7,254,0,21,254,0,25,254,0,27,254,0,29,254,0,79,254,0,83,254,49,
-  68,252,72,252,80,252,82,252,85,237,86,249,87,245,88,249,90,240,118,
-  252,119,250,120,250,122,250,200,252,211,252,212,252,213,252,214,
-  252,215,252,217,252,218,249,219,249,220,249,221,249,222,240,250,
-  252,251,252,252,252,253,252,254,250,0,1,250,0,8,252,0,14,252,0,32,
-  252,0,36,252,0,78,252,0,82,252,0,100,237,0,102,237,0,108,249,0,109,
-  252,0,112,249,0,113,252,0,114,249,0,115,252,0,116,249,0,117,252,
-  0,122,240,6,119,254,120,254,122,252,254,252,0,1,252,49,68,252,72,
-  252,80,252,82,252,85,237,86,249,87,245,88,249,90,240,118,252,119,
-  250,120,250,122,250,200,252,211,252,212,252,213,252,214,252,215,
-  252,217,252,218,249,219,249,220,249,221,249,222,240,250,252,251,
-  252,252,252,253,252,254,250,0,1,250,0,8,252,0,14,252,0,32,252,0,
-  36,252,0,78,252,0,82,252,0,100,237,0,102,237,0,108,249,0,109,252,
-  0,112,249,0,113,252,0,114,249,0,115,252,0,116,249,0,117,252,0,122,
-  240,6,119,254,120,254,122,252,254,252,0,1,252,49,68,252,72,252,80,
-  252,82,252,85,237,86,249,87,245,88,249,90,240,118,252,119,250,120,
-  250,122,250,200,252,211,252,212,252,213,252,214,252,215,252,217,
-  252,218,249,219,249,220,249,221,249,222,240,250,252,251,252,252,
-  252,253,252,254,250,0,1,250,0,8,252,0,14,252,0,32,252,0,36,252,0,
-  78,252,0,82,252,0,100,237,0,102,237,0,108,249,0,109,252,0,112,249,
-  0,113,252,0,114,249,0,115,252,0,116,249,0,117,252,0,122,240,6,119,
-  254,120,254,122,252,254,252,0,1,252,3,45,252,47,252,4,45,254,108,
-  254,0,57,254,3,45,252,47,252,4,45,254,108,254,0,57,254,18,45,245,
-  47,245,66,250,87,245,88,250,90,242,193,250,194,250,195,250,196,250,
-  197,250,198,250,222,242,0,2,250,0,4,250,0,6,250,0,122,242,18,45,
-  245,47,245,66,250,87,245,88,250,90,242,193,250,194,250,195,250,196,
-  250,197,250,198,250,222,242,0,2,250,0,4,250,0,6,250,0,122,242,9,
-  45,254,47,254,119,252,120,254,121,252,122,254,254,254,0,1,254,9,
-  45,254,47,254,119,252,120,254,121,252,122,254,254,254,0,1,254,9,
-  45,254,47,254,119,252,120,254,121,252,122,254,254,254,0,1,254,9,
-  45,254,47,254,119,252,120,254,121,252,122,254,254,254,0,1,254,5,
-  115,255,0,87,255,0,89,255,0,91,255,5,115,255,0,87,255,0,89,255,0,
-  91,255,40,80,249,102,250,112,250,118,252,122,249,211,249,212,249,
-  213,249,214,249,215,249,217,249,233,250,234,250,235,250,236,250,
-  243,250,244,250,245,250,246,250,247,250,249,250,250,252,251,252,
-  252,252,253,252,254,249,0,1,249,0,21,250,0,25,250,0,27,250,0,29,
-  250,0,78,249,0,79,250,0,82,249,0,83,250,0,109,252,0,113,252,0,115,
-  252,0,117,252,19,102,254,112,254,233,254,234,254,235,254,236,254,
-  243,254,244,254,245,254,246,254,247,254,249,254,0,21,254,0,25,254,
-  0,27,254,0,29,254,0,79,254,0,83,254,14,85,239,87,239,88,245,90,234,
-  122,252,222,234,254,252,0,1,252,0,100,239,0,102,239,0,122,234,1,
-  32,25,230,1,32,29,234,14,85,239,87,239,88,245,90,234,122,252,222,
-  234,254,252,0,1,252,0,100,239,0,102,239,0,122,234,1,32,25,230,1,
-  32,29,234,14,85,239,87,239,88,245,90,234,122,252,222,234,254,252,
-  0,1,252,0,100,239,0,102,239,0,122,234,1,32,25,230,1,32,29,234,14,
-  85,239,87,239,88,245,90,234,122,252,222,234,254,252,0,1,252,0,100,
-  239,0,102,239,0,122,234,1,32,25,230,1,32,29,234,14,118,255,119,254,
-  122,254,250,255,251,255,252,255,253,255,254,254,0,1,254,0,109,255,
-  0,113,255,0,115,255,0,117,255,14,118,255,119,254,122,254,250,255,
-  251,255,252,255,253,255,254,254,0,1,254,0,109,255,0,113,255,0,115,
-  255,0,117,255,14,118,255,119,254,122,254,250,255,251,255,252,255,
-  253,255,254,254,0,1,254,0,109,255,0,113,255,0,115,255,0,117,255,
-  22,45,250,47,250,66,254,85,250,87,249,88,252,89,247,90,245,193,254,
-  194,254,195,254,196,254,197,254,198,254,222,245,0,2,254,0,4,254,
-  0,6,254,0,100,250,0,102,250,0,122,245,9,45,250,47,250,119,254,120,
-  254,121,252,122,252,254,252,0,1,252,22,45,250,47,250,66,254,85,250,
-  87,249,88,252,89,247,90,245,193,254,194,254,195,254,196,254,197,
-  254,198,254,222,245,0,2,254,0,4,254,0,6,254,0,100,250,0,102,250,
-  0,122,245,9,45,250,47,250,119,254,120,254,121,252,122,252,254,252,
-  0,1,252,27,80,254,85,252,86,250,87,249,88,252,90,249,211,254,212,
-  254,213,254,214,254,215,254,217,254,218,250,219,250,220,250,221,
-  250,222,249,0,78,254,0,82,254,0,100,252,0,102,252,0,108,250,0,112,
-  250,0,114,250,0,116,250,0,122,249,50,45,249,47,249,59,5,60,5,98,
-  255,106,3,108,3,109,3,110,4,111,4,113,5,117,7,118,3,119,5,122,5,
-  225,255,226,255,227,255,228,255,229,255,230,255,237,3,238,3,239,
-  3,240,3,242,4,250,3,251,3,252,3,253,3,254,5,0,1,5,0,3,255,0,5,255,
-  0,7,255,0,45,3,0,49,3,0,57,3,0,60,3,0,62,3,0,68,3,0,70,4,0,72,4,
-  0,74,4,0,101,7,0,109,3,0,113,3,0,115,3,0,117,3,27,80,254,85,252,
-  86,250,87,249,88,252,90,249,211,254,212,254,213,254,214,254,215,
-  254,217,254,218,250,219,250,220,250,221,250,222,249,0,78,254,0,82,
-  254,0,100,252,0,102,252,0,108,250,0,112,250,0,114,250,0,116,250,
-  0,122,249,50,45,249,47,249,59,5,60,5,98,255,106,3,108,3,109,3,110,
-  4,111,4,113,5,117,7,118,3,119,5,122,5,225,255,226,255,227,255,228,
-  255,229,255,230,255,237,3,238,3,239,3,240,3,242,4,250,3,251,3,252,
-  3,253,3,254,5,0,1,5,0,3,255,0,5,255,0,7,255,0,45,3,0,49,3,0,57,3,
-  0,60,3,0,62,3,0,68,3,0,70,4,0,72,4,0,74,4,0,101,7,0,109,3,0,113,
-  3,0,115,3,0,117,3,27,80,254,85,252,86,250,87,249,88,252,90,249,211,
-  254,212,254,213,254,214,254,215,254,217,254,218,250,219,250,220,
-  250,221,250,222,249,0,78,254,0,82,254,0,100,252,0,102,252,0,108,
-  250,0,112,250,0,114,250,0,116,250,0,122,249,50,45,249,47,249,59,
-  5,60,5,98,255,106,3,108,3,109,3,110,4,111,4,113,5,117,7,118,3,119,
-  5,122,5,225,255,226,255,227,255,228,255,229,255,230,255,237,3,238,
-  3,239,3,240,3,242,4,250,3,251,3,252,3,253,3,254,5,0,1,5,0,3,255,
-  0,5,255,0,7,255,0,45,3,0,49,3,0,57,3,0,60,3,0,62,3,0,68,3,0,70,4,
-  0,72,4,0,74,4,0,101,7,0,109,3,0,113,3,0,115,3,0,117,3,3,45,254,47,
-  254,4,45,254,47,254,120,252,3,45,254,47,254,4,45,254,47,254,120,
-  252,3,45,254,47,254,4,45,254,47,254,120,252,70,45,237,46,234,47,
-  237,59,254,60,254,66,237,80,250,98,237,102,237,112,237,115,237,118,
-  237,120,237,122,237,193,237,194,237,195,237,196,237,197,237,198,
-  237,211,250,212,250,213,250,214,250,215,250,217,250,225,237,226,
-  237,227,237,228,247,229,237,230,237,233,247,234,237,235,237,236,
-  237,243,237,244,237,245,237,246,247,247,237,249,237,250,237,251,
-  237,252,237,253,237,254,237,0,1,247,0,2,237,0,3,247,0,4,237,0,5,
-  247,0,6,237,0,7,237,0,21,247,0,25,237,0,27,237,0,29,237,0,78,250,
-  0,79,247,0,82,250,0,83,237,0,87,237,0,89,237,0,91,237,0,109,247,
-  0,113,237,0,115,237,0,117,237,70,45,237,46,234,47,237,59,254,60,
-  254,66,237,80,250,98,237,102,237,112,237,115,237,118,237,120,237,
-  122,237,193,237,194,237,195,237,196,237,197,237,198,237,211,250,
-  212,250,213,250,214,250,215,250,217,250,225,237,226,237,227,237,
-  228,247,229,237,230,237,233,247,234,237,235,237,236,237,243,237,
-  244,237,245,237,246,247,247,237,249,237,250,237,251,237,252,237,
-  253,237,254,237,0,1,247,0,2,237,0,3,247,0,4,237,0,5,247,0,6,237,
-  0,7,237,0,21,247,0,25,237,0,27,237,0,29,237,0,78,250,0,79,247,0,
-  82,250,0,83,237,0,87,237,0,89,237,0,91,237,0,109,247,0,113,237,0,
-  115,237,0,117,237,13,45,250,47,250,66,250,193,250,194,250,195,250,
-  196,250,197,250,198,250,0,2,250,0,4,250,0,6,250,13,45,250,47,250,
-  66,250,193,250,194,250,195,250,196,250,197,250,198,250,0,2,250,0,
-  4,250,0,6,250,13,45,250,47,250,66,250,193,250,194,250,195,250,196,
-  250,197,250,198,250,0,2,250,0,4,250,0,6,250,13,45,250,47,250,66,
-  250,193,250,194,250,195,250,196,250,197,250,198,250,0,2,250,0,4,
-  250,0,6,250,65,45,234,46,234,47,234,59,247,60,247,66,239,80,243,
-  98,234,102,234,106,254,112,234,118,239,193,239,194,239,195,239,196,
-  239,197,239,198,239,211,243,212,243,213,243,214,243,215,243,217,
-  243,225,234,226,234,227,234,228,245,229,234,230,234,233,234,234,
-  234,235,234,236,234,238,254,243,234,244,234,245,234,246,234,247,
-  234,249,234,250,239,251,239,252,239,253,239,0,2,239,0,3,245,0,4,
-  239,0,5,245,0,6,239,0,7,234,0,21,245,0,25,234,0,27,234,0,29,234,
-  0,49,254,0,78,243,0,79,234,0,82,243,0,83,234,0,109,239,0,113,239,
-  0,115,239,0,117,239,19,102,254,112,254,233,254,234,254,235,254,236,
-  254,243,254,244,254,245,254,246,254,247,254,249,254,0,21,254,0,25,
-  254,0,27,254,0,29,254,0,79,254,0,83,254,19,102,254,112,254,233,254,
-  234,254,235,254,236,254,243,254,244,254,245,254,246,254,247,254,
-  249,254,0,21,254,0,25,254,0,27,254,0,29,254,0,79,254,0,83,254,19,
-  102,254,112,254,233,254,234,254,235,254,236,254,243,254,244,254,
-  245,254,246,254,247,254,249,254,0,21,254,0,25,254,0,27,254,0,29,
-  254,0,79,254,0,83,254,3,45,254,47,254,4,45,254,47,254,120,252,2,
-  1,32,24,247,14,33,245,101,249,115,249,116,249,0,19,249,0,87,249,
-  0,89,249,0,91,249,0,93,249,0,97,249,0,99,249,1,2,25,249,1,32,25,
-  247,2,33,250
-};
-static afm_cuint16 afm_Helvetica_Oblique_highchars_index[] = { /* 220 */
-  161,162,163,164,165,166,167,168,169,170,171,172,174,175,176,177,
-  178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,
-  194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,
-  210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,
-  226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,
-  242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,
-  258,259,260,261,262,263,268,269,270,271,272,273,274,275,278,279,
-  280,281,282,283,286,287,290,291,298,299,302,303,304,305,310,311,
-  313,314,315,316,317,318,321,322,323,324,325,326,327,328,332,333,
-  336,337,338,339,340,341,342,343,344,345,346,347,350,351,352,353,
-  354,355,356,357,362,363,366,367,368,369,370,371,376,377,378,379,
-  380,381,382,402,536,537,710,711,728,729,730,731,732,733,8211,8212,
-  8216,8217,8218,8220,8221,8222,8224,8225,8226,8230,8240,8249,8250,
-  8260,8364,8482,8706,8710,8721,8722,8730,8800,8804,8805,9674,63171,
-  64257,64258
-};
-static afm_cunicode afm_Helvetica_Oblique_ligatures[] = { /* 3 */
-  102,105,64257
-};
-
-
-/* ------------------------------------------------------------------*/
-/* FontName: ZapfDingbats */
-/* FullName: ITC Zapf Dingbats */
-/* FamilyName: ZapfDingbats */
-static afm_cuint8 afm_ZapfDingbats_widths[] = { /* 202 */
-  46,162,160,162,163,120,132,132,132,115,160,157,92,143,152,156,152,
-  158,162,126,141,127,127,95,113,127,127,127,126,82,92,90,96,115,131,
-  131,131,132,132,132,136,137,132,140,137,139,136,139,154,124,121,
-  125,132,132,116,129,128,132,127,118,118,114,117,138,136,132,132,
-  118,115,116,115,131,131,119,132,131,132,146,127,127,127,127,127,
-  149,149,131,131,73,23,46,69,65,65,111,111,65,65,53,53,46,46,85,85,
-  68,68,39,39,56,56,122,91,91,152,111,127,127,129,99,116,104,131,131,
-  131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,
-  131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,131,
-  131,131,131,131,131,131,149,140,169,76,125,154,125,153,155,155,155,
-  139,146,138,154,154,153,155,155,77,147,139,139,145,145,116,116,146,
-  146,127,158,129,144,129,148,161,148,139,146,155,162,153
-};
-static afm_cuint16 afm_ZapfDingbats_highchars_index[] = { /* 107 */
-  128,129,130,131,132,133,134,135,136,137,138,139,140,141,161,162,
-  163,164,165,166,167,168,169,170,171,172,173,174,175,176,177,178,
-  179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,194,
-  195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,210,
-  211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,226,
-  227,228,229,230,231,232,233,234,235,236,237,238,239,241,242,243,
-  244,245,246,247,248,249,250,251,252,253,254
-};
-
-
-/* ------------------------------------------------------------------*/
-/* FontName: Symbol */
-/* FullName: Symbol */
-/* FamilyName: Symbol */
-static afm_cuint8 afm_Symbol_widths[] = { /* 251 */
-  42,56,0,83,0,139,130,0,56,56,0,92,42,0,42,46,83,83,83,83,83,83,83,
-  83,83,83,46,46,92,92,92,74,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-  0,0,0,0,0,0,0,0,56,0,56,0,83,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-  0,0,0,0,0,0,0,0,0,80,33,80,0,119,67,92,96,92,92,83,120,111,101,102,
-  102,120,124,56,120,114,148,120,108,120,128,93,99,102,115,127,120,
-  133,105,92,69,82,73,82,101,87,55,92,92,87,82,92,92,92,73,101,73,
-  96,87,92,114,114,105,103,101,119,77,167,41,69,28,125,114,165,133,
-  128,137,165,101,165,101,174,110,165,101,165,101,174,119,82,92,137,
-  102,119,119,119,73,137,119,92,83,92,119,119,128,101,101,128,128,
-  46,144,92,92,92,92,92,92,92,119,119,119,119,119,128,128,110,42,114,
-  114,55,55,82,126,126,126,126,132,132,148,83,101,167,132,132,131,
-  64,64,64,64,64,64,82,82,82,82,114,64,64,64,64,64,64,82,82,82
-};
-static afm_cuint16 afm_Symbol_highchars_index[] = { /* 156 */
-  172,176,177,181,215,247,402,913,914,915,917,918,919,920,921,922,
-  923,924,925,926,927,928,929,931,932,933,934,935,936,945,946,947,
-  948,949,950,951,952,953,954,955,957,958,959,960,961,962,963,964,
-  965,966,967,968,969,977,978,981,982,8226,8230,8242,8243,8260,8364,
-  8465,8472,8476,8486,8501,8592,8593,8594,8595,8596,8629,8656,8657,
-  8658,8659,8660,8704,8706,8707,8709,8710,8711,8712,8713,8715,8719,
-  8721,8722,8727,8730,8733,8734,8736,8743,8744,8745,8746,8747,8756,
-  8764,8773,8776,8800,8801,8804,8805,8834,8835,8836,8838,8839,8853,
-  8855,8869,8901,8992,8993,9001,9002,9674,9824,9827,9829,9830,63193,
-  63194,63195,63717,63718,63719,63720,63721,63722,63723,63724,63725,
-  63726,63727,63728,63729,63730,63731,63732,63733,63734,63735,63736,
-  63737,63738,63739,63740,63741,63742
-};
-
-
-/* ------------------------------------------------------------------*/
-/* FontName: Times-Bold */
-/* FullName: Times Bold */
-/* FamilyName: Times */
-static afm_cuint8 afm_Times_Bold_widths[] = { /* 315 */
-  42,56,93,83,83,167,139,46,56,56,83,95,42,56,42,46,83,83,83,83,83,
-  83,83,83,83,83,56,56,95,95,95,83,155,120,111,120,120,111,102,130,
-  130,65,83,130,111,157,120,130,102,130,120,93,111,120,120,167,120,
-  120,111,56,46,56,97,83,56,83,93,74,93,74,56,83,93,46,56,93,46,139,
-  93,83,93,93,74,65,56,93,83,120,83,83,74,66,37,66,87,56,83,83,83,
-  83,37,83,56,125,50,83,95,125,56,67,95,50,50,56,93,90,42,56,50,55,
-  83,125,125,125,83,120,120,120,120,120,120,167,120,111,111,111,111,
-  65,65,65,65,120,120,130,130,130,130,130,95,130,120,120,120,120,120,
-  102,93,83,83,83,83,83,83,120,74,74,74,74,74,46,46,46,46,83,93,83,
-  83,83,83,83,95,83,93,93,93,93,83,93,83,120,83,120,83,120,83,120,
-  74,120,74,120,112,120,93,111,74,111,74,111,74,111,74,130,83,130,
-  83,65,46,65,46,65,46,130,93,111,46,111,46,111,66,111,46,120,93,120,
-  93,120,93,130,83,130,83,167,120,120,74,120,74,120,74,93,65,93,65,
-  93,65,111,56,111,69,120,93,120,93,120,93,120,93,120,111,74,111,74,
-  111,74,83,93,65,56,56,56,56,56,56,56,56,83,167,56,56,56,83,83,83,
-  83,83,58,167,167,56,56,28,83,167,82,102,100,95,92,92,92,92,82,42,
-  93,93
-};
-static afm_sint16 afm_Times_Bold_kerning_index[] = { /* 315 */
-  1,0,0,0,0,0,0,0,0,0,0,0,44,0,53,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-  0,0,62,183,0,229,0,266,0,0,0,359,472,564,0,599,623,668,761,786,0,
-  848,1016,1044,1209,0,1364,0,0,0,0,0,0,0,1512,1515,0,1544,1547,1550,
-  1588,1591,1599,0,1602,0,0,1652,1655,0,0,1660,0,0,0,1746,1816,0,1841,
-  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-  0,0,0,1888,2009,2130,2251,2372,2493,0,0,0,0,0,0,0,0,0,0,0,2614,2638,
-  2683,2728,2773,2818,0,2863,2908,2936,2964,2992,3020,0,0,3168,3171,
-  3174,3177,3180,3183,0,0,3186,3189,3192,3195,3198,3201,3204,3207,
-  0,3210,3213,3218,3223,3228,3233,0,3238,0,0,0,0,3243,0,3290,3337,
-  3458,3461,3582,3585,3706,0,0,0,0,3709,0,3746,3783,0,3786,0,3789,
-  0,3792,0,3795,0,3798,0,3801,0,3804,0,3807,0,0,3810,3902,3952,0,3987,
-  0,0,0,4022,0,4057,4081,4084,4108,4111,4135,4138,4183,4188,4233,0,
-  0,4238,4300,4386,4448,4534,4596,0,0,0,0,0,0,4682,0,4850,0,5018,0,
-  5046,0,5074,0,5102,0,5130,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-  5278,5306,0,5346,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
-};
-static afm_cuint8 afm_Times_Bold_kerning_data[] = { /* 5370 */
-  42,19,66,248,85,252,87,249,88,252,90,248,193,248,194,248,195,248,
-  196,248,197,248,198,248,222,248,0,2,248,0,4,248,0,6,248,0,100,252,
-  0,102,252,0,122,248,3,1,32,25,248,1,32,29,249,3,1,32,25,248,1,32,
-  29,248,51,68,248,72,248,80,249,82,249,85,241,86,249,87,233,88,235,
-  90,240,113,253,118,249,119,240,120,242,122,245,200,248,211,249,212,
-  249,213,249,214,249,215,249,217,249,218,249,219,249,220,249,221,
-  249,222,240,250,249,251,249,252,249,253,249,254,245,0,1,245,0,8,
-  248,0,14,248,0,32,248,0,36,248,0,78,249,0,82,249,0,100,241,0,102,
-  241,0,108,249,0,109,249,0,112,249,0,113,249,0,114,249,0,115,249,
-  0,116,249,0,117,249,0,122,240,1,32,25,245,20,66,252,86,255,193,252,
-  194,252,195,252,196,252,197,252,198,252,218,255,219,255,220,255,
-  221,255,0,2,252,0,4,252,0,6,252,0,108,255,0,112,255,0,114,255,0,
-  116,255,17,47,254,66,251,87,250,88,250,90,250,193,251,194,251,195,
-  251,196,251,197,251,198,251,222,250,0,2,251,0,4,251,0,6,251,0,122,
-  250,41,45,242,47,239,66,242,98,253,102,253,112,253,193,242,194,242,
-  195,242,196,242,197,242,198,242,225,253,226,253,227,253,228,253,
-  229,253,230,253,233,253,234,253,235,253,236,253,243,253,244,253,
-  245,253,246,253,247,253,249,253,0,2,242,0,3,253,0,4,242,0,5,253,
-  0,6,242,0,7,253,0,21,253,0,25,253,0,27,253,0,29,253,0,79,253,0,83,
-  253,49,47,254,66,252,98,254,102,254,112,254,118,254,193,252,194,
-  252,195,252,196,252,197,252,198,252,225,254,226,254,227,254,228,
-  254,229,254,230,254,233,254,234,254,235,254,236,254,243,254,244,
-  254,245,254,246,254,247,254,249,254,250,254,251,254,252,254,253,
-  254,0,2,252,0,3,254,0,4,252,0,5,254,0,6,252,0,7,254,0,21,254,0,25,
-  254,0,27,254,0,29,254,0,79,254,0,83,254,0,109,254,0,113,254,0,115,
-  254,0,117,254,40,80,252,102,253,112,253,118,254,122,249,211,252,
-  212,252,213,252,214,252,215,252,217,252,233,253,234,253,235,253,
-  236,253,243,253,244,253,245,253,246,253,247,253,249,253,250,254,
-  251,254,252,254,253,254,254,249,0,1,249,0,21,253,0,25,253,0,27,253,
-  0,29,253,0,78,252,0,79,253,0,82,252,0,83,253,0,109,254,0,113,254,
-  0,115,254,0,117,254,14,85,242,87,242,88,242,90,242,122,248,222,242,
-  254,248,0,1,248,0,100,242,0,102,242,0,122,242,1,32,25,239,1,32,29,
-  254,11,66,254,193,254,194,254,195,254,196,254,197,254,198,254,0,
-  2,254,0,4,254,0,6,254,20,66,250,85,250,87,249,88,249,89,250,90,249,
-  193,250,194,250,195,250,196,250,197,250,198,250,222,249,0,2,250,
-  0,4,250,0,6,250,0,100,250,0,102,250,0,122,249,41,45,242,47,239,66,
-  245,98,255,102,254,112,254,193,245,194,245,195,245,196,245,197,245,
-  198,245,225,255,226,255,227,255,228,255,229,255,230,255,233,254,
-  234,254,235,254,236,254,243,254,244,254,245,254,246,254,247,254,
-  249,254,0,2,245,0,3,255,0,4,245,0,5,255,0,6,245,0,7,255,0,21,254,
-  0,25,254,0,27,254,0,29,254,0,79,254,0,83,254,11,47,254,86,255,218,
-  255,219,255,220,255,221,255,0,108,255,0,112,255,0,114,255,0,116,
-  255,27,80,252,85,250,86,252,87,248,88,251,90,251,211,252,212,252,
-  213,252,214,252,215,252,217,252,218,252,219,252,220,252,221,252,
-  222,251,0,78,252,0,82,252,0,100,250,0,102,250,0,108,252,0,112,252,
-  0,114,252,0,116,252,0,122,251,73,45,245,46,242,47,242,59,245,60,
-  245,66,242,80,254,98,242,102,242,106,254,112,242,115,245,118,242,
-  120,245,122,251,193,242,194,242,195,242,196,242,197,242,198,242,
-  211,254,212,254,213,254,214,254,215,254,217,254,225,248,226,242,
-  227,248,228,248,229,248,230,242,233,248,234,242,235,242,236,248,
-  238,254,243,242,244,242,245,242,246,242,247,242,249,242,250,242,
-  251,242,252,242,253,242,254,251,0,1,251,0,2,242,0,3,248,0,4,242,
-  0,5,248,0,6,242,0,7,242,0,21,248,0,25,242,0,27,242,0,29,242,0,49,
-  254,0,78,254,0,79,242,0,82,254,0,83,242,0,87,245,0,89,245,0,91,245,
-  0,109,242,0,113,242,0,115,242,0,117,242,13,45,249,47,249,66,247,
-  193,247,194,247,195,247,196,247,197,247,198,247,0,2,247,0,4,247,
-  0,6,247,72,45,235,46,245,47,233,59,242,60,242,66,234,72,252,80,249,
-  98,242,102,240,106,251,112,240,118,242,193,234,194,234,195,234,196,
-  234,197,234,198,234,211,249,212,249,213,249,214,249,215,249,217,
-  249,225,242,226,242,227,242,228,242,229,242,230,242,233,240,234,
-  240,235,240,236,240,237,251,238,251,239,251,240,251,243,240,244,
-  240,245,240,246,240,247,240,249,240,250,242,251,242,252,242,253,
-  242,0,2,234,0,3,242,0,4,234,0,5,242,0,6,234,0,7,242,0,21,240,0,25,
-  240,0,27,240,0,29,240,0,32,252,0,36,252,0,45,251,0,49,251,0,78,249,
-  0,79,240,0,82,249,0,83,240,0,109,242,0,113,242,0,115,242,0,117,242,
-  68,45,242,46,251,47,242,59,248,60,248,66,237,80,255,98,246,102,246,
-  106,254,112,244,118,249,122,247,193,237,194,237,195,237,196,237,
-  197,237,198,237,211,255,212,255,213,255,214,255,215,255,217,255,
-  225,246,226,246,227,246,228,246,229,246,230,246,233,246,234,246,
-  235,246,236,246,238,254,243,244,244,244,245,244,246,244,247,244,
-  249,244,250,249,251,249,252,249,253,249,254,247,0,1,247,0,2,237,
-  0,3,246,0,4,237,0,5,246,0,6,237,0,7,246,0,21,246,0,25,246,0,27,246,
-  0,29,246,0,49,254,0,78,255,0,79,244,0,82,255,0,83,244,0,109,249,
-  0,113,249,0,115,249,0,117,249,65,45,242,46,242,47,242,59,242,60,
-  242,66,239,80,251,98,243,102,238,106,251,112,238,118,242,193,239,
-  194,239,195,239,196,239,197,239,198,239,211,251,212,251,213,251,
-  214,251,215,251,217,251,225,243,226,243,227,243,228,243,229,243,
-  230,243,233,245,234,238,235,238,236,245,238,251,243,238,244,238,
-  245,238,246,238,247,238,249,238,250,242,251,242,252,242,253,242,
-  0,2,239,0,3,243,0,4,239,0,5,243,0,6,239,0,7,243,0,21,245,0,25,238,
-  0,27,238,0,29,238,0,49,251,0,78,251,0,79,238,0,82,251,0,83,238,0,
-  109,242,0,113,242,0,115,242,0,117,242,2,119,253,13,47,250,99,255,
-  118,254,119,254,250,254,251,254,252,254,253,254,0,109,254,0,113,
-  254,0,115,254,0,117,254,2,120,254,2,119,254,16,45,254,47,254,106,
-  253,112,253,243,253,244,253,245,253,246,253,247,253,249,253,0,51,
-  251,0,79,253,0,83,253,1,32,25,9,1,32,29,8,2,47,254,4,122,254,254,
-  254,0,1,254,2,119,255,22,102,255,112,254,122,254,233,255,234,255,
-  235,255,236,255,243,254,244,254,245,254,246,254,247,254,249,254,
-  254,254,0,1,254,0,21,255,0,25,255,0,27,255,0,29,255,0,79,254,0,83,
-  254,2,119,250,3,119,255,120,255,37,45,242,46,251,47,240,100,254,
-  102,254,104,255,111,254,112,254,113,255,114,254,119,255,232,254,
-  233,254,234,254,235,254,236,254,242,254,243,254,244,254,245,254,
-  246,254,247,254,249,254,0,9,254,0,15,254,0,21,254,0,25,254,0,27,
-  254,0,29,254,0,33,255,0,37,255,0,70,254,0,72,254,0,74,254,0,79,254,
-  0,83,254,31,45,248,47,245,98,255,102,255,112,255,225,255,226,255,
-  227,255,228,255,229,255,230,255,233,255,234,255,235,255,236,255,
-  243,255,244,255,245,255,246,255,247,255,249,255,0,3,255,0,5,255,
-  0,7,255,0,21,255,0,25,255,0,27,255,0,29,255,0,79,255,0,83,255,12,
-  45,248,47,245,112,255,243,255,244,255,245,255,246,255,247,255,249,
-  255,0,79,255,0,83,255,21,45,248,47,245,102,255,112,253,233,255,234,
-  255,235,255,236,255,243,253,244,253,245,253,246,253,247,253,249,
-  253,0,21,255,0,25,255,0,27,255,0,29,255,0,79,253,0,83,253,51,68,
-  248,72,248,80,249,82,249,85,241,86,249,87,233,88,235,90,240,113,
-  253,118,249,119,240,120,242,122,245,200,248,211,249,212,249,213,
-  249,214,249,215,249,217,249,218,249,219,249,220,249,221,249,222,
-  240,250,249,251,249,252,249,253,249,254,245,0,1,245,0,8,248,0,14,
-  248,0,32,248,0,36,248,0,78,249,0,82,249,0,100,241,0,102,241,0,108,
-  249,0,109,249,0,112,249,0,113,249,0,114,249,0,115,249,0,116,249,
-  0,117,249,0,122,240,1,32,25,245,51,68,248,72,248,80,249,82,249,85,
-  241,86,249,87,233,88,235,90,240,113,253,118,249,119,240,120,242,
-  122,245,200,248,211,249,212,249,213,249,214,249,215,249,217,249,
-  218,249,219,249,220,249,221,249,222,240,250,249,251,249,252,249,
-  253,249,254,245,0,1,245,0,8,248,0,14,248,0,32,248,0,36,248,0,78,
-  249,0,82,249,0,100,241,0,102,241,0,108,249,0,109,249,0,112,249,0,
-  113,249,0,114,249,0,115,249,0,116,249,0,117,249,0,122,240,1,32,25,
-  245,51,68,248,72,248,80,249,82,249,85,241,86,249,87,233,88,235,90,
-  240,113,253,118,249,119,240,120,242,122,245,200,248,211,249,212,
-  249,213,249,214,249,215,249,217,249,218,249,219,249,220,249,221,
-  249,222,240,250,249,251,249,252,249,253,249,254,245,0,1,245,0,8,
-  248,0,14,248,0,32,248,0,36,248,0,78,249,0,82,249,0,100,241,0,102,
-  241,0,108,249,0,109,249,0,112,249,0,113,249,0,114,249,0,115,249,
-  0,116,249,0,117,249,0,122,240,1,32,25,245,51,68,248,72,248,80,249,
-  82,249,85,241,86,249,87,233,88,235,90,240,113,253,118,249,119,240,
-  120,242,122,245,200,248,211,249,212,249,213,249,214,249,215,249,
-  217,249,218,249,219,249,220,249,221,249,222,240,250,249,251,249,
-  252,249,253,249,254,245,0,1,245,0,8,248,0,14,248,0,32,248,0,36,248,
-  0,78,249,0,82,249,0,100,241,0,102,241,0,108,249,0,109,249,0,112,
-  249,0,113,249,0,114,249,0,115,249,0,116,249,0,117,249,0,122,240,
-  1,32,25,245,51,68,248,72,248,80,249,82,249,85,241,86,249,87,233,
-  88,235,90,240,113,253,118,249,119,240,120,242,122,245,200,248,211,
-  249,212,249,213,249,214,249,215,249,217,249,218,249,219,249,220,
-  249,221,249,222,240,250,249,251,249,252,249,253,249,254,245,0,1,
-  245,0,8,248,0,14,248,0,32,248,0,36,248,0,78,249,0,82,249,0,100,241,
-  0,102,241,0,108,249,0,109,249,0,112,249,0,113,249,0,114,249,0,115,
-  249,0,116,249,0,117,249,0,122,240,1,32,25,245,51,68,248,72,248,80,
-  249,82,249,85,241,86,249,87,233,88,235,90,240,113,253,118,249,119,
-  240,120,242,122,245,200,248,211,249,212,249,213,249,214,249,215,
-  249,217,249,218,249,219,249,220,249,221,249,222,240,250,249,251,
-  249,252,249,253,249,254,245,0,1,245,0,8,248,0,14,248,0,32,248,0,
-  36,248,0,78,249,0,82,249,0,100,241,0,102,241,0,108,249,0,109,249,
-  0,112,249,0,113,249,0,114,249,0,115,249,0,116,249,0,117,249,0,122,
-  240,1,32,25,245,11,66,254,193,254,194,254,195,254,196,254,197,254,
-  198,254,0,2,254,0,4,254,0,6,254,20,66,250,85,250,87,249,88,249,89,
-  250,90,249,193,250,194,250,195,250,196,250,197,250,198,250,222,249,
-  0,2,250,0,4,250,0,6,250,0,100,250,0,102,250,0,122,249,20,66,250,
-  85,250,87,249,88,249,89,250,90,249,193,250,194,250,195,250,196,250,
-  197,250,198,250,222,249,0,2,250,0,4,250,0,6,250,0,100,250,0,102,
-  250,0,122,249,20,66,250,85,250,87,249,88,249,89,250,90,249,193,250,
-  194,250,195,250,196,250,197,250,198,250,222,249,0,2,250,0,4,250,
-  0,6,250,0,100,250,0,102,250,0,122,249,20,66,250,85,250,87,249,88,
-  249,89,250,90,249,193,250,194,250,195,250,196,250,197,250,198,250,
-  222,249,0,2,250,0,4,250,0,6,250,0,100,250,0,102,250,0,122,249,20,
-  66,250,85,250,87,249,88,249,89,250,90,249,193,250,194,250,195,250,
-  196,250,197,250,198,250,222,249,0,2,250,0,4,250,0,6,250,0,100,250,
-  0,102,250,0,122,249,20,66,250,85,250,87,249,88,249,89,250,90,249,
-  193,250,194,250,195,250,196,250,197,250,198,250,222,249,0,2,250,
-  0,4,250,0,6,250,0,100,250,0,102,250,0,122,249,13,45,249,47,249,66,
-  247,193,247,194,247,195,247,196,247,197,247,198,247,0,2,247,0,4,
-  247,0,6,247,13,45,249,47,249,66,247,193,247,194,247,195,247,196,
-  247,197,247,198,247,0,2,247,0,4,247,0,6,247,13,45,249,47,249,66,
-  247,193,247,194,247,195,247,196,247,197,247,198,247,0,2,247,0,4,
-  247,0,6,247,13,45,249,47,249,66,247,193,247,194,247,195,247,196,
-  247,197,247,198,247,0,2,247,0,4,247,0,6,247,65,45,242,46,242,47,
-  242,59,242,60,242,66,239,80,251,98,243,102,238,106,251,112,238,118,
-  242,193,239,194,239,195,239,196,239,197,239,198,239,211,251,212,
-  251,213,251,214,251,215,251,217,251,225,243,226,243,227,243,228,
-  243,229,243,230,243,233,245,234,238,235,238,236,245,238,251,243,
-  238,244,238,245,238,246,238,247,238,249,238,250,242,251,242,252,
-  242,253,242,0,2,239,0,3,243,0,4,239,0,5,243,0,6,239,0,7,243,0,21,
-  245,0,25,238,0,27,238,0,29,238,0,49,251,0,78,251,0,79,238,0,82,251,
-  0,83,238,0,109,242,0,113,242,0,115,242,0,117,242,2,119,253,2,119,
-  253,2,119,253,2,119,253,2,119,253,2,119,253,2,119,254,2,119,254,
-  2,119,254,2,119,254,2,119,255,2,119,255,2,119,255,2,119,255,2,119,
-  250,3,119,255,120,255,3,119,255,120,255,3,119,255,120,255,3,119,
-  255,120,255,3,119,255,120,255,3,119,255,120,255,21,45,248,47,245,
-  102,255,112,253,233,255,234,255,235,255,236,255,243,253,244,253,
-  245,253,246,253,247,253,249,253,0,21,255,0,25,255,0,27,255,0,29,
-  255,0,79,253,0,83,253,21,45,248,47,245,102,255,112,253,233,255,234,
-  255,235,255,236,255,243,253,244,253,245,253,246,253,247,253,249,
-  253,0,21,255,0,25,255,0,27,255,0,29,255,0,79,253,0,83,253,51,68,
-  248,72,248,80,249,82,249,85,241,86,249,87,233,88,235,90,240,113,
-  253,118,249,119,240,120,242,122,245,200,248,211,249,212,249,213,
-  249,214,249,215,249,217,249,218,249,219,249,220,249,221,249,222,
-  240,250,249,251,249,252,249,253,249,254,245,0,1,245,0,8,248,0,14,
-  248,0,32,248,0,36,248,0,78,249,0,82,249,0,100,241,0,102,241,0,108,
-  249,0,109,249,0,112,249,0,113,249,0,114,249,0,115,249,0,116,249,
-  0,117,249,0,122,240,1,32,25,245,2,119,253,51,68,248,72,248,80,249,
-  82,249,85,241,86,249,87,233,88,235,90,240,113,253,118,249,119,240,
-  120,242,122,245,200,248,211,249,212,249,213,249,214,249,215,249,
-  217,249,218,249,219,249,220,249,221,249,222,240,250,249,251,249,
-  252,249,253,249,254,245,0,1,245,0,8,248,0,14,248,0,32,248,0,36,248,
-  0,78,249,0,82,249,0,100,241,0,102,241,0,108,249,0,109,249,0,112,
-  249,0,113,249,0,114,249,0,115,249,0,116,249,0,117,249,0,122,240,
-  1,32,25,245,2,119,253,51,68,248,72,248,80,249,82,249,85,241,86,249,
-  87,233,88,235,90,240,113,253,118,249,119,240,120,242,122,251,200,
-  248,211,249,212,249,213,249,214,249,215,249,217,249,218,249,219,
-  249,220,249,221,249,222,240,250,249,251,249,252,249,253,249,254,
-  251,0,1,251,0,8,248,0,14,248,0,32,248,0,36,248,0,78,249,0,82,249,
-  0,100,241,0,102,241,0,108,249,0,109,249,0,112,249,0,113,249,0,114,
-  249,0,115,249,0,116,249,0,117,249,0,122,240,1,32,25,245,2,119,253,
-  17,47,254,66,251,87,250,88,250,90,250,193,251,194,251,195,251,196,
-  251,197,251,198,251,222,250,0,2,251,0,4,251,0,6,251,0,122,250,17,
-  47,254,66,251,87,250,88,250,90,250,193,251,194,251,195,251,196,251,
-  197,251,198,251,222,250,0,2,251,0,4,251,0,6,251,0,122,250,2,120,
-  254,2,119,254,2,119,254,2,119,254,2,119,254,2,47,254,2,47,254,2,
-  119,255,2,119,255,40,80,252,102,253,112,253,118,254,122,249,211,
-  252,212,252,213,252,214,252,215,252,217,252,233,253,234,253,235,
-  253,236,253,243,253,244,253,245,253,246,253,247,253,249,253,250,
-  254,251,254,252,254,253,254,254,249,0,1,249,0,21,253,0,25,253,0,
-  27,253,0,29,253,0,78,252,0,79,253,0,82,252,0,83,253,0,109,254,0,
-  113,254,0,115,254,0,117,254,22,102,255,112,254,122,254,233,255,234,
-  255,235,255,236,255,243,254,244,254,245,254,246,254,247,254,249,
-  254,254,254,0,1,254,0,21,255,0,25,255,0,27,255,0,29,255,0,79,254,
-  0,83,254,14,85,242,87,242,88,242,90,242,122,248,222,242,254,248,
-  0,1,248,0,100,242,0,102,242,0,122,242,1,32,25,239,1,32,29,254,14,
-  85,242,87,242,88,242,90,242,122,248,222,242,254,248,0,1,248,0,100,
-  242,0,102,242,0,122,242,1,32,25,239,1,32,29,254,14,85,242,87,242,
-  88,242,90,242,122,248,222,242,254,248,0,1,248,0,100,242,0,102,242,
-  0,122,242,1,32,25,239,1,32,29,254,11,66,254,193,254,194,254,195,
-  254,196,254,197,254,198,254,0,2,254,0,4,254,0,6,254,2,119,250,11,
-  66,254,193,254,194,254,195,254,196,254,197,254,198,254,0,2,254,0,
-  4,254,0,6,254,2,119,250,11,66,254,193,254,194,254,195,254,196,254,
-  197,254,198,254,0,2,254,0,4,254,0,6,254,2,119,250,20,66,250,85,250,
-  87,249,88,249,89,250,90,249,193,250,194,250,195,250,196,250,197,
-  250,198,250,222,249,0,2,250,0,4,250,0,6,250,0,100,250,0,102,250,
-  0,122,249,3,119,255,120,255,20,66,250,85,250,87,249,88,249,89,250,
-  90,249,193,250,194,250,195,250,196,250,197,250,198,250,222,249,0,
-  2,250,0,4,250,0,6,250,0,100,250,0,102,250,0,122,249,3,119,255,120,
-  255,27,80,252,85,250,86,252,87,248,88,251,90,251,211,252,212,252,
-  213,252,214,252,215,252,217,252,218,252,219,252,220,252,221,252,
-  222,251,0,78,252,0,82,252,0,100,250,0,102,250,0,108,252,0,112,252,
-  0,114,252,0,116,252,0,122,251,37,45,242,46,251,47,240,100,254,102,
-  254,104,255,111,254,112,254,113,255,114,254,119,255,232,254,233,
-  254,234,254,235,254,236,254,242,254,243,254,244,254,245,254,246,
-  254,247,254,249,254,0,9,254,0,15,254,0,21,254,0,25,254,0,27,254,
-  0,29,254,0,33,255,0,37,255,0,70,254,0,72,254,0,74,254,0,79,254,0,
-  83,254,27,80,252,85,250,86,252,87,248,88,251,90,251,211,252,212,
-  252,213,252,214,252,215,252,217,252,218,252,219,252,220,252,221,
-  252,222,251,0,78,252,0,82,252,0,100,250,0,102,250,0,108,252,0,112,
-  252,0,114,252,0,116,252,0,122,251,37,45,242,46,251,47,240,100,254,
-  102,254,104,255,111,254,112,254,113,255,114,254,119,255,232,254,
-  233,254,234,254,235,254,236,254,242,254,243,254,244,254,245,254,
-  246,254,247,254,249,254,0,9,254,0,15,254,0,21,254,0,25,254,0,27,
-  254,0,29,254,0,33,255,0,37,255,0,70,254,0,72,254,0,74,254,0,79,254,
-  0,83,254,27,80,252,85,250,86,252,87,248,88,251,90,251,211,252,212,
-  252,213,252,214,252,215,252,217,252,218,252,219,252,220,252,221,
-  252,222,251,0,78,252,0,82,252,0,100,250,0,102,250,0,108,252,0,112,
-  252,0,114,252,0,116,252,0,122,251,37,45,242,46,251,47,240,100,254,
-  102,254,104,255,111,254,112,254,113,255,114,254,119,255,232,254,
-  233,254,234,254,235,254,236,254,242,254,243,254,244,254,245,254,
-  246,254,247,254,249,254,0,9,254,0,15,254,0,21,254,0,25,254,0,27,
-  254,0,29,254,0,33,255,0,37,255,0,70,254,0,72,254,0,74,254,0,79,254,
-  0,83,254,73,45,245,46,242,47,242,59,245,60,245,66,242,80,254,98,
-  242,102,242,106,254,112,242,115,245,118,242,120,245,122,251,193,
-  242,194,242,195,242,196,242,197,242,198,242,211,254,212,254,213,
-  254,214,254,215,254,217,254,225,248,226,242,227,248,228,248,229,
-  248,230,242,233,248,234,242,235,242,236,248,238,254,243,242,244,
-  242,245,242,246,242,247,242,249,242,250,242,251,242,252,242,253,
-  242,254,251,0,1,251,0,2,242,0,3,248,0,4,242,0,5,248,0,6,242,0,7,
-  242,0,21,248,0,25,242,0,27,242,0,29,242,0,49,254,0,78,254,0,79,242,
-  0,82,254,0,83,242,0,87,245,0,89,245,0,91,245,0,109,242,0,113,242,
-  0,115,242,0,117,242,73,45,245,46,242,47,242,59,245,60,245,66,242,
-  80,254,98,242,102,242,106,254,112,242,115,245,118,242,120,245,122,
-  251,193,242,194,242,195,242,196,242,197,242,198,242,211,254,212,
-  254,213,254,214,254,215,254,217,254,225,248,226,242,227,248,228,
-  248,229,248,230,242,233,248,234,242,235,242,236,248,238,254,243,
-  242,244,242,245,242,246,242,247,242,249,242,250,242,251,242,252,
-  242,253,242,254,251,0,1,251,0,2,242,0,3,248,0,4,242,0,5,248,0,6,
-  242,0,7,242,0,21,248,0,25,242,0,27,242,0,29,242,0,49,254,0,78,254,
-  0,79,242,0,82,254,0,83,242,0,87,245,0,89,245,0,91,245,0,109,242,
-  0,113,242,0,115,242,0,117,242,13,45,249,47,249,66,247,193,247,194,
-  247,195,247,196,247,197,247,198,247,0,2,247,0,4,247,0,6,247,13,45,
-  249,47,249,66,247,193,247,194,247,195,247,196,247,197,247,198,247,
-  0,2,247,0,4,247,0,6,247,13,45,249,47,249,66,247,193,247,194,247,
-  195,247,196,247,197,247,198,247,0,2,247,0,4,247,0,6,247,13,45,249,
-  47,249,66,247,193,247,194,247,195,247,196,247,197,247,198,247,0,
-  2,247,0,4,247,0,6,247,65,45,242,46,242,47,242,59,242,60,242,66,239,
-  80,251,98,243,102,238,106,251,112,238,118,242,193,239,194,239,195,
-  239,196,239,197,239,198,239,211,251,212,251,213,251,214,251,215,
-  251,217,251,225,243,226,243,227,243,228,243,229,243,230,243,233,
-  245,234,238,235,238,236,245,238,251,243,238,244,238,245,238,246,
-  238,247,238,249,238,250,242,251,242,252,242,253,242,0,2,239,0,3,
-  243,0,4,239,0,5,243,0,6,239,0,7,243,0,21,245,0,25,238,0,27,238,0,
-  29,238,0,49,251,0,78,251,0,79,238,0,82,251,0,83,238,0,109,242,0,
-  113,242,0,115,242,0,117,242,12,66,255,193,255,194,255,195,255,196,
-  255,197,255,198,255,0,2,255,0,4,255,0,6,255,1,32,24,246,15,33,245,
-  101,254,115,254,116,251,119,254,0,19,254,0,87,254,0,89,254,0,91,
-  254,0,93,251,0,97,251,0,99,251,1,2,25,251,1,32,25,246,11,66,255,
-  193,255,194,255,195,255,196,255,197,255,198,255,0,2,255,0,4,255,
-  0,6,255
-};
-static afm_cuint16 afm_Times_Bold_highchars_index[] = { /* 220 */
-  161,162,163,164,165,166,167,168,169,170,171,172,174,175,176,177,
-  178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,
-  194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,
-  210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,
-  226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,
-  242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,
-  258,259,260,261,262,263,268,269,270,271,272,273,274,275,278,279,
-  280,281,282,283,286,287,290,291,298,299,302,303,304,305,310,311,
-  313,314,315,316,317,318,321,322,323,324,325,326,327,328,332,333,
-  336,337,338,339,340,341,342,343,344,345,346,347,350,351,352,353,
-  354,355,356,357,362,363,366,367,368,369,370,371,376,377,378,379,
-  380,381,382,402,536,537,710,711,728,729,730,731,732,733,8211,8212,
-  8216,8217,8218,8220,8221,8222,8224,8225,8226,8230,8240,8249,8250,
-  8260,8364,8482,8706,8710,8721,8722,8730,8800,8804,8805,9674,63171,
-  64257,64258
-};
-static afm_cunicode afm_Times_Bold_ligatures[] = { /* 3 */
-  102,105,64257
-};
-
-
-/* ------------------------------------------------------------------*/
-/* FontName: Times-BoldItalic */
-/* FullName: Times Bold Italic */
-/* FamilyName: Times */
-static afm_cuint8 afm_Times_BoldItalic_widths[] = { /* 315 */
-  42,65,93,83,83,139,130,46,56,56,83,95,42,56,42,46,83,83,83,83,83,
-  83,83,83,83,83,56,56,95,95,95,83,139,111,111,111,120,111,111,120,
-  130,65,83,111,102,148,120,120,102,120,111,93,102,120,111,148,111,
-  102,102,56,46,56,95,83,56,83,83,74,83,74,56,83,93,46,46,83,46,130,
-  93,83,83,83,65,65,46,93,74,111,83,74,65,58,37,58,95,65,83,83,83,
-  83,37,83,56,125,44,83,101,125,56,67,95,50,50,56,96,83,42,56,50,50,
-  83,125,125,125,83,111,111,111,111,111,111,157,111,111,111,111,111,
-  65,65,65,65,120,120,120,120,120,120,120,95,120,120,120,120,120,102,
-  102,83,83,83,83,83,83,83,120,74,74,74,74,74,46,46,46,46,83,93,83,
-  83,83,83,83,95,83,93,93,93,93,74,83,74,111,83,111,83,111,83,111,
-  74,111,74,120,101,120,83,111,74,111,74,111,74,111,74,120,83,120,
-  83,65,46,65,46,65,46,111,83,102,46,102,46,102,64,102,46,120,93,120,
-  93,120,93,120,83,120,83,157,120,111,65,111,65,111,65,93,65,93,65,
-  93,65,102,46,102,61,120,93,120,93,120,93,120,93,102,102,65,102,65,
-  102,65,83,93,65,56,56,56,56,56,56,56,56,83,167,56,56,56,83,83,83,
-  83,83,58,167,167,56,56,28,83,167,82,102,100,101,92,92,92,92,82,42,
-  93,93
-};
-static afm_sint16 afm_Times_BoldItalic_kerning_index[] = { /* 315 */
-  1,0,0,0,0,0,0,0,0,0,0,0,36,0,45,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-  0,0,54,173,0,219,0,254,0,0,0,374,489,581,0,612,636,681,774,797,0,
-  859,1027,1051,1207,0,1362,0,0,0,0,0,0,0,0,1510,1537,0,1545,1548,
-  0,0,0,0,1587,0,0,1630,1633,0,0,1647,0,0,0,1652,1699,1769,1792,0,
-  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-  0,0,1797,1916,2035,2154,2273,2392,0,0,0,0,0,0,0,0,0,0,0,2511,2535,
-  2580,2625,2670,2715,0,2760,2805,2829,2853,2877,2901,0,0,0,0,0,0,
-  0,0,0,3049,3057,3060,3063,3066,0,0,0,0,0,3069,3072,3086,3100,3114,
-  3128,0,3142,0,0,0,0,3156,0,3161,3166,0,3285,0,3404,0,0,3523,0,3531,
-  3539,0,3574,0,0,3609,0,3612,0,3615,0,3618,0,0,0,0,0,0,0,0,0,0,3621,
-  3713,3756,0,3787,0,0,0,3818,0,3849,3873,3876,3900,3903,3927,3930,
-  3975,3989,4034,0,0,4048,4110,4115,4177,4182,4244,0,0,0,0,0,0,4249,
-  0,4417,0,4585,0,4609,0,4633,0,4657,0,4681,0,0,0,0,0,0,0,0,0,0,0,
-  0,0,0,0,0,0,0,0,4829,4834,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-  0,0,0,0,0,0,0
-};
-static afm_cuint8 afm_Times_BoldItalic_kerning_data[] = { /* 4879 */
-  42,16,66,251,87,245,88,245,90,245,193,251,194,251,195,251,196,251,
-  197,251,198,251,222,245,0,2,251,0,4,251,0,6,251,0,122,245,3,1,32,
-  25,241,1,32,29,241,3,1,32,25,241,1,32,29,241,50,68,246,72,247,80,
-  249,82,248,85,248,86,249,87,241,88,240,90,245,118,252,119,245,120,
-  245,122,245,200,246,211,249,212,249,213,249,214,249,215,249,217,
-  249,218,249,219,249,220,249,221,249,222,245,250,252,251,252,252,
-  252,253,252,254,245,0,1,245,0,8,246,0,14,246,0,32,247,0,36,247,0,
-  78,249,0,82,249,0,100,248,0,102,248,0,108,249,0,109,252,0,112,249,
-  0,113,252,0,114,249,0,115,252,0,116,249,0,117,252,0,122,245,1,32,
-  25,245,20,66,253,86,255,193,253,194,253,195,253,196,253,197,253,
-  198,253,218,255,219,255,220,255,221,255,0,2,253,0,4,253,0,6,253,
-  0,108,255,0,112,255,0,114,255,0,116,255,16,66,253,87,249,88,250,
-  90,249,193,253,194,253,195,253,196,253,197,253,198,253,222,249,0,
-  2,253,0,4,253,0,6,253,0,122,249,52,45,235,47,235,66,240,98,241,102,
-  240,106,250,112,245,115,249,193,240,194,240,195,240,196,240,197,
-  240,198,240,225,241,226,241,227,241,228,241,229,241,230,241,233,
-  240,234,240,235,240,236,240,237,250,238,250,239,250,240,250,243,
-  245,244,245,245,245,246,245,247,245,249,245,0,2,240,0,3,241,0,4,
-  240,0,5,241,0,6,240,0,7,241,0,21,240,0,25,240,0,27,240,0,29,240,
-  0,45,250,0,49,250,0,79,245,0,83,245,0,87,249,0,89,249,0,91,249,50,
-  45,255,47,255,66,253,98,250,102,250,112,250,118,250,193,253,194,
-  253,195,253,196,253,197,253,198,253,225,250,226,250,227,250,228,
-  250,229,250,230,250,233,250,234,250,235,250,236,250,243,250,244,
-  250,245,250,246,250,247,250,249,250,250,250,251,250,252,250,253,
-  250,0,2,253,0,3,250,0,4,253,0,5,250,0,6,253,0,7,250,0,21,250,0,25,
-  250,0,27,250,0,29,250,0,79,250,0,83,250,0,109,250,0,113,250,0,115,
-  250,0,117,250,40,80,252,102,253,112,253,118,254,122,254,211,252,
-  212,252,213,252,214,252,215,252,217,252,233,253,234,253,235,253,
-  236,253,243,253,244,253,245,253,246,253,247,253,249,253,250,254,
-  251,254,252,254,253,254,254,254,0,1,254,0,21,253,0,25,253,0,27,253,
-  0,29,253,0,78,252,0,79,253,0,82,252,0,83,253,0,109,254,0,113,254,
-  0,115,254,0,117,254,13,85,254,87,251,88,251,90,251,122,251,222,251,
-  254,251,0,1,251,0,100,254,0,102,254,0,122,251,1,32,25,248,11,66,
-  252,193,252,194,252,195,252,196,252,197,252,198,252,0,2,252,0,4,
-  252,0,6,252,20,66,250,85,250,87,249,88,249,89,250,90,249,193,250,
-  194,250,195,250,196,250,197,250,198,250,222,249,0,2,250,0,4,250,
-  0,6,250,0,100,250,0,102,250,0,122,249,41,45,235,47,235,66,243,98,
-  250,102,249,112,248,193,243,194,243,195,243,196,243,197,243,198,
-  243,225,250,226,250,227,250,228,250,229,250,230,250,233,249,234,
-  249,235,249,236,249,243,248,244,248,245,248,246,248,247,248,249,
-  248,0,2,243,0,3,250,0,4,243,0,5,250,0,6,243,0,7,250,0,21,249,0,25,
-  249,0,27,249,0,29,249,0,79,248,0,83,248,10,86,255,218,255,219,255,
-  220,255,221,255,0,108,255,0,112,255,0,114,255,0,116,255,27,80,250,
-  85,252,86,250,87,254,88,254,90,254,211,250,212,250,213,250,214,250,
-  215,250,217,250,218,250,219,250,220,250,221,250,222,254,0,78,250,
-  0,82,250,0,100,252,0,102,252,0,108,250,0,112,250,0,114,250,0,116,
-  250,0,122,254,73,45,242,46,242,47,242,59,245,60,245,66,248,80,254,
-  98,242,102,242,106,251,112,241,115,251,118,251,120,251,122,251,193,
-  248,194,248,195,248,196,248,197,248,198,248,211,254,212,254,213,
-  254,214,254,215,254,217,254,225,242,226,242,227,242,228,242,229,
-  242,230,242,233,248,234,242,235,242,236,248,238,251,243,241,244,
-  241,245,241,246,241,247,241,249,241,250,251,251,251,252,251,253,
-  251,254,251,0,1,251,0,2,248,0,3,242,0,4,248,0,5,242,0,6,248,0,7,
-  242,0,21,248,0,25,242,0,27,242,0,29,242,0,49,251,0,78,254,0,79,241,
-  0,82,254,0,83,241,0,87,251,0,89,251,0,91,251,0,109,251,0,113,251,
-  0,115,251,0,117,251,11,66,249,193,249,194,249,195,249,196,249,197,
-  249,198,249,0,2,249,0,4,249,0,6,249,68,45,235,46,245,47,235,59,245,
-  60,245,66,243,72,255,80,252,98,238,102,238,106,248,112,238,118,248,
-  193,243,194,243,195,243,196,243,197,243,198,243,211,252,212,252,
-  213,252,214,252,215,252,217,252,225,238,226,238,227,238,228,238,
-  229,238,230,238,233,245,234,238,235,238,236,245,238,248,243,238,
-  244,238,245,238,246,238,247,238,249,238,250,248,251,248,252,248,
-  253,248,0,2,243,0,3,238,0,4,243,0,5,238,0,6,243,0,7,238,0,21,245,
-  0,25,238,0,27,238,0,29,238,0,32,255,0,36,255,0,49,248,0,78,252,0,
-  79,238,0,82,252,0,83,238,0,109,248,0,113,248,0,115,248,0,117,248,
-  68,45,245,46,249,47,245,59,248,60,248,66,245,80,254,98,243,102,242,
-  106,251,112,244,118,248,122,248,193,245,194,245,195,245,196,245,
-  197,245,198,245,211,254,212,254,213,254,214,254,215,254,217,254,
-  225,243,226,243,227,243,228,243,229,243,230,243,233,249,234,242,
-  235,242,236,249,238,251,243,244,244,244,245,244,246,244,247,244,
-  249,244,250,248,251,248,252,248,253,248,254,248,0,1,248,0,2,245,
-  0,3,243,0,4,245,0,5,243,0,6,245,0,7,243,0,21,249,0,25,242,0,27,242,
-  0,29,242,0,49,251,0,78,254,0,79,244,0,82,254,0,83,244,0,109,248,
-  0,113,248,0,115,248,0,117,248,65,45,242,46,242,47,245,59,242,60,
-  242,66,245,80,253,98,242,102,238,106,248,112,238,118,242,193,245,
-  194,245,195,245,196,245,197,245,198,245,211,253,212,253,213,253,
-  214,253,215,253,217,253,225,242,226,242,227,242,228,242,229,242,
-  230,242,233,245,234,238,235,245,236,245,238,248,243,238,244,238,
-  245,238,246,238,247,238,249,238,250,242,251,242,252,242,253,242,
-  0,2,245,0,3,242,0,4,245,0,5,242,0,6,245,0,7,242,0,21,245,0,25,238,
-  0,27,238,0,29,238,0,49,248,0,78,253,0,79,238,0,82,253,0,83,238,0,
-  109,242,0,113,242,0,115,242,0,117,242,12,47,250,99,255,118,254,250,
-  254,251,254,252,254,253,254,0,109,254,0,113,254,0,115,254,0,117,
-  254,4,105,255,108,255,0,57,255,2,99,255,17,45,255,47,255,102,255,
-  103,254,112,255,234,255,243,255,244,255,245,255,246,255,249,255,
-  0,25,255,0,27,255,0,51,252,0,83,255,1,32,25,9,19,102,252,112,255,
-  233,252,234,252,235,252,236,252,243,255,244,255,245,255,246,255,
-  247,255,249,255,0,21,252,0,25,252,0,27,252,0,29,252,0,79,255,0,83,
-  255,2,119,250,7,119,254,120,253,121,255,122,255,254,255,0,1,255,
-  3,45,246,47,246,21,45,251,47,251,102,254,112,254,233,254,234,254,
-  235,254,236,254,243,254,244,254,245,254,246,254,247,254,249,254,
-  0,21,254,0,25,254,0,27,254,0,29,254,0,79,254,0,83,254,31,45,251,
-  47,251,98,255,102,255,112,254,225,255,226,255,227,255,228,255,229,
-  255,230,255,233,255,234,255,235,255,236,255,243,254,244,254,245,
-  254,246,254,247,254,249,254,0,3,255,0,5,255,0,7,255,0,21,255,0,25,
-  255,0,27,255,0,29,255,0,79,254,0,83,254,10,102,255,233,255,234,255,
-  235,255,236,255,0,21,255,0,25,255,0,27,255,0,29,255,3,45,251,47,
-  251,50,68,246,72,247,80,249,82,248,85,248,86,249,87,241,88,240,90,
-  245,118,252,119,245,120,245,122,245,200,246,211,249,212,249,213,
-  249,214,249,215,249,217,249,218,249,219,249,220,249,221,249,222,
-  245,250,252,251,252,252,252,253,252,254,245,0,1,245,0,8,246,0,14,
-  246,0,32,247,0,36,247,0,78,249,0,82,249,0,100,248,0,102,248,0,108,
-  249,0,109,252,0,112,249,0,113,252,0,114,249,0,115,252,0,116,249,
-  0,117,252,0,122,245,1,32,25,245,50,68,246,72,247,80,249,82,248,85,
-  248,86,249,87,241,88,240,90,245,118,252,119,245,120,245,122,245,
-  200,246,211,249,212,249,213,249,214,249,215,249,217,249,218,249,
-  219,249,220,249,221,249,222,245,250,252,251,252,252,252,253,252,
-  254,245,0,1,245,0,8,246,0,14,246,0,32,247,0,36,247,0,78,249,0,82,
-  249,0,100,248,0,102,248,0,108,249,0,109,252,0,112,249,0,113,252,
-  0,114,249,0,115,252,0,116,249,0,117,252,0,122,245,1,32,25,245,50,
-  68,246,72,247,80,249,82,248,85,248,86,249,87,241,88,240,90,245,118,
-  252,119,245,120,245,122,245,200,246,211,249,212,249,213,249,214,
-  249,215,249,217,249,218,249,219,249,220,249,221,249,222,245,250,
-  252,251,252,252,252,253,252,254,245,0,1,245,0,8,246,0,14,246,0,32,
-  247,0,36,247,0,78,249,0,82,249,0,100,248,0,102,248,0,108,249,0,109,
-  252,0,112,249,0,113,252,0,114,249,0,115,252,0,116,249,0,117,252,
-  0,122,245,1,32,25,245,50,68,246,72,247,80,249,82,248,85,248,86,249,
-  87,241,88,240,90,245,118,252,119,245,120,245,122,245,200,246,211,
-  249,212,249,213,249,214,249,215,249,217,249,218,249,219,249,220,
-  249,221,249,222,245,250,252,251,252,252,252,253,252,254,245,0,1,
-  245,0,8,246,0,14,246,0,32,247,0,36,247,0,78,249,0,82,249,0,100,248,
-  0,102,248,0,108,249,0,109,252,0,112,249,0,113,252,0,114,249,0,115,
-  252,0,116,249,0,117,252,0,122,245,1,32,25,245,50,68,246,72,247,80,
-  249,82,248,85,248,86,249,87,241,88,240,90,245,118,252,119,245,120,
-  245,122,245,200,246,211,249,212,249,213,249,214,249,215,249,217,
-  249,218,249,219,249,220,249,221,249,222,245,250,252,251,252,252,
-  252,253,252,254,245,0,1,245,0,8,246,0,14,246,0,32,247,0,36,247,0,
-  78,249,0,82,249,0,100,248,0,102,248,0,108,249,0,109,252,0,112,249,
-  0,113,252,0,114,249,0,115,252,0,116,249,0,117,252,0,122,245,1,32,
-  25,245,50,68,246,72,247,80,249,82,248,85,248,86,249,87,241,88,240,
-  90,245,118,252,119,245,120,245,122,245,200,246,211,249,212,249,213,
-  249,214,249,215,249,217,249,218,249,219,249,220,249,221,249,222,
-  245,250,252,251,252,252,252,253,252,254,245,0,1,245,0,8,246,0,14,
-  246,0,32,247,0,36,247,0,78,249,0,82,249,0,100,248,0,102,248,0,108,
-  249,0,109,252,0,112,249,0,113,252,0,114,249,0,115,252,0,116,249,
-  0,117,252,0,122,245,1,32,25,245,11,66,252,193,252,194,252,195,252,
-  196,252,197,252,198,252,0,2,252,0,4,252,0,6,252,20,66,250,85,250,
-  87,249,88,249,89,250,90,249,193,250,194,250,195,250,196,250,197,
-  250,198,250,222,249,0,2,250,0,4,250,0,6,250,0,100,250,0,102,250,
-  0,122,249,20,66,250,85,250,87,249,88,249,89,250,90,249,193,250,194,
-  250,195,250,196,250,197,250,198,250,222,249,0,2,250,0,4,250,0,6,
-  250,0,100,250,0,102,250,0,122,249,20,66,250,85,250,87,249,88,249,
-  89,250,90,249,193,250,194,250,195,250,196,250,197,250,198,250,222,
-  249,0,2,250,0,4,250,0,6,250,0,100,250,0,102,250,0,122,249,20,66,
-  250,85,250,87,249,88,249,89,250,90,249,193,250,194,250,195,250,196,
-  250,197,250,198,250,222,249,0,2,250,0,4,250,0,6,250,0,100,250,0,
-  102,250,0,122,249,20,66,250,85,250,87,249,88,249,89,250,90,249,193,
-  250,194,250,195,250,196,250,197,250,198,250,222,249,0,2,250,0,4,
-  250,0,6,250,0,100,250,0,102,250,0,122,249,20,66,250,85,250,87,249,
-  88,249,89,250,90,249,193,250,194,250,195,250,196,250,197,250,198,
-  250,222,249,0,2,250,0,4,250,0,6,250,0,100,250,0,102,250,0,122,249,
-  11,66,249,193,249,194,249,195,249,196,249,197,249,198,249,0,2,249,
-  0,4,249,0,6,249,11,66,249,193,249,194,249,195,249,196,249,197,249,
-  198,249,0,2,249,0,4,249,0,6,249,11,66,249,193,249,194,249,195,249,
-  196,249,197,249,198,249,0,2,249,0,4,249,0,6,249,11,66,249,193,249,
-  194,249,195,249,196,249,197,249,198,249,0,2,249,0,4,249,0,6,249,
-  65,45,242,46,242,47,245,59,242,60,242,66,245,80,253,98,242,102,238,
-  106,248,112,238,118,242,193,245,194,245,195,245,196,245,197,245,
-  198,245,211,253,212,253,213,253,214,253,215,253,217,253,225,242,
-  226,242,227,242,228,242,229,242,230,242,233,245,234,238,235,245,
-  236,245,238,248,243,238,244,238,245,238,246,238,247,238,249,238,
-  250,242,251,242,252,242,253,242,0,2,245,0,3,242,0,4,245,0,5,242,
-  0,6,245,0,7,242,0,21,245,0,25,238,0,27,238,0,29,238,0,49,248,0,78,
-  253,0,79,238,0,82,253,0,83,238,0,109,242,0,113,242,0,115,242,0,117,
-  242,4,105,255,108,255,0,57,255,2,99,255,2,99,255,2,99,255,2,99,255,
-  2,119,250,7,119,254,120,253,121,255,122,255,254,255,0,1,255,7,119,
-  254,120,253,121,255,122,255,254,255,0,1,255,7,119,254,120,253,121,
-  255,122,255,254,255,0,1,255,7,119,254,120,253,121,255,122,255,254,
-  255,0,1,255,7,119,254,120,253,121,255,122,255,254,255,0,1,255,7,
-  119,254,120,253,121,255,122,255,254,255,0,1,255,3,45,251,47,251,
-  3,45,251,47,251,50,68,246,72,247,80,249,82,248,85,248,86,249,87,
-  241,88,240,90,245,118,252,119,245,120,245,122,245,200,246,211,249,
-  212,249,213,249,214,249,215,249,217,249,218,249,219,249,220,249,
-  221,249,222,245,250,252,251,252,252,252,253,252,254,245,0,1,245,
-  0,8,246,0,14,246,0,32,247,0,36,247,0,78,249,0,82,249,0,100,248,0,
-  102,248,0,108,249,0,109,252,0,112,249,0,113,252,0,114,249,0,115,
-  252,0,116,249,0,117,252,0,122,245,1,32,25,245,50,68,246,72,247,80,
-  249,82,248,85,248,86,249,87,241,88,240,90,245,118,252,119,245,120,
-  245,122,245,200,246,211,249,212,249,213,249,214,249,215,249,217,
-  249,218,249,219,249,220,249,221,249,222,245,250,252,251,252,252,
-  252,253,252,254,245,0,1,245,0,8,246,0,14,246,0,32,247,0,36,247,0,
-  78,249,0,82,249,0,100,248,0,102,248,0,108,249,0,109,252,0,112,249,
-  0,113,252,0,114,249,0,115,252,0,116,249,0,117,252,0,122,245,1,32,
-  25,245,50,68,246,72,247,80,249,82,248,85,248,86,249,87,241,88,240,
-  90,245,118,252,119,245,120,245,122,251,200,246,211,249,212,249,213,
-  249,214,249,215,249,217,249,218,249,219,249,220,249,221,249,222,
-  245,250,252,251,252,252,252,253,252,254,251,0,1,251,0,8,246,0,14,
-  246,0,32,247,0,36,247,0,78,249,0,82,249,0,100,248,0,102,248,0,108,
-  249,0,109,252,0,112,249,0,113,252,0,114,249,0,115,252,0,116,249,
-  0,117,252,0,122,245,1,32,25,245,4,105,255,108,255,0,57,255,4,105,
-  255,108,255,0,57,255,16,66,253,87,249,88,250,90,249,193,253,194,
-  253,195,253,196,253,197,253,198,253,222,249,0,2,253,0,4,253,0,6,
-  253,0,122,249,16,66,253,87,249,88,250,90,249,193,253,194,253,195,
-  253,196,253,197,253,198,253,222,249,0,2,253,0,4,253,0,6,253,0,122,
-  249,2,99,255,2,99,255,2,99,255,2,99,255,40,80,252,102,253,112,253,
-  118,254,122,254,211,252,212,252,213,252,214,252,215,252,217,252,
-  233,253,234,253,235,253,236,253,243,253,244,253,245,253,246,253,
-  247,253,249,253,250,254,251,254,252,254,253,254,254,254,0,1,254,
-  0,21,253,0,25,253,0,27,253,0,29,253,0,78,252,0,79,253,0,82,252,0,
-  83,253,0,109,254,0,113,254,0,115,254,0,117,254,19,102,252,112,255,
-  233,252,234,252,235,252,236,252,243,255,244,255,245,255,246,255,
-  247,255,249,255,0,21,252,0,25,252,0,27,252,0,29,252,0,79,255,0,83,
-  255,13,85,254,87,251,88,251,90,251,122,251,222,251,254,251,0,1,251,
-  0,100,254,0,102,254,0,122,251,1,32,25,248,13,85,254,87,251,88,251,
-  90,251,122,251,222,251,254,251,0,1,251,0,100,254,0,102,254,0,122,
-  251,1,32,25,248,13,85,254,87,251,88,251,90,251,122,251,222,251,254,
-  251,0,1,251,0,100,254,0,102,254,0,122,251,1,32,25,248,11,66,252,
-  193,252,194,252,195,252,196,252,197,252,198,252,0,2,252,0,4,252,
-  0,6,252,2,119,250,11,66,252,193,252,194,252,195,252,196,252,197,
-  252,198,252,0,2,252,0,4,252,0,6,252,2,119,250,11,66,252,193,252,
-  194,252,195,252,196,252,197,252,198,252,0,2,252,0,4,252,0,6,252,
-  2,119,250,20,66,250,85,250,87,249,88,249,89,250,90,249,193,250,194,
-  250,195,250,196,250,197,250,198,250,222,249,0,2,250,0,4,250,0,6,
-  250,0,100,250,0,102,250,0,122,249,7,119,254,120,253,121,255,122,
-  255,254,255,0,1,255,20,66,250,85,250,87,249,88,249,89,250,90,249,
-  193,250,194,250,195,250,196,250,197,250,198,250,222,249,0,2,250,
-  0,4,250,0,6,250,0,100,250,0,102,250,0,122,249,7,119,254,120,253,
-  121,255,122,255,254,255,0,1,255,27,80,250,85,252,86,250,87,254,88,
-  254,90,254,211,250,212,250,213,250,214,250,215,250,217,250,218,250,
-  219,250,220,250,221,250,222,254,0,78,250,0,82,250,0,100,252,0,102,
-  252,0,108,250,0,112,250,0,114,250,0,116,250,0,122,254,3,45,246,47,
-  246,27,80,250,85,252,86,250,87,254,88,254,90,254,211,250,212,250,
-  213,250,214,250,215,250,217,250,218,250,219,250,220,250,221,250,
-  222,254,0,78,250,0,82,250,0,100,252,0,102,252,0,108,250,0,112,250,
-  0,114,250,0,116,250,0,122,254,3,45,246,47,246,27,80,250,85,252,86,
-  250,87,254,88,254,90,254,211,250,212,250,213,250,214,250,215,250,
-  217,250,218,250,219,250,220,250,221,250,222,254,0,78,250,0,82,250,
-  0,100,252,0,102,252,0,108,250,0,112,250,0,114,250,0,116,250,0,122,
-  254,3,45,246,47,246,73,45,242,46,242,47,242,59,245,60,245,66,248,
-  80,254,98,242,102,242,106,251,112,241,115,251,118,251,120,251,122,
-  251,193,248,194,248,195,248,196,248,197,248,198,248,211,254,212,
-  254,213,254,214,254,215,254,217,254,225,242,226,242,227,242,228,
-  242,229,242,230,242,233,248,234,242,235,242,236,248,238,251,243,
-  241,244,241,245,241,246,241,247,241,249,241,250,251,251,251,252,
-  251,253,251,254,251,0,1,251,0,2,248,0,3,242,0,4,248,0,5,242,0,6,
-  248,0,7,242,0,21,248,0,25,242,0,27,242,0,29,242,0,49,251,0,78,254,
-  0,79,241,0,82,254,0,83,241,0,87,251,0,89,251,0,91,251,0,109,251,
-  0,113,251,0,115,251,0,117,251,73,45,242,46,242,47,242,59,245,60,
-  245,66,248,80,254,98,242,102,242,106,251,112,241,115,251,118,251,
-  120,251,122,251,193,248,194,248,195,248,196,248,197,248,198,248,
-  211,254,212,254,213,254,214,254,215,254,217,254,225,242,226,242,
-  227,242,228,242,229,242,230,242,233,248,234,242,235,242,236,248,
-  238,251,243,241,244,241,245,241,246,241,247,241,249,241,250,251,
-  251,251,252,251,253,251,254,251,0,1,251,0,2,248,0,3,242,0,4,248,
-  0,5,242,0,6,248,0,7,242,0,21,248,0,25,242,0,27,242,0,29,242,0,49,
-  251,0,78,254,0,79,241,0,82,254,0,83,241,0,87,251,0,89,251,0,91,251,
-  0,109,251,0,113,251,0,115,251,0,117,251,11,66,249,193,249,194,249,
-  195,249,196,249,197,249,198,249,0,2,249,0,4,249,0,6,249,11,66,249,
-  193,249,194,249,195,249,196,249,197,249,198,249,0,2,249,0,4,249,
-  0,6,249,11,66,249,193,249,194,249,195,249,196,249,197,249,198,249,
-  0,2,249,0,4,249,0,6,249,11,66,249,193,249,194,249,195,249,196,249,
-  197,249,198,249,0,2,249,0,4,249,0,6,249,65,45,242,46,242,47,245,
-  59,242,60,242,66,245,80,253,98,242,102,238,106,248,112,238,118,242,
-  193,245,194,245,195,245,196,245,197,245,198,245,211,253,212,253,
-  213,253,214,253,215,253,217,253,225,242,226,242,227,242,228,242,
-  229,242,230,242,233,245,234,238,235,245,236,245,238,248,243,238,
-  244,238,245,238,246,238,247,238,249,238,250,242,251,242,252,242,
-  253,242,0,2,245,0,3,242,0,4,245,0,5,242,0,6,245,0,7,242,0,21,245,
-  0,25,238,0,27,238,0,29,238,0,49,248,0,78,253,0,79,238,0,82,253,0,
-  83,238,0,109,242,0,113,242,0,115,242,0,117,242,2,1,32,24,245,17,
-  33,245,101,254,115,254,116,245,117,251,119,254,0,19,254,0,87,254,
-  0,89,254,0,91,254,0,93,245,0,97,245,0,99,245,0,101,251,1,2,25,245,
-  1,32,25,245
-};
-static afm_cuint16 afm_Times_BoldItalic_highchars_index[] = { /* 220 */
-  161,162,163,164,165,166,167,168,169,170,171,172,174,175,176,177,
-  178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,
-  194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,
-  210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,
-  226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,
-  242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,
-  258,259,260,261,262,263,268,269,270,271,272,273,274,275,278,279,
-  280,281,282,283,286,287,290,291,298,299,302,303,304,305,310,311,
-  313,314,315,316,317,318,321,322,323,324,325,326,327,328,332,333,
-  336,337,338,339,340,341,342,343,344,345,346,347,350,351,352,353,
-  354,355,356,357,362,363,366,367,368,369,370,371,376,377,378,379,
-  380,381,382,402,536,537,710,711,728,729,730,731,732,733,8211,8212,
-  8216,8217,8218,8220,8221,8222,8224,8225,8226,8230,8240,8249,8250,
-  8260,8364,8482,8706,8710,8721,8722,8730,8800,8804,8805,9674,63171,
-  64257,64258
-};
-static afm_cunicode afm_Times_BoldItalic_ligatures[] = { /* 3 */
-  102,105,64257
-};
-
-
-/* ------------------------------------------------------------------*/
-/* FontName: Times-Italic */
-/* FullName: Times Italic */
-/* FamilyName: Times */
-static afm_cuint8 afm_Times_Italic_widths[] = { /* 315 */
-  42,56,70,83,83,139,130,36,56,56,83,113,42,56,42,46,83,83,83,83,83,
-  83,83,83,83,83,56,56,113,113,113,83,153,102,102,111,120,102,102,
-  120,120,56,74,111,93,139,111,120,102,120,102,83,93,120,102,139,102,
-  93,93,65,46,65,70,83,56,83,83,74,83,74,46,83,83,46,46,74,46,120,
-  83,83,83,83,65,65,46,83,74,111,74,74,65,67,46,67,90,65,83,83,83,
-  83,46,83,56,127,46,83,113,127,56,67,113,50,50,56,83,87,42,56,50,
-  52,83,125,125,125,83,102,102,102,102,102,102,148,111,102,102,102,
-  102,56,56,56,56,120,111,120,120,120,120,120,113,120,120,120,120,
-  120,93,102,83,83,83,83,83,83,83,111,74,74,74,74,74,46,46,46,46,83,
-  83,83,83,83,83,83,113,83,83,83,83,83,74,83,74,102,83,102,83,102,
-  83,111,74,111,74,120,91,120,83,102,74,102,74,102,74,102,74,120,83,
-  120,83,56,46,56,46,56,46,111,74,93,46,93,46,102,50,93,46,111,83,
-  111,83,111,83,120,83,120,83,157,111,102,65,102,65,102,65,83,65,83,
-  65,83,65,93,46,93,50,120,83,120,83,120,83,120,83,93,93,65,93,65,
-  93,65,83,83,65,56,56,56,56,56,56,56,56,83,148,56,56,56,93,93,93,
-  83,83,58,148,167,56,56,28,83,163,79,102,100,113,76,92,92,92,79,42,
-  83,83
-};
-static afm_sint16 afm_Times_Italic_kerning_index[] = { /* 315 */
-  1,0,0,0,0,0,0,0,0,0,0,0,44,0,53,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-  0,0,62,181,0,227,0,262,0,0,0,382,497,589,0,620,644,689,782,805,0,
-  859,1027,1055,1212,0,1367,0,0,0,0,0,0,0,1524,1533,1558,0,1566,1592,
-  1611,0,0,0,1646,0,0,1696,1699,0,0,1710,0,0,0,1822,1827,0,1832,0,
-  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-  0,0,1837,1956,2075,2194,2313,2432,0,0,0,0,0,0,0,0,0,0,0,2551,2575,
-  2620,2665,2710,2755,0,2800,2845,2873,2901,2929,2957,0,0,3114,3123,
-  3132,3141,3150,3159,0,3168,3176,3202,3228,3254,0,0,0,0,0,3280,3283,
-  3294,3305,3316,3327,0,3338,0,0,0,0,3349,0,3354,3359,3478,3487,3606,
-  3615,3734,0,3743,0,3751,3759,0,3794,0,0,3829,0,3855,0,3881,0,3907,
-  0,3933,0,3968,0,0,0,0,0,0,4003,4095,4145,0,4176,0,0,0,4207,0,4238,
-  4262,4265,4289,4292,4316,4319,4364,4375,4420,0,0,4431,4485,4597,
-  4651,4763,4817,0,0,0,0,0,0,4929,0,5097,0,5265,0,5293,0,5321,0,5349,
-  0,5377,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,5534,5539,0,0,0,0,0,
-  0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0
-};
-static afm_cuint8 afm_Times_Italic_kerning_data[] = { /* 5584 */
-  42,19,66,254,85,254,87,251,88,250,90,244,193,254,194,254,195,254,
-  196,254,197,254,198,254,222,244,0,2,254,0,4,254,0,6,254,0,100,254,
-  0,102,254,0,122,244,3,1,32,25,234,1,32,29,234,3,1,32,25,234,1,32,
-  29,234,50,68,252,72,251,80,250,82,250,85,251,86,249,87,239,88,241,
-  90,248,118,254,119,248,120,248,122,248,200,252,211,250,212,250,213,
-  250,214,250,215,250,217,250,218,249,219,249,220,249,221,249,222,
-  248,250,254,251,254,252,254,253,254,254,248,0,1,248,0,8,252,0,14,
-  252,0,32,251,0,36,251,0,78,250,0,82,250,0,100,251,0,102,251,0,108,
-  249,0,109,254,0,112,249,0,113,254,0,114,249,0,115,254,0,116,249,
-  0,117,254,0,122,248,1,32,25,251,20,66,253,86,255,193,253,194,253,
-  195,253,196,253,197,253,198,253,218,255,219,255,220,255,221,255,
-  0,2,253,0,4,253,0,6,253,0,108,255,0,112,255,0,114,255,0,116,255,
-  16,66,251,87,250,88,250,90,250,193,251,194,251,195,251,196,251,197,
-  251,198,251,222,250,0,2,251,0,4,251,0,6,251,0,122,250,52,45,234,
-  47,234,66,238,98,244,102,244,106,249,112,239,115,248,193,238,194,
-  238,195,238,196,238,197,238,198,238,225,244,226,244,227,244,228,
-  244,229,244,230,244,233,244,234,244,235,244,236,244,237,249,238,
-  249,239,249,240,249,243,239,244,239,245,239,246,239,247,239,249,
-  239,0,2,238,0,3,244,0,4,238,0,5,244,0,6,238,0,7,244,0,21,244,0,25,
-  244,0,27,244,0,29,244,0,45,249,0,49,249,0,79,239,0,83,239,0,87,248,
-  0,89,248,0,91,248,50,45,253,47,253,66,250,98,251,102,253,112,253,
-  118,251,193,250,194,250,195,250,196,250,197,250,198,250,225,251,
-  226,251,227,251,228,251,229,251,230,251,233,253,234,253,235,253,
-  236,253,243,253,244,253,245,253,246,253,247,253,249,253,250,251,
-  251,251,252,251,253,251,0,2,250,0,3,251,0,4,250,0,5,251,0,6,250,
-  0,7,251,0,21,253,0,25,253,0,27,253,0,29,253,0,79,253,0,83,253,0,
-  109,251,0,113,251,0,115,251,0,117,251,40,80,249,102,251,112,250,
-  118,250,122,250,211,249,212,249,213,249,214,249,215,249,217,249,
-  233,251,234,251,235,251,236,251,243,250,244,250,245,250,246,250,
-  247,250,249,250,250,250,251,250,252,250,253,250,254,250,0,1,250,
-  0,21,251,0,25,251,0,27,251,0,29,251,0,78,249,0,79,250,0,82,249,0,
-  83,250,0,109,250,0,113,250,0,115,250,0,117,250,13,85,254,87,248,
-  88,248,90,254,122,252,222,254,254,252,0,1,252,0,100,254,0,102,254,
-  0,122,254,1,32,25,251,11,66,252,193,252,194,252,195,252,196,252,
-  197,252,198,252,0,2,252,0,4,252,0,6,252,20,66,248,85,250,87,249,
-  88,249,89,250,90,249,193,248,194,248,195,248,196,248,197,248,198,
-  248,222,249,0,2,248,0,4,248,0,6,248,0,100,250,0,102,250,0,122,249,
-  41,45,234,47,234,66,242,98,244,102,244,112,244,193,242,194,242,195,
-  242,196,242,197,242,198,242,225,244,226,244,227,244,228,244,229,
-  244,230,244,233,244,234,244,235,244,236,244,243,244,244,244,245,
-  244,246,244,247,244,249,244,0,2,242,0,3,244,0,4,242,0,5,244,0,6,
-  242,0,7,244,0,21,244,0,25,244,0,27,244,0,29,244,0,79,244,0,83,244,
-  10,86,255,218,255,219,255,220,255,221,255,0,108,255,0,112,255,0,
-  114,255,0,116,255,24,80,250,86,250,87,254,88,254,90,254,211,250,
-  212,250,213,250,214,250,215,250,217,250,218,250,219,250,220,250,
-  221,250,222,254,0,78,250,0,82,250,0,108,250,0,112,250,0,114,250,
-  0,116,250,0,122,254,73,45,245,46,245,47,245,59,248,60,246,66,249,
-  80,254,98,242,102,242,106,248,112,242,115,248,118,248,120,245,122,
-  245,193,249,194,249,195,249,196,249,197,249,198,249,211,254,212,
-  254,213,254,214,254,215,254,217,254,225,242,226,242,227,242,228,
-  242,229,242,230,242,233,248,234,242,235,248,236,248,238,248,243,
-  242,244,242,245,242,246,242,247,242,249,242,250,248,251,248,252,
-  248,253,248,254,245,0,1,251,0,2,249,0,3,242,0,4,249,0,5,242,0,6,
-  249,0,7,242,0,21,248,0,25,242,0,27,242,0,29,242,0,49,248,0,78,254,
-  0,79,242,0,82,254,0,83,242,0,87,248,0,89,248,0,91,248,0,109,248,
-  0,113,248,0,115,248,0,117,248,13,45,253,47,253,66,250,193,250,194,
-  250,195,250,196,250,197,250,198,250,0,2,250,0,4,250,0,6,250,69,45,
-  235,46,248,47,235,59,246,60,245,66,247,80,252,98,238,102,238,106,
-  245,112,238,118,245,193,247,194,247,195,247,196,247,197,247,198,
-  247,211,252,212,252,213,252,214,252,215,252,217,252,225,238,226,
-  238,227,238,228,238,229,238,230,238,233,245,234,238,235,238,236,
-  245,237,251,238,245,239,251,240,251,243,238,244,238,245,238,246,
-  238,247,238,249,238,250,245,251,245,252,245,253,245,0,2,247,0,3,
-  238,0,4,247,0,5,238,0,6,247,0,7,238,0,21,245,0,25,238,0,27,238,0,
-  29,238,0,45,251,0,49,245,0,78,252,0,79,238,0,82,252,0,83,238,0,109,
-  245,0,113,245,0,115,245,0,117,245,68,45,242,46,251,47,242,59,246,
-  60,246,66,247,80,253,98,242,102,242,106,248,112,242,118,248,122,
-  245,193,247,194,247,195,247,196,247,197,247,198,247,211,253,212,
-  253,213,253,214,253,215,253,217,253,225,242,226,242,227,242,228,
-  242,229,242,230,242,233,248,234,242,235,242,236,248,238,248,243,
-  242,244,242,245,242,246,242,247,242,249,242,250,248,251,248,252,
-  248,253,248,254,245,0,1,245,0,2,247,0,3,242,0,4,247,0,5,242,0,6,
-  247,0,7,242,0,21,248,0,25,242,0,27,242,0,29,242,0,49,248,0,78,253,
-  0,79,242,0,82,253,0,83,242,0,109,248,0,113,248,0,115,248,0,117,248,
-  69,45,242,46,245,47,242,59,246,60,246,66,249,80,254,98,242,102,242,
-  106,245,112,242,118,242,193,249,194,249,195,249,196,249,197,249,
-  198,249,211,254,212,254,213,254,214,254,215,254,217,254,225,242,
-  226,242,227,242,228,242,229,242,230,242,233,248,234,242,235,242,
-  236,248,237,251,238,245,239,251,240,251,243,242,244,242,245,242,
-  246,242,247,242,249,242,250,242,251,242,252,242,253,242,0,2,249,
-  0,3,242,0,4,249,0,5,242,0,6,249,0,7,242,0,21,248,0,25,242,0,27,242,
-  0,29,242,0,45,251,0,49,245,0,78,254,0,79,242,0,82,254,0,83,242,0,
-  109,242,0,113,242,0,115,242,0,117,242,4,104,255,0,33,255,0,37,255,
-  11,47,250,118,254,250,254,251,254,252,254,253,254,0,109,254,0,113,
-  254,0,115,254,0,117,254,4,105,254,108,254,0,57,254,12,45,255,47,
-  254,104,250,119,254,120,254,121,254,122,252,254,252,0,1,252,0,33,
-  250,0,37,250,8,45,255,47,254,103,254,106,254,0,49,254,0,51,247,1,
-  32,25,15,15,45,255,47,254,102,255,104,255,233,255,234,255,235,255,
-  236,255,0,21,255,0,25,255,0,27,255,0,29,255,0,33,255,0,37,255,22,
-  102,255,112,255,122,255,233,255,234,255,235,255,236,255,243,255,
-  244,255,245,255,246,255,247,255,249,255,254,255,0,1,255,0,21,255,
-  0,25,255,0,27,255,0,29,255,0,79,255,0,83,255,2,119,250,5,104,255,
-  119,255,0,33,255,0,37,255,47,45,238,46,254,47,238,98,254,100,251,
-  101,251,102,251,104,251,112,249,114,251,116,255,225,254,226,254,
-  227,254,228,254,229,254,230,254,232,251,233,251,234,251,235,251,
-  236,251,243,249,244,249,245,249,246,249,247,249,249,249,0,3,254,
-  0,5,254,0,7,254,0,9,251,0,15,251,0,19,251,0,21,251,0,25,251,0,27,
-  251,0,29,251,0,33,251,0,37,251,0,79,249,0,83,249,0,93,255,0,97,255,
-  0,99,255,1,2,25,255,3,45,245,47,245,3,45,245,47,245,3,45,248,47,
-  248,50,68,252,72,251,80,250,82,250,85,251,86,249,87,239,88,241,90,
-  248,118,254,119,248,120,248,122,248,200,252,211,250,212,250,213,
-  250,214,250,215,250,217,250,218,249,219,249,220,249,221,249,222,
-  248,250,254,251,254,252,254,253,254,254,248,0,1,248,0,8,252,0,14,
-  252,0,32,251,0,36,251,0,78,250,0,82,250,0,100,251,0,102,251,0,108,
-  249,0,109,254,0,112,249,0,113,254,0,114,249,0,115,254,0,116,249,
-  0,117,254,0,122,248,1,32,25,251,50,68,252,72,251,80,250,82,250,85,
-  251,86,249,87,239,88,241,90,248,118,254,119,248,120,248,122,248,
-  200,252,211,250,212,250,213,250,214,250,215,250,217,250,218,249,
-  219,249,220,249,221,249,222,248,250,254,251,254,252,254,253,254,
-  254,248,0,1,248,0,8,252,0,14,252,0,32,251,0,36,251,0,78,250,0,82,
-  250,0,100,251,0,102,251,0,108,249,0,109,254,0,112,249,0,113,254,
-  0,114,249,0,115,254,0,116,249,0,117,254,0,122,248,1,32,25,251,50,
-  68,252,72,251,80,250,82,250,85,251,86,249,87,239,88,241,90,248,118,
-  254,119,248,120,248,122,248,200,252,211,250,212,250,213,250,214,
-  250,215,250,217,250,218,249,219,249,220,249,221,249,222,248,250,
-  254,251,254,252,254,253,254,254,248,0,1,248,0,8,252,0,14,252,0,32,
-  251,0,36,251,0,78,250,0,82,250,0,100,251,0,102,251,0,108,249,0,109,
-  254,0,112,249,0,113,254,0,114,249,0,115,254,0,116,249,0,117,254,
-  0,122,248,1,32,25,251,50,68,252,72,251,80,250,82,250,85,251,86,249,
-  87,239,88,241,90,248,118,254,119,248,120,248,122,248,200,252,211,
-  250,212,250,213,250,214,250,215,250,217,250,218,249,219,249,220,
-  249,221,249,222,248,250,254,251,254,252,254,253,254,254,248,0,1,
-  248,0,8,252,0,14,252,0,32,251,0,36,251,0,78,250,0,82,250,0,100,251,
-  0,102,251,0,108,249,0,109,254,0,112,249,0,113,254,0,114,249,0,115,
-  254,0,116,249,0,117,254,0,122,248,1,32,25,251,50,68,252,72,251,80,
-  250,82,250,85,251,86,249,87,239,88,241,90,248,118,254,119,248,120,
-  248,122,248,200,252,211,250,212,250,213,250,214,250,215,250,217,
-  250,218,249,219,249,220,249,221,249,222,248,250,254,251,254,252,
-  254,253,254,254,248,0,1,248,0,8,252,0,14,252,0,32,251,0,36,251,0,
-  78,250,0,82,250,0,100,251,0,102,251,0,108,249,0,109,254,0,112,249,
-  0,113,254,0,114,249,0,115,254,0,116,249,0,117,254,0,122,248,1,32,
-  25,251,50,68,252,72,251,80,250,82,250,85,251,86,249,87,239,88,241,
-  90,248,118,254,119,248,120,248,122,248,200,252,211,250,212,250,213,
-  250,214,250,215,250,217,250,218,249,219,249,220,249,221,249,222,
-  248,250,254,251,254,252,254,253,254,254,248,0,1,248,0,8,252,0,14,
-  252,0,32,251,0,36,251,0,78,250,0,82,250,0,100,251,0,102,251,0,108,
-  249,0,109,254,0,112,249,0,113,254,0,114,249,0,115,254,0,116,249,
-  0,117,254,0,122,248,1,32,25,251,11,66,252,193,252,194,252,195,252,
-  196,252,197,252,198,252,0,2,252,0,4,252,0,6,252,20,66,248,85,250,
-  87,249,88,249,89,250,90,249,193,248,194,248,195,248,196,248,197,
-  248,198,248,222,249,0,2,248,0,4,248,0,6,248,0,100,250,0,102,250,
-  0,122,249,20,66,248,85,250,87,249,88,249,89,250,90,249,193,248,194,
-  248,195,248,196,248,197,248,198,248,222,249,0,2,248,0,4,248,0,6,
-  248,0,100,250,0,102,250,0,122,249,20,66,248,85,250,87,249,88,249,
-  89,250,90,249,193,248,194,248,195,248,196,248,197,248,198,248,222,
-  249,0,2,248,0,4,248,0,6,248,0,100,250,0,102,250,0,122,249,20,66,
-  248,85,250,87,249,88,249,89,250,90,249,193,248,194,248,195,248,196,
-  248,197,248,198,248,222,249,0,2,248,0,4,248,0,6,248,0,100,250,0,
-  102,250,0,122,249,20,66,248,85,250,87,249,88,249,89,250,90,249,193,
-  248,194,248,195,248,196,248,197,248,198,248,222,249,0,2,248,0,4,
-  248,0,6,248,0,100,250,0,102,250,0,122,249,20,66,248,85,250,87,249,
-  88,249,89,250,90,249,193,248,194,248,195,248,196,248,197,248,198,
-  248,222,249,0,2,248,0,4,248,0,6,248,0,100,250,0,102,250,0,122,249,
-  13,45,253,47,253,66,250,193,250,194,250,195,250,196,250,197,250,
-  198,250,0,2,250,0,4,250,0,6,250,13,45,253,47,253,66,250,193,250,
-  194,250,195,250,196,250,197,250,198,250,0,2,250,0,4,250,0,6,250,
-  13,45,253,47,253,66,250,193,250,194,250,195,250,196,250,197,250,
-  198,250,0,2,250,0,4,250,0,6,250,13,45,253,47,253,66,250,193,250,
-  194,250,195,250,196,250,197,250,198,250,0,2,250,0,4,250,0,6,250,
-  69,45,242,46,245,47,242,59,246,60,246,66,249,80,254,98,242,102,242,
-  106,245,112,242,118,242,193,249,194,249,195,249,196,249,197,249,
-  198,249,211,254,212,254,213,254,214,254,215,254,217,254,225,242,
-  226,242,227,242,228,242,229,242,230,242,233,248,234,242,235,242,
-  236,248,237,251,238,245,239,251,240,251,243,242,244,242,245,242,
-  246,242,247,242,249,242,250,242,251,242,252,242,253,242,0,2,249,
-  0,3,242,0,4,249,0,5,242,0,6,249,0,7,242,0,21,248,0,25,242,0,27,242,
-  0,29,242,0,45,251,0,49,245,0,78,254,0,79,242,0,82,254,0,83,242,0,
-  109,242,0,113,242,0,115,242,0,117,242,4,104,255,0,33,255,0,37,255,
-  4,104,255,0,33,255,0,37,255,4,104,255,0,33,255,0,37,255,4,104,255,
-  0,33,255,0,37,255,4,104,255,0,33,255,0,37,255,4,104,255,0,33,255,
-  0,37,255,4,105,254,108,254,0,57,254,12,45,255,47,254,104,250,119,
-  254,120,254,121,254,122,252,254,252,0,1,252,0,33,250,0,37,250,12,
-  45,255,47,254,104,250,119,254,120,254,121,254,122,252,254,252,0,
-  1,252,0,33,250,0,37,250,12,45,255,47,254,104,250,119,254,120,254,
-  121,254,122,252,254,252,0,1,252,0,33,250,0,37,250,12,45,255,47,254,
-  104,250,119,254,120,254,121,254,122,252,254,252,0,1,252,0,33,250,
-  0,37,250,2,119,250,5,104,255,119,255,0,33,255,0,37,255,5,104,255,
-  119,255,0,33,255,0,37,255,5,104,255,119,255,0,33,255,0,37,255,5,
-  104,255,119,255,0,33,255,0,37,255,5,104,255,119,255,0,33,255,0,37,
-  255,5,104,255,119,255,0,33,255,0,37,255,3,45,248,47,248,3,45,248,
-  47,248,50,68,252,72,251,80,250,82,250,85,251,86,249,87,239,88,241,
-  90,248,118,254,119,248,120,248,122,248,200,252,211,250,212,250,213,
-  250,214,250,215,250,217,250,218,249,219,249,220,249,221,249,222,
-  248,250,254,251,254,252,254,253,254,254,248,0,1,248,0,8,252,0,14,
-  252,0,32,251,0,36,251,0,78,250,0,82,250,0,100,251,0,102,251,0,108,
-  249,0,109,254,0,112,249,0,113,254,0,114,249,0,115,254,0,116,249,
-  0,117,254,0,122,248,1,32,25,251,4,104,255,0,33,255,0,37,255,50,68,
-  252,72,251,80,250,82,250,85,251,86,249,87,239,88,241,90,248,118,
-  254,119,248,120,248,122,248,200,252,211,250,212,250,213,250,214,
-  250,215,250,217,250,218,249,219,249,220,249,221,249,222,248,250,
-  254,251,254,252,254,253,254,254,248,0,1,248,0,8,252,0,14,252,0,32,
-  251,0,36,251,0,78,250,0,82,250,0,100,251,0,102,251,0,108,249,0,109,
-  254,0,112,249,0,113,254,0,114,249,0,115,254,0,116,249,0,117,254,
-  0,122,248,1,32,25,251,4,104,255,0,33,255,0,37,255,50,68,252,72,251,
-  80,250,82,250,85,251,86,249,87,239,88,241,90,248,118,254,119,248,
-  120,248,122,248,200,252,211,250,212,250,213,250,214,250,215,250,
-  217,250,218,249,219,249,220,249,221,249,222,248,250,254,251,254,
-  252,254,253,254,254,248,0,1,248,0,8,252,0,14,252,0,32,251,0,36,251,
-  0,78,250,0,82,250,0,100,251,0,102,251,0,108,249,0,109,254,0,112,
-  249,0,113,254,0,114,249,0,115,254,0,116,249,0,117,254,0,122,248,
-  1,32,25,251,4,104,255,0,33,255,0,37,255,4,105,254,108,254,0,57,254,
-  4,105,254,108,254,0,57,254,16,66,251,87,250,88,250,90,250,193,251,
-  194,251,195,251,196,251,197,251,198,251,222,250,0,2,251,0,4,251,
-  0,6,251,0,122,250,16,66,251,87,250,88,250,90,250,193,251,194,251,
-  195,251,196,251,197,251,198,251,222,250,0,2,251,0,4,251,0,6,251,
-  0,122,250,12,45,255,47,254,104,250,119,254,120,254,121,254,122,252,
-  254,252,0,1,252,0,33,250,0,37,250,12,45,255,47,254,104,250,119,254,
-  120,254,121,254,122,252,254,252,0,1,252,0,33,250,0,37,250,12,45,
-  255,47,254,104,250,119,254,120,254,121,254,122,252,254,252,0,1,252,
-  0,33,250,0,37,250,12,45,255,47,254,104,250,119,254,120,254,121,254,
-  122,252,254,252,0,1,252,0,33,250,0,37,250,15,45,255,47,254,102,255,
-  104,255,233,255,234,255,235,255,236,255,0,21,255,0,25,255,0,27,255,
-  0,29,255,0,33,255,0,37,255,15,45,255,47,254,102,255,104,255,233,
-  255,234,255,235,255,236,255,0,21,255,0,25,255,0,27,255,0,29,255,
-  0,33,255,0,37,255,40,80,249,102,251,112,250,118,250,122,250,211,
-  249,212,249,213,249,214,249,215,249,217,249,233,251,234,251,235,
-  251,236,251,243,250,244,250,245,250,246,250,247,250,249,250,250,
-  250,251,250,252,250,253,250,254,250,0,1,250,0,21,251,0,25,251,0,
-  27,251,0,29,251,0,78,249,0,79,250,0,82,249,0,83,250,0,109,250,0,
-  113,250,0,115,250,0,117,250,22,102,255,112,255,122,255,233,255,234,
-  255,235,255,236,255,243,255,244,255,245,255,246,255,247,255,249,
-  255,254,255,0,1,255,0,21,255,0,25,255,0,27,255,0,29,255,0,79,255,
-  0,83,255,13,85,254,87,248,88,248,90,254,122,252,222,254,254,252,
-  0,1,252,0,100,254,0,102,254,0,122,254,1,32,25,251,13,85,254,87,248,
-  88,248,90,254,122,252,222,254,254,252,0,1,252,0,100,254,0,102,254,
-  0,122,254,1,32,25,251,13,85,254,87,248,88,248,90,254,122,252,222,
-  254,254,252,0,1,252,0,100,254,0,102,254,0,122,254,1,32,25,251,11,
-  66,252,193,252,194,252,195,252,196,252,197,252,198,252,0,2,252,0,
-  4,252,0,6,252,2,119,250,11,66,252,193,252,194,252,195,252,196,252,
-  197,252,198,252,0,2,252,0,4,252,0,6,252,2,119,250,11,66,252,193,
-  252,194,252,195,252,196,252,197,252,198,252,0,2,252,0,4,252,0,6,
-  252,2,119,250,20,66,248,85,250,87,249,88,249,89,250,90,249,193,248,
-  194,248,195,248,196,248,197,248,198,248,222,249,0,2,248,0,4,248,
-  0,6,248,0,100,250,0,102,250,0,122,249,5,104,255,119,255,0,33,255,
-  0,37,255,20,66,248,85,250,87,249,88,249,89,250,90,249,193,248,194,
-  248,195,248,196,248,197,248,198,248,222,249,0,2,248,0,4,248,0,6,
-  248,0,100,250,0,102,250,0,122,249,5,104,255,119,255,0,33,255,0,37,
-  255,24,80,250,86,250,87,254,88,254,90,254,211,250,212,250,213,250,
-  214,250,215,250,217,250,218,250,219,250,220,250,221,250,222,254,
-  0,78,250,0,82,250,0,108,250,0,112,250,0,114,250,0,116,250,0,122,
-  254,47,45,238,46,254,47,238,98,254,100,251,101,251,102,251,104,251,
-  112,249,114,251,116,255,225,254,226,254,227,254,228,254,229,254,
-  230,254,232,251,233,251,234,251,235,251,236,251,243,249,244,249,
-  245,249,246,249,247,249,249,249,0,3,254,0,5,254,0,7,254,0,9,251,
-  0,15,251,0,19,251,0,21,251,0,25,251,0,27,251,0,29,251,0,33,251,0,
-  37,251,0,79,249,0,83,249,0,93,255,0,97,255,0,99,255,1,2,25,255,24,
-  80,250,86,250,87,254,88,254,90,254,211,250,212,250,213,250,214,250,
-  215,250,217,250,218,250,219,250,220,250,221,250,222,254,0,78,250,
-  0,82,250,0,108,250,0,112,250,0,114,250,0,116,250,0,122,254,47,45,
-  238,46,254,47,238,98,254,100,251,101,251,102,251,104,251,112,249,
-  114,251,116,255,225,254,226,254,227,254,228,254,229,254,230,254,
-  232,251,233,251,234,251,235,251,236,251,243,249,244,249,245,249,
-  246,249,247,249,249,249,0,3,254,0,5,254,0,7,254,0,9,251,0,15,251,
-  0,19,251,0,21,251,0,25,251,0,27,251,0,29,251,0,33,251,0,37,251,0,
-  79,249,0,83,249,0,93,255,0,97,255,0,99,255,1,2,25,255,24,80,250,
-  86,250,87,254,88,254,90,254,211,250,212,250,213,250,214,250,215,
-  250,217,250,218,250,219,250,220,250,221,250,222,254,0,78,250,0,82,
-  250,0,108,250,0,112,250,0,114,250,0,116,250,0,122,254,47,45,238,
-  46,254,47,238,98,254,100,251,101,251,102,251,104,251,112,249,114,
-  251,116,255,225,254,226,254,227,254,228,254,229,254,230,254,232,
-  251,233,251,234,251,235,251,236,251,243,249,244,249,245,249,246,
-  249,247,249,249,249,0,3,254,0,5,254,0,7,254,0,9,251,0,15,251,0,19,
-  251,0,21,251,0,25,251,0,27,251,0,29,251,0,33,251,0,37,251,0,79,249,
-  0,83,249,0,93,255,0,97,255,0,99,255,1,2,25,255,73,45,245,46,245,
-  47,245,59,248,60,246,66,249,80,254,98,242,102,242,106,248,112,242,
-  115,248,118,248,120,245,122,245,193,249,194,249,195,249,196,249,
-  197,249,198,249,211,254,212,254,213,254,214,254,215,254,217,254,
-  225,242,226,242,227,242,228,242,229,242,230,242,233,248,234,242,
-  235,248,236,248,238,248,243,242,244,242,245,242,246,242,247,242,
-  249,242,250,248,251,248,252,248,253,248,254,245,0,1,251,0,2,249,
-  0,3,242,0,4,249,0,5,242,0,6,249,0,7,242,0,21,248,0,25,242,0,27,242,
-  0,29,242,0,49,248,0,78,254,0,79,242,0,82,254,0,83,242,0,87,248,0,
-  89,248,0,91,248,0,109,248,0,113,248,0,115,248,0,117,248,73,45,245,
-  46,245,47,245,59,248,60,246,66,249,80,254,98,242,102,242,106,248,
-  112,242,115,248,118,248,120,245,122,245,193,249,194,249,195,249,
-  196,249,197,249,198,249,211,254,212,254,213,254,214,254,215,254,
-  217,254,225,242,226,242,227,242,228,242,229,242,230,242,233,248,
-  234,242,235,248,236,248,238,248,243,242,244,242,245,242,246,242,
-  247,242,249,242,250,248,251,248,252,248,253,248,254,245,0,1,251,
-  0,2,249,0,3,242,0,4,249,0,5,242,0,6,249,0,7,242,0,21,248,0,25,242,
-  0,27,242,0,29,242,0,49,248,0,78,254,0,79,242,0,82,254,0,83,242,0,
-  87,248,0,89,248,0,91,248,0,109,248,0,113,248,0,115,248,0,117,248,
-  13,45,253,47,253,66,250,193,250,194,250,195,250,196,250,197,250,
-  198,250,0,2,250,0,4,250,0,6,250,13,45,253,47,253,66,250,193,250,
-  194,250,195,250,196,250,197,250,198,250,0,2,250,0,4,250,0,6,250,
-  13,45,253,47,253,66,250,193,250,194,250,195,250,196,250,197,250,
-  198,250,0,2,250,0,4,250,0,6,250,13,45,253,47,253,66,250,193,250,
-  194,250,195,250,196,250,197,250,198,250,0,2,250,0,4,250,0,6,250,
-  69,45,242,46,245,47,242,59,246,60,246,66,249,80,254,98,242,102,242,
-  106,245,112,242,118,242,193,249,194,249,195,249,196,249,197,249,
-  198,249,211,254,212,254,213,254,214,254,215,254,217,254,225,242,
-  226,242,227,242,228,242,229,242,230,242,233,248,234,242,235,242,
-  236,248,237,251,238,245,239,251,240,251,243,242,244,242,245,242,
-  246,242,247,242,249,242,250,242,251,242,252,242,253,242,0,2,249,
-  0,3,242,0,4,249,0,5,242,0,6,249,0,7,242,0,21,248,0,25,242,0,27,242,
-  0,29,242,0,45,251,0,49,245,0,78,254,0,79,242,0,82,254,0,83,242,0,
-  109,242,0,113,242,0,115,242,0,117,242,2,1,32,24,238,17,33,238,101,
-  253,115,253,116,250,117,252,119,255,0,19,253,0,87,253,0,89,253,0,
-  91,253,0,93,250,0,97,250,0,99,250,0,101,252,1,2,25,250,1,32,25,238
-};
-static afm_cuint16 afm_Times_Italic_highchars_index[] = { /* 220 */
-  161,162,163,164,165,166,167,168,169,170,171,172,174,175,176,177,
-  178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,
-  194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,
-  210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,
-  226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,
-  242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,
-  258,259,260,261,262,263,268,269,270,271,272,273,274,275,278,279,
-  280,281,282,283,286,287,290,291,298,299,302,303,304,305,310,311,
-  313,314,315,316,317,318,321,322,323,324,325,326,327,328,332,333,
-  336,337,338,339,340,341,342,343,344,345,346,347,350,351,352,353,
-  354,355,356,357,362,363,366,367,368,369,370,371,376,377,378,379,
-  380,381,382,402,536,537,710,711,728,729,730,731,732,733,8211,8212,
-  8216,8217,8218,8220,8221,8222,8224,8225,8226,8230,8240,8249,8250,
-  8260,8364,8482,8706,8710,8721,8722,8730,8800,8804,8805,9674,63171,
-  64257,64258
-};
-static afm_cunicode afm_Times_Italic_ligatures[] = { /* 3 */
-  102,105,64257
-};
-
-
-/* ------------------------------------------------------------------*/
-/* FontName: Times-Roman */
-/* FullName: Times Roman */
-/* FamilyName: Times */
-static afm_cuint8 afm_Times_Roman_widths[] = { /* 315 */
-  42,56,68,83,83,139,130,30,56,56,83,94,42,56,42,46,83,83,83,83,83,
-  83,83,83,83,83,46,46,94,94,94,74,154,120,111,111,120,102,93,120,
-  120,56,65,120,102,148,120,120,93,120,111,93,102,120,120,157,120,
-  120,102,56,46,56,78,83,56,74,83,74,83,74,56,83,83,46,46,83,46,130,
-  83,83,83,83,56,65,46,83,83,120,83,83,74,80,33,80,90,56,83,83,83,
-  83,33,83,56,127,46,83,94,127,56,67,94,50,50,56,83,76,42,56,50,52,
-  83,125,125,125,74,120,120,120,120,120,120,148,111,102,102,102,102,
-  56,56,56,56,120,120,120,120,120,120,120,94,120,120,120,120,120,120,
-  93,83,74,74,74,74,74,74,111,74,74,74,74,74,46,46,46,46,83,83,83,
-  83,83,83,83,94,83,83,83,83,83,83,83,83,120,74,120,74,120,74,111,
-  74,111,74,120,98,120,83,102,74,102,74,102,74,102,74,120,83,120,83,
-  56,46,56,46,56,46,120,83,102,46,102,46,102,57,102,46,120,83,120,
-  83,120,83,120,83,120,83,148,120,111,56,111,56,111,56,93,65,93,65,
-  93,65,102,46,102,54,120,83,120,83,120,83,120,83,120,102,74,102,74,
-  102,74,83,93,65,56,56,56,56,56,56,56,56,83,167,56,56,56,74,74,74,
-  83,83,58,167,167,56,56,28,83,163,79,102,100,94,76,92,92,92,79,42,
-  93,93
-};
-static afm_sint16 afm_Times_Roman_kerning_index[] = { /* 315 */
-  1,0,0,0,0,0,0,0,0,0,0,0,44,0,53,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-  0,0,62,159,0,205,0,240,0,0,0,311,335,427,0,458,482,527,578,601,0,
-  663,831,855,1020,0,1175,0,0,0,0,0,0,0,1323,1328,1355,0,1363,1385,
-  0,0,1422,0,1425,1475,0,1478,1488,1500,0,1508,0,0,0,1523,1593,1641,
-  1664,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-  0,0,0,0,0,1669,1766,1863,1960,2057,2154,0,0,0,0,0,0,0,0,0,0,0,2251,
-  2275,2320,2365,2410,2455,0,2500,2545,2569,2593,2617,2641,0,0,2789,
-  2794,2799,2804,2809,2814,0,2819,2827,2849,2871,2893,2915,2918,2921,
-  2924,0,2927,2937,2949,2961,2973,2985,0,2997,0,0,0,0,3009,0,3014,
-  3019,3116,3121,3218,3223,3320,0,3325,0,3333,3341,0,3376,0,0,3411,
-  0,3433,0,3455,0,3477,0,0,0,0,0,3499,0,3502,0,0,3505,3597,3647,3678,
-  3681,3712,3715,0,3727,3758,3761,3785,3795,3819,3829,3853,3863,3908,
-  3920,3965,0,0,3977,4039,4054,4116,4131,4193,0,0,0,0,0,0,4208,0,4376,
-  0,4544,0,4568,0,4592,0,4616,0,4640,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-  0,0,0,0,4788,4816,0,4872,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,0,
-  0,0,0,0
-};
-static afm_cuint8 afm_Times_Roman_kerning_data[] = { /* 4896 */
-  42,19,66,248,85,254,87,249,88,252,90,242,193,248,194,248,195,248,
-  196,248,197,248,198,248,222,242,0,2,248,0,4,248,0,6,248,0,100,254,
-  0,102,254,0,122,242,3,1,32,25,245,1,32,29,245,3,1,32,25,245,1,32,
-  29,245,41,68,250,72,250,80,248,82,248,85,238,86,248,87,234,88,242,
-  90,239,119,245,120,242,122,242,200,250,211,248,212,248,213,248,214,
-  248,215,248,217,248,218,248,219,248,220,248,221,248,222,239,254,
-  242,0,1,242,0,8,250,0,14,250,0,32,250,0,36,250,0,78,248,0,82,248,
-  0,100,238,0,102,238,0,108,248,0,112,248,0,114,248,0,116,248,0,122,
-  239,1,32,25,238,20,66,251,86,255,193,251,194,251,195,251,196,251,
-  197,251,198,251,218,255,219,255,220,255,221,255,0,2,251,0,4,251,
-  0,6,251,0,108,255,0,112,255,0,114,255,0,116,255,16,66,250,87,250,
-  88,252,90,248,193,250,194,250,195,250,196,250,197,250,198,250,222,
-  248,0,2,250,0,4,250,0,6,250,0,122,248,32,45,244,47,244,66,245,98,
-  254,112,254,193,245,194,245,195,245,196,245,197,245,198,245,225,
-  254,226,254,227,254,228,254,229,254,230,254,243,254,244,254,245,
-  254,246,254,247,254,249,254,0,2,245,0,3,254,0,4,245,0,5,254,0,6,
-  245,0,7,254,0,79,254,0,83,254,11,66,247,193,247,194,247,195,247,
-  196,247,197,247,198,247,0,2,247,0,4,247,0,6,247,40,80,252,102,253,
-  112,251,118,254,122,253,211,252,212,252,213,252,214,252,215,252,
-  217,252,233,253,234,253,235,253,236,253,243,251,244,251,245,251,
-  246,251,247,251,249,251,250,254,251,254,252,254,253,254,254,253,
-  0,1,253,0,21,253,0,25,253,0,27,253,0,29,253,0,78,252,0,79,251,0,
-  82,252,0,83,251,0,109,254,0,113,254,0,115,254,0,117,254,13,85,242,
-  87,240,88,245,90,240,122,248,222,240,254,248,0,1,248,0,100,242,0,
-  102,242,0,122,240,1,32,25,242,11,66,251,193,251,194,251,195,251,
-  196,251,197,251,198,251,0,2,251,0,4,251,0,6,251,20,66,251,85,250,
-  87,249,88,251,89,250,90,249,193,251,194,251,195,251,196,251,197,
-  251,198,251,222,249,0,2,251,0,4,251,0,6,251,0,100,250,0,102,250,
-  0,122,249,23,45,238,47,238,66,242,98,254,193,242,194,242,195,242,
-  196,242,197,242,198,242,225,254,226,254,227,254,228,254,229,254,
-  230,254,0,2,242,0,3,254,0,4,242,0,5,254,0,6,242,0,7,254,10,86,255,
-  218,255,219,255,220,255,221,255,0,108,255,0,112,255,0,114,255,0,
-  116,255,27,80,250,85,247,86,250,87,244,88,248,90,246,211,250,212,
-  250,213,250,214,250,215,250,217,250,218,250,219,250,220,250,221,
-  250,222,246,0,78,250,0,82,250,0,100,247,0,102,247,0,108,250,0,112,
-  250,0,114,250,0,116,250,0,122,246,73,45,245,46,242,47,245,59,249,
-  60,248,66,241,80,254,98,244,102,245,106,251,112,244,115,251,118,
-  249,120,244,122,244,193,241,194,241,195,241,196,241,197,241,198,
-  241,211,254,212,254,213,254,214,254,215,254,217,254,225,250,226,
-  244,227,244,228,250,229,250,230,244,233,245,234,245,235,245,236,
-  252,238,251,243,244,244,244,245,244,246,244,247,244,249,244,250,
-  249,251,249,252,249,253,249,254,244,0,1,244,0,2,241,0,3,250,0,4,
-  241,0,5,244,0,6,241,0,7,244,0,21,252,0,25,245,0,27,245,0,29,245,
-  0,49,251,0,78,254,0,79,244,0,82,254,0,83,244,0,87,251,0,89,251,0,
-  91,251,0,109,249,0,113,249,0,115,249,0,117,249,11,66,250,193,250,
-  194,250,195,250,196,250,197,250,198,250,0,2,250,0,4,250,0,6,250,
-  72,45,235,46,240,47,235,59,245,60,245,66,234,72,254,80,250,98,238,
-  102,238,106,247,112,235,118,244,193,234,194,234,195,234,196,234,
-  197,234,198,234,211,250,212,250,213,250,214,250,215,250,217,250,
-  225,245,226,238,227,245,228,245,229,245,230,238,233,245,234,238,
-  235,245,236,245,237,254,238,247,239,254,240,254,243,242,244,235,
-  245,235,246,242,247,242,249,235,250,244,251,244,252,244,253,244,
-  0,2,234,0,3,245,0,4,234,0,5,238,0,6,234,0,7,238,0,21,245,0,25,238,
-  0,27,238,0,29,245,0,32,254,0,36,254,0,45,254,0,49,247,0,78,250,0,
-  79,242,0,82,250,0,83,235,0,109,244,0,113,244,0,115,244,0,117,244,
-  68,45,242,46,246,47,242,59,251,60,251,66,237,80,255,98,244,102,244,
-  106,250,112,244,118,249,122,245,193,237,194,237,195,237,196,237,
-  197,237,198,237,211,255,212,255,213,255,214,255,215,255,217,255,
-  225,244,226,244,227,244,228,244,229,244,230,244,233,250,234,244,
-  235,244,236,250,238,250,243,244,244,244,245,244,246,244,247,244,
-  249,244,250,249,251,249,252,249,253,249,254,245,0,1,245,0,2,237,
-  0,3,244,0,4,237,0,5,244,0,6,237,0,7,244,0,21,250,0,25,244,0,27,244,
-  0,29,244,0,49,250,0,78,255,0,79,244,0,82,255,0,83,244,0,109,249,
-  0,113,249,0,115,249,0,117,249,65,45,235,46,238,47,235,59,242,60,
-  242,66,237,80,252,98,240,102,240,106,248,112,239,118,238,193,237,
-  194,237,195,237,196,237,197,237,198,237,211,252,212,252,213,252,
-  214,252,215,252,217,252,225,247,226,240,227,240,228,247,229,247,
-  230,240,233,247,234,240,235,240,236,247,238,248,243,245,244,239,
-  245,239,246,245,247,245,249,239,250,245,251,238,252,238,253,245,
-  0,2,237,0,3,247,0,4,237,0,5,240,0,6,237,0,7,240,0,21,247,0,25,240,
-  0,27,240,0,29,240,0,49,248,0,78,252,0,79,245,0,82,252,0,83,239,0,
-  109,245,0,113,238,0,115,238,0,117,238,3,119,254,120,254,12,47,250,
-  118,254,119,254,250,254,251,254,252,254,253,254,0,109,254,0,113,
-  254,0,115,254,0,117,254,4,122,254,254,254,0,1,254,10,104,254,119,
-  253,120,253,121,254,122,254,254,254,0,1,254,0,33,254,0,37,254,16,
-  98,255,103,253,106,254,225,255,226,255,227,255,228,255,229,255,230,
-  255,238,254,0,3,255,0,5,255,0,7,255,0,51,249,1,32,25,9,2,119,253,
-  22,102,255,112,255,122,254,233,255,234,255,235,255,236,255,243,255,
-  244,255,245,255,246,255,247,255,249,255,254,254,0,1,254,0,21,255,
-  0,25,255,0,27,255,0,29,255,0,79,255,0,83,255,2,120,255,5,119,250,
-  122,254,254,254,0,1,254,6,119,254,120,253,122,255,254,255,0,1,255,
-  4,122,255,254,255,0,1,255,7,45,250,46,254,47,248,104,254,0,33,254,
-  0,37,254,31,45,246,47,246,98,253,102,254,112,254,225,253,226,253,
-  227,253,228,253,229,253,230,253,233,254,234,254,235,254,236,254,
-  243,254,244,254,245,254,246,254,247,254,249,254,0,3,253,0,5,253,
-  0,7,253,0,21,254,0,25,254,0,27,254,0,29,254,0,79,254,0,83,254,22,
-  45,246,47,246,98,255,112,255,225,255,226,255,227,255,228,255,229,
-  255,230,255,243,255,244,255,245,255,246,255,247,255,249,255,0,3,
-  255,0,5,255,0,7,255,0,79,255,0,83,255,10,102,254,233,254,234,254,
-  235,254,236,254,0,21,254,0,25,254,0,27,254,0,29,254,3,45,246,47,
-  246,41,68,250,72,250,80,248,82,248,85,238,86,248,87,234,88,242,90,
-  239,119,245,120,242,122,242,200,250,211,248,212,248,213,248,214,
-  248,215,248,217,248,218,248,219,248,220,248,221,248,222,239,254,
-  242,0,1,242,0,8,250,0,14,250,0,32,250,0,36,250,0,78,248,0,82,248,
-  0,100,238,0,102,238,0,108,248,0,112,248,0,114,248,0,116,248,0,122,
-  239,1,32,25,238,41,68,250,72,250,80,248,82,248,85,238,86,248,87,
-  234,88,242,90,239,119,245,120,242,122,242,200,250,211,248,212,248,
-  213,248,214,248,215,248,217,248,218,248,219,248,220,248,221,248,
-  222,239,254,242,0,1,242,0,8,250,0,14,250,0,32,250,0,36,250,0,78,
-  248,0,82,248,0,100,238,0,102,238,0,108,248,0,112,248,0,114,248,0,
-  116,248,0,122,239,1,32,25,238,41,68,250,72,250,80,248,82,248,85,
-  238,86,248,87,234,88,242,90,239,119,245,120,242,122,242,200,250,
-  211,248,212,248,213,248,214,248,215,248,217,248,218,248,219,248,
-  220,248,221,248,222,239,254,242,0,1,242,0,8,250,0,14,250,0,32,250,
-  0,36,250,0,78,248,0,82,248,0,100,238,0,102,238,0,108,248,0,112,248,
-  0,114,248,0,116,248,0,122,239,1,32,25,238,41,68,250,72,250,80,248,
-  82,248,85,238,86,248,87,234,88,242,90,239,119,245,120,242,122,242,
-  200,250,211,248,212,248,213,248,214,248,215,248,217,248,218,248,
-  219,248,220,248,221,248,222,239,254,242,0,1,242,0,8,250,0,14,250,
-  0,32,250,0,36,250,0,78,248,0,82,248,0,100,238,0,102,238,0,108,248,
-  0,112,248,0,114,248,0,116,248,0,122,239,1,32,25,238,41,68,250,72,
-  250,80,248,82,248,85,238,86,248,87,234,88,242,90,239,119,245,120,
-  242,122,242,200,250,211,248,212,248,213,248,214,248,215,248,217,
-  248,218,248,219,248,220,248,221,248,222,239,254,242,0,1,242,0,8,
-  250,0,14,250,0,32,250,0,36,250,0,78,248,0,82,248,0,100,238,0,102,
-  238,0,108,248,0,112,248,0,114,248,0,116,248,0,122,239,1,32,25,238,
-  41,68,250,72,250,80,248,82,248,85,238,86,248,87,234,88,242,90,239,
-  119,245,120,242,122,242,200,250,211,248,212,248,213,248,214,248,
-  215,248,217,248,218,248,219,248,220,248,221,248,222,239,254,242,
-  0,1,242,0,8,250,0,14,250,0,32,250,0,36,250,0,78,248,0,82,248,0,100,
-  238,0,102,238,0,108,248,0,112,248,0,114,248,0,116,248,0,122,239,
-  1,32,25,238,11,66,251,193,251,194,251,195,251,196,251,197,251,198,
-  251,0,2,251,0,4,251,0,6,251,20,66,251,85,250,87,249,88,251,89,250,
-  90,249,193,251,194,251,195,251,196,251,197,251,198,251,222,249,0,
-  2,251,0,4,251,0,6,251,0,100,250,0,102,250,0,122,249,20,66,251,85,
-  250,87,249,88,251,89,250,90,249,193,251,194,251,195,251,196,251,
-  197,251,198,251,222,249,0,2,251,0,4,251,0,6,251,0,100,250,0,102,
-  250,0,122,249,20,66,251,85,250,87,249,88,251,89,250,90,249,193,251,
-  194,251,195,251,196,251,197,251,198,251,222,249,0,2,251,0,4,251,
-  0,6,251,0,100,250,0,102,250,0,122,249,20,66,251,85,250,87,249,88,
-  251,89,250,90,249,193,251,194,251,195,251,196,251,197,251,198,251,
-  222,249,0,2,251,0,4,251,0,6,251,0,100,250,0,102,250,0,122,249,20,
-  66,251,85,250,87,249,88,251,89,250,90,249,193,251,194,251,195,251,
-  196,251,197,251,198,251,222,249,0,2,251,0,4,251,0,6,251,0,100,250,
-  0,102,250,0,122,249,20,66,251,85,250,87,249,88,251,89,250,90,249,
-  193,251,194,251,195,251,196,251,197,251,198,251,222,249,0,2,251,
-  0,4,251,0,6,251,0,100,250,0,102,250,0,122,249,11,66,250,193,250,
-  194,250,195,250,196,250,197,250,198,250,0,2,250,0,4,250,0,6,250,
-  11,66,250,193,250,194,250,195,250,196,250,197,250,198,250,0,2,250,
-  0,4,250,0,6,250,11,66,250,193,250,194,250,195,250,196,250,197,250,
-  198,250,0,2,250,0,4,250,0,6,250,11,66,250,193,250,194,250,195,250,
-  196,250,197,250,198,250,0,2,250,0,4,250,0,6,250,65,45,235,46,238,
-  47,235,59,242,60,242,66,237,80,252,98,240,102,240,106,248,112,239,
-  118,238,193,237,194,237,195,237,196,237,197,237,198,237,211,252,
-  212,252,213,252,214,252,215,252,217,252,225,247,226,240,227,240,
-  228,247,229,247,230,240,233,247,234,240,235,240,236,247,238,248,
-  243,245,244,239,245,239,246,245,247,245,249,239,250,245,251,238,
-  252,238,253,245,0,2,237,0,3,247,0,4,237,0,5,240,0,6,237,0,7,240,
-  0,21,247,0,25,240,0,27,240,0,29,240,0,49,248,0,78,252,0,79,245,0,
-  82,252,0,83,239,0,109,245,0,113,238,0,115,238,0,117,238,3,119,254,
-  120,254,3,119,254,120,254,3,119,254,120,254,3,119,254,120,254,3,
-  119,254,120,254,3,119,254,120,254,4,122,254,254,254,0,1,254,10,104,
-  254,119,253,120,253,121,254,122,254,254,254,0,1,254,0,33,254,0,37,
-  254,10,104,254,119,253,120,253,121,254,122,254,254,254,0,1,254,0,
-  33,254,0,37,254,10,104,254,119,253,120,253,121,254,122,254,254,254,
-  0,1,254,0,33,254,0,37,254,10,104,254,119,253,120,253,121,254,122,
-  254,254,254,0,1,254,0,33,254,0,37,254,2,119,253,2,119,253,2,119,
-  253,2,119,253,5,119,250,122,254,254,254,0,1,254,6,119,254,120,253,
-  122,255,254,255,0,1,255,6,119,254,120,253,122,255,254,255,0,1,255,
-  6,119,254,120,253,122,255,254,255,0,1,255,6,119,254,120,253,122,
-  255,254,255,0,1,255,6,119,254,120,253,122,255,254,255,0,1,255,6,
-  119,254,120,253,122,255,254,255,0,1,255,3,45,246,47,246,3,45,246,
-  47,246,41,68,250,72,250,80,248,82,248,85,238,86,248,87,234,88,242,
-  90,239,119,245,120,242,122,242,200,250,211,248,212,248,213,248,214,
-  248,215,248,217,248,218,248,219,248,220,248,221,248,222,239,254,
-  242,0,1,242,0,8,250,0,14,250,0,32,250,0,36,250,0,78,248,0,82,248,
-  0,100,238,0,102,238,0,108,248,0,112,248,0,114,248,0,116,248,0,122,
-  239,1,32,25,238,3,119,254,120,254,41,68,250,72,250,80,248,82,248,
-  85,238,86,248,87,234,88,242,90,239,119,245,120,242,122,242,200,250,
-  211,248,212,248,213,248,214,248,215,248,217,248,218,248,219,248,
-  220,248,221,248,222,239,254,242,0,1,242,0,8,250,0,14,250,0,32,250,
-  0,36,250,0,78,248,0,82,248,0,100,238,0,102,238,0,108,248,0,112,248,
-  0,114,248,0,116,248,0,122,239,1,32,25,238,3,119,254,120,254,41,68,
-  250,72,250,80,248,82,248,85,238,86,248,87,234,88,242,90,239,119,
-  245,120,248,122,248,200,250,211,248,212,248,213,248,214,248,215,
-  248,217,248,218,248,219,248,220,248,221,248,222,239,254,248,0,1,
-  248,0,8,250,0,14,250,0,32,250,0,36,250,0,78,248,0,82,248,0,100,238,
-  0,102,238,0,108,248,0,112,248,0,114,248,0,116,248,0,122,239,1,32,
-  25,238,3,119,254,120,254,4,122,254,254,254,0,1,254,4,122,254,254,
-  254,0,1,254,16,66,250,87,250,88,252,90,248,193,250,194,250,195,250,
-  196,250,197,250,198,250,222,248,0,2,250,0,4,250,0,6,250,0,122,248,
-  16,66,250,87,250,88,252,90,248,193,250,194,250,195,250,196,250,197,
-  250,198,250,222,248,0,2,250,0,4,250,0,6,250,0,122,248,10,104,254,
-  119,253,120,253,121,254,122,254,254,254,0,1,254,0,33,254,0,37,254,
-  10,104,254,119,253,120,253,121,254,122,254,254,254,0,1,254,0,33,
-  254,0,37,254,10,104,254,119,253,120,253,121,254,122,254,254,254,
-  0,1,254,0,33,254,0,37,254,10,104,254,119,253,120,253,121,254,122,
-  254,254,254,0,1,254,0,33,254,0,37,254,2,119,253,2,119,253,40,80,
-  252,102,253,112,251,118,254,122,253,211,252,212,252,213,252,214,
-  252,215,252,217,252,233,253,234,253,235,253,236,253,243,251,244,
-  251,245,251,246,251,247,251,249,251,250,254,251,254,252,254,253,
-  254,254,253,0,1,253,0,21,253,0,25,253,0,27,253,0,29,253,0,78,252,
-  0,79,251,0,82,252,0,83,251,0,109,254,0,113,254,0,115,254,0,117,254,
-  22,102,255,112,255,122,254,233,255,234,255,235,255,236,255,243,255,
-  244,255,245,255,246,255,247,255,249,255,254,254,0,1,254,0,21,255,
-  0,25,255,0,27,255,0,29,255,0,79,255,0,83,255,13,85,242,87,240,88,
-  245,90,240,122,248,222,240,254,248,0,1,248,0,100,242,0,102,242,0,
-  122,240,1,32,25,242,2,120,255,13,85,242,87,240,88,245,90,240,122,
-  248,222,240,254,248,0,1,248,0,100,242,0,102,242,0,122,240,1,32,25,
-  242,2,120,255,5,122,248,254,248,0,1,248,1,32,25,242,13,85,242,87,
-  240,88,245,90,240,122,248,222,240,254,248,0,1,248,0,100,242,0,102,
-  242,0,122,240,1,32,25,242,2,120,255,11,66,251,193,251,194,251,195,
-  251,196,251,197,251,198,251,0,2,251,0,4,251,0,6,251,5,119,250,122,
-  254,254,254,0,1,254,11,66,251,193,251,194,251,195,251,196,251,197,
-  251,198,251,0,2,251,0,4,251,0,6,251,5,119,250,122,254,254,254,0,
-  1,254,11,66,251,193,251,194,251,195,251,196,251,197,251,198,251,
-  0,2,251,0,4,251,0,6,251,5,119,250,122,254,254,254,0,1,254,20,66,
-  251,85,250,87,249,88,251,89,250,90,249,193,251,194,251,195,251,196,
-  251,197,251,198,251,222,249,0,2,251,0,4,251,0,6,251,0,100,250,0,
-  102,250,0,122,249,6,119,254,120,253,122,255,254,255,0,1,255,20,66,
-  251,85,250,87,249,88,251,89,250,90,249,193,251,194,251,195,251,196,
-  251,197,251,198,251,222,249,0,2,251,0,4,251,0,6,251,0,100,250,0,
-  102,250,0,122,249,6,119,254,120,253,122,255,254,255,0,1,255,27,80,
-  250,85,247,86,250,87,244,88,248,90,246,211,250,212,250,213,250,214,
-  250,215,250,217,250,218,250,219,250,220,250,221,250,222,246,0,78,
-  250,0,82,250,0,100,247,0,102,247,0,108,250,0,112,250,0,114,250,0,
-  116,250,0,122,246,7,45,250,46,254,47,248,104,254,0,33,254,0,37,254,
-  27,80,250,85,247,86,250,87,244,88,248,90,246,211,250,212,250,213,
-  250,214,250,215,250,217,250,218,250,219,250,220,250,221,250,222,
-  246,0,78,250,0,82,250,0,100,247,0,102,247,0,108,250,0,112,250,0,
-  114,250,0,116,250,0,122,246,7,45,250,46,254,47,248,104,254,0,33,
-  254,0,37,254,27,80,250,85,247,86,250,87,244,88,248,90,246,211,250,
-  212,250,213,250,214,250,215,250,217,250,218,250,219,250,220,250,
-  221,250,222,246,0,78,250,0,82,250,0,100,247,0,102,247,0,108,250,
-  0,112,250,0,114,250,0,116,250,0,122,246,7,45,250,46,254,47,248,104,
-  254,0,33,254,0,37,254,73,45,245,46,242,47,245,59,249,60,248,66,241,
-  80,254,98,244,102,245,106,251,112,244,115,251,118,249,120,244,122,
-  244,193,241,194,241,195,241,196,241,197,241,198,241,211,254,212,
-  254,213,254,214,254,215,254,217,254,225,250,226,244,227,244,228,
-  250,229,250,230,244,233,252,234,245,235,252,236,252,238,251,243,
-  244,244,244,245,244,246,244,247,244,249,244,250,249,251,249,252,
-  249,253,249,254,244,0,1,244,0,2,241,0,3,250,0,4,241,0,5,244,0,6,
-  241,0,7,244,0,21,245,0,25,245,0,27,245,0,29,245,0,49,251,0,78,254,
-  0,79,244,0,82,254,0,83,244,0,87,251,0,89,251,0,91,251,0,109,249,
-  0,113,249,0,115,249,0,117,249,73,45,245,46,242,47,245,59,249,60,
-  248,66,241,80,254,98,244,102,245,106,251,112,244,115,251,118,249,
-  120,244,122,244,193,241,194,241,195,241,196,241,197,241,198,241,
-  211,254,212,254,213,254,214,254,215,254,217,254,225,250,226,244,
-  227,244,228,250,229,250,230,244,233,245,234,245,235,252,236,252,
-  238,251,243,244,244,244,245,244,246,244,247,244,249,244,250,249,
-  251,249,252,249,253,249,254,244,0,1,244,0,2,241,0,3,250,0,4,241,
-  0,5,244,0,6,241,0,7,244,0,21,252,0,25,245,0,27,245,0,29,245,0,49,
-  251,0,78,254,0,79,244,0,82,254,0,83,244,0,87,251,0,89,251,0,91,251,
-  0,109,249,0,113,249,0,115,249,0,117,249,11,66,250,193,250,194,250,
-  195,250,196,250,197,250,198,250,0,2,250,0,4,250,0,6,250,11,66,250,
-  193,250,194,250,195,250,196,250,197,250,198,250,0,2,250,0,4,250,
-  0,6,250,11,66,250,193,250,194,250,195,250,196,250,197,250,198,250,
-  0,2,250,0,4,250,0,6,250,11,66,250,193,250,194,250,195,250,196,250,
-  197,250,198,250,0,2,250,0,4,250,0,6,250,65,45,235,46,238,47,235,
-  59,242,60,242,66,237,80,252,98,240,102,240,106,248,112,239,118,238,
-  193,237,194,237,195,237,196,237,197,237,198,237,211,252,212,252,
-  213,252,214,252,215,252,217,252,225,247,226,240,227,240,228,240,
-  229,247,230,240,233,247,234,240,235,240,236,247,238,248,243,245,
-  244,239,245,239,246,245,247,245,249,239,250,245,251,238,252,238,
-  253,245,0,2,237,0,3,247,0,4,237,0,5,240,0,6,237,0,7,240,0,21,247,
-  0,25,240,0,27,240,0,29,240,0,49,248,0,78,252,0,79,245,0,82,252,0,
-  83,239,0,109,245,0,113,238,0,115,238,0,117,238,12,66,244,193,244,
-  194,244,195,244,196,244,197,244,198,244,0,2,244,0,4,244,0,6,244,
-  1,32,24,245,21,33,245,101,249,109,255,115,249,116,248,117,254,119,
-  249,0,19,249,0,60,255,0,62,255,0,68,255,0,87,249,0,89,249,0,91,249,
-  0,93,248,0,97,248,0,99,248,0,101,254,1,2,25,248,1,32,25,245,11,66,
-  244,193,244,194,244,195,244,196,244,197,244,198,244,0,2,244,0,4,
-  244,0,6,244
-};
-static afm_cuint16 afm_Times_Roman_highchars_index[] = { /* 220 */
-  161,162,163,164,165,166,167,168,169,170,171,172,174,175,176,177,
-  178,179,180,181,182,183,184,185,186,187,188,189,190,191,192,193,
-  194,195,196,197,198,199,200,201,202,203,204,205,206,207,208,209,
-  210,211,212,213,214,215,216,217,218,219,220,221,222,223,224,225,
-  226,227,228,229,230,231,232,233,234,235,236,237,238,239,240,241,
-  242,243,244,245,246,247,248,249,250,251,252,253,254,255,256,257,
-  258,259,260,261,262,263,268,269,270,271,272,273,274,275,278,279,
-  280,281,282,283,286,287,290,291,298,299,302,303,304,305,310,311,
-  313,314,315,316,317,318,321,322,323,324,325,326,327,328,332,333,
-  336,337,338,339,340,341,342,343,344,345,346,347,350,351,352,353,
-  354,355,356,357,362,363,366,367,368,369,370,371,376,377,378,379,
-  380,381,382,402,536,537,710,711,728,729,730,731,732,733,8211,8212,
-  8216,8217,8218,8220,8221,8222,8224,8225,8226,8230,8240,8249,8250,
-  8260,8364,8482,8706,8710,8721,8722,8730,8800,8804,8805,9674,63171,
-  64257,64258
-};
-static afm_cunicode afm_Times_Roman_ligatures[] = { /* 3 */
-  102,105,64257
-};
-const afm_fontinfo afm_fontinfolist[] = {
-  { /* Courier.afm   761 bytes */
-      "Courier", "Courier",
-      629, -157,
-      afm_Courier_widths,
-      NULL,
-      NULL,
-      afm_Courier_highchars_index, 220,
-      afm_Courier_ligatures, 1},
-  { /* Courier-Bold.afm   761 bytes */
-      "Courier-Bold", "Courier Bold",
-      629, -157,
-      afm_Courier_Bold_widths,
-      NULL,
-      NULL,
-      afm_Courier_Bold_highchars_index, 220,
-      afm_Courier_Bold_ligatures, 1},
-  { /* Courier-BoldOblique.afm   761 bytes */
-      "Courier-BoldOblique", "Courier Bold Oblique",
-      629, -157,
-      afm_Courier_BoldOblique_widths,
-      NULL,
-      NULL,
-      afm_Courier_BoldOblique_highchars_index, 220,
-      afm_Courier_BoldOblique_ligatures, 1},
-  { /* Courier-Oblique.afm   761 bytes */
-      "Courier-Oblique", "Courier Oblique",
-      629, -157,
-      afm_Courier_Oblique_widths,
-      NULL,
-      NULL,
-      afm_Courier_Oblique_highchars_index, 220,
-      afm_Courier_Oblique_ligatures, 1},
-  { /* Helvetica.afm   7841 bytes */
-      "Helvetica", "Helvetica",
-      718, -207,
-      afm_Helvetica_widths,
-      afm_Helvetica_kerning_index,
-      afm_Helvetica_kerning_data,
-      afm_Helvetica_highchars_index, 220,
-      afm_Helvetica_ligatures, 1},
-  { /* Helvetica-Bold.afm   7336 bytes */
-      "Helvetica-Bold", "Helvetica Bold",
-      718, -207,
-      afm_Helvetica_Bold_widths,
-      afm_Helvetica_Bold_kerning_index,
-      afm_Helvetica_Bold_kerning_data,
-      afm_Helvetica_Bold_highchars_index, 220,
-      afm_Helvetica_Bold_ligatures, 1},
-  { /* Helvetica-BoldOblique.afm   7336 bytes */
-      "Helvetica-BoldOblique", "Helvetica Bold Oblique",
-      718, -207,
-      afm_Helvetica_BoldOblique_widths,
-      afm_Helvetica_BoldOblique_kerning_index,
-      afm_Helvetica_BoldOblique_kerning_data,
-      afm_Helvetica_BoldOblique_highchars_index, 220,
-      afm_Helvetica_BoldOblique_ligatures, 1},
-  { /* Helvetica-Oblique.afm   7841 bytes */
-      "Helvetica-Oblique", "Helvetica Oblique",
-      718, -207,
-      afm_Helvetica_Oblique_widths,
-      afm_Helvetica_Oblique_kerning_index,
-      afm_Helvetica_Oblique_kerning_data,
-      afm_Helvetica_Oblique_highchars_index, 220,
-      afm_Helvetica_Oblique_ligatures, 1},
-  { /* ZapfDingbats.afm   416 bytes */
-      "ZapfDingbats", "ITC Zapf Dingbats",
-      0, 0,
-      afm_ZapfDingbats_widths,
-      NULL,
-      NULL,
-      afm_ZapfDingbats_highchars_index, 107,
-      NULL, 0},
-  { /* Symbol.afm   563 bytes */
-      "Symbol", "Symbol",
-      0, 0,
-      afm_Symbol_widths,
-      NULL,
-      NULL,
-      afm_Symbol_highchars_index, 156,
-      NULL, 0},
-  { /* Times-Bold.afm   6761 bytes */
-      "Times-Bold", "Times Bold",
-      683, -217,
-      afm_Times_Bold_widths,
-      afm_Times_Bold_kerning_index,
-      afm_Times_Bold_kerning_data,
-      afm_Times_Bold_highchars_index, 220,
-      afm_Times_Bold_ligatures, 1},
-  { /* Times-BoldItalic.afm   6270 bytes */
-      "Times-BoldItalic", "Times Bold Italic",
-      683, -217,
-      afm_Times_BoldItalic_widths,
-      afm_Times_BoldItalic_kerning_index,
-      afm_Times_BoldItalic_kerning_data,
-      afm_Times_BoldItalic_highchars_index, 220,
-      afm_Times_BoldItalic_ligatures, 1},
-  { /* Times-Italic.afm   6975 bytes */
-      "Times-Italic", "Times Italic",
-      683, -217,
-      afm_Times_Italic_widths,
-      afm_Times_Italic_kerning_index,
-      afm_Times_Italic_kerning_data,
-      afm_Times_Italic_highchars_index, 220,
-      afm_Times_Italic_ligatures, 1},
-  { /* Times-Roman.afm   6287 bytes */
-      "Times-Roman", "Times Roman",
-      683, -217,
-      afm_Times_Roman_widths,
-      afm_Times_Roman_kerning_index,
-      afm_Times_Roman_kerning_data,
-      afm_Times_Roman_highchars_index, 220,
-      afm_Times_Roman_ligatures, 1},
-  { 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0 }
-};
-const int afm_fontinfo_count = 14;
diff --git a/src/rrd_afm_data.h b/src/rrd_afm_data.h
deleted file mode 100644 (file)
index 076e959..0000000
+++ /dev/null
@@ -1,191 +0,0 @@
-/****************************************************************************
- * RRDtool 1.2.27  Copyright by Tobi Oetiker, 1997-2008
- ****************************************************************************
- * rrd_afm_data.h  Encoded afm (Adobe Font Metrics) for selected fonts.
- ****************************************************************************/
-
-#ifndef  RRD_AFM_DATA_H
-#define RRD_AFM_DATA_H
-
-/*
-Description of data structures:
-
-  Ideally, the struct should be a list of fonts, and each font
-  is a list of character-info.
-  Each character has a structure:
-    struct charinfo {
-      char16 thechar;
-      int width;
-      struct {
-       char16 nextchar;
-       int deltawidth;
-      } kernings[];
-      struct {
-       char16 nextchar;
-       char16 resultingchar;
-      } ligatures[];
-    }
-
-    The data for typical fonts makes this a very sparse data structure.
-    For most fonts, only the letter "f" has ligatures.
-    All fonts have all (or almost all) of the characters 32-126,
-    most fonts have all 161-255,
-    and all fonts have very few 256-65535.
-    Most kerning pairs have both chars 32-126.
-
-    The most basic design decisionÊis to have all this data as 
-    const C globals all set up by array/struct initialisers
-    so runtime setup overhead is minimal.
-    The complete other possibility would be to parse and load
-    this info at runtime, but for rrdtool I have preferred
-    speed for flexibility as the same few fonts will be used 
-    zillions of times.
-
-    So the idea is to rewrite the above structure into
-    something which:
-    1) uses/wastes minimal memory
-    2) is fast for most characters
-    3) supports at least Iso-Latin-1, prefer full unicode.
-    4) doesn't need full precision in char width
-       (we can afford to loose 0.2% as rrdtool only needs to calculate
-       overall layout of elements, not positioning individual
-       characters)
-    5) can be written as constant initialisers to C structs/arrays
-       so we don't have runtime overhead starting rrdtool.
-    6) can be easily generated by some script so it is easy
-       to select a set of fonts and have the C data updated.
-       So adding/removing fonts is a matter of a recompile.
-
-Implementation design:
-    All character structs are sorted by unicode value. Info for
-    characters below 32 is discarded and the chars are treated 
-    as a space. Missing characters in the 32-126 range are 
-    substituted with default values so we can use direct array 
-    access for those. For characters above 126, binary search 
-    is used (not yet, liniar now but uses good guess for most latin 1
-    characters).
-
-    Ligature handling can be discarded as ligatures have very small
-    effects on string width. The width of the "fi" ligature
-    is the same (or very close) to the width of "f" plus the width 
-    of "i".
-    If implemented, it can be a simple list (global for the font,
-    not for each character) because all fonts I've seen that have
-    ligatures has max 3 pairs: "fi", "fl", "ffl" and no other. 
-
-    Most characters has less than 10 kern pairs, few 10-20, and
-    extremly few 20-30. This is implemented as a simple
-    linear search with characters 256-65536 encoding using a prefix
-    so most kern pairs only take 2 bytes:
-    unsigned 8 bit char value and signed 8 bit kern width.
-    Using a non-packed format would enable binary search, but
-    would use almost twice as much memory for a yet unknown
-    gain in speed.
-
-    Character widths are stored as unsigned bytes. Width of
-    one character is font-size * bytevalue * (1000 / 6)
-    AFM specifies widths as integers with 1000 representing 1 * font-size.
-    Kerning delta widths has same scaling factor, but the value
-    is a signed byte as many kerning widths are negative and smaller
-    than avarage character width.
-
-    Kerning info is stored in a shared packed int8 array
-    to reduce the number of structs and memory usage.
-    This sets the maximum number of kerning pairs to
-    approx 15000.
-      The font I have seen with most kern pairs is
-      "Bodoni Old Face BE Bold Italic Oldstyle Figures"
-      which has 1718 pairs for 62 chars.
-      Typical fonts have 100-150 pairs.
-    For each character needs then only a 16 bit index
-    into this shared table.
-    The format of the sub-arrays are:
-      count ( unicode deltawidth )
-    with the (...) repeated count times.
-    The count and the unicode is packed because a lot
-    entries is less than 256, and most below 400.
-    Therefore an escape sequence is used.
-    If the value is >= 510
-      1, high-8bits, low-8bits
-    else if the value is >= 254
-      0, value minus 254
-    else
-      value plus 1
-    An index of zero is treated as a NULL pointer,
-    and the first byte in a shared array is
-    therefore not used (and filled with a dummy value).
-    The array is only created if non-empty.
-       No entries can be zero (they are redundant),
-       and no subarray can be empty (as the index pointer
-       then is 0 meaning no sub array).
-       The deltawidth is stored as a non-escaped signed byte.
-
-    So for each character needed info is:
-      width: unsigned 8 bit int.
-      kerning-subarray-index: unsigned 16 bit int.
-
-    The first 126-32+1 entries are for the characters
-    32-126. If any is missing, a dummy entry is created.
-    For characters 126-65535 a font-global
-    array of struct {unicode, char-index} is
-    used for binary search (not yet, liniar now).
-
-    Ligatures can be implemented as a font-global
-    array of struct {
-      unicode char1, char2, resultingchar;
-    }
-
-    Font-global info is stored in a struct afm_fontinfo (see below).
-
-    The highchars_index and ligatures structures are flattened
-    to a simple array to avoid accidental padding between
-    structs if the structsize is problematic for some platforms.
-
-    All fonts are stored in an array of this struct,
-    sorted by fullname for binary search (not yet sorted).
-
-    The .afm files are compiled by a perl script which creates
-    rrd_afm_data.c 
-    The only thing rrd_afm_data.c contains is this compiled data.
-
-    Compiled on Mac OS X the size of rrd_afm_data.o
-    is 67 Kb for the standard 14 postscript fonts,
-    and 490 Kb for a set of 276 Adobe fonts.
-*/
-
-typedef unsigned char  afm_uint8;
-typedef signed   char  afm_sint8;
-typedef unsigned short afm_uint16;
-typedef signed   short afm_sint16;
-typedef unsigned short afm_unicode;
-
-typedef const afm_uint8   afm_cuint8;
-typedef const afm_sint8   afm_csint8;
-typedef const afm_uint16  afm_cuint16;
-typedef const afm_sint16  afm_csint16;
-typedef const afm_unicode afm_cunicode;
-
-typedef struct afm_fontinfo {
-  const char   *fullname; /* e.g. "Futura Bold Oblique" */
-  const char   *postscript_name; /* e.g. "Futura-BoldOblique" */
-  afm_cuint16 ascender, descender;
-  afm_cuint8   *widths;
-  afm_csint16  *kerning_index;
-  afm_cuint8   *kerning_data;
-  afm_cuint16  *highchars_index;
-  afm_cuint16   highchars_count;
-  afm_cunicode *ligatures;
-  afm_cuint16   ligatures_count;
-}      afm_fontinfo;
-
-typedef struct old_afm_fontinfo {
-  const char *fontname, *fullname;
-  const unsigned short *charinfo, *intarray;
-  const unsigned short charinfocount;
-  const unsigned short fixedpitch;
-} old_afm_fontinfo;
-
-extern const afm_fontinfo afm_fontinfolist[];
-extern const int afm_fontinfo_count;
-
-#endif
index e87c70cc5bf59e46b32e7ebafe517f83bafbf3a9..0355dfcf4e5e5b56cb082619b1f4d856f2ad7fa1 100644 (file)
 /*****************************************************************************
- * RRDtool 1.2.27  Copyright by Tobi Oetiker, 1997-2008
+ * RRDtool 1.3rc4  Copyright by Tobi Oetiker, 1997-2008
  *****************************************************************************
  * rrd_cgi.c  RRD Web Page Generator
  *****************************************************************************/
 
 #include "rrd_tool.h"
-
+#ifdef HAVE_STDLIB_H
+#include <stdlib.h>
+#endif
 
 #define MEMBLK 1024
 /*#define DEBUG_PARSER
 #define DEBUG_VARS*/
 
 typedef struct var_s {
-       char    *name, *value;
+    char     *name, *value;
 } s_var;
 
 typedef struct cgi_s {
-       s_var **vars;
+    s_var   **vars;
 } s_cgi;
 
 /* in arg[0] find tags beginning with arg[1] call arg[2] on them
    and replace by result of arg[2] call */
-int parse(char **, long, char *, char *(*)(long , const char **));
+int       parse(
+    char **,
+    long,
+    char *,
+    char *    (*)(long,
+                  const char **));
 
 /**************************************************/
 /* tag replacers ... they are called from parse   */
 /* through function pointers                      */
 /**************************************************/
 
-/* return cgi var named arg[0] */ 
-char* cgiget(long , const char **);
+/* return cgi var named arg[0] */
+char     *cgiget(
+    long,
+    const char **);
 
-/* return a quoted cgi var named arg[0] */ 
-char* cgigetq(long , const char **);
+/* return a quoted cgi var named arg[0] */
+char     *cgigetq(
+    long,
+    const char **);
 
 /* return a quoted and sanitized cgi variable */
-char* cgigetqp(long , const char **);
+char     *cgigetqp(
+    long,
+    const char **);
 
 /* call rrd_graph and insert appropriate image tag */
-char* drawgraph(long, const char **);
+char     *drawgraph(
+    long,
+    const char **);
 
 /* return PRINT functions from last rrd_graph call */
-char* drawprint(long, const char **);
+char     *drawprint(
+    long,
+    const char **);
 
 /* pretty-print the <last></last> value for some.rrd via strftime() */
-char* printtimelast(long, const char **);
+char     *printtimelast(
+    long,
+    const char **);
 
 /* pretty-print current time */
-char* printtimenow(long, const char **);
+char     *printtimenow(
+    long,
+    const char **);
 
 /* set an environment variable */
-char* rrdsetenv(long, const char **);
+char     *rrdsetenv(
+    long,
+    const char **);
 
 /* get an environment variable */
-char* rrdgetenv(long, const char **);
+char     *rrdgetenv(
+    long,
+    const char **);
 
 /* include the named file at this point */
-char* includefile(long, const char **);
+char     *includefile(
+    long,
+    const char **);
 
 /* for how long is the output of the cgi valid ? */
-char* rrdgoodfor(long, const char **);
-
-/* return rrdcgi version string */ 
-char* rrdgetinternal(long, const char **);
-
-char* rrdstrip(char *buf);
-char* scanargs(char *line, int *argc, char ***args);
+char     *rrdgoodfor(
+    long,
+    const char **);
+
+/* return rrdcgi version string */
+char     *rrdgetinternal(
+    long,
+    const char **);
+
+char     *rrdstrip(
+    char *buf);
+char     *scanargs(
+    char *line,
+    int *argc,
+    char ***args);
 
 /* format at-time specified times using strftime */
-char* printstrftime(long, const char**);
+char     *printstrftime(
+    long,
+    const char **);
 
 /** HTTP protocol needs special format, and GMT time **/
-char *http_time(time_t *);
+char     *http_time(
+    time_t *);
 
 /* return a pointer to newly allocated copy of this string */
-char *stralloc(const char *);
+char     *stralloc(
+    const char *);
 
 /* global variable for rrdcgi */
-s_cgi *rrdcgiArg;
+s_cgi    *rrdcgiArg;
 
 /* rrdcgiHeader
  * 
  *  Prints a valid CGI Header (Content-type...) etc.
  */
-void rrdcgiHeader(void);
+void      rrdcgiHeader(
+    void);
 
 /* rrdcgiDecodeString
  * decode html escapes
  */
-char *rrdcgiDecodeString(char *text);
+
+char     *rrdcgiDecodeString(
+    char *text);
 
 /* rrdcgiDebug
  * 
  *  Set/unsets debugging
  */
-void rrdcgiDebug(int level, int where);
+void      rrdcgiDebug(
+    int level,
+    int where);
 
 /* rrdcgiInit
  *
  *  Reads in variables set via POST or stdin.
  */
-s_cgi *rrdcgiInit (void);
+s_cgi    *rrdcgiInit(
+    void);
 
 /* rrdcgiGetValue
  *
  *  Returns the value of the specified variable or NULL if it's empty
  *  or doesn't exist.
  */
-char *rrdcgiGetValue (s_cgi *parms, const char *name);
+char     *rrdcgiGetValue(
+    s_cgi * parms,
+    const char *name);
 
 /* rrdcgiFreeList
  *
  * Frees a list as returned by rrdcgiGetVariables()
  */
-void rrdcgiFreeList (char **list);
+void      rrdcgiFreeList(
+    char **list);
 
 /* rrdcgiFree
  *
  * Frees the internal data structures
  */
-void rrdcgiFree (s_cgi *parms);
+void      rrdcgiFree(
+    s_cgi * parms);
 
 /*  rrdcgiReadVariables()
  *
  *  Read from stdin if no string is provided via CGI.  Variables that
  *  doesn't have a value associated with it doesn't get stored.
  */
-s_var **rrdcgiReadVariables(void);
+s_var   **rrdcgiReadVariables(
+    void);
 
 
-int rrdcgiDebugLevel = 0;
-int rrdcgiDebugStderr = 1;
-char *rrdcgiHeaderString = NULL;
-char *rrdcgiType = NULL;
+int       rrdcgiDebugLevel = 0;
+int       rrdcgiDebugStderr = 1;
+char     *rrdcgiHeaderString = NULL;
+char     *rrdcgiType = NULL;
 
 /* rrd interface to the variable functions {put,get}var() */
-char* rrdgetvar(long argc, const char **args);
-char* rrdsetvar(long argc, const char **args);
-char* rrdsetvarconst(long argc, const char **args);
+char     *rrdgetvar(
+    long argc,
+    const char **args);
+char     *rrdsetvar(
+    long argc,
+    const char **args);
+char     *rrdsetvarconst(
+    long argc,
+    const char **args);
 
 
 /* variable store: put/get key-value pairs */
-static int   initvar();
-static void  donevar();
-static const char* getvar(const char* varname);
-static const char* putvar(const char* name, const char* value, int is_const);
+static int initvar(
+    );
+static void donevar(
+    );
+static const char *getvar(
+    const char *varname);
+static const char *putvar(
+    const char *name,
+    const char *value,
+    int is_const);
 
 /* key value pair that makes up an entry in the variable store */
-typedef struct
-{
-       int is_const;           /* const variable or not */
-       const char* name;       /* variable name */
-       const char* value;      /* variable value */
+typedef struct {
+    int       is_const; /* const variable or not */
+    const char *name;   /* variable name */
+    const char *value;  /* variable value */
 } vardata;
 
 /* the variable heap: 
    start with a heapsize of 10 variables */
 #define INIT_VARSTORE_SIZE     10
-static vardata* varheap    = NULL;
+static vardata *varheap = NULL;
 static size_t varheap_size = 0;
 
 /* allocate and initialize variable heap */
-static int
-initvar()
+static int initvar(
+    void)
 {
-       varheap = (vardata*)malloc(sizeof(vardata) * INIT_VARSTORE_SIZE);
-       if (varheap == NULL) {
-               fprintf(stderr, "ERROR: unable to initialize variable store\n");
-               return -1;
-       }
-       memset(varheap, 0, sizeof(vardata) * INIT_VARSTORE_SIZE);
-       varheap_size = INIT_VARSTORE_SIZE;
-       return 0;
+    varheap = (vardata *) malloc(sizeof(vardata) * INIT_VARSTORE_SIZE);
+    if (varheap == NULL) {
+        fprintf(stderr, "ERROR: unable to initialize variable store\n");
+        return -1;
+    }
+    memset(varheap, 0, sizeof(vardata) * INIT_VARSTORE_SIZE);
+    varheap_size = INIT_VARSTORE_SIZE;
+    return 0;
 }
 
 /* cleanup: free allocated memory */
-static void
-donevar()
+static void donevar(
+    void)
 {
-       int i;
-       if (varheap) {
-               for (i=0; i<(int)varheap_size; i++) {
-                       if (varheap[i].name) {
-                               free((char*)varheap[i].name);
-                       }
-                       if (varheap[i].value) {
-                               free((char*)varheap[i].value);
-                       }
-               }
-               free(varheap);
-       }
+    int       i;
+
+    if (varheap) {
+        for (i = 0; i < (int) varheap_size; i++) {
+            if (varheap[i].name) {
+                free((char *) varheap[i].name);
+            }
+            if (varheap[i].value) {
+                free((char *) varheap[i].value);
+            }
+        }
+        free(varheap);
+    }
 }
 
 /* Get a variable from the variable store.
    Return NULL in case the requested variable was not found. */
-static const char*
-getvar(const char* name)
+static const char *getvar(
+    const char *name)
 {
-       int i;
-       for (i=0; i<(int)varheap_size && varheap[i].name; i++) {
-               if (0 == strcmp(name, varheap[i].name)) {
+    int       i;
+
+    for (i = 0; i < (int) varheap_size && varheap[i].name; i++) {
+        if (0 == strcmp(name, varheap[i].name)) {
 #ifdef         DEBUG_VARS
-                       printf("<!-- getvar(%s) -> %s -->\n", name, varheap[i].value);
+            printf("<!-- getvar(%s) -> %s -->\n", name, varheap[i].value);
 #endif
-                       return varheap[i].value;
-               }
-       }
+            return varheap[i].value;
+        }
+    }
 #ifdef DEBUG_VARS
-       printf("<!-- getvar(%s) -> Not found-->\n", name);
+    printf("<!-- getvar(%s) -> Not found-->\n", name);
 #endif
-       return NULL;
+    return NULL;
 }
 
 /* Put a variable into the variable store. If a variable by that
    name exists, it's value is overwritten with the new value unless it was
    marked as 'const' (initialized by RRD::SETCONSTVAR).
    Returns a copy the newly allocated value on success, NULL on error. */
-static const char*
-putvar(const char* name, const char* value, int is_const)
+static const char *putvar(
+    const char *name,
+    const char *value,
+    int is_const)
 {
-       int i;
-       for (i=0; i < (int)varheap_size && varheap[i].name; i++) {
-               if (0 == strcmp(name, varheap[i].name)) {
-                       /* overwrite existing entry */
-                       if (varheap[i].is_const) {
-#ifdef                 DEBUG_VARS
-                               printf("<!-- setver(%s, %s): not assigning: "
-                                               "const variable -->\n", name, value);
-#                              endif
-                               return varheap[i].value;
-                       }
-#ifdef         DEBUG_VARS
-                       printf("<!-- setvar(%s, %s): overwriting old value (%s) -->\n",
-                                       name, value, varheap[i].value);
+    int       i;
+
+    for (i = 0; i < (int) varheap_size && varheap[i].name; i++) {
+        if (0 == strcmp(name, varheap[i].name)) {
+            /* overwrite existing entry */
+            if (varheap[i].is_const) {
+#ifdef DEBUG_VARS
+                printf("<!-- setver(%s, %s): not assigning: "
+                       "const variable -->\n", name, value);
 #endif
-                       /* make it possible to promote a variable to readonly */
-                       varheap[i].is_const = is_const;
-                       free((char*)varheap[i].value);
-                       varheap[i].value = stralloc(value);
-                       return varheap[i].value;
-               }
-       }
-
-       /* no existing variable found by that name, add it */
-       if (i == (int)varheap_size) {
-               /* ran out of heap: resize heap to double size */
-               size_t new_size = varheap_size * 2;
-               varheap = (vardata*)(realloc(varheap, sizeof(vardata) * new_size));
-               if (!varheap) {
-                       fprintf(stderr, "ERROR: Unable to realloc variable heap\n");
-                       return NULL;
-               }
-               /* initialize newly allocated memory */;
-               memset(&varheap[varheap_size], 0, sizeof(vardata) * varheap_size);
-               varheap_size = new_size;
-       }
-       varheap[i].is_const = is_const;
-       varheap[i].name  = stralloc(name);
-       varheap[i].value = stralloc(value);
+                return varheap[i].value;
+            }
+#ifdef DEBUG_VARS
+            printf("<!-- setvar(%s, %s): overwriting old value (%s) -->\n",
+                   name, value, varheap[i].value);
+#endif
+            /* make it possible to promote a variable to readonly */
+            varheap[i].is_const = is_const;
+            free((char *) varheap[i].value);
+            varheap[i].value = stralloc(value);
+            return varheap[i].value;
+        }
+    }
+
+    /* no existing variable found by that name, add it */
+    if (i == (int) varheap_size) {
+        /* ran out of heap: resize heap to double size */
+        size_t    new_size = varheap_size * 2;
+
+        varheap = (vardata *) (realloc(varheap, sizeof(vardata) * new_size));
+        if (!varheap) {
+            fprintf(stderr, "ERROR: Unable to realloc variable heap\n");
+            return NULL;
+        }
+        /* initialize newly allocated memory */ ;
+        memset(&varheap[varheap_size], 0, sizeof(vardata) * varheap_size);
+        varheap_size = new_size;
+    }
+    varheap[i].is_const = is_const;
+    varheap[i].name = stralloc(name);
+    varheap[i].value = stralloc(value);
 
 #ifdef         DEBUG_VARS
-       printf("<!-- setvar(%s, %s): adding new variable -->\n", name, value);
+    printf("<!-- setvar(%s, %s): adding new variable -->\n", name, value);
 #endif
-       return varheap[i].value;
+    return varheap[i].value;
 }
 
 /* expand those RRD:* directives that can be used recursivly */
-static char*
-rrd_expand_vars(char* buffer)
+static char *rrd_expand_vars(
+    char *buffer)
 {
-       int i;
+    int       i;
 
 #ifdef DEBUG_PARSER
-       printf("expanding variables in '%s'\n", buffer);
+    printf("expanding variables in '%s'\n", buffer);
 #endif
 
-       for (i=0; buffer[i]; i++) {
-               if (buffer[i] != '<')
-                       continue;
-               parse(&buffer, i, "<RRD::CV", cgiget);
-               parse(&buffer, i, "<RRD::CV::QUOTE", cgigetq);
-               parse(&buffer, i, "<RRD::CV::PATH", cgigetqp);
-               parse(&buffer, i, "<RRD::GETENV", rrdgetenv);    
-               parse(&buffer, i, "<RRD::GETVAR", rrdgetvar);    
-                parse(&buffer, i, "<RRD::TIME::LAST", printtimelast);
-                parse(&buffer, i, "<RRD::TIME::NOW", printtimenow);
-                parse(&buffer, i, "<RRD::TIME::STRFTIME", printstrftime);
-               parse(&buffer, i, "<RRD::INTERNAL", rrdgetinternal);
-       }
-       return buffer;
+    for (i = 0; buffer[i]; i++) {
+        if (buffer[i] != '<')
+            continue;
+        parse(&buffer, i, "<RRD::CV", cgiget);
+        parse(&buffer, i, "<RRD::CV::QUOTE", cgigetq);
+        parse(&buffer, i, "<RRD::CV::PATH", cgigetqp);
+        parse(&buffer, i, "<RRD::GETENV", rrdgetenv);
+        parse(&buffer, i, "<RRD::GETVAR", rrdgetvar);
+        parse(&buffer, i, "<RRD::TIME::LAST", printtimelast);
+        parse(&buffer, i, "<RRD::TIME::NOW", printtimenow);
+        parse(&buffer, i, "<RRD::TIME::STRFTIME", printstrftime);
+        parse(&buffer, i, "<RRD::INTERNAL", rrdgetinternal);
+    }
+    return buffer;
 }
 
-static long goodfor=0;
-static char **calcpr=NULL;
-static void calfree (void){
-  if (calcpr) {
-    long i;
-    for(i=0;calcpr[i];i++){
-      if (calcpr[i]){
-             free(calcpr[i]);
-      }
-    } 
+static long goodfor = 0;
+static char **calcpr = NULL;
+static void calfree(
+    void)
+{
     if (calcpr) {
-           free(calcpr);
+        long      i;
+
+        for (i = 0; calcpr[i]; i++) {
+            if (calcpr[i]) {
+                free(calcpr[i]);
+            }
+        }
+        if (calcpr) {
+            free(calcpr);
+        }
     }
-  }
 }
 
 /* create freeable version of the string */
-char * stralloc(const char *str){
-  char* nstr;
-  if (!str) {
-         return NULL;
-  }
-  nstr = malloc((strlen(str)+1));
-  strcpy(nstr,str);
-  return(nstr);
+char     *stralloc(
+    const char *str)
+{
+    char     *nstr;
+
+    if (!str) {
+        return NULL;
+    }
+    nstr = malloc((strlen(str) + 1));
+    strcpy(nstr, str);
+    return (nstr);
 }
 
-int main(int argc, char *argv[]) {
-       long length;
-       char *buffer;
-       char *server_url = NULL;
-       long i;
-       long filter=0;
+int main(
+    int argc,
+    char *argv[])
+{
+    long      length;
+    char     *buffer;
+    char     *server_url = NULL;
+    long      i;
+    long      filter = 0;
+    struct option long_options[] = {
+        {"filter", no_argument, 0, 'f'},
+        {0, 0, 0, 0}
+    };
+
 #ifdef MUST_DISABLE_SIGFPE
-       signal(SIGFPE,SIG_IGN);
+    signal(SIGFPE, SIG_IGN);
 #endif
 #ifdef MUST_DISABLE_FPMASK
-       fpsetmask(0);
+    fpsetmask(0);
 #endif
-        optind = 0; opterr = 0;  /* initialize getopt */
-
-       /* what do we get for cmdline arguments?
-       for (i=0;i<argc;i++)
-       printf("%d-'%s'\n",i,argv[i]); */
-       while (1) {
-               static struct option long_options[] = {
-                       { "filter", no_argument, 0, 'f' },
-                       { 0, 0, 0, 0}
-               };
-               int option_index = 0;
-               int opt;
-               opt = getopt_long(argc, argv, "f", long_options, &option_index);
-               if (opt == EOF) {
-                       break;
-               }
-
-               switch(opt) {
-               case 'f':
-                               filter=1;
-                       break;
-               case '?':
-                       printf("unknown commandline option '%s'\n",argv[optind-1]);
-                       return -1;
-               }
-       }
-
-       if (!filter) {
-               rrdcgiDebug(0,0);
-               rrdcgiArg = rrdcgiInit();
-               server_url = getenv("SERVER_URL");
-       }
-
-       /* make sure we have one extra argument, 
-          if there are others, we do not care Apache gives several */
-
-       /* if ( (optind != argc-2 
-          && strstr( getenv("SERVER_SOFTWARE"),"Apache/2") != NULL) 
-          && optind != argc-1) { */
-
-       if ( optind >= argc ) { 
-               fprintf(stderr, "ERROR: expected a filename\n");
-               exit(1);
-       } else {
-               length = readfile(argv[optind], &buffer, 1);
-       }
-
-       if(rrd_test_error()) {
-               fprintf(stderr, "ERROR: %s\n",rrd_get_error());
-               exit(1);
-       }
-
-       /* initialize variable heap */
-       initvar();
+    optind = 0;
+    opterr = 0;         /* initialize getopt */
+
+    /* what do we get for cmdline arguments?
+       for (i=0;i<argc;i++)
+       printf("%d-'%s'\n",i,argv[i]); */
+    while (1) {
+        int       option_index = 0;
+        int       opt;
+
+        opt = getopt_long(argc, argv, "f", long_options, &option_index);
+        if (opt == EOF) {
+            break;
+        }
+
+        switch (opt) {
+        case 'f':
+            filter = 1;
+            break;
+        case '?':
+            printf("unknown commandline option '%s'\n", argv[optind - 1]);
+            return -1;
+        }
+    }
+
+    if (!filter) {
+        rrdcgiDebug(0, 0);
+        rrdcgiArg = rrdcgiInit();
+        server_url = getenv("SERVER_URL");
+    }
+
+    /* make sure we have one extra argument, 
+       if there are others, we do not care Apache gives several */
+
+    /* if ( (optind != argc-2 
+       && strstr( getenv("SERVER_SOFTWARE"),"Apache/2") != NULL) 
+       && optind != argc-1) { */
+
+    if (optind >= argc) {
+        fprintf(stderr, "ERROR: expected a filename\n");
+        exit(1);
+    } else {
+        length = readfile(argv[optind], &buffer, 1);
+    }
+
+    if (rrd_test_error()) {
+        fprintf(stderr, "ERROR: %s\n", rrd_get_error());
+        exit(1);
+    }
+
+    /* initialize variable heap */
+    initvar();
 
 #ifdef DEBUG_PARSER
-       /* some fake header for testing */
-       printf ("Content-Type: text/html\nContent-Length: 10000000\n\n\n");
+    /* some fake header for testing */
+    printf("Content-Type: text/html\nContent-Length: 10000000\n\n\n");
 #endif
 
 
-       /* expand rrd directives in buffer recursivly */
-       for (i=0; buffer[i]; i++) {
-               if (buffer[i] != '<')
-                       continue;
-               if (!filter) {
-                       parse(&buffer, i, "<RRD::CV", cgiget);
-                       parse(&buffer, i, "<RRD::CV::PATH", cgigetqp);
-                       parse(&buffer, i, "<RRD::CV::QUOTE", cgigetq);
-                       parse(&buffer, i, "<RRD::GETENV", rrdgetenv);
-               }
-               parse(&buffer, i, "<RRD::GETVAR", rrdgetvar);
-               parse(&buffer, i, "<RRD::GOODFOR", rrdgoodfor);
-               parse(&buffer, i, "<RRD::GRAPH", drawgraph);
-               parse(&buffer, i, "<RRD::INCLUDE", includefile);
-               parse(&buffer, i, "<RRD::PRINT", drawprint);
-               parse(&buffer, i, "<RRD::SETCONSTVAR", rrdsetvarconst);
-               parse(&buffer, i, "<RRD::SETENV", rrdsetenv);
-               parse(&buffer, i, "<RRD::SETVAR", rrdsetvar);
-               parse(&buffer, i, "<RRD::TIME::LAST", printtimelast);
-               parse(&buffer, i, "<RRD::TIME::NOW", printtimenow);
-               parse(&buffer, i, "<RRD::TIME::STRFTIME", printstrftime);
-               parse(&buffer, i, "<RRD::INTERNAL", rrdgetinternal);
-       }
-
-       if (!filter) {
-               printf ("Content-Type: text/html\n" 
-                               "Content-Length: %d\n", 
-                               strlen(buffer));
-
-               if (labs(goodfor) > 0) {
-                       time_t now;
-                       now = time(NULL);
-                       printf("Last-Modified: %s\n", http_time(&now));
-                       now += labs(goodfor);
-                       printf("Expires: %s\n", http_time(&now));
-                       if (goodfor < 0) {
-                               printf("Refresh: %ld\n", labs(goodfor));
-                       }
-               }
-               printf("\n");
-       }
-
-       /* output result */
-       printf("%s", buffer);
-
-       /* cleanup */
-       calfree();
-       if (buffer){
-               free(buffer);
-       }
-       donevar();
-       exit(0);
+    /* expand rrd directives in buffer recursivly */
+    for (i = 0; buffer[i]; i++) {
+        if (buffer[i] != '<')
+            continue;
+        if (!filter) {
+            parse(&buffer, i, "<RRD::CV", cgiget);
+            parse(&buffer, i, "<RRD::CV::PATH", cgigetqp);
+            parse(&buffer, i, "<RRD::CV::QUOTE", cgigetq);
+            parse(&buffer, i, "<RRD::GETENV", rrdgetenv);
+        }
+        parse(&buffer, i, "<RRD::GETVAR", rrdgetvar);
+        parse(&buffer, i, "<RRD::GOODFOR", rrdgoodfor);
+        parse(&buffer, i, "<RRD::GRAPH", drawgraph);
+        parse(&buffer, i, "<RRD::INCLUDE", includefile);
+        parse(&buffer, i, "<RRD::PRINT", drawprint);
+        parse(&buffer, i, "<RRD::SETCONSTVAR", rrdsetvarconst);
+        parse(&buffer, i, "<RRD::SETENV", rrdsetenv);
+        parse(&buffer, i, "<RRD::SETVAR", rrdsetvar);
+        parse(&buffer, i, "<RRD::TIME::LAST", printtimelast);
+        parse(&buffer, i, "<RRD::TIME::NOW", printtimenow);
+        parse(&buffer, i, "<RRD::TIME::STRFTIME", printstrftime);
+        parse(&buffer, i, "<RRD::INTERNAL", rrdgetinternal);
+    }
+
+    if (!filter) {
+        printf("Content-Type: text/html\n"
+               "Content-Length: %zd\n", strlen(buffer));
+
+        if (labs(goodfor) > 0) {
+            time_t    now;
+
+            now = time(NULL);
+            printf("Last-Modified: %s\n", http_time(&now));
+            now += labs(goodfor);
+            printf("Expires: %s\n", http_time(&now));
+            if (goodfor < 0) {
+                printf("Refresh: %ld\n", labs(goodfor));
+            }
+        }
+        printf("\n");
+    }
+
+    /* output result */
+    printf("%s", buffer);
+
+    /* cleanup */
+    calfree();
+    if (buffer) {
+        free(buffer);
+    }
+    donevar();
+    exit(0);
 }
 
 /* remove occurrences of .. this is a general measure to make
    paths which came in via cgi do not go UP ... */
 
-char* rrdsetenv(long argc, const char **args) {
-       if (argc >= 2) {
-               char *xyz = malloc((strlen(args[0]) + strlen(args[1]) + 2));
-               if (xyz == NULL) {
-                       return stralloc("[ERROR: allocating setenv buffer]");
-               };
-               sprintf(xyz, "%s=%s", args[0], args[1]);
-               if(putenv(xyz) == -1) {
-                       free(xyz);
-                       return stralloc("[ERROR: failed to do putenv]");
-               };
-               return stralloc("");
-       }
-       return stralloc("[ERROR: setenv failed because not enough "
-                                       "arguments were defined]");
+char     *rrdsetenv(
+    long argc,
+    const char **args)
+{
+    if (argc >= 2) {
+        char     *xyz = malloc((strlen(args[0]) + strlen(args[1]) + 2));
+
+        if (xyz == NULL) {
+            return stralloc("[ERROR: allocating setenv buffer]");
+        };
+        sprintf(xyz, "%s=%s", args[0], args[1]);
+        if (putenv(xyz) == -1) {
+            free(xyz);
+            return stralloc("[ERROR: failed to do putenv]");
+        };
+        return stralloc("");
+    }
+    return stralloc("[ERROR: setenv failed because not enough "
+                    "arguments were defined]");
 }
 
 /* rrd interface to the variable function putvar() */
-char*
-rrdsetvar(long argc, const char **args)
+char     *rrdsetvar(
+    long argc,
+    const char **args)
 {
-       if (argc >= 2)
-       {
-               const char* result = putvar(args[0], args[1], 0 /* not const */);
-               if (result) {
-                       /* setvar does not return the value set */
-                       return stralloc("");
-               }
-               return stralloc("[ERROR: putvar failed]");
-       }
-       return stralloc("[ERROR: putvar failed because not enough arguments "
-                                       "were defined]");
+    if (argc >= 2) {
+        const char *result = putvar(args[0], args[1], 0 /* not const */ );
+
+        if (result) {
+            /* setvar does not return the value set */
+            return stralloc("");
+        }
+        return stralloc("[ERROR: putvar failed]");
+    }
+    return stralloc("[ERROR: putvar failed because not enough arguments "
+                    "were defined]");
 }
 
 /* rrd interface to the variable function putvar() */
-char*
-rrdsetvarconst(long argc, const char **args)
+char     *rrdsetvarconst(
+    long argc,
+    const char **args)
 {
-       if (argc >= 2)
-       {
-               const char* result = putvar(args[0], args[1], 1 /* const */);
-               if (result) {
-                       /* setvar does not return the value set */
-                       return stralloc("");
-               }
-               return stralloc("[ERROR: putvar failed]");
-       }
-       return stralloc("[ERROR: putvar failed because not enough arguments "
-                                       "were defined]");
+    if (argc >= 2) {
+        const char *result = putvar(args[0], args[1], 1 /* const */ );
+
+        if (result) {
+            /* setvar does not return the value set */
+            return stralloc("");
+        }
+        return stralloc("[ERROR: putvar failed]");
+    }
+    return stralloc("[ERROR: putvar failed because not enough arguments "
+                    "were defined]");
 }
 
-char* rrdgetenv(long argc, const char **args) {
-       char buf[128];
-       const char* envvar;
-       if (argc != 1) {
-               return stralloc("[ERROR: getenv failed because it did not "
-                                               "get 1 argument only]");
-       };
-       envvar = getenv(args[0]);
-       if (envvar) {
-               return stralloc(envvar);
-       } else {
-                snprintf(buf, sizeof(buf), "[ERROR:_getenv_'%s'_failed", args[0]);
-                return stralloc(buf);
-       }
+char     *rrdgetenv(
+    long argc,
+    const char **args)
+{
+    char      buf[128];
+    const char *envvar;
+
+    if (argc != 1) {
+        return stralloc("[ERROR: getenv failed because it did not "
+                        "get 1 argument only]");
+    };
+    envvar = getenv(args[0]);
+    if (envvar) {
+        return stralloc(envvar);
+    } else {
+        snprintf(buf, sizeof(buf), "[ERROR:_getenv_'%s'_failed", args[0]);
+        return stralloc(buf);
+    }
 }
 
-char* rrdgetvar(long argc, const char **args) {
-       char buf[128];
-       const char* value;
-       if (argc != 1) {
-               return stralloc("[ERROR: getvar failed because it did not "
-                                               "get 1 argument only]");
-       };
-       value = getvar(args[0]);
-       if (value) {
-               return stralloc(value);
-       } else {
-                snprintf(buf, sizeof(buf), "[ERROR:_getvar_'%s'_failed", args[0]);
-               return stralloc(buf);
-       }
+char     *rrdgetvar(
+    long argc,
+    const char **args)
+{
+    char      buf[128];
+    const char *value;
+
+    if (argc != 1) {
+        return stralloc("[ERROR: getvar failed because it did not "
+                        "get 1 argument only]");
+    };
+    value = getvar(args[0]);
+    if (value) {
+        return stralloc(value);
+    } else {
+        snprintf(buf, sizeof(buf), "[ERROR:_getvar_'%s'_failed", args[0]);
+        return stralloc(buf);
+    }
 }
 
-char* rrdgoodfor(long argc, const char **args){
-  if (argc == 1) {
-      goodfor = atol(args[0]);
-  } else {
-    return stralloc("[ERROR: goodfor expected 1 argument]");
-  }
-   
-  if (goodfor == 0){
-     return stralloc("[ERROR: goodfor value must not be 0]");
-  }
-   
-  return stralloc("");
+char     *rrdgoodfor(
+    long argc,
+    const char **args)
+{
+    if (argc == 1) {
+        goodfor = atol(args[0]);
+    } else {
+        return stralloc("[ERROR: goodfor expected 1 argument]");
+    }
+
+    if (goodfor == 0) {
+        return stralloc("[ERROR: goodfor value must not be 0]");
+    }
+
+    return stralloc("");
 }
 
-char* rrdgetinternal(long argc, const char **args){
-  if (argc == 1) {
-    if( strcasecmp( args[0], "VERSION") == 0) {
-      return stralloc(PACKAGE_VERSION);
-    } else if( strcasecmp( args[0], "COMPILETIME") == 0) {
-      return stralloc(__DATE__ " " __TIME__);
+char     *rrdgetinternal(
+    long argc,
+    const char **args)
+{
+    if (argc == 1) {
+        if (strcasecmp(args[0], "VERSION") == 0) {
+            return stralloc(PACKAGE_VERSION);
+        } else if (strcasecmp(args[0], "COMPILETIME") == 0) {
+            return stralloc(__DATE__ " " __TIME__);
+        } else {
+            return stralloc("[ERROR: internal unknown argument]");
+        }
     } else {
-      return stralloc("[ERROR: internal unknown argument]");
+        return stralloc("[ERROR: internal expected 1 argument]");
     }
-  } else {
-    return stralloc("[ERROR: internal expected 1 argument]");
-  }
 }
 
 /* Format start or end times using strftime.  We always need both the
  * start and end times, because, either might be relative to the other.
  * */
 #define MAX_STRFTIME_SIZE 256
-char* printstrftime(long argc, const char **args){
-       struct  rrd_time_value start_tv, end_tv;
-       char    *parsetime_error = NULL;
-       char    formatted[MAX_STRFTIME_SIZE];
-       struct tm *the_tm;
-       time_t  start_tmp, end_tmp;
-
-       /* Make sure that we were given the right number of args */
-       if( argc != 4) {
-               rrd_set_error( "wrong number of args %d", argc);
-               return stralloc("");
-       }
-
-       /* Init start and end time */
-       parsetime("end-24h", &start_tv);
-       parsetime("now", &end_tv);
-
-       /* Parse the start and end times we were given */
-       if( (parsetime_error = parsetime( args[1], &start_tv))) {
-               rrd_set_error( "start time: %s", parsetime_error);
-               return stralloc("");
-       }
-       if( (parsetime_error = parsetime( args[2], &end_tv))) {
-               rrd_set_error( "end time: %s", parsetime_error);
-               return stralloc("");
-       }
-       if( proc_start_end( &start_tv, &end_tv, &start_tmp, &end_tmp) == -1) {
-               return stralloc("");
-       }
-
-       /* Do we do the start or end */
-       if( strcasecmp( args[0], "START") == 0) {
-               the_tm = localtime( &start_tmp);
-       }
-       else if( strcasecmp( args[0], "END") == 0) {
-               the_tm = localtime( &end_tmp);
-       }
-       else {
-               rrd_set_error( "start/end not found in '%s'", args[0]);
-               return stralloc("");
-       }
-
-       /* now format it */
-       if( strftime( formatted, MAX_STRFTIME_SIZE, args[3], the_tm)) {
-               return( stralloc( formatted));
-       }
-       else {
-               rrd_set_error( "strftime failed");
-               return stralloc("");
-       }
+char     *printstrftime(
+    long argc,
+    const char **args)
+{
+    struct rrd_time_value start_tv, end_tv;
+    char     *parsetime_error = NULL;
+    char      formatted[MAX_STRFTIME_SIZE];
+    struct tm *the_tm;
+    time_t    start_tmp, end_tmp;
+
+    /* Make sure that we were given the right number of args */
+    if (argc != 4) {
+        rrd_set_error("wrong number of args %d", argc);
+        return stralloc("");
+    }
+
+    /* Init start and end time */
+    parsetime("end-24h", &start_tv);
+    parsetime("now", &end_tv);
+
+    /* Parse the start and end times we were given */
+    if ((parsetime_error = parsetime(args[1], &start_tv))) {
+        rrd_set_error("start time: %s", parsetime_error);
+        return stralloc("");
+    }
+    if ((parsetime_error = parsetime(args[2], &end_tv))) {
+        rrd_set_error("end time: %s", parsetime_error);
+        return stralloc("");
+    }
+    if (proc_start_end(&start_tv, &end_tv, &start_tmp, &end_tmp) == -1) {
+        return stralloc("");
+    }
+
+    /* Do we do the start or end */
+    if (strcasecmp(args[0], "START") == 0) {
+        the_tm = localtime(&start_tmp);
+    } else if (strcasecmp(args[0], "END") == 0) {
+        the_tm = localtime(&end_tmp);
+    } else {
+        rrd_set_error("start/end not found in '%s'", args[0]);
+        return stralloc("");
+    }
+
+    /* now format it */
+    if (strftime(formatted, MAX_STRFTIME_SIZE, args[3], the_tm)) {
+        return (stralloc(formatted));
+    } else {
+        rrd_set_error("strftime failed");
+        return stralloc("");
+    }
 }
 
-char* includefile(long argc, const char **args){
-  char *buffer;
-  if (argc >= 1) {
-      const char* filename = args[0];
-      readfile(filename, &buffer, 0);
-      if (rrd_test_error()) {
-               char *err = malloc((strlen(rrd_get_error())+DS_NAM_SIZE));
-         sprintf(err, "[ERROR: %s]",rrd_get_error());
-         rrd_clear_error();
-         return err;
-      } else {
-       return buffer;
-      }
-  }
-  else
-  {
-      return stralloc("[ERROR: No Inclue file defined]");
-  }
+char     *includefile(
+    long argc,
+    const char **args)
+{
+    char     *buffer;
+
+    if (argc >= 1) {
+        const char *filename = args[0];
+
+        readfile(filename, &buffer, 0);
+        if (rrd_test_error()) {
+            char     *err = malloc((strlen(rrd_get_error()) + DS_NAM_SIZE));
+
+            sprintf(err, "[ERROR: %s]", rrd_get_error());
+            rrd_clear_error();
+            return err;
+        } else {
+            return buffer;
+        }
+    } else {
+        return stralloc("[ERROR: No Inclue file defined]");
+    }
 }
 
 /* make a copy of buf and replace open/close brackets with '_' */
-char* rrdstrip(char *buf) {
-  char* p;
-  if (buf == NULL) {
-         return NULL;
-  }
-  /* make a copy of the buffer */
-  buf = stralloc(buf);
-  if (buf == NULL) {
-         return NULL;
-  }
-
-  p = buf;
-  while (*p) {
-         if (*p == '<' || *p == '>') {
-                 *p = '_';
-         }
-         p++;
-  }
-  return buf;
+char     *rrdstrip(
+    char *buf)
+{
+    char     *p;
+
+    if (buf == NULL) {
+        return NULL;
+    }
+    /* make a copy of the buffer */
+    buf = stralloc(buf);
+    if (buf == NULL) {
+        return NULL;
+    }
+
+    p = buf;
+    while (*p) {
+        if (*p == '<' || *p == '>') {
+            *p = '_';
+        }
+        p++;
+    }
+    return buf;
 }
 
-char* cgigetq(long argc, const char **args){
-  if (argc>= 1){
-    char *buf = rrdstrip(rrdcgiGetValue(rrdcgiArg,args[0]));
-    char *buf2;
-    char *c,*d;
-    int  qc=0;
-    if (buf==NULL) return NULL;
-
-    for(c=buf;*c != '\0';c++)
-      if (*c == '"') qc++;
-    if ((buf2 = malloc((strlen(buf) + 4 * qc + 4))) == NULL) {
-       perror("Malloc Buffer");
-       exit(1);
-    };
-    c=buf;
-    d=buf2;
-    *(d++) = '"';
-    while(*c != '\0'){
-       if (*c == '"') {
-           *(d++) = '"';
-           *(d++) = '\'';
-           *(d++) = '"';
-           *(d++) = '\'';
-       } 
-       *(d++) = *(c++);
-    }
-    *(d++) = '"';
-    *(d) = '\0';
-    free(buf);
-    return buf2;
-  }
+char     *cgigetq(
+    long argc,
+    const char **args)
+{
+    if (argc >= 1) {
+        char     *buf = rrdstrip(rrdcgiGetValue(rrdcgiArg, args[0]));
+        char     *buf2;
+        char     *c, *d;
+        int       qc = 0;
+
+        if (buf == NULL)
+            return NULL;
+
+        for (c = buf; *c != '\0'; c++)
+            if (*c == '"')
+                qc++;
+        if ((buf2 = malloc((strlen(buf) + 4 * qc + 4))) == NULL) {
+            perror("Malloc Buffer");
+            exit(1);
+        };
+        c = buf;
+        d = buf2;
+        *(d++) = '"';
+        while (*c != '\0') {
+            if (*c == '"') {
+                *(d++) = '"';
+                *(d++) = '\'';
+                *(d++) = '"';
+                *(d++) = '\'';
+            }
+            *(d++) = *(c++);
+        }
+        *(d++) = '"';
+        *(d) = '\0';
+        free(buf);
+        return buf2;
+    }
 
-  return stralloc("[ERROR: not enough argument for RRD::CV::QUOTE]");
+    return stralloc("[ERROR: not enough argument for RRD::CV::QUOTE]");
 }
 
 /* remove occurrences of .. this is a general measure to make
    paths which came in via cgi do not go UP ... */
 
-char* cgigetqp(long argc, const char **args){
-       char* buf;
-    char* buf2;
-    char* p;
-        char* d;
+char     *cgigetqp(
+    long argc,
+    const char **args)
+{
+    char     *buf;
+    char     *buf2;
+    char     *p;
+    char     *d;
 
-        if (argc < 1)
-        {
-                return stralloc("[ERROR: not enough arguments for RRD::CV::PATH]");
-        }
+    if (argc < 1) {
+        return stralloc("[ERROR: not enough arguments for RRD::CV::PATH]");
+    }
 
-        buf = rrdstrip(rrdcgiGetValue(rrdcgiArg, args[0]));
-    if (!buf)
-        {
-                return NULL;
-        }
+    buf = rrdstrip(rrdcgiGetValue(rrdcgiArg, args[0]));
+    if (!buf) {
+        return NULL;
+    }
 
-        buf2 = malloc(strlen(buf)+1);
-    if (!buf2)
-        {
-                perror("cgigetqp(): Malloc Path Buffer");
-                exit(1);
+    buf2 = malloc(strlen(buf) + 1);
+    if (!buf2) {
+        perror("cgigetqp(): Malloc Path Buffer");
+        exit(1);
     };
 
     p = buf;
     d = buf2;
 
-    while (*p)
-        {
-                /* prevent mallicious paths from entering the system */
-                if (p[0] == '.' && p[1] == '.')
-                {
-                        p += 2;
-                        *d++ = '_';
-                        *d++ = '_';     
-                }
-                else
-                {
-                        *d++ = *p++;
-                }
+    while (*p) {
+        /* prevent mallicious paths from entering the system */
+        if (p[0] == '.' && p[1] == '.') {
+            p += 2;
+            *d++ = '_';
+            *d++ = '_';
+        } else {
+            *d++ = *p++;
+        }
     }
 
     *d = 0;
@@ -743,101 +850,127 @@ char* cgigetqp(long argc, const char **args){
 
     /* Make sure the path is relative, e.g. does not start with '/' */
     p = buf2;
-    while ('/' == *p)
-        {
-            *p++ = '_';
+    while ('/' == *p) {
+        *p++ = '_';
     }
 
     return buf2;
 }
 
 
-char* cgiget(long argc, const char **args){
-  if (argc>= 1)
-    return rrdstrip(rrdcgiGetValue(rrdcgiArg,args[0]));
-  else
-    return stralloc("[ERROR: not enough arguments for RRD::CV]");
+char     *cgiget(
+    long argc,
+    const char **args)
+{
+    if (argc >= 1)
+        return rrdstrip(rrdcgiGetValue(rrdcgiArg, args[0]));
+    else
+        return stralloc("[ERROR: not enough arguments for RRD::CV]");
 }
 
 
 
-char* drawgraph(long argc, const char **args){
-  int i,xsize, ysize;
-  double ymin,ymax;
-  for(i=0;i<argc;i++)
-    if(strcmp(args[i],"--imginfo")==0 || strcmp(args[i],"-g")==0) break;
-  if(i==argc) {
-    args[argc++] = "--imginfo";
-    args[argc++] = "<IMG SRC=\"./%s\" WIDTH=\"%lu\" HEIGHT=\"%lu\">";
-  }
-  calfree();
-  if( rrd_graph(argc+1, (char **) args-1, &calcpr, &xsize, &ysize,NULL,&ymin,&ymax) != -1 ) {
-    return stralloc(calcpr[0]);
-  } else {
-    if (rrd_test_error()) {
-      char *err = malloc((strlen(rrd_get_error())+DS_NAM_SIZE)*sizeof(char));
-      sprintf(err, "[ERROR: %s]",rrd_get_error());
-      rrd_clear_error();
-      calfree();
-      return err;
-    }
-  }
-  return NULL;
+char     *drawgraph(
+    long argc,
+    const char **args)
+{
+    int       i, xsize, ysize;
+    double    ymin, ymax;
+
+    for (i = 0; i < argc; i++)
+        if (strcmp(args[i], "--imginfo") == 0 || strcmp(args[i], "-g") == 0)
+            break;
+    if (i == argc) {
+        args[argc++] = "--imginfo";
+        args[argc++] = "<IMG SRC=\"./%s\" WIDTH=\"%lu\" HEIGHT=\"%lu\">";
+    }
+    calfree();
+    if (rrd_graph
+        (argc + 1, (char **) args - 1, &calcpr, &xsize, &ysize, NULL, &ymin,
+         &ymax) != -1) {
+        return stralloc(calcpr[0]);
+    } else {
+        if (rrd_test_error()) {
+            char     *err =
+                malloc((strlen(rrd_get_error()) +
+                        DS_NAM_SIZE) * sizeof(char));
+            sprintf(err, "[ERROR: %s]", rrd_get_error());
+            rrd_clear_error();
+            calfree();
+            return err;
+        }
+    }
+    return NULL;
 }
 
-char* drawprint(long argc, const char **args){
-  if (argc==1 && calcpr){
-    long i=0;
-    while (calcpr[i] != NULL) i++; /*determine number lines in calcpr*/
-    if (atol(args[0])<i-1)
-      return stralloc(calcpr[atol(args[0])+1]);    
-  }
-  return stralloc("[ERROR: RRD::PRINT argument error]");
+char     *drawprint(
+    long argc,
+    const char **args)
+{
+    if (argc == 1 && calcpr) {
+        long      i = 0;
+
+        while (calcpr[i] != NULL)
+            i++;        /*determine number lines in calcpr */
+        if (atol(args[0]) < i - 1)
+            return stralloc(calcpr[atol(args[0]) + 1]);
+    }
+    return stralloc("[ERROR: RRD::PRINT argument error]");
 }
 
-char* printtimelast(long argc, const char **args) {
-  time_t last;
-  struct tm tm_last;
-  char *buf;
-  if ( argc == 2 ) {
-    buf = malloc(255);
-    if (buf == NULL){  
-       return stralloc("[ERROR: allocating strftime buffer]");
-    };
-    last = rrd_last(argc+1, (char **) args-1); 
-    if (rrd_test_error()) {
-      char *err = malloc((strlen(rrd_get_error())+DS_NAM_SIZE)*sizeof(char));
-      sprintf(err, "[ERROR: %s]",rrd_get_error());
-      rrd_clear_error();
-      return err;
+char     *printtimelast(
+    long argc,
+    const char **args)
+{
+    time_t    last;
+    struct tm tm_last;
+    char     *buf;
+
+    if (argc == 2) {
+        buf = malloc(255);
+        if (buf == NULL) {
+            return stralloc("[ERROR: allocating strftime buffer]");
+        };
+        last = rrd_last(argc + 1, (char **) args - 1);
+        if (rrd_test_error()) {
+            char     *err =
+                malloc((strlen(rrd_get_error()) +
+                        DS_NAM_SIZE) * sizeof(char));
+            sprintf(err, "[ERROR: %s]", rrd_get_error());
+            rrd_clear_error();
+            return err;
+        }
+        tm_last = *localtime(&last);
+        strftime(buf, 254, args[1], &tm_last);
+        return buf;
     }
-    tm_last = *localtime(&last);
-    strftime(buf,254,args[1],&tm_last);
-    return buf;
-  }
-  if ( argc < 2 ) {
-    return stralloc("[ERROR: too few arguments for RRD::TIME::LAST]");
-  }
-  return stralloc("[ERROR: not enough arguments for RRD::TIME::LAST]");
+    if (argc < 2) {
+        return stralloc("[ERROR: too few arguments for RRD::TIME::LAST]");
+    }
+    return stralloc("[ERROR: not enough arguments for RRD::TIME::LAST]");
 }
 
-char* printtimenow(long argc, const char **args) {
-  time_t now = time(NULL);
-  struct tm tm_now;
-  char *buf;
-  if ( argc == 1 ) {
-    buf = malloc(255);
-    if (buf == NULL){  
-       return stralloc("[ERROR: allocating strftime buffer]");
-    };
-    tm_now = *localtime(&now);
-    strftime(buf,254,args[0],&tm_now);
-    return buf;
-  }
-  if ( argc < 1 ) {
-    return stralloc("[ERROR: too few arguments for RRD::TIME::NOW]");
-  }
-  return stralloc("[ERROR: not enough arguments for RRD::TIME::NOW]");
+char     *printtimenow(
+    long argc,
+    const char **args)
+{
+    time_t    now = time(NULL);
+    struct tm tm_now;
+    char     *buf;
+
+    if (argc == 1) {
+        buf = malloc(255);
+        if (buf == NULL) {
+            return stralloc("[ERROR: allocating strftime buffer]");
+        };
+        tm_now = *localtime(&now);
+        strftime(buf, 254, args[0], &tm_now);
+        return buf;
+    }
+    if (argc < 1) {
+        return stralloc("[ERROR: too few arguments for RRD::TIME::NOW]");
+    }
+    return stralloc("[ERROR: not enough arguments for RRD::TIME::NOW]");
 }
 
 /* Scan buffer until an unescaped '>' arives.
@@ -849,164 +982,163 @@ char* printtimenow(long argc, const char **args) {
  * that contain RRD::x directives. These introduce a small memory leak
  * since we have to stralloc the arguments the way parse() works.
  */
-char*
-scanargs(char *line, int *argument_count, char ***arguments)
+char     *scanargs(
+    char *line,
+    int *argument_count,
+    char ***arguments)
 {
-       char    *getP;          /* read cursor */
-       char    *putP;          /* write cursor */
-       char    Quote;          /* type of quote if in quoted string, 0 otherwise */
-       int     tagcount;       /* open tag count */
-       int     in_arg;         /* if we currently are parsing an argument or not */
-       int     argsz;          /* argument array size */
-       int             curarg_contains_rrd_directives;
-
-       /* local array of arguments while parsing */
-       int argc = 0;
-       char** argv;
+    char     *getP;     /* read cursor */
+    char     *putP;     /* write cursor */
+    char      Quote;    /* type of quote if in quoted string, 0 otherwise */
+    int       tagcount; /* open tag count */
+    int       in_arg;   /* if we currently are parsing an argument or not */
+    int       argsz;    /* argument array size */
+    int       curarg_contains_rrd_directives;
+
+    /* local array of arguments while parsing */
+    int       argc = 0;
+    char    **argv;
 
 #ifdef DEBUG_PARSER
-       printf("<-- scanargs(%s) -->\n", line);
+    printf("<-- scanargs(%s) -->\n", line);
 #endif
 
-       *arguments = NULL;
-       *argument_count = 0;
-
-       /* create initial argument array of char pointers */
-       argsz = 32;
-       argv = (char **)malloc(argsz * sizeof(char *));
-       if (!argv) {
-               return NULL;
-       }
-
-       /* skip leading blanks */
-       while (isspace((int)*line)) {
-               line++;
-       }
-
-       getP = line;
-       putP = line;
-
-       Quote    = 0;
-       in_arg   = 0;
-       tagcount = 0;
-
-       curarg_contains_rrd_directives = 0;
-
-       /* start parsing 'line' for arguments */
-       while (*getP)
-       {
-               unsigned char c = *getP++;
-
-               if (c == '>' && !Quote && !tagcount) {
-                       /* this is our closing tag, quit scanning */
-                       break;
-               }
-
-               /* remove all special chars */
-               if (c < ' ') {
-                       c = ' ';
-               }
-
-               switch (c)
-               {
-               case ' ': 
-                       if (Quote || tagcount) {
-                               /* copy quoted/tagged (=RRD expanded) string */
-                               *putP++ = c;
-                       }
-                       else if (in_arg)
-                       {
-                               /* end argument string */
-                               *putP++ = 0;
-                               in_arg = 0;
-                               if (curarg_contains_rrd_directives) {
-                                       argv[argc-1] = rrd_expand_vars(stralloc(argv[argc-1]));
-                                       curarg_contains_rrd_directives = 0;
-                               }
-                       }
-                       break;
-
-               case '"': /* Fall through */
-               case '\'':
-                       if (Quote != 0) {
-                               if (Quote == c) {
-                                       Quote = 0;
-                               } else {
-                                       /* copy quoted string */
-                                       *putP++ = c;
-                               }
-                       } else {
-                               if (!in_arg) {
-                                       /* reference start of argument string in argument array */
-                                       argv[argc++] = putP;
-                                       in_arg=1;
-                               }
-                               Quote = c;
-                       }
-                       break;
-
-               default:
-                               if (!in_arg) {
-                                       /* start new argument */
-                                       argv[argc++] = putP;
-                                       in_arg = 1;
-                               }
-                               if (c == '>') {
-                                       if (tagcount) {
-                                               tagcount--;
-                                       }
-                               }
-                               if (c == '<') {
-                                       tagcount++;
-                                       if (0 == strncmp(getP, "RRD::", strlen("RRD::"))) {
-                                               curarg_contains_rrd_directives = 1;
-                                       }
-                               }
-                       *putP++ = c;
-                       break;
-               }
-
-               /* check if our argument array is still large enough */
-               if (argc == argsz) {
-                       /* resize argument array */
-                       argsz *= 2;
-                       argv = rrd_realloc(argv, argsz * sizeof(char *));
-                       if (*argv == NULL) {
-                               return NULL;
-                       }
-               }
-       }
-
-       /* terminate last argument found */
-       *putP = '\0';
-       if (curarg_contains_rrd_directives) {
-               argv[argc-1] = rrd_expand_vars(stralloc(argv[argc-1]));
-       }
+    *arguments = NULL;
+    *argument_count = 0;
+
+    /* create initial argument array of char pointers */
+    argsz = 32;
+    argv = (char **) malloc(argsz * sizeof(char *));
+    if (!argv) {
+        return NULL;
+    }
+
+    /* skip leading blanks */
+    while (isspace((int) *line)) {
+        line++;
+    }
+
+    getP = line;
+    putP = line;
+
+    Quote = 0;
+    in_arg = 0;
+    tagcount = 0;
+
+    curarg_contains_rrd_directives = 0;
+
+    /* start parsing 'line' for arguments */
+    while (*getP) {
+        unsigned char c = *getP++;
+
+        if (c == '>' && !Quote && !tagcount) {
+            /* this is our closing tag, quit scanning */
+            break;
+        }
+
+        /* remove all special chars */
+        if (c < ' ') {
+            c = ' ';
+        }
+
+        switch (c) {
+        case ' ':
+            if (Quote || tagcount) {
+                /* copy quoted/tagged (=RRD expanded) string */
+                *putP++ = c;
+            } else if (in_arg) {
+                /* end argument string */
+                *putP++ = 0;
+                in_arg = 0;
+                if (curarg_contains_rrd_directives) {
+                    argv[argc - 1] =
+                        rrd_expand_vars(stralloc(argv[argc - 1]));
+                    curarg_contains_rrd_directives = 0;
+                }
+            }
+            break;
+
+        case '"':      /* Fall through */
+        case '\'':
+            if (Quote != 0) {
+                if (Quote == c) {
+                    Quote = 0;
+                } else {
+                    /* copy quoted string */
+                    *putP++ = c;
+                }
+            } else {
+                if (!in_arg) {
+                    /* reference start of argument string in argument array */
+                    argv[argc++] = putP;
+                    in_arg = 1;
+                }
+                Quote = c;
+            }
+            break;
+
+        default:
+            if (!in_arg) {
+                /* start new argument */
+                argv[argc++] = putP;
+                in_arg = 1;
+            }
+            if (c == '>') {
+                if (tagcount) {
+                    tagcount--;
+                }
+            }
+            if (c == '<') {
+                tagcount++;
+                if (0 == strncmp(getP, "RRD::", strlen("RRD::"))) {
+                    curarg_contains_rrd_directives = 1;
+                }
+            }
+            *putP++ = c;
+            break;
+        }
 
+        /* check if our argument array is still large enough */
+        if (argc == argsz) {
+            /* resize argument array */
+            argsz *= 2;
+            argv = rrd_realloc(argv, argsz * sizeof(char *));
+            if (*argv == NULL) {
+                return NULL;
+            }
+        }
+    }
+
+    /* terminate last argument found */
+    *putP = '\0';
+    if (curarg_contains_rrd_directives) {
+        argv[argc - 1] = rrd_expand_vars(stralloc(argv[argc - 1]));
+    }
 #ifdef DEBUG_PARSER
-       if (argc > 0) {
-               int n;
-               printf("<-- arguments found [%d]\n", argc);
-               for (n=0; n<argc; n++) {
-                       printf("arg %02d: '%s'\n", n, argv[n]);
-               }
-               printf("-->\n");
-       } else {
-               printf("<!-- No arguments found -->\n");
-       }
+    if (argc > 0) {
+        int       n;
+
+        printf("<-- arguments found [%d]\n", argc);
+        for (n = 0; n < argc; n++) {
+            printf("arg %02d: '%s'\n", n, argv[n]);
+        }
+        printf("-->\n");
+    } else {
+        printf("<!-- No arguments found -->\n");
+    }
 #endif
 
-       /* update caller's notion of the argument array and it's size */
-       *arguments = argv;
-       *argument_count = argc;
+    /* update caller's notion of the argument array and it's size */
+    *arguments = argv;
+    *argument_count = argc;
 
-       if (Quote) {
-               return NULL;
-       }
+    if (Quote) {
+        return NULL;
+    }
 
-       /* Return new scanning cursor:
-          pointer to char after closing bracket */
-       return getP;
+    /* Return new scanning cursor:
+       pointer to char after closing bracket */
+    return getP;
 }
 
 
@@ -1016,155 +1148,161 @@ scanargs(char *line, int *argument_count, char ***arguments)
  * The result of func is inserted at the current position
  * in the buffer.
  */
-int
-parse(
-       char **buf,     /* buffer */
-       long i,                 /* offset in buffer */
-       char *tag,      /* tag to handle  */
-       char *(*func)(long , const char **) /* function to call for 'tag' */
-       )
+int parse(
+    char **buf,         /* buffer */
+    long i,             /* offset in buffer */
+    char *tag,          /* tag to handle  */
+    char *    (*func) (long,
+                       const char **)   /* function to call for 'tag' */
+    )
 {
-       /* the name of the vairable ... */
-       char *val;
-       long valln;  
-       char **args;
-       char *end;
-       long end_offset;
-       int  argc;
-       size_t taglen = strlen(tag);
-
-       /* Current position in buffer should start with 'tag' */
-       if (strncmp((*buf)+i, tag, taglen) != 0) {
-               return 0;
-       }
-       /* .. and match exactly (a whitespace following 'tag') */
-       if (! isspace(*((*buf) + i + taglen)) ) {
-               return 0;
-       }
-
+    /* the name of the vairable ... */
+    char     *val;
+    long      valln;
+    char    **args;
+    char     *end;
+    long      end_offset;
+    int       argc;
+    size_t    taglen = strlen(tag);
+
+    /* Current position in buffer should start with 'tag' */
+    if (strncmp((*buf) + i, tag, taglen) != 0) {
+        return 0;
+    }
+    /* .. and match exactly (a whitespace following 'tag') */
+    if (!isspace(*((*buf) + i + taglen))) {
+        return 0;
+    }
 #ifdef DEBUG_PARSER
-       printf("parse(): handling tag '%s'\n", tag);
+    printf("parse(): handling tag '%s'\n", tag);
 #endif
 
-       /* Scan for arguments following the tag;
-          scanargs() puts \0 into *buf ... so after scanargs it is probably
-          not a good time to use strlen on buf */
-       end = scanargs((*buf) + i + taglen, &argc, &args);
-       if (end)
-       {
-               /* got arguments, call function for 'tag' with arguments */
-               val = func(argc, (const char **) args);
-               free(args);
-       }
-       else
-       {
-               /* unable to parse arguments, undo 0-termination by scanargs */
-               for (; argc > 0; argc--) {
-                       *((args[argc-1])-1) = ' ';
-               }
-
-               /* next call, try parsing at current offset +1 */
-               end = (*buf) + i + 1;
-
-               val = stralloc("[ERROR: Parsing Problem with the following text\n"
-                                               " Check original file. This may have been altered "
-                                               "by parsing.]\n\n");
-       }
-
-       /* remember offset where we have to continue parsing */
-       end_offset = end - (*buf);
-
-       valln = 0;
-       if (val) {
-               valln = strlen(val);
-       }
-
-       /* Optionally resize buffer to hold the replacement value:
-          Calculating the new length of the buffer is simple. add current
-          buffer pos (i) to length of string after replaced tag to length
-          of replacement string and add 1 for the final zero ... */
-       if (end - (*buf) < (i + valln)) {
-               /* make sure we do not shrink the mallocd block */
-               size_t newbufsize = i + strlen(end) + valln + 1;
-               *buf = rrd_realloc(*buf, newbufsize);
-
-               if (*buf == NULL) {
-                       perror("Realoc buf:");
-                       exit(1);
-               };
-       }
-
-       /* Update new end pointer:
-          make sure the 'end' pointer gets moved along with the 
-          buf pointer when realloc moves memory ... */
-       end = (*buf) + end_offset; 
-
-       /* splice the variable:
-          step 1. Shift pending data to make room for 'val' */
-       memmove((*buf) + i + valln, end, strlen(end) + 1);
-
-       /* step 2. Insert val */
-       if (val) {
-               memmove((*buf)+i, val, valln);
-               free(val);
-       }
-       return (valln > 0 ? valln-1: valln);
+    /* Scan for arguments following the tag;
+       scanargs() puts \0 into *buf ... so after scanargs it is probably
+       not a good time to use strlen on buf */
+    end = scanargs((*buf) + i + taglen, &argc, &args);
+    if (end) {
+        /* got arguments, call function for 'tag' with arguments */
+        val = func(argc, (const char **) args);
+        free(args);
+    } else {
+        /* unable to parse arguments, undo 0-termination by scanargs */
+        for (; argc > 0; argc--) {
+            *((args[argc - 1]) - 1) = ' ';
+        }
+
+        /* next call, try parsing at current offset +1 */
+        end = (*buf) + i + 1;
+
+        val = stralloc("[ERROR: Parsing Problem with the following text\n"
+                       " Check original file. This may have been altered "
+                       "by parsing.]\n\n");
+    }
+
+    /* remember offset where we have to continue parsing */
+    end_offset = end - (*buf);
+
+    valln = 0;
+    if (val) {
+        valln = strlen(val);
+    }
+
+    /* Optionally resize buffer to hold the replacement value:
+       Calculating the new length of the buffer is simple. add current
+       buffer pos (i) to length of string after replaced tag to length
+       of replacement string and add 1 for the final zero ... */
+    if (end - (*buf) < (i + valln)) {
+        /* make sure we do not shrink the mallocd block */
+        size_t    newbufsize = i + strlen(end) + valln + 1;
+
+        *buf = rrd_realloc(*buf, newbufsize);
+
+        if (*buf == NULL) {
+            perror("Realoc buf:");
+            exit(1);
+        };
+    }
+
+    /* Update new end pointer:
+       make sure the 'end' pointer gets moved along with the 
+       buf pointer when realloc moves memory ... */
+    end = (*buf) + end_offset;
+
+    /* splice the variable:
+       step 1. Shift pending data to make room for 'val' */
+    memmove((*buf) + i + valln, end, strlen(end) + 1);
+
+    /* step 2. Insert val */
+    if (val) {
+        memmove((*buf) + i, val, valln);
+        free(val);
+    }
+    return (valln > 0 ? valln - 1 : valln);
 }
 
-char *
-http_time(time_t *now) {
-        struct tm *tmptime;
-        static char buf[60];
+char     *http_time(
+    time_t *now)
+{
+    struct tm *tmptime;
+    static char buf[60];
 
-        tmptime=gmtime(now);
-        strftime(buf,sizeof(buf),"%a, %d %b %Y %H:%M:%S GMT",tmptime);
-        return(buf);
+    tmptime = gmtime(now);
+    strftime(buf, sizeof(buf), "%a, %d %b %Y %H:%M:%S GMT", tmptime);
+    return (buf);
 }
 
-void rrdcgiHeader(void)
+void rrdcgiHeader(
+    void)
 {
     if (rrdcgiType)
-       printf ("Content-type: %s\n", rrdcgiType);
+        printf("Content-type: %s\n", rrdcgiType);
     else
-       printf ("Content-type: text/html\n");
+        printf("Content-type: text/html\n");
     if (rrdcgiHeaderString)
-       printf ("%s", rrdcgiHeaderString);
-    printf ("\n");
+        printf("%s", rrdcgiHeaderString);
+    printf("\n");
 }
 
-void rrdcgiDebug(int level, int where)
+void rrdcgiDebug(
+    int level,
+    int where)
 {
     if (level > 0)
-       rrdcgiDebugLevel = level;
+        rrdcgiDebugLevel = level;
     else
-       rrdcgiDebugLevel = 0;
+        rrdcgiDebugLevel = 0;
     if (where)
-       rrdcgiDebugStderr = 0;
+        rrdcgiDebugStderr = 0;
     else
-       rrdcgiDebugStderr = 1;
+        rrdcgiDebugStderr = 1;
 }
 
-char *rrdcgiDecodeString(char *text)
+char     *rrdcgiDecodeString(
+    char *text)
 {
-    char *cp, *xp;
-
-    for (cp=text,xp=text; *cp; cp++) {
-       if (*cp == '%') {
-           if (strchr("0123456789ABCDEFabcdef", *(cp+1))
-               && strchr("0123456789ABCDEFabcdef", *(cp+2))) {
-               if (islower(*(cp+1)))
-                   *(cp+1) = toupper(*(cp+1));
-               if (islower(*(cp+2)))
-                   *(cp+2) = toupper(*(cp+2));
-               *(xp) = (*(cp+1) >= 'A' ? *(cp+1) - 'A' + 10 : *(cp+1) - '0' ) * 16
-                   + (*(cp+2) >= 'A' ? *(cp+2) - 'A' + 10 : *(cp+2) - '0');
-               xp++;cp+=2;
-           }
-       } else {
-           *(xp++) = *cp;
-       }
-    }
-    memset(xp, 0, cp-xp);
+    char     *cp, *xp;
+
+    for (cp = text, xp = text; *cp; cp++) {
+        if (*cp == '%') {
+            if (strchr("0123456789ABCDEFabcdef", *(cp + 1))
+                && strchr("0123456789ABCDEFabcdef", *(cp + 2))) {
+                if (islower(*(cp + 1)))
+                    *(cp + 1) = toupper(*(cp + 1));
+                if (islower(*(cp + 2)))
+                    *(cp + 2) = toupper(*(cp + 2));
+                *(xp) =
+                    (*(cp + 1) >=
+                     'A' ? *(cp + 1) - 'A' + 10 : *(cp + 1) - '0') * 16 +
+                    (*(cp + 2) >=
+                     'A' ? *(cp + 2) - 'A' + 10 : *(cp + 2) - '0');
+                xp++;
+                cp += 2;
+            }
+        } else {
+            *(xp++) = *cp;
+        }
+    }
+    memset(xp, 0, cp - xp);
     return text;
 }
 
@@ -1173,64 +1311,65 @@ char *rrdcgiDecodeString(char *text)
  *  Read from stdin if no string is provided via CGI.  Variables that
  *  doesn't have a value associated with it doesn't get stored.
  */
-s_var **rrdcgiReadVariables(void)
+s_var   **rrdcgiReadVariables(
+    void)
 {
-    int length;
-    char *line = NULL;
-    int numargs;
-    char *cp, *ip, *esp, *sptr;
-    s_var **result;
-    int i, k, len;
-    char tmp[101];
+    int       length;
+    char     *line = NULL;
+    int       numargs;
+    char     *cp, *ip, *esp, *sptr;
+    s_var   **result;
+    int       i, k, len;
+    char      tmp[101];
 
     cp = getenv("REQUEST_METHOD");
     ip = getenv("CONTENT_LENGTH");
 
     if (cp && !strcmp(cp, "POST")) {
-       if (ip) {
-           length = atoi(ip);
-           if ((line = (char *)malloc (length+2)) == NULL)
-               return NULL;
-           fgets(line, length+1, stdin);
-       } else
-           return NULL;
+        if (ip) {
+            length = atoi(ip);
+            if ((line = (char *) malloc(length + 2)) == NULL)
+                return NULL;
+            fgets(line, length + 1, stdin);
+        } else
+            return NULL;
     } else if (cp && !strcmp(cp, "GET")) {
-       esp = getenv("QUERY_STRING");
-       if (esp && strlen(esp)) {
-           if ((line = (char *)malloc (strlen(esp)+2)) == NULL)
-               return NULL;
-           sprintf (line, "%s", esp);
-       } else
-           return NULL;
+        esp = getenv("QUERY_STRING");
+        if (esp && strlen(esp)) {
+            if ((line = (char *) malloc(strlen(esp) + 2)) == NULL)
+                return NULL;
+            sprintf(line, "%s", esp);
+        } else
+            return NULL;
     } else {
         length = 0;
-       printf ("(offline mode: enter name=value pairs on standard input)\n");
-       memset (tmp, 0, sizeof(tmp));
-       while((cp = fgets (tmp, 100, stdin)) != NULL) {
-           if (strlen(tmp)) {
-               if (tmp[strlen(tmp)-1] == '\n')
-                   tmp[strlen(tmp)-1] = '&';
-               if (length) {
-                   length += strlen(tmp);
-                   len = (length+1) * sizeof(char);
-                   if ((line = (char *)realloc (line, len)) == NULL)
-                       return NULL;
-                   strcat (line, tmp);
-               } else {
-                   length = strlen(tmp);
-                   len = (length+1) * sizeof(char);
-                   if ((line = (char *)malloc (len)) == NULL)
-                       return NULL;
-                   memset (line, 0, len);
-                   strcpy (line, tmp);
-               }
-           }
-           memset (tmp, 0, sizeof(tmp));
-       }
-       if (!line)
-           return NULL;
-       if (line[strlen(line)-1] == '&')
-           line[strlen(line)-1] = '\0';
+        printf("(offline mode: enter name=value pairs on standard input)\n");
+        memset(tmp, 0, sizeof(tmp));
+        while ((cp = fgets(tmp, 100, stdin)) != NULL) {
+            if (strlen(tmp)) {
+                if (tmp[strlen(tmp) - 1] == '\n')
+                    tmp[strlen(tmp) - 1] = '&';
+                if (length) {
+                    length += strlen(tmp);
+                    len = (length + 1) * sizeof(char);
+                    if ((line = (char *) realloc(line, len)) == NULL)
+                        return NULL;
+                    strcat(line, tmp);
+                } else {
+                    length = strlen(tmp);
+                    len = (length + 1) * sizeof(char);
+                    if ((line = (char *) malloc(len)) == NULL)
+                        return NULL;
+                    memset(line, 0, len);
+                    strcpy(line, tmp);
+                }
+            }
+            memset(tmp, 0, sizeof(tmp));
+        }
+        if (!line)
+            return NULL;
+        if (line[strlen(line) - 1] == '&')
+            line[strlen(line) - 1] = '\0';
     }
 
     /*
@@ -1239,89 +1378,100 @@ s_var **rrdcgiReadVariables(void)
      */
 
     if (rrdcgiDebugLevel > 0) {
-       if (rrdcgiDebugStderr)
-           fprintf (stderr, "Received cgi input: %s\n", line);
-       else
-           printf ("<b>Received cgi input</b><br>\n<pre>\n--\n%s\n--\n</pre>\n\n", line);
+        if (rrdcgiDebugStderr)
+            fprintf(stderr, "Received cgi input: %s\n", line);
+        else
+            printf
+                ("<b>Received cgi input</b><br>\n<pre>\n--\n%s\n--\n</pre>\n\n",
+                 line);
     }
 
-    for (cp=line; *cp; cp++)
-       if (*cp == '+')
-           *cp = ' ';
+    for (cp = line; *cp; cp++)
+        if (*cp == '+')
+            *cp = ' ';
 
     if (strlen(line)) {
-       for (numargs=1,cp=line; *cp; cp++)
-           if (*cp == '&') numargs++;
+        for (numargs = 1, cp = line; *cp; cp++)
+            if (*cp == '&')
+                numargs++;
     } else
-       numargs = 0;
+        numargs = 0;
     if (rrdcgiDebugLevel > 0) {
-       if (rrdcgiDebugStderr)
-           fprintf (stderr, "%d cgi variables found.\n", numargs);
-       else
-           printf ("%d cgi variables found.<br>\n", numargs);
+        if (rrdcgiDebugStderr)
+            fprintf(stderr, "%d cgi variables found.\n", numargs);
+        else
+            printf("%d cgi variables found.<br>\n", numargs);
     }
 
-    len = (numargs+1) * sizeof(s_var *);
-    if ((result = (s_var **)malloc (len)) == NULL)
-       return NULL;
-    memset (result, 0, len);
+    len = (numargs + 1) * sizeof(s_var *);
+    if ((result = (s_var **) malloc(len)) == NULL)
+        return NULL;
+    memset(result, 0, len);
 
     cp = line;
-    i=0;
+    i = 0;
     while (*cp) {
-       if ((ip = (char *)strchr(cp, '&')) != NULL) {
-           *ip = '\0';
-       }else
-           ip = cp + strlen(cp);
-
-       if ((esp=(char *)strchr(cp, '=')) == NULL) {
-           cp = ++ip;
-           continue;
-       }
-
-       if (!strlen(esp)) {
-           cp = ++ip;
-           continue;
-       }
-
-       if (i<numargs) {
-
-           /* try to find out if there's already such a variable */
-           for (k=0; k<i && (strncmp (result[k]->name,cp, esp-cp) || !(strlen (result[k]->name) == (size_t)(esp-cp))); k++);
-
-           if (k == i) {       /* No such variable yet */
-               if ((result[i] = (s_var *)malloc(sizeof(s_var))) == NULL)
-                   return NULL;
-               if ((result[i]->name = (char *)malloc((esp-cp+1) * sizeof(char))) == NULL)
-                   return NULL;
-               memset (result[i]->name, 0, esp-cp+1);
-               strncpy(result[i]->name, cp, esp-cp);
-               cp = ++esp;
-               if ((result[i]->value = (char *)malloc((ip-esp+1) * sizeof(char))) == NULL)
-                   return NULL;
-               memset (result[i]->value, 0, ip-esp+1);
-               strncpy(result[i]->value, cp, ip-esp);
-               result[i]->value = rrdcgiDecodeString(result[i]->value);
-               if (rrdcgiDebugLevel) {
-                   if (rrdcgiDebugStderr)
-                       fprintf (stderr, "%s: %s\n", result[i]->name, result[i]->value);
-                   else
-                       printf ("<h3>Variable %s</h3>\n<pre>\n%s\n</pre>\n\n", result[i]->name, result[i]->value);
-               }
-               i++;
-           } else {    /* There is already such a name, suppose a mutiple field */
-               cp = ++esp;
-               len = (strlen(result[k]->value)+(ip-esp)+2) * sizeof (char);
-               if ((sptr = (char *)malloc(len)) == NULL)
-                   return NULL;
-               memset (sptr, 0, len);
-               sprintf (sptr, "%s\n", result[k]->value);
-               strncat(sptr, cp, ip-esp);
-               free(result[k]->value);
-               result[k]->value = rrdcgiDecodeString (sptr);
-           }
-       }
-       cp = ++ip;
+        if ((ip = (char *) strchr(cp, '&')) != NULL) {
+            *ip = '\0';
+        } else
+            ip = cp + strlen(cp);
+
+        if ((esp = (char *) strchr(cp, '=')) == NULL) {
+            cp = ++ip;
+            continue;
+        }
+
+        if (!strlen(esp)) {
+            cp = ++ip;
+            continue;
+        }
+
+        if (i < numargs) {
+
+            /* try to find out if there's already such a variable */
+            for (k = 0; k < i && (strncmp(result[k]->name, cp, esp - cp)
+                                  || !(strlen(result[k]->name) ==
+                                       (size_t) (esp - cp))); k++);
+
+            if (k == i) {   /* No such variable yet */
+                if ((result[i] = (s_var *) malloc(sizeof(s_var))) == NULL)
+                    return NULL;
+                if ((result[i]->name =
+                     (char *) malloc((esp - cp + 1) * sizeof(char))) == NULL)
+                    return NULL;
+                memset(result[i]->name, 0, esp - cp + 1);
+                strncpy(result[i]->name, cp, esp - cp);
+                cp = ++esp;
+                if ((result[i]->value =
+                     (char *) malloc((ip - esp + 1) * sizeof(char))) == NULL)
+                    return NULL;
+                memset(result[i]->value, 0, ip - esp + 1);
+                strncpy(result[i]->value, cp, ip - esp);
+                result[i]->value = rrdcgiDecodeString(result[i]->value);
+                if (rrdcgiDebugLevel) {
+                    if (rrdcgiDebugStderr)
+                        fprintf(stderr, "%s: %s\n", result[i]->name,
+                                result[i]->value);
+                    else
+                        printf("<h3>Variable %s</h3>\n<pre>\n%s\n</pre>\n\n",
+                               result[i]->name, result[i]->value);
+                }
+                i++;
+            } else {    /* There is already such a name, suppose a mutiple field */
+                cp = ++esp;
+                len =
+                    (strlen(result[k]->value) + (ip - esp) +
+                     2) * sizeof(char);
+                if ((sptr = (char *) malloc(len)) == NULL)
+                    return NULL;
+                memset(sptr, 0, len);
+                sprintf(sptr, "%s\n", result[k]->value);
+                strncat(sptr, cp, ip - esp);
+                free(result[k]->value);
+                result[k]->value = rrdcgiDecodeString(sptr);
+            }
+        }
+        cp = ++ip;
     }
     return result;
 }
@@ -1331,82 +1481,88 @@ s_var **rrdcgiReadVariables(void)
  *  Read from stdin if no string is provided via CGI.  Variables that
  *  doesn't have a value associated with it doesn't get stored.
  */
-s_cgi *rrdcgiInit(void)
+s_cgi    *rrdcgiInit(
+    void)
 {
-    s_cgi *res;
-    s_var **vars;
+    s_cgi    *res;
+    s_var   **vars;
 
     vars = rrdcgiReadVariables();
 
     if (!vars)
-       return NULL;
+        return NULL;
 
-    if ((res = (s_cgi *)malloc (sizeof (s_cgi))) == NULL)
-       return NULL;
+    if ((res = (s_cgi *) malloc(sizeof(s_cgi))) == NULL)
+        return NULL;
     res->vars = vars;
 
     return res;
 }
 
-char *rrdcgiGetValue(s_cgi *parms, const char *name)
+char     *rrdcgiGetValue(
+    s_cgi * parms,
+    const char *name)
 {
-    int i;
+    int       i;
 
     if (!parms || !parms->vars)
-       return NULL;
-    for (i=0;parms->vars[i]; i++)
-       if (!strcmp(name,parms->vars[i]->name)) {
-           if (rrdcgiDebugLevel > 0) {
-               if (rrdcgiDebugStderr)
-                   fprintf (stderr, "%s found as %s\n", name, parms->vars[i]->value);
-               else
-                   printf ("%s found as %s<br>\n", name, parms->vars[i]->value);
-           }
-           return parms->vars[i]->value;
-       }
+        return NULL;
+    for (i = 0; parms->vars[i]; i++)
+        if (!strcmp(name, parms->vars[i]->name)) {
+            if (rrdcgiDebugLevel > 0) {
+                if (rrdcgiDebugStderr)
+                    fprintf(stderr, "%s found as %s\n", name,
+                            parms->vars[i]->value);
+                else
+                    printf("%s found as %s<br>\n", name,
+                           parms->vars[i]->value);
+            }
+            return parms->vars[i]->value;
+        }
     if (rrdcgiDebugLevel) {
-       if (rrdcgiDebugStderr)
-           fprintf (stderr, "%s not found\n", name);
-       else
-           printf ("%s not found<br>\n", name);
+        if (rrdcgiDebugStderr)
+            fprintf(stderr, "%s not found\n", name);
+        else
+            printf("%s not found<br>\n", name);
     }
     return NULL;
 }
 
-void rrdcgiFreeList (char **list)
+void rrdcgiFreeList(
+    char **list)
 {
-    int i;
+    int       i;
 
-    for (i=0; list[i] != NULL; i++)
-       free (list[i]);
-       free (list);
+    for (i = 0; list[i] != NULL; i++)
+        free(list[i]);
+    free(list);
 }
 
-void rrdcgiFree (s_cgi *parms)
+void rrdcgiFree(
+    s_cgi * parms)
 {
-    int i;
+    int       i;
 
     if (!parms)
-       return;
+        return;
     if (parms->vars) {
-               for (i=0;parms->vars[i]; i++) {
-                       if (parms->vars[i]->name)
-                               free (parms->vars[i]->name);
-                       if (parms->vars[i]->value)
-                               free (parms->vars[i]->value);
-           free (parms->vars[i]);
-               }
-               free (parms->vars);
+        for (i = 0; parms->vars[i]; i++) {
+            if (parms->vars[i]->name)
+                free(parms->vars[i]->name);
+            if (parms->vars[i]->value)
+                free(parms->vars[i]->value);
+            free(parms->vars[i]);
+        }
+        free(parms->vars);
     }
-    free (parms);
+    free(parms);
 
     if (rrdcgiHeaderString) {
-       free (rrdcgiHeaderString);
-       rrdcgiHeaderString = NULL;
+        free(rrdcgiHeaderString);
+        rrdcgiHeaderString = NULL;
     }
     if (rrdcgiType) {
-       free (rrdcgiType);
-       rrdcgiType = NULL;
+        free(rrdcgiType);
+        rrdcgiType = NULL;
     }
 }
-
index 9e5b0557a8fa51d1a33fa33b4ca86e47ba3d2f40..25c1133acaedcdb12c7017d50ad42fd64ecee474 100644 (file)
 /*****************************************************************************
- * RRDtool 1.2.27  Copyright by Tobi Oetiker, 1997-2008
+ * RRDtool 1.3rc4  Copyright by Tobi Oetiker, 1997-2008
  *****************************************************************************
  * rrd_create.c  creates new rrds
  *****************************************************************************/
 
+#include <stdlib.h>
+#include <time.h>
+#include <locale.h>
+
 #include "rrd_tool.h"
 #include "rrd_rpncalc.h"
 #include "rrd_hw.h"
 
 #include "rrd_is_thread_safe.h"
 
-unsigned long FnvHash(const char *str);
-int create_hw_contingent_rras(rrd_t *rrd, unsigned short period, unsigned long hashed_name);
-void parseGENERIC_DS(const char *def,rrd_t *rrd, int ds_idx);
+unsigned long FnvHash(
+    const char *str);
+int       create_hw_contingent_rras(
+    rrd_t *rrd,
+    unsigned short period,
+    unsigned long hashed_name);
+void      parseGENERIC_DS(
+    const char *def,
+    rrd_t *rrd,
+    int ds_idx);
+long int  rra_random_row(
+    rra_def_t *);
 
-int
-rrd_create(int argc, char **argv) 
+int rrd_create(
+    int argc,
+    char **argv)
 {
-    time_t            last_up = time(NULL)-10;
-    unsigned long     pdp_step = 300;
+    struct option long_options[] = {
+        {"start", required_argument, 0, 'b'},
+        {"step", required_argument, 0, 's'},
+        {0, 0, 0, 0}
+    };
+    int       option_index = 0;
+    int       opt;
+    time_t    last_up = time(NULL) - 10;
+    unsigned long pdp_step = 300;
     struct rrd_time_value last_up_tv;
-    char *parsetime_error = NULL;
-    long              long_tmp;
-    int               rc;
-    optind = 0; opterr = 0;  /* initialize getopt */
-
-    while (1){
-       static struct option long_options[] =
-       {
-           {"start",      required_argument, 0, 'b'},
-           {"step",        required_argument,0,'s'},
-           {0,0,0,0}
-       };
-       int option_index = 0;
-       int opt;
-       opt = getopt_long(argc, argv, "b:s:", 
-                         long_options, &option_index);
-       
-       if (opt == EOF)
-           break;
-       
-       switch(opt) {
-       case 'b':
+    char     *parsetime_error = NULL;
+    long      long_tmp;
+    int       rc;
+
+    optind = 0;
+    opterr = 0;         /* initialize getopt */
+
+    while (1) {
+        opt = getopt_long(argc, argv, "b:s:", long_options, &option_index);
+
+        if (opt == EOF)
+            break;
+
+        switch (opt) {
+        case 'b':
             if ((parsetime_error = parsetime(optarg, &last_up_tv))) {
-                rrd_set_error("start time: %s", parsetime_error );
-                return(-1);
-           }
-           if (last_up_tv.type == RELATIVE_TO_END_TIME ||
-               last_up_tv.type == RELATIVE_TO_START_TIME) {
-               rrd_set_error("specifying time relative to the 'start' "
+                rrd_set_error("start time: %s", parsetime_error);
+                return (-1);
+            }
+            if (last_up_tv.type == RELATIVE_TO_END_TIME ||
+                last_up_tv.type == RELATIVE_TO_START_TIME) {
+                rrd_set_error("specifying time relative to the 'start' "
                               "or 'end' makes no sense here");
-               return(-1);
-           }
-
-           last_up = mktime(&last_up_tv.tm) + last_up_tv.offset;
-           
-           if (last_up < 3600*24*365*10){
-               rrd_set_error("the first entry to the RRD should be after 1980");
-               return(-1);
-           }   
-           break;
-
-       case 's':
-           long_tmp = atol(optarg);
-           if (long_tmp < 1){
-               rrd_set_error("step size should be no less than one second");
-               return(-1);
-           }
-           pdp_step = long_tmp;
-           break;
-
-       case '?':
+                return (-1);
+            }
+
+            last_up = mktime(&last_up_tv.tm) +last_up_tv.offset;
+
+            if (last_up < 3600 * 24 * 365 * 10) {
+                rrd_set_error
+                    ("the first entry to the RRD should be after 1980");
+                return (-1);
+            }
+            break;
+
+        case 's':
+            long_tmp = atol(optarg);
+            if (long_tmp < 1) {
+                rrd_set_error("step size should be no less than one second");
+                return (-1);
+            }
+            pdp_step = long_tmp;
+            break;
+
+        case '?':
             if (optopt != 0)
                 rrd_set_error("unknown option '%c'", optopt);
             else
-                rrd_set_error("unknown option '%s'",argv[optind-1]);
-           return(-1);
-       }
+                rrd_set_error("unknown option '%s'", argv[optind - 1]);
+            return (-1);
+        }
     }
     if (optind == argc) {
-         rrd_set_error("what is the name of the rrd file you want to create?");
-         return -1;
+        rrd_set_error("need name of an rrd file to create");
+        return -1;
     }
     rc = rrd_create_r(argv[optind],
-                     pdp_step, last_up,
-                     argc - optind - 1, (const char **)(argv + optind + 1));
-    
+                      pdp_step, last_up,
+                      argc - optind - 1, (const char **) (argv + optind + 1));
+
     return rc;
 }
 
 /* #define DEBUG */
-int
-rrd_create_r(const char *filename,
-            unsigned long pdp_step, time_t last_up,
-            int argc, const char **argv) 
+int rrd_create_r(
+    const char *filename,
+    unsigned long pdp_step,
+    time_t last_up,
+    int argc,
+    const char **argv)
 {
-    rrd_t             rrd;
-    long              i;
-    int               offset;
-    char *token;
-    char dummychar1[2], dummychar2[2];
-    unsigned short token_idx, error_flag, period=0;
+    rrd_t     rrd;
+    long      i;
+    int       offset;
+    char     *token;
+    char      dummychar1[2], dummychar2[2];
+    unsigned short token_idx, error_flag, period = 0;
     unsigned long hashed_name;
 
     /* init rrd clean */
     rrd_init(&rrd);
     /* static header */
-    if((rrd.stat_head = calloc(1,sizeof(stat_head_t)))==NULL){
-       rrd_set_error("allocating rrd.stat_head");
-       rrd_free(&rrd);
-       return(-1);
+    if ((rrd.stat_head = calloc(1, sizeof(stat_head_t))) == NULL) {
+        rrd_set_error("allocating rrd.stat_head");
+        free(rrd.stat_head);
+        return (-1);
     }
 
     /* live header */
-    if((rrd.live_head = calloc(1,sizeof(live_head_t)))==NULL){
-       rrd_set_error("allocating rrd.live_head");
-       rrd_free(&rrd);
-       return(-1);
+    if ((rrd.live_head = calloc(1, sizeof(live_head_t))) == NULL) {
+        rrd_set_error("allocating rrd.live_head");
+        free(rrd.stat_head);
+        free(rrd.live_head);
+        return (-1);
     }
 
     /* set some defaults */
-    strcpy(rrd.stat_head->cookie,RRD_COOKIE);
-    strcpy(rrd.stat_head->version,RRD_VERSION);
+    strcpy(rrd.stat_head->cookie, RRD_COOKIE);
+    strcpy(rrd.stat_head->version, RRD_VERSION3);   /* by default we are still version 3 */
     rrd.stat_head->float_cookie = FLOAT_COOKIE;
-    rrd.stat_head->ds_cnt = 0; /* this will be adjusted later */
+    rrd.stat_head->ds_cnt = 0;  /* this will be adjusted later */
     rrd.stat_head->rra_cnt = 0; /* ditto */
     rrd.stat_head->pdp_step = pdp_step; /* 5 minute default */
 
@@ -132,241 +150,324 @@ rrd_create_r(const char *filename,
     rrd.rra_def = NULL;
 
     rrd.live_head->last_up = last_up;
-       
-       /* optind points to the first non-option command line arg,
-        * in this case, the file name. */
-       /* Compute the FNV hash value (used by SEASONAL and DEVSEASONAL
-        * arrays. */
+
+    /* optind points to the first non-option command line arg,
+     * in this case, the file name. */
+    /* Compute the FNV hash value (used by SEASONAL and DEVSEASONAL
+     * arrays. */
     hashed_name = FnvHash(filename);
-    for(i=0;i<argc;i++){
-       unsigned int ii;
-       if (strncmp(argv[i],"DS:",3)==0){
-           size_t old_size = sizeof(ds_def_t)*(rrd.stat_head->ds_cnt);
-           if((rrd.ds_def = rrd_realloc(rrd.ds_def,
-                                         old_size+sizeof(ds_def_t)))==NULL){
-               rrd_set_error("allocating rrd.ds_def");
-               rrd_free(&rrd);
-               return(-1);     
-           }
-           memset(&rrd.ds_def[rrd.stat_head->ds_cnt], 0, sizeof(ds_def_t));
+    for (i = 0; i < argc; i++) {
+        unsigned int ii;
+
+        if (strncmp(argv[i], "DS:", 3) == 0) {
+            size_t    old_size = sizeof(ds_def_t) * (rrd.stat_head->ds_cnt);
+
+            if ((rrd.ds_def = rrd_realloc(rrd.ds_def,
+                                          old_size + sizeof(ds_def_t))) ==
+                NULL) {
+                rrd_set_error("allocating rrd.ds_def");
+                free(rrd.stat_head);
+                free(rrd.live_head);
+                return (-1);
+            }
+            memset(&rrd.ds_def[rrd.stat_head->ds_cnt], 0, sizeof(ds_def_t));
             /* extract the name and type */
-           switch (sscanf(&argv[i][3],
-                       DS_NAM_FMT "%1[:]" DST_FMT "%1[:]%n",
-                       rrd.ds_def[rrd.stat_head->ds_cnt].ds_nam,
-                       dummychar1,
-                       rrd.ds_def[rrd.stat_head->ds_cnt].dst,
-                       dummychar2,
-                       &offset)) {
-               case 0:
-               case 1: rrd_set_error("Invalid DS name"); break;
-               case 2:
-               case 3: rrd_set_error("Invalid DS type"); break;
-               case 4: /* (%n may or may not be counted) */
-               case 5: /* check for duplicate datasource names */
-                   for (ii=0;ii<rrd.stat_head->ds_cnt;ii++)
-                       if(strcmp(rrd.ds_def[rrd.stat_head->ds_cnt].ds_nam,
-                               rrd.ds_def[ii].ds_nam) == 0)
-                           rrd_set_error("Duplicate DS name: %s",
-                                       rrd.ds_def[ii].ds_nam);
-                   /* DS_type may be valid or not. Checked later */
-                   break;
-               default: rrd_set_error("invalid DS format");
+            switch (sscanf(&argv[i][3],
+                           DS_NAM_FMT "%1[:]" DST_FMT "%1[:]%n",
+                           rrd.ds_def[rrd.stat_head->ds_cnt].ds_nam,
+                           dummychar1,
+                           rrd.ds_def[rrd.stat_head->ds_cnt].dst,
+                           dummychar2, &offset)) {
+            case 0:
+            case 1:
+                rrd_set_error("Invalid DS name");
+                break;
+            case 2:
+            case 3:
+                rrd_set_error("Invalid DS type");
+                break;
+            case 4:    /* (%n may or may not be counted) */
+            case 5:    /* check for duplicate datasource names */
+                for (ii = 0; ii < rrd.stat_head->ds_cnt; ii++)
+                    if (strcmp(rrd.ds_def[rrd.stat_head->ds_cnt].ds_nam,
+                               rrd.ds_def[ii].ds_nam) == 0)
+                        rrd_set_error("Duplicate DS name: %s",
+                                      rrd.ds_def[ii].ds_nam);
+                /* DS_type may be valid or not. Checked later */
+                break;
+            default:
+                rrd_set_error("invalid DS format");
             }
-           if (rrd_test_error()) {
-                rrd_free(&rrd);
+            if (rrd_test_error()) {
+                free(rrd.stat_head);
+                free(rrd.live_head);
                 return -1;
             }
-            
+
             /* parse the remainder of the arguments */
-            switch(dst_conv(rrd.ds_def[rrd.stat_head->ds_cnt].dst))
-           {
+            switch (dst_conv(rrd.ds_def[rrd.stat_head->ds_cnt].dst)) {
             case DST_COUNTER:
             case DST_ABSOLUTE:
             case DST_GAUGE:
             case DST_DERIVE:
-                parseGENERIC_DS(&argv[i][offset+3],&rrd, rrd.stat_head->ds_cnt);
+                parseGENERIC_DS(&argv[i][offset + 3], &rrd,
+                                rrd.stat_head->ds_cnt);
                 break;
             case DST_CDEF:
-                parseCDEF_DS(&argv[i][offset+3],&rrd, rrd.stat_head->ds_cnt);
+                parseCDEF_DS(&argv[i][offset + 3], &rrd,
+                             rrd.stat_head->ds_cnt);
                 break;
             default:
                 rrd_set_error("invalid DS type specified");
                 break;
             }
-            
+
             if (rrd_test_error()) {
-                rrd_free(&rrd);
+                free(rrd.stat_head);
+                free(rrd.live_head);
                 return -1;
             }
-            rrd.stat_head -> ds_cnt++;
-       } else if (strncmp(argv[i],"RRA:",4)==0){
-            char *argvcopy;
-           char *tokptr;
-           size_t old_size = sizeof(rra_def_t)*(rrd.stat_head->rra_cnt);
-           if((rrd.rra_def = rrd_realloc(rrd.rra_def,
-                                          old_size+sizeof(rra_def_t)))==NULL)
-           {
+            rrd.stat_head->ds_cnt++;
+        } else if (strncmp(argv[i], "RRA:", 4) == 0) {
+            char     *argvcopy;
+            char     *tokptr;
+            size_t    old_size = sizeof(rra_def_t) * (rrd.stat_head->rra_cnt);
+
+            if ((rrd.rra_def = rrd_realloc(rrd.rra_def,
+                                           old_size + sizeof(rra_def_t))) ==
+                NULL) {
                 rrd_set_error("allocating rrd.rra_def");
-                rrd_free(&rrd);
-                return(-1);    
-           }
-           memset(&rrd.rra_def[rrd.stat_head->rra_cnt], 0, sizeof(rra_def_t));
+                free(rrd.stat_head);
+                free(rrd.live_head);
+                return (-1);
+            }
+            memset(&rrd.rra_def[rrd.stat_head->rra_cnt], 0,
+                   sizeof(rra_def_t));
 
             argvcopy = strdup(argv[i]);
-           token = strtok_r(&argvcopy[4],":", &tokptr);
-           token_idx = error_flag = 0;
-           while (token != NULL)
-           {
-                switch(token_idx)
-                {
+            token = strtok_r(&argvcopy[4], ":", &tokptr);
+            token_idx = error_flag = 0;
+            while (token != NULL) {
+                switch (token_idx) {
                 case 0:
-                    if (sscanf(token,CF_NAM_FMT,
-                               rrd.rra_def[rrd.stat_head->rra_cnt].cf_nam) != 1)
+                    if (sscanf(token, CF_NAM_FMT,
+                               rrd.rra_def[rrd.stat_head->rra_cnt].cf_nam) !=
+                        1)
                         rrd_set_error("Failed to parse CF name");
-                    switch(cf_conv(rrd.rra_def[rrd.stat_head->rra_cnt].cf_nam))
-                    {
+                    switch (cf_conv
+                            (rrd.rra_def[rrd.stat_head->rra_cnt].cf_nam)) {
+                    case CF_MHWPREDICT:
+                        strcpy(rrd.stat_head->version, RRD_VERSION);    /* MHWPREDICT causes Version 4 */
                     case CF_HWPREDICT:
                         /* initialize some parameters */
-                        rrd.rra_def[rrd.stat_head->rra_cnt].par[RRA_hw_alpha].u_val = 0.1;
-                        rrd.rra_def[rrd.stat_head->rra_cnt].par[RRA_hw_beta].u_val = 1.0/288;
-                        rrd.rra_def[rrd.stat_head->rra_cnt].par[RRA_dependent_rra_idx].u_cnt = 
-                            rrd.stat_head -> rra_cnt;
+                        rrd.rra_def[rrd.stat_head->rra_cnt].par[RRA_hw_alpha].
+                            u_val = 0.1;
+                        rrd.rra_def[rrd.stat_head->rra_cnt].par[RRA_hw_beta].
+                            u_val = 1.0 / 288;
+                        rrd.rra_def[rrd.stat_head->rra_cnt].
+                            par[RRA_dependent_rra_idx].u_cnt =
+                            rrd.stat_head->rra_cnt;
                         break;
                     case CF_DEVSEASONAL:
                     case CF_SEASONAL:
                         /* initialize some parameters */
-                        rrd.rra_def[rrd.stat_head->rra_cnt].par[RRA_seasonal_gamma].u_val = 0.1;
+                        rrd.rra_def[rrd.stat_head->rra_cnt].
+                            par[RRA_seasonal_gamma].u_val = 0.1;
+                        rrd.rra_def[rrd.stat_head->rra_cnt].
+                            par[RRA_seasonal_smoothing_window].u_val = 0.05;
                         /* fall through */
                     case CF_DEVPREDICT:
-                        rrd.rra_def[rrd.stat_head->rra_cnt].par[RRA_dependent_rra_idx].u_cnt = -1;
+                        rrd.rra_def[rrd.stat_head->rra_cnt].
+                            par[RRA_dependent_rra_idx].u_cnt = -1;
                         break;
                     case CF_FAILURES:
-                        rrd.rra_def[rrd.stat_head->rra_cnt].par[RRA_delta_pos].u_val = 2.0;
-                        rrd.rra_def[rrd.stat_head->rra_cnt].par[RRA_delta_neg].u_val = 2.0;
-                        rrd.rra_def[rrd.stat_head->rra_cnt].par[RRA_window_len].u_cnt = 3;
-                        rrd.rra_def[rrd.stat_head->rra_cnt].par[RRA_failure_threshold].u_cnt = 2;
-                        rrd.rra_def[rrd.stat_head->rra_cnt].par[RRA_dependent_rra_idx].u_cnt = -1;
+                        rrd.rra_def[rrd.stat_head->rra_cnt].
+                            par[RRA_delta_pos].u_val = 2.0;
+                        rrd.rra_def[rrd.stat_head->rra_cnt].
+                            par[RRA_delta_neg].u_val = 2.0;
+                        rrd.rra_def[rrd.stat_head->rra_cnt].
+                            par[RRA_window_len].u_cnt = 3;
+                        rrd.rra_def[rrd.stat_head->rra_cnt].
+                            par[RRA_failure_threshold].u_cnt = 2;
+                        rrd.rra_def[rrd.stat_head->rra_cnt].
+                            par[RRA_dependent_rra_idx].u_cnt = -1;
                         break;
                         /* invalid consolidation function */
                     case -1:
-                        rrd_set_error("Unrecognized consolidation function %s",
-                                      rrd.rra_def[rrd.stat_head->rra_cnt].cf_nam);
+                        rrd_set_error
+                            ("Unrecognized consolidation function %s",
+                             rrd.rra_def[rrd.stat_head->rra_cnt].cf_nam);
                     default:
                         break;
                     }
-                    /* default: 1 pdp per cdp */ 
+                    /* default: 1 pdp per cdp */
                     rrd.rra_def[rrd.stat_head->rra_cnt].pdp_cnt = 1;
                     break;
                 case 1:
-                    switch(cf_conv(rrd.rra_def[rrd.stat_head->rra_cnt].cf_nam))
-                    {
+                    switch (cf_conv
+                            (rrd.rra_def[rrd.stat_head->rra_cnt].cf_nam)) {
                     case CF_HWPREDICT:
+                    case CF_MHWPREDICT:
                     case CF_DEVSEASONAL:
                     case CF_SEASONAL:
                     case CF_DEVPREDICT:
                     case CF_FAILURES:
-                        rrd.rra_def[rrd.stat_head->rra_cnt].row_cnt = atoi(token);
+                        rrd.rra_def[rrd.stat_head->rra_cnt].row_cnt =
+                            atoi(token);
                         break;
                     default:
-                        rrd.rra_def[rrd.stat_head->rra_cnt].par[RRA_cdp_xff_val].u_val = atof(token);
-                        if (rrd.rra_def[rrd.stat_head->rra_cnt].par[RRA_cdp_xff_val].u_val<0.0 ||
-                            rrd.rra_def[rrd.stat_head->rra_cnt].par[RRA_cdp_xff_val].u_val>=1.0)
-                            rrd_set_error("Invalid xff: must be between 0 and 1");
+                        rrd.rra_def[rrd.stat_head->rra_cnt].
+                            par[RRA_cdp_xff_val].u_val = atof(token);
+                        if (rrd.rra_def[rrd.stat_head->rra_cnt].
+                            par[RRA_cdp_xff_val].u_val < 0.0
+                            || rrd.rra_def[rrd.stat_head->rra_cnt].
+                            par[RRA_cdp_xff_val].u_val >= 1.0)
+                            rrd_set_error
+                                ("Invalid xff: must be between 0 and 1");
                         break;
                     }
                     break;
                 case 2:
-                    switch(cf_conv(rrd.rra_def[rrd.stat_head->rra_cnt].cf_nam))
-                    {
+                    switch (cf_conv
+                            (rrd.rra_def[rrd.stat_head->rra_cnt].cf_nam)) {
                     case CF_HWPREDICT:
-                        rrd.rra_def[rrd.stat_head->rra_cnt].par[RRA_hw_alpha].u_val = atof(token);
+                    case CF_MHWPREDICT:
+                        rrd.rra_def[rrd.stat_head->rra_cnt].par[RRA_hw_alpha].
+                            u_val = atof(token);
                         if (atof(token) <= 0.0 || atof(token) >= 1.0)
-                            rrd_set_error("Invalid alpha: must be between 0 and 1");
+                            rrd_set_error
+                                ("Invalid alpha: must be between 0 and 1");
                         break;
                     case CF_DEVSEASONAL:
                     case CF_SEASONAL:
-                        rrd.rra_def[rrd.stat_head->rra_cnt].par[RRA_seasonal_gamma].u_val = 
-                            atof(token);
+                        rrd.rra_def[rrd.stat_head->rra_cnt].
+                            par[RRA_seasonal_gamma].u_val = atof(token);
                         if (atof(token) <= 0.0 || atof(token) >= 1.0)
-                            rrd_set_error("Invalid gamma: must be between 0 and 1");
-                        rrd.rra_def[rrd.stat_head->rra_cnt].par[RRA_seasonal_smooth_idx].u_cnt
-                            = hashed_name % rrd.rra_def[rrd.stat_head->rra_cnt].row_cnt; 
+                            rrd_set_error
+                                ("Invalid gamma: must be between 0 and 1");
+                        rrd.rra_def[rrd.stat_head->rra_cnt].
+                            par[RRA_seasonal_smooth_idx].u_cnt =
+                            hashed_name %
+                            rrd.rra_def[rrd.stat_head->rra_cnt].row_cnt;
                         break;
                     case CF_FAILURES:
                         /* specifies the # of violations that constitutes the failure threshold */
-                        rrd.rra_def[rrd.stat_head->rra_cnt].par[RRA_failure_threshold].u_cnt =
-                            atoi(token);
-                        if (atoi(token) < 1 || atoi(token) > MAX_FAILURES_WINDOW_LEN)
-                            rrd_set_error("Failure threshold is out of range %d, %d",1,
-                                          MAX_FAILURES_WINDOW_LEN);
+                        rrd.rra_def[rrd.stat_head->rra_cnt].
+                            par[RRA_failure_threshold].u_cnt = atoi(token);
+                        if (atoi(token) < 1
+                            || atoi(token) > MAX_FAILURES_WINDOW_LEN)
+                            rrd_set_error
+                                ("Failure threshold is out of range %d, %d",
+                                 1, MAX_FAILURES_WINDOW_LEN);
                         break;
                     case CF_DEVPREDICT:
                         /* specifies the index (1-based) of CF_DEVSEASONAL array
                          * associated with this CF_DEVPREDICT array. */
-                        rrd.rra_def[rrd.stat_head->rra_cnt].par[RRA_dependent_rra_idx].u_cnt =
+                        rrd.rra_def[rrd.stat_head->rra_cnt].
+                            par[RRA_dependent_rra_idx].u_cnt =
                             atoi(token) - 1;
                         break;
                     default:
-                        rrd.rra_def[rrd.stat_head->rra_cnt].pdp_cnt = atoi(token);
+                        rrd.rra_def[rrd.stat_head->rra_cnt].pdp_cnt =
+                            atoi(token);
                         break;
                     }
                     break;
                 case 3:
-                    switch(cf_conv(rrd.rra_def[rrd.stat_head->rra_cnt].cf_nam))
-                    {
+                    switch (cf_conv
+                            (rrd.rra_def[rrd.stat_head->rra_cnt].cf_nam)) {
                     case CF_HWPREDICT:
-                        rrd.rra_def[rrd.stat_head->rra_cnt].par[RRA_hw_beta].u_val = atof(token);
+                    case CF_MHWPREDICT:
+                        rrd.rra_def[rrd.stat_head->rra_cnt].par[RRA_hw_beta].
+                            u_val = atof(token);
                         if (atof(token) < 0.0 || atof(token) > 1.0)
-                            rrd_set_error("Invalid beta: must be between 0 and 1");
+                            rrd_set_error
+                                ("Invalid beta: must be between 0 and 1");
                         break;
                     case CF_DEVSEASONAL:
                     case CF_SEASONAL:
                         /* specifies the index (1-based) of CF_HWPREDICT array
                          * associated with this CF_DEVSEASONAL or CF_SEASONAL array. 
                          * */
-                        rrd.rra_def[rrd.stat_head->rra_cnt].par[RRA_dependent_rra_idx].u_cnt =
+                        rrd.rra_def[rrd.stat_head->rra_cnt].
+                            par[RRA_dependent_rra_idx].u_cnt =
                             atoi(token) - 1;
                         break;
                     case CF_FAILURES:
                         /* specifies the window length */
-                        rrd.rra_def[rrd.stat_head->rra_cnt].par[RRA_window_len].u_cnt =
-                            atoi(token);
-                        if (atoi(token) < 1 || atoi(token) > MAX_FAILURES_WINDOW_LEN)
-                            rrd_set_error("Window length is out of range %d, %d",1,
-                                          MAX_FAILURES_WINDOW_LEN);
+                        rrd.rra_def[rrd.stat_head->rra_cnt].
+                            par[RRA_window_len].u_cnt = atoi(token);
+                        if (atoi(token) < 1
+                            || atoi(token) > MAX_FAILURES_WINDOW_LEN)
+                            rrd_set_error
+                                ("Window length is out of range %d, %d", 1,
+                                 MAX_FAILURES_WINDOW_LEN);
                         /* verify that window length exceeds the failure threshold */
-                        if (rrd.rra_def[rrd.stat_head->rra_cnt].par[RRA_window_len].u_cnt <
-                            rrd.rra_def[rrd.stat_head->rra_cnt].par[RRA_failure_threshold].u_cnt)
-                            rrd_set_error("Window length is shorter than the failure threshold");
+                        if (rrd.rra_def[rrd.stat_head->rra_cnt].
+                            par[RRA_window_len].u_cnt <
+                            rrd.rra_def[rrd.stat_head->rra_cnt].
+                            par[RRA_failure_threshold].u_cnt)
+                            rrd_set_error
+                                ("Window length is shorter than the failure threshold");
                         break;
                     case CF_DEVPREDICT:
                         /* shouldn't be any more arguments */
-                        rrd_set_error("Unexpected extra argument for consolidation function DEVPREDICT");
+                        rrd_set_error
+                            ("Unexpected extra argument for consolidation function DEVPREDICT");
                         break;
                     default:
-                        rrd.rra_def[rrd.stat_head->rra_cnt].row_cnt = atoi(token);
+                        rrd.rra_def[rrd.stat_head->rra_cnt].row_cnt =
+                            atoi(token);
                         break;
                     }
                     break;
                 case 4:
-                    switch(cf_conv(rrd.rra_def[rrd.stat_head->rra_cnt].cf_nam))
-                    {
+                    switch (cf_conv
+                            (rrd.rra_def[rrd.stat_head->rra_cnt].cf_nam)) {
                     case CF_FAILURES:
                         /* specifies the index (1-based) of CF_DEVSEASONAL array
                          * associated with this CF_DEVFAILURES array. */
-                        rrd.rra_def[rrd.stat_head->rra_cnt].par[RRA_dependent_rra_idx].u_cnt =
+                        rrd.rra_def[rrd.stat_head->rra_cnt].
+                            par[RRA_dependent_rra_idx].u_cnt =
                             atoi(token) - 1;
                         break;
+                    case CF_DEVSEASONAL:
+                    case CF_SEASONAL:
+                        /* optional smoothing window */
+                        if (sscanf(token, "smoothing-window=%lf",
+                                   &(rrd.rra_def[rrd.stat_head->rra_cnt].
+                                     par[RRA_seasonal_smoothing_window].
+                                     u_val))) {
+                            strcpy(rrd.stat_head->version, RRD_VERSION);    /* smoothing-window causes Version 4 */
+                            if (rrd.rra_def[rrd.stat_head->rra_cnt].
+                                par[RRA_seasonal_smoothing_window].u_val < 0.0
+                                || rrd.rra_def[rrd.stat_head->rra_cnt].
+                                par[RRA_seasonal_smoothing_window].u_val >
+                                1.0) {
+                                rrd_set_error
+                                    ("Invalid smoothing-window %f: must be between 0 and 1",
+                                     rrd.rra_def[rrd.stat_head->rra_cnt].
+                                     par[RRA_seasonal_smoothing_window].
+                                     u_val);
+                            }
+                        } else {
+                            rrd_set_error("Invalid option %s", token);
+                        }
+                        break;
                     case CF_HWPREDICT:
+                    case CF_MHWPREDICT:
                         /* length of the associated CF_SEASONAL and CF_DEVSEASONAL arrays. */
                         period = atoi(token);
-                        if (period > rrd.rra_def[rrd.stat_head->rra_cnt].row_cnt)
-                            rrd_set_error("Length of seasonal cycle exceeds length of HW prediction array");
+                        if (period >
+                            rrd.rra_def[rrd.stat_head->rra_cnt].row_cnt)
+                            rrd_set_error
+                                ("Length of seasonal cycle exceeds length of HW prediction array");
                         break;
                     default:
                         /* shouldn't be any more arguments */
-                        rrd_set_error("Unexpected extra argument for consolidation function %s",
-                                      rrd.rra_def[rrd.stat_head->rra_cnt].cf_nam);
+                        rrd_set_error
+                            ("Unexpected extra argument for consolidation function %s",
+                             rrd.rra_def[rrd.stat_head->rra_cnt].cf_nam);
                         break;
                     }
                     break;
@@ -377,312 +478,347 @@ rrd_create_r(const char *filename,
                      * is missing, then the CF_SEASONAL, CF_DEVSEASONAL, CF_DEVPREDICT,
                      * CF_FAILURES.
                      * arrays are created automatically. */
-                    rrd.rra_def[rrd.stat_head->rra_cnt].par[RRA_dependent_rra_idx].u_cnt =
-                        atoi(token) - 1;
+                    rrd.rra_def[rrd.stat_head->rra_cnt].
+                        par[RRA_dependent_rra_idx].u_cnt = atoi(token) - 1;
                     break;
                 default:
                     /* should never get here */
                     rrd_set_error("Unknown error");
                     break;
-                } /* end switch */
-                if (rrd_test_error())
-                {
+                }       /* end switch */
+                if (rrd_test_error()) {
                     /* all errors are unrecoverable */
                     free(argvcopy);
-                    rrd_free(&rrd);
+                    free(rrd.stat_head);
+                    free(rrd.live_head);
                     return (-1);
                 }
-                token = strtok_r(NULL,":", &tokptr);
+                token = strtok_r(NULL, ":", &tokptr);
                 token_idx++;
-           } /* end while */
-           free(argvcopy);
+            }           /* end while */
+            free(argvcopy);
 #ifdef DEBUG
-           fprintf(stderr,"Creating RRA CF: %s, dep idx %lu, current idx %lu\n",
-                   rrd.rra_def[rrd.stat_head->rra_cnt].cf_nam,
-                   rrd.rra_def[rrd.stat_head->rra_cnt].par[RRA_dependent_rra_idx].u_cnt, 
-                   rrd.stat_head -> rra_cnt);
+            fprintf(stderr,
+                    "Creating RRA CF: %s, dep idx %lu, current idx %lu\n",
+                    rrd.rra_def[rrd.stat_head->rra_cnt].cf_nam,
+                    rrd.rra_def[rrd.stat_head->rra_cnt].
+                    par[RRA_dependent_rra_idx].u_cnt, rrd.stat_head->rra_cnt);
 #endif
-           /* should we create CF_SEASONAL, CF_DEVSEASONAL, and CF_DEVPREDICT? */
-           if (cf_conv(rrd.rra_def[rrd.stat_head->rra_cnt].cf_nam) == CF_HWPREDICT
-               && rrd.rra_def[rrd.stat_head->rra_cnt].par[RRA_dependent_rra_idx].u_cnt 
-               == rrd.stat_head -> rra_cnt)
-           {
+            /* should we create CF_SEASONAL, CF_DEVSEASONAL, and CF_DEVPREDICT? */
+            if ((cf_conv(rrd.rra_def[rrd.stat_head->rra_cnt].cf_nam) ==
+                 CF_HWPREDICT
+                 || cf_conv(rrd.rra_def[rrd.stat_head->rra_cnt].cf_nam) ==
+                 CF_MHWPREDICT)
+                && rrd.rra_def[rrd.stat_head->rra_cnt].
+                par[RRA_dependent_rra_idx].u_cnt == rrd.stat_head->rra_cnt) {
 #ifdef DEBUG
-                fprintf(stderr,"Creating HW contingent RRAs\n");
+                fprintf(stderr, "Creating HW contingent RRAs\n");
 #endif
-                if (create_hw_contingent_rras(&rrd,period,hashed_name) == -1) {
+                if (create_hw_contingent_rras(&rrd, period, hashed_name) ==
+                    -1) {
                     rrd_set_error("creating contingent RRA");
-                    rrd_free(&rrd);
+                    free(rrd.stat_head);
+                    free(rrd.live_head);
                     return -1;
                 }
-           }
-           rrd.stat_head->rra_cnt++;                   
-       } else {
-           rrd_set_error("can't parse argument '%s'",argv[i]);
-           rrd_free(&rrd);
+            }
+            rrd.stat_head->rra_cnt++;
+        } else {
+            rrd_set_error("can't parse argument '%s'", argv[i]);
+            free(rrd.stat_head);
+            free(rrd.live_head);
             return -1;
-       }
+        }
     }
-    
-    
-    if (rrd.stat_head->rra_cnt < 1){
-       rrd_set_error("you must define at least one Round Robin Archive");
-       rrd_free(&rrd);
-       return(-1);
+
+
+    if (rrd.stat_head->rra_cnt < 1) {
+        rrd_set_error("you must define at least one Round Robin Archive");
+        free(rrd.stat_head);
+        free(rrd.live_head);
+        return (-1);
     }
-    
-    if (rrd.stat_head->ds_cnt < 1){
-       rrd_set_error("you must define at least one Data Source");
-       rrd_free(&rrd);
-       return(-1);
+
+    if (rrd.stat_head->ds_cnt < 1) {
+        rrd_set_error("you must define at least one Data Source");
+        free(rrd.stat_head);
+        free(rrd.live_head);
+        return (-1);
     }
     return rrd_create_fn(filename, &rrd);
 }
 
-void parseGENERIC_DS(const char *def,rrd_t *rrd, int ds_idx)
+void parseGENERIC_DS(
+    const char *def,
+    rrd_t *rrd,
+    int ds_idx)
 {
-    char minstr[DS_NAM_SIZE], maxstr[DS_NAM_SIZE];     
+    char      minstr[DS_NAM_SIZE], maxstr[DS_NAM_SIZE];
+    char     *old_locale;
+
     /*
-      int temp;
-      
-      temp = sscanf(def,"%lu:%18[^:]:%18[^:]", 
-      &(rrd -> ds_def[ds_idx].par[DS_mrhb_cnt].u_cnt),
-      minstr,maxstr);
-    */
-    if (sscanf(def,"%lu:%18[^:]:%18[^:]",      
-               &(rrd -> ds_def[ds_idx].par[DS_mrhb_cnt].u_cnt),
-               minstr,maxstr) == 3)
-    {
+       int temp;
+
+       temp = sscanf(def,"%lu:%18[^:]:%18[^:]", 
+       &(rrd -> ds_def[ds_idx].par[DS_mrhb_cnt].u_cnt),
+       minstr,maxstr);
+     */
+    old_locale = setlocale(LC_NUMERIC, "C");
+    if (sscanf(def, "%lu:%18[^:]:%18[^:]",
+               &(rrd->ds_def[ds_idx].par[DS_mrhb_cnt].u_cnt),
+               minstr, maxstr) == 3) {
         if (minstr[0] == 'U' && minstr[1] == 0)
-            rrd -> ds_def[ds_idx].par[DS_min_val].u_val = DNAN;
+            rrd->ds_def[ds_idx].par[DS_min_val].u_val = DNAN;
         else
-            rrd -> ds_def[ds_idx].par[DS_min_val].u_val = atof(minstr);
-        
+            rrd->ds_def[ds_idx].par[DS_min_val].u_val = atof(minstr);
+
         if (maxstr[0] == 'U' && maxstr[1] == 0)
-            rrd -> ds_def[ds_idx].par[DS_max_val].u_val = DNAN;
+            rrd->ds_def[ds_idx].par[DS_max_val].u_val = DNAN;
         else
-            rrd -> ds_def[ds_idx].par[DS_max_val].u_val  = atof(maxstr);
-        
-        if (! isnan(rrd -> ds_def[ds_idx].par[DS_min_val].u_val) &&
-            ! isnan(rrd -> ds_def[ds_idx].par[DS_max_val].u_val) &&
-            rrd -> ds_def[ds_idx].par[DS_min_val].u_val
-            >= rrd -> ds_def[ds_idx].par[DS_max_val].u_val ) {
+            rrd->ds_def[ds_idx].par[DS_max_val].u_val = atof(maxstr);
+
+        if (!isnan(rrd->ds_def[ds_idx].par[DS_min_val].u_val) &&
+            !isnan(rrd->ds_def[ds_idx].par[DS_max_val].u_val) &&
+            rrd->ds_def[ds_idx].par[DS_min_val].u_val
+            >= rrd->ds_def[ds_idx].par[DS_max_val].u_val) {
             rrd_set_error("min must be less than max in DS definition");
-            return;            
+            setlocale(LC_NUMERIC, old_locale);
+            return;
         }
     } else {
         rrd_set_error("failed to parse data source %s", def);
     }
+    setlocale(LC_NUMERIC, old_locale);
 }
 
 /* Create the CF_DEVPREDICT, CF_DEVSEASONAL, CF_SEASONAL, and CF_FAILURES RRAs
  * associated with a CF_HWPREDICT RRA. */
-int
-create_hw_contingent_rras(rrd_t *rrd, unsigned short period, unsigned long hashed_name)
+int create_hw_contingent_rras(
+    rrd_t *rrd,
+    unsigned short period,
+    unsigned long hashed_name)
 {
-    size_t old_size;
-    rra_def_tcurrent_rra;
-    
+    size_t    old_size;
+    rra_def_t *current_rra;
+
     /* save index to CF_HWPREDICT */
-    unsigned long hw_index = rrd -> stat_head -> rra_cnt;
+    unsigned long hw_index = rrd->stat_head->rra_cnt;
+
     /* advance the pointer */
-    (rrd -> stat_head -> rra_cnt)++;                   
+    (rrd->stat_head->rra_cnt)++;
     /* allocate the memory for the 4 contingent RRAs */
-    old_size = sizeof(rra_def_t)*(rrd -> stat_head->rra_cnt);
-    if ((rrd -> rra_def = rrd_realloc(rrd -> rra_def,
-                                      old_size+4*sizeof(rra_def_t)))==NULL)
-    {
+    old_size = sizeof(rra_def_t) * (rrd->stat_head->rra_cnt);
+    if ((rrd->rra_def = rrd_realloc(rrd->rra_def,
+                                    old_size + 4 * sizeof(rra_def_t))) ==
+        NULL) {
         rrd_set_error("allocating rrd.rra_def");
-        return(-1);    
+        return (-1);
     }
     /* clear memory */
-    memset(&(rrd -> rra_def[rrd -> stat_head->rra_cnt]), 0, 4*sizeof(rra_def_t));
-    
+    memset(&(rrd->rra_def[rrd->stat_head->rra_cnt]), 0,
+           4 * sizeof(rra_def_t));
+
     /* create the CF_SEASONAL RRA */
-    current_rra = &(rrd -> rra_def[rrd -> stat_head -> rra_cnt]);
-    strcpy(current_rra -> cf_nam,"SEASONAL");
-    current_rra -> row_cnt = period;
-    current_rra -> par[RRA_seasonal_smooth_idx].u_cnt = hashed_name % period;
-    current_rra -> pdp_cnt = 1;
-    current_rra -> par[RRA_seasonal_gamma].u_val = 
-        rrd -> rra_def[hw_index].par[RRA_hw_alpha].u_val;
-    current_rra -> par[RRA_dependent_rra_idx].u_cnt = hw_index; 
-    rrd -> rra_def[hw_index].par[RRA_dependent_rra_idx].u_cnt = rrd -> stat_head -> rra_cnt;
-    
+    current_rra = &(rrd->rra_def[rrd->stat_head->rra_cnt]);
+    strcpy(current_rra->cf_nam, "SEASONAL");
+    current_rra->row_cnt = period;
+    current_rra->par[RRA_seasonal_smooth_idx].u_cnt = hashed_name % period;
+    current_rra->pdp_cnt = 1;
+    current_rra->par[RRA_seasonal_gamma].u_val =
+        rrd->rra_def[hw_index].par[RRA_hw_alpha].u_val;
+    current_rra->par[RRA_dependent_rra_idx].u_cnt = hw_index;
+    rrd->rra_def[hw_index].par[RRA_dependent_rra_idx].u_cnt =
+        rrd->stat_head->rra_cnt;
+
     /* create the CF_DEVSEASONAL RRA */
-    (rrd -> stat_head -> rra_cnt)++; 
-    current_rra = &(rrd -> rra_def[rrd -> stat_head -> rra_cnt]);
-    strcpy(current_rra -> cf_nam,"DEVSEASONAL");
-    current_rra -> row_cnt = period;
-    current_rra -> par[RRA_seasonal_smooth_idx].u_cnt = hashed_name % period;
-    current_rra -> pdp_cnt = 1;
-    current_rra -> par[RRA_seasonal_gamma].u_val = 
-        rrd -> rra_def[hw_index].par[RRA_hw_alpha].u_val;
-    current_rra -> par[RRA_dependent_rra_idx].u_cnt = hw_index; 
-    
+    (rrd->stat_head->rra_cnt)++;
+    current_rra = &(rrd->rra_def[rrd->stat_head->rra_cnt]);
+    strcpy(current_rra->cf_nam, "DEVSEASONAL");
+    current_rra->row_cnt = period;
+    current_rra->par[RRA_seasonal_smooth_idx].u_cnt = hashed_name % period;
+    current_rra->pdp_cnt = 1;
+    current_rra->par[RRA_seasonal_gamma].u_val =
+        rrd->rra_def[hw_index].par[RRA_hw_alpha].u_val;
+    current_rra->par[RRA_dependent_rra_idx].u_cnt = hw_index;
+
     /* create the CF_DEVPREDICT RRA */
-    (rrd -> stat_head -> rra_cnt)++; 
-    current_rra = &(rrd -> rra_def[rrd -> stat_head -> rra_cnt]);
-    strcpy(current_rra -> cf_nam,"DEVPREDICT");
-    current_rra -> row_cnt = (rrd -> rra_def[hw_index]).row_cnt;
-    current_rra -> pdp_cnt = 1;
-    current_rra -> par[RRA_dependent_rra_idx].u_cnt 
-        = hw_index + 2; /* DEVSEASONAL */
-    
+    (rrd->stat_head->rra_cnt)++;
+    current_rra = &(rrd->rra_def[rrd->stat_head->rra_cnt]);
+    strcpy(current_rra->cf_nam, "DEVPREDICT");
+    current_rra->row_cnt = (rrd->rra_def[hw_index]).row_cnt;
+    current_rra->pdp_cnt = 1;
+    current_rra->par[RRA_dependent_rra_idx].u_cnt = hw_index + 2;   /* DEVSEASONAL */
+
     /* create the CF_FAILURES RRA */
-    (rrd -> stat_head -> rra_cnt)++; 
-    current_rra = &(rrd -> rra_def[rrd -> stat_head -> rra_cnt]);
-    strcpy(current_rra -> cf_nam,"FAILURES");
-    current_rra -> row_cnt = period; 
-    current_rra -> pdp_cnt = 1;
-    current_rra -> par[RRA_delta_pos].u_val = 2.0;
-    current_rra -> par[RRA_delta_neg].u_val = 2.0;
-    current_rra -> par[RRA_failure_threshold].u_cnt = 7;
-    current_rra -> par[RRA_window_len].u_cnt = 9;
-    current_rra -> par[RRA_dependent_rra_idx].u_cnt = 
-        hw_index + 2; /* DEVSEASONAL */
+    (rrd->stat_head->rra_cnt)++;
+    current_rra = &(rrd->rra_def[rrd->stat_head->rra_cnt]);
+    strcpy(current_rra->cf_nam, "FAILURES");
+    current_rra->row_cnt = period;
+    current_rra->pdp_cnt = 1;
+    current_rra->par[RRA_delta_pos].u_val = 2.0;
+    current_rra->par[RRA_delta_neg].u_val = 2.0;
+    current_rra->par[RRA_failure_threshold].u_cnt = 7;
+    current_rra->par[RRA_window_len].u_cnt = 9;
+    current_rra->par[RRA_dependent_rra_idx].u_cnt = hw_index + 2;   /* DEVSEASONAL */
     return 0;
 }
 
 /* create and empty rrd file according to the specs given */
 
-int
-rrd_create_fn(const char *file_name, rrd_t *rrd)
+int rrd_create_fn(
+    const char *file_name,
+    rrd_t *rrd)
 {
-    unsigned long    i,ii;
-    FILE             *rrd_file;
-    rrd_value_t      *unknown;
-    int        unkn_cnt;
-    
-    if ((rrd_file = fopen(file_name,"wb")) == NULL ) {
-       rrd_set_error("creating '%s': %s",file_name, rrd_strerror(errno));
-        rrd_free(rrd);
-       return(-1);
+    unsigned long i, ii;
+    int       rrd_file;
+    rrd_value_t *unknown;
+    int       unkn_cnt;
+    rrd_file_t *rrd_file_dn;
+    rrd_t     rrd_dn;
+
+    if ((rrd_file = open(file_name, O_WRONLY | O_CREAT | O_TRUNC, 0666)) < 0) {
+        rrd_set_error("creating '%s': %s", file_name, rrd_strerror(errno));
+        free(rrd->stat_head);
+        free(rrd->live_head);
+        return (-1);
     }
-    
-    fwrite(rrd->stat_head,
-          sizeof(stat_head_t), 1, rrd_file);
-    
-    fwrite(rrd->ds_def,
-          sizeof(ds_def_t), rrd->stat_head->ds_cnt, rrd_file);
-    
-    fwrite(rrd->rra_def,
-          sizeof(rra_def_t), rrd->stat_head->rra_cnt, rrd_file);
-    
-    fwrite(rrd->live_head,
-          sizeof(live_head_t),1, rrd_file);
-
-    if((rrd->pdp_prep = calloc(1,sizeof(pdp_prep_t))) == NULL){
-       rrd_set_error("allocating pdp_prep");
-       rrd_free(rrd);
-       fclose(rrd_file);
-       return(-1);
+
+    write(rrd_file, rrd->stat_head, sizeof(stat_head_t));
+
+    write(rrd_file, rrd->ds_def, sizeof(ds_def_t) * rrd->stat_head->ds_cnt);
+
+    write(rrd_file, rrd->rra_def,
+          sizeof(rra_def_t) * rrd->stat_head->rra_cnt);
+
+    write(rrd_file, rrd->live_head, sizeof(live_head_t));
+
+    if ((rrd->pdp_prep = calloc(1, sizeof(pdp_prep_t))) == NULL) {
+        rrd_set_error("allocating pdp_prep");
+        free(rrd->stat_head);
+        free(rrd->live_head);
+        close(rrd_file);
+        return (-1);
     }
 
-    strcpy(rrd->pdp_prep->last_ds,"UNKN");
+    strcpy(rrd->pdp_prep->last_ds, "U");
 
     rrd->pdp_prep->scratch[PDP_val].u_val = 0.0;
-    rrd->pdp_prep->scratch[PDP_unkn_sec_cnt].u_cnt = 
-       rrd->live_head->last_up % rrd->stat_head->pdp_step;
-
-    for(i=0; i < rrd->stat_head->ds_cnt; i++)
-       fwrite( rrd->pdp_prep,sizeof(pdp_prep_t),1,rrd_file);
-    
-    if((rrd->cdp_prep = calloc(1,sizeof(cdp_prep_t))) == NULL){
-       rrd_set_error("allocating cdp_prep");
-       rrd_free(rrd);
-       fclose(rrd_file);
-       return(-1);
+    rrd->pdp_prep->scratch[PDP_unkn_sec_cnt].u_cnt =
+        rrd->live_head->last_up % rrd->stat_head->pdp_step;
+
+    for (i = 0; i < rrd->stat_head->ds_cnt; i++)
+        write(rrd_file, rrd->pdp_prep, sizeof(pdp_prep_t));
+
+    if ((rrd->cdp_prep = calloc(1, sizeof(cdp_prep_t))) == NULL) {
+        rrd_set_error("allocating cdp_prep");
+        free(rrd->stat_head);
+        free(rrd->live_head);
+        close(rrd_file);
+        return (-1);
     }
 
 
-    for(i=0; i < rrd->stat_head->rra_cnt; i++) {
-       switch (cf_conv(rrd->rra_def[i].cf_nam))
-          {
-           case CF_HWPREDICT:
-               init_hwpredict_cdp(rrd->cdp_prep);
-               break;
-           case CF_SEASONAL:
-           case CF_DEVSEASONAL:
-               init_seasonal_cdp(rrd->cdp_prep);
-               break;
-           case CF_FAILURES:
-               /* initialize violation history to 0 */
-               for (ii = 0; ii < MAX_CDP_PAR_EN; ii++)
-               {
-                               /* We can zero everything out, by setting u_val to the
-                                * NULL address. Each array entry in scratch is 8 bytes
-                                * (a double), but u_cnt only accessed 4 bytes (long) */
-                   rrd->cdp_prep->scratch[ii].u_val = 0.0;
-               }
-               break;
-           default:
-               /* can not be zero because we don't know anything ... */
-               rrd->cdp_prep->scratch[CDP_val].u_val = DNAN;
-               /* startup missing pdp count */
-               rrd->cdp_prep->scratch[CDP_unkn_pdp_cnt].u_cnt = 
-                   ((rrd->live_head->last_up -
-                rrd->pdp_prep->scratch[PDP_unkn_sec_cnt].u_cnt)
-                    % (rrd->stat_head->pdp_step 
-                       * rrd->rra_def[i].pdp_cnt)) / rrd->stat_head->pdp_step; 
-               break;
-          }
-       
-       for(ii=0; ii < rrd->stat_head->ds_cnt; ii++) 
-       {
-           fwrite( rrd->cdp_prep,sizeof(cdp_prep_t),1,rrd_file);
-       }
+    for (i = 0; i < rrd->stat_head->rra_cnt; i++) {
+        switch (cf_conv(rrd->rra_def[i].cf_nam)) {
+        case CF_HWPREDICT:
+        case CF_MHWPREDICT:
+            init_hwpredict_cdp(rrd->cdp_prep);
+            break;
+        case CF_SEASONAL:
+        case CF_DEVSEASONAL:
+            init_seasonal_cdp(rrd->cdp_prep);
+            break;
+        case CF_FAILURES:
+            /* initialize violation history to 0 */
+            for (ii = 0; ii < MAX_CDP_PAR_EN; ii++) {
+                /* We can zero everything out, by setting u_val to the
+                 * NULL address. Each array entry in scratch is 8 bytes
+                 * (a double), but u_cnt only accessed 4 bytes (long) */
+                rrd->cdp_prep->scratch[ii].u_val = 0.0;
+            }
+            break;
+        default:
+            /* can not be zero because we don't know anything ... */
+            rrd->cdp_prep->scratch[CDP_val].u_val = DNAN;
+            /* startup missing pdp count */
+            rrd->cdp_prep->scratch[CDP_unkn_pdp_cnt].u_cnt =
+                ((rrd->live_head->last_up -
+                  rrd->pdp_prep->scratch[PDP_unkn_sec_cnt].u_cnt)
+                 % (rrd->stat_head->pdp_step
+                    * rrd->rra_def[i].pdp_cnt)) / rrd->stat_head->pdp_step;
+            break;
+        }
+
+        for (ii = 0; ii < rrd->stat_head->ds_cnt; ii++) {
+            write(rrd_file, rrd->cdp_prep, sizeof(cdp_prep_t));
+        }
     }
-    
+
     /* now, we must make sure that the rest of the rrd
        struct is properly initialized */
-    
-    if((rrd->rra_ptr = calloc(1,sizeof(rra_ptr_t))) == NULL) {
-       rrd_set_error("allocating rra_ptr");
-       rrd_free(rrd);
-       fclose(rrd_file);
-       return(-1);
+
+    if ((rrd->rra_ptr = calloc(1, sizeof(rra_ptr_t))) == NULL) {
+        rrd_set_error("allocating rra_ptr");
+        free(rrd->stat_head);
+        free(rrd->live_head);
+        close(rrd_file);
+        return (-1);
     }
-    
+
     /* changed this initialization to be consistent with
      * rrd_restore. With the old value (0), the first update
      * would occur for cur_row = 1 because rrd_update increments
      * the pointer a priori. */
-    for (i=0; i < rrd->stat_head->rra_cnt; i++)
-    {
-        rrd->rra_ptr->cur_row = rrd->rra_def[i].row_cnt - 1;
-        fwrite( rrd->rra_ptr, sizeof(rra_ptr_t),1,rrd_file);
+    for (i = 0; i < rrd->stat_head->rra_cnt; i++) {
+        rrd->rra_ptr->cur_row = rra_random_row(&rrd->rra_def[i]);
+        write(rrd_file, rrd->rra_ptr, sizeof(rra_ptr_t));
     }
-    
+
     /* write the empty data area */
-    if ((unknown = (rrd_value_t *)malloc(512 * sizeof(rrd_value_t))) == NULL) {
-       rrd_set_error("allocating unknown");
-       rrd_free(rrd);
-       fclose(rrd_file);
-       return(-1);
+    if ((unknown = (rrd_value_t *) malloc(512 * sizeof(rrd_value_t))) == NULL) {
+        rrd_set_error("allocating unknown");
+        free(rrd->stat_head);
+        free(rrd->live_head);
+        close(rrd_file);
+        return (-1);
     }
     for (i = 0; i < 512; ++i)
-       unknown[i] = DNAN;
-    
+        unknown[i] = DNAN;
+
     unkn_cnt = 0;
     for (i = 0; i < rrd->stat_head->rra_cnt; i++)
         unkn_cnt += rrd->stat_head->ds_cnt * rrd->rra_def[i].row_cnt;
-                     
+
     while (unkn_cnt > 0) {
-       fwrite(unknown, sizeof(rrd_value_t), min(unkn_cnt, 512), rrd_file);
-       unkn_cnt -= 512;
-     }
+        write(rrd_file, unknown, sizeof(rrd_value_t) * min(unkn_cnt, 512));
+
+        unkn_cnt -= 512;
+    }
     free(unknown);
-    
-    /* lets see if we had an error */
-    if(ferror(rrd_file)){
-       rrd_set_error("a file error occurred while creating '%s'",file_name);
-       fclose(rrd_file);       
-       rrd_free(rrd);
-       return(-1);
+    fdatasync(rrd_file);
+    free(rrd->stat_head);
+    free(rrd->live_head);
+    if (close(rrd_file) == -1) {
+        rrd_set_error("creating rrd: %s", rrd_strerror(errno));
+        return -1;
     }
-    
-    fclose(rrd_file);    
-    rrd_free(rrd);
+    /* flush all we don't need out of the cache */
+    rrd_file_dn = rrd_open(file_name, &rrd_dn, RRD_READONLY);
+    rrd_dontneed(rrd_file_dn, &rrd_dn);
+    rrd_free(&rrd_dn);
+    rrd_close(rrd_file_dn);
     return (0);
 }
+
+static int rand_init = 0;
+
+long int rra_random_row(
+    rra_def_t *rra)
+{
+    if (!rand_init) {
+        srandom((unsigned int) time(NULL) + (unsigned int) getpid());
+        rand_init++;
+    }
+
+    return random() % rra->row_cnt;
+}
index d8ca8389f263052217a57032af16c1c98a3bbcdb..23d8a0d445242bd9ac8be0eb3f27559c58376393 100644 (file)
@@ -1,11 +1,11 @@
 /*****************************************************************************
- * RRDtool 1.2.27  Copyright by Tobi Oetiker, 1997-2008
+ * RRDtool 1.3rc4  Copyright by Tobi Oetiker, 1997-2008
  * This code is stolen from rateup (mrtg-2.x) by Dave Rand
  *****************************************************************************
  * diff calculate the difference between two very long integers available as
  *      strings
  *****************************************************************************
- * $Id: rrd_diff.c 1286 2008-02-17 10:08:10Z oetiker $
+ * $Id: rrd_diff.c 1366 2008-05-18 13:06:44Z oetiker $
  * $Log$
  * Revision 1.4  2003/03/10 00:30:34  oetiker
  * handle cases with two negative numbers
 
 #include "rrd_tool.h"
 
-double
-rrd_diff(char *a, char *b)
+double rrd_diff(
+    char *a,
+    char *b)
 {
-    char res[LAST_DS_LEN+1], *a1, *b1, *r1, *fix;
-    int c,x,m;
-    char a_neg=0, b_neg=0;
-    double result;
-   
-    while (!(isdigit((int)*a) || *a==0)) {
-        if(*a=='-') 
-           a_neg = 1;
+    char      res[LAST_DS_LEN + 1], *a1, *b1, *r1, *fix;
+    int       c, x, m;
+    char      a_neg = 0, b_neg = 0;
+    double    result;
+
+    while (!(isdigit((int) *a) || *a == 0)) {
+        if (*a == '-')
+            a_neg = 1;
         a++;
     }
-    fix=a;
-    while (isdigit((int)*fix)) 
-       fix++;
-    *fix = 0; /* maybe there is some non digit data in the string */ 
-    while (!(isdigit((int)*b) || *b==0)) {
-       if(*b=='-') 
-           b_neg = 1;  
+    fix = a;
+    while (isdigit((int) *fix))
+        fix++;
+    *fix = 0;           /* maybe there is some non digit data in the string */
+    while (!(isdigit((int) *b) || *b == 0)) {
+        if (*b == '-')
+            b_neg = 1;
         b++;
     }
-    fix=b;
-    while (isdigit((int)*fix)) 
-       fix++;
-    *fix = 0; /* maybe there is some non digit data in the string */ 
-    if(!isdigit((int)*a) || !isdigit((int)*b))
-       return DNAN;
-    if(a_neg+b_neg == 1) /* can not handle numbers with different signs yet */
-       return DNAN;
-    a1 = &a[strlen(a)-1];
-    m = max(strlen(a),strlen(b));
-    if (m > LAST_DS_LEN) return DNAN; /* result string too short */
+    fix = b;
+    while (isdigit((int) *fix))
+        fix++;
+    *fix = 0;           /* maybe there is some non digit data in the string */
+    if (!isdigit((int) *a) || !isdigit((int) *b))
+        return DNAN;
+    if (a_neg + b_neg == 1) /* can not handle numbers with different signs yet */
+        return DNAN;
+    a1 = &a[strlen(a) - 1];
+    m = max(strlen(a), strlen(b));
+    if (m > LAST_DS_LEN)
+        return DNAN;    /* result string too short */
 
-    r1 = &res[m+1];
-    for (b1 = res;b1 <= r1; b1++) *b1 = ' ';
-    b1 = &b[strlen(b)-1];
-    r1[1] = 0;  /* Null terminate result */
+    r1 = &res[m + 1];
+    for (b1 = res; b1 <= r1; b1++)
+        *b1 = ' ';
+    b1 = &b[strlen(b) - 1];
+    r1[1] = 0;          /* Null terminate result */
     c = 0;
-    for (x=0; x<m; x++) {
+    for (x = 0; x < m; x++) {
         if (a1 >= a && b1 >= b) {
             *r1 = ((*a1 - c) - *b1) + '0';
         } else if (a1 >= a) {
@@ -86,33 +89,34 @@ rrd_diff(char *a, char *b)
         }
         if (*r1 < '0') {
             *r1 += 10;
-            c=1;
-        } else
-         if (*r1 > '9') { /* 0 - 10 */
-           *r1 -= 10;
-           c=1;            
-         } else {
-            c=0;
+            c = 1;
+        } else if (*r1 > '9') { /* 0 - 10 */
+            *r1 -= 10;
+            c = 1;
+        } else {
+            c = 0;
         }
-        a1--;b1--;r1--;
+        a1--;
+        b1--;
+        r1--;
     }
     if (c) {
-        r1 = &res[m+1];
-        for (x=0; isdigit((int)*r1) && x<m; x++,r1--)  {
+        r1 = &res[m + 1];
+        for (x = 0; isdigit((int) *r1) && x < m; x++, r1--) {
             *r1 = ('9' - *r1 + c) + '0';
             if (*r1 > '9') {
                 *r1 -= 10;
-                c=1;
+                c = 1;
             } else {
-                c=0;
+                c = 0;
             }
         }
         result = -atof(res);
     } else
         result = atof(res);
 
-    if(a_neg+b_neg==2) /* both are negatives, reverse sign */
+    if (a_neg + b_neg == 2) /* both are negatives, reverse sign */
         result = -result;
-    
+
     return result;
-}                                                       
+}
index bb6859313749e51e8dfdf131ee949bcbad8a7d07..69893e08ed7d74791202746683f255f5f162d1cd 100644 (file)
@@ -1,9 +1,9 @@
 /*****************************************************************************
- * RRDtool 1.2.27  Copyright by Tobi Oetiker, 1997-2008
+ * RRDtool 1.3rc4  Copyright by Tobi Oetiker, 1997-2008
  *****************************************************************************
  * rrd_dump  Display a RRD
  *****************************************************************************
- * $Id: rrd_dump.c 1286 2008-02-17 10:08:10Z oetiker $
+ * $Id: rrd_dump.c 1366 2008-05-18 13:06:44Z oetiker $
  * $Log$
  * Revision 1.7  2004/05/25 20:53:21  oetiker
  * prevent small leak when resources are exhausted -- Mike Slifcak
 extern char *tzname[2];
 #endif
 
-int
-rrd_dump(int argc, char **argv) 
-{
-    int                 rc;
-
-    if (argc < 2) {
-       rrd_set_error("Not enough arguments");
-       return -1;
-    }
 
-    if (argc == 3)
-    {
-      rc = rrd_dump_r(argv[1], argv[2]);
-    }
-    else
-    {
-      rc = rrd_dump_r(argv[1], NULL);                  
-    }
-
-    return rc;
-}
+int rrd_dump_opt_r(
+    const char *filename,
+    char *outname,
+    int  opt_noheader
+)
+{
+    unsigned int i, ii, ix, iii = 0;
+    time_t    now;
+    char      somestring[255];
+    rrd_value_t my_cdp;
+    off_t     rra_base, rra_start, rra_next;
+    rrd_file_t *rrd_file;
+    FILE     *out_file;
+    rrd_t     rrd;
+    rrd_value_t value;
+    struct tm tm;
 
-int
-rrd_dump_r(const char *filename, char *outname)    
-{   
-    unsigned int i,ii,ix,iii=0;
-    time_t       now;
-    char         somestring[255];
-    rrd_value_t  my_cdp;
-    long         rra_base, rra_start, rra_next;
-    FILE        *in_file;
-               FILE                            *out_file;
-    rrd_t        rrd;
-    rrd_value_t  value;
-    struct tm    tm;
-    if(rrd_open(filename, &in_file,&rrd, RRD_READONLY)==-1){
-       rrd_free(&rrd);
-       return(-1);
+    rrd_file = rrd_open(filename, &rrd, RRD_READONLY | RRD_READAHEAD);
+    if (rrd_file == NULL) {
+        rrd_free(&rrd);
+        return (-1);
     }
 
     out_file = NULL;
-    if (outname)
-    {
-      if (!(out_file = fopen(outname, "w")))
-      {
-        return (-1);     
-      }
+    if (outname) {
+        if (!(out_file = fopen(outname, "w"))) {
+            return (-1);
+        }
+    } else {
+        out_file = stdout;
     }
-    else 
-    {
-      out_file = stdout;
+
+    if (!opt_noheader){
+      fputs("<?xml version=\"1.0\" encoding=\"utf-8\"?>\n", out_file);
+      fputs
+        ("<!DOCTYPE rrd SYSTEM \"http://oss.oetiker.ch/rrdtool/rrdtool.dtd\">\n",
+         out_file);
     }
-               
     fputs("<!-- Round Robin Database Dump -->", out_file);
     fputs("<rrd>", out_file);
-    fprintf(out_file, "\t<version> %s </version>\n",RRD_VERSION);
-    fprintf(out_file, "\t<step> %lu </step> <!-- Seconds -->\n",rrd.stat_head->pdp_step);
+    if (atoi(rrd.stat_head->version) <= 3) {
+        fprintf(out_file, "\t<version> %s </version>\n", RRD_VERSION3);
+    } else {
+        fprintf(out_file, "\t<version> %s </version>\n", RRD_VERSION);
+    }
+    fprintf(out_file, "\t<step> %lu </step> <!-- Seconds -->\n",
+            rrd.stat_head->pdp_step);
 #if HAVE_STRFTIME
     localtime_r(&rrd.live_head->last_up, &tm);
-    strftime(somestring,200,"%Y-%m-%d %H:%M:%S %Z",
-            &tm);
+    strftime(somestring, 200, "%Y-%m-%d %H:%M:%S %Z", &tm);
 #else
 # error "Need strftime"
 #endif
-    fprintf(out_file, "\t<lastupdate> %ld </lastupdate> <!-- %s -->\n\n",
-          rrd.live_head->last_up,somestring);
-    for(i=0;i<rrd.stat_head->ds_cnt;i++){
-          fprintf(out_file, "\t<ds>\n");
-          fprintf(out_file, "\t\t<name> %s </name>\n",rrd.ds_def[i].ds_nam);
-          fprintf(out_file, "\t\t<type> %s </type>\n",rrd.ds_def[i].dst);
-       if (dst_conv(rrd.ds_def[i].dst) != DST_CDEF) {
-          fprintf(out_file, "\t\t<minimal_heartbeat> %lu </minimal_heartbeat>\n",rrd.ds_def[i].par[DS_mrhb_cnt].u_cnt);
-             if (isnan(rrd.ds_def[i].par[DS_min_val].u_val)){
-                 fprintf(out_file, "\t\t<min> NaN </min>\n");
-             } else {
-                 fprintf(out_file, "\t\t<min> %0.10e </min>\n",rrd.ds_def[i].par[DS_min_val].u_val);
-             }
-             if (isnan(rrd.ds_def[i].par[DS_max_val].u_val)){
-                 fprintf(out_file, "\t\t<max> NaN </max>\n");
-             } else {
-                 fprintf(out_file, "\t\t<max> %0.10e </max>\n",rrd.ds_def[i].par[DS_max_val].u_val);
-             }
-       } else { /* DST_CDEF */
-             char *str=NULL;
-             rpn_compact2str((rpn_cdefds_t *) &(rrd.ds_def[i].par[DS_cdef]),rrd.ds_def,&str);
-             fprintf(out_file, "\t\t<cdef> %s </cdef>\n", str);
-             free(str);
-          }
-          fprintf(out_file, "\n\t\t<!-- PDP Status -->\n");
-          fprintf(out_file, "\t\t<last_ds> %s </last_ds>\n",rrd.pdp_prep[i].last_ds);
-          if (isnan(rrd.pdp_prep[i].scratch[PDP_val].u_val)){
-             fprintf(out_file, "\t\t<value> NaN </value>\n");
-          } else {
-             fprintf(out_file, "\t\t<value> %0.10e </value>\n",rrd.pdp_prep[i].scratch[PDP_val].u_val);
-          }
-             fprintf(out_file, "\t\t<unknown_sec> %lu </unknown_sec>\n",
-                     rrd.pdp_prep[i].scratch[PDP_unkn_sec_cnt].u_cnt);
-       
-             fprintf(out_file, "\t</ds>\n\n");
-       }
+    fprintf(out_file, "\t<lastupdate> %lu </lastupdate> <!-- %s -->\n\n",
+            (unsigned long) rrd.live_head->last_up, somestring);
+    for (i = 0; i < rrd.stat_head->ds_cnt; i++) {
+        fprintf(out_file, "\t<ds>\n");
+        fprintf(out_file, "\t\t<name> %s </name>\n", rrd.ds_def[i].ds_nam);
+        fprintf(out_file, "\t\t<type> %s </type>\n", rrd.ds_def[i].dst);
+        if (dst_conv(rrd.ds_def[i].dst) != DST_CDEF) {
+            fprintf(out_file,
+                    "\t\t<minimal_heartbeat> %lu </minimal_heartbeat>\n",
+                    rrd.ds_def[i].par[DS_mrhb_cnt].u_cnt);
+            if (isnan(rrd.ds_def[i].par[DS_min_val].u_val)) {
+                fprintf(out_file, "\t\t<min> NaN </min>\n");
+            } else {
+                fprintf(out_file, "\t\t<min> %0.10e </min>\n",
+                        rrd.ds_def[i].par[DS_min_val].u_val);
+            }
+            if (isnan(rrd.ds_def[i].par[DS_max_val].u_val)) {
+                fprintf(out_file, "\t\t<max> NaN </max>\n");
+            } else {
+                fprintf(out_file, "\t\t<max> %0.10e </max>\n",
+                        rrd.ds_def[i].par[DS_max_val].u_val);
+            }
+        } else {        /* DST_CDEF */
+            char     *str = NULL;
+
+            rpn_compact2str((rpn_cdefds_t *) &(rrd.ds_def[i].par[DS_cdef]),
+                            rrd.ds_def, &str);
+            fprintf(out_file, "\t\t<cdef> %s </cdef>\n", str);
+            free(str);
+        }
+        fprintf(out_file, "\n\t\t<!-- PDP Status -->\n");
+        fprintf(out_file, "\t\t<last_ds> %s </last_ds>\n",
+                rrd.pdp_prep[i].last_ds);
+        if (isnan(rrd.pdp_prep[i].scratch[PDP_val].u_val)) {
+            fprintf(out_file, "\t\t<value> NaN </value>\n");
+        } else {
+            fprintf(out_file, "\t\t<value> %0.10e </value>\n",
+                    rrd.pdp_prep[i].scratch[PDP_val].u_val);
+        }
+        fprintf(out_file, "\t\t<unknown_sec> %lu </unknown_sec>\n",
+                rrd.pdp_prep[i].scratch[PDP_unkn_sec_cnt].u_cnt);
+
+        fprintf(out_file, "\t</ds>\n\n");
+    }
 
     fputs("<!-- Round Robin Archives -->", out_file);
 
-    rra_base=ftell(in_file);    
+    rra_base = rrd_file->header_len;
     rra_next = rra_base;
 
-    for(i=0;i<rrd.stat_head->rra_cnt;i++){
-       
-       long timer=0;
-       rra_start= rra_next;
-       rra_next +=  ( rrd.stat_head->ds_cnt
-                      * rrd.rra_def[i].row_cnt
-                      * sizeof(rrd_value_t));
-       fprintf(out_file, "\t<rra>\n");
-       fprintf(out_file, "\t\t<cf> %s </cf>\n",rrd.rra_def[i].cf_nam);
-       fprintf(out_file, "\t\t<pdp_per_row> %lu </pdp_per_row> <!-- %lu seconds -->\n\n",
-              rrd.rra_def[i].pdp_cnt, rrd.rra_def[i].pdp_cnt
-              *rrd.stat_head->pdp_step);
-       /* support for RRA parameters */
-       fprintf(out_file, "\t\t<params>\n");
-       switch(cf_conv(rrd.rra_def[i].cf_nam)) {
-       case CF_HWPREDICT:
-          fprintf(out_file, "\t\t<hw_alpha> %0.10e </hw_alpha>\n", 
-                 rrd.rra_def[i].par[RRA_hw_alpha].u_val);
-          fprintf(out_file, "\t\t<hw_beta> %0.10e </hw_beta>\n", 
-                 rrd.rra_def[i].par[RRA_hw_beta].u_val);
-          fprintf(out_file, "\t\t<dependent_rra_idx> %lu </dependent_rra_idx>\n",
-                 rrd.rra_def[i].par[RRA_dependent_rra_idx].u_cnt);
-          break;
-       case CF_SEASONAL:
-       case CF_DEVSEASONAL:
-          fprintf(out_file, "\t\t<seasonal_gamma> %0.10e </seasonal_gamma>\n", 
-                 rrd.rra_def[i].par[RRA_seasonal_gamma].u_val);
-          fprintf(out_file, "\t\t<seasonal_smooth_idx> %lu </seasonal_smooth_idx>\n",
-                 rrd.rra_def[i].par[RRA_seasonal_smooth_idx].u_cnt);
-          fprintf(out_file, "\t\t<dependent_rra_idx> %lu </dependent_rra_idx>\n",
-                 rrd.rra_def[i].par[RRA_dependent_rra_idx].u_cnt);
-          break;
-       case CF_FAILURES:
-          fprintf(out_file, "\t\t<delta_pos> %0.10e </delta_pos>\n", 
-                 rrd.rra_def[i].par[RRA_delta_pos].u_val);
-          fprintf(out_file, "\t\t<delta_neg> %0.10e </delta_neg>\n", 
-                 rrd.rra_def[i].par[RRA_delta_neg].u_val);
-          fprintf(out_file, "\t\t<window_len> %lu </window_len>\n",
-                 rrd.rra_def[i].par[RRA_window_len].u_cnt);
-          fprintf(out_file, "\t\t<failure_threshold> %lu </failure_threshold>\n",
-                 rrd.rra_def[i].par[RRA_failure_threshold].u_cnt);
-                 /* fall thru */
-       case CF_DEVPREDICT:
-          fprintf(out_file, "\t\t<dependent_rra_idx> %lu </dependent_rra_idx>\n",
-                 rrd.rra_def[i].par[RRA_dependent_rra_idx].u_cnt);
-          break;
-       case CF_AVERAGE:
-       case CF_MAXIMUM:
-       case CF_MINIMUM:
-       case CF_LAST:
-       default:
-          fprintf(out_file, "\t\t<xff> %0.10e </xff>\n", rrd.rra_def[i].par[RRA_cdp_xff_val].u_val);
-          break;
-       }
-       fprintf(out_file, "\t\t</params>\n");
-       fprintf(out_file, "\t\t<cdp_prep>\n");
-       for(ii=0;ii<rrd.stat_head->ds_cnt;ii++){
-               unsigned long ivalue;
-               fprintf(out_file, "\t\t\t<ds>\n");
-               /* support for exporting all CDP parameters */
-               /* parameters common to all CFs */
-                   /* primary_val and secondary_val do not need to be saved between updates
-                        * so strictly speaking they could be omitted.
-                        * However, they can be useful for diagnostic purposes, so are included here. */
-               value = rrd.cdp_prep[i*rrd.stat_head->ds_cnt
-                          +ii].scratch[CDP_primary_val].u_val;
-                       if (isnan(value)) {
-                          fprintf(out_file, "\t\t\t<primary_value> NaN </primary_value>\n");
-                       } else {
-                          fprintf(out_file, "\t\t\t<primary_value> %0.10e </primary_value>\n", value);
-                       }
-               value = rrd.cdp_prep[i*rrd.stat_head->ds_cnt+ii].scratch[CDP_secondary_val].u_val;
-                       if (isnan(value)) {
-                          fprintf(out_file, "\t\t\t<secondary_value> NaN </secondary_value>\n");
-                       } else {
-                          fprintf(out_file, "\t\t\t<secondary_value> %0.10e </secondary_value>\n", value);
-                       }
-               switch(cf_conv(rrd.rra_def[i].cf_nam)) {
-               case CF_HWPREDICT:
-               value = rrd.cdp_prep[i*rrd.stat_head->ds_cnt+ii].scratch[CDP_hw_intercept].u_val;
-                       if (isnan(value)) {
-                          fprintf(out_file, "\t\t\t<intercept> NaN </intercept>\n");
-                       } else {
-                          fprintf(out_file, "\t\t\t<intercept> %0.10e </intercept>\n", value);
-                       }
-               value = rrd.cdp_prep[i*rrd.stat_head->ds_cnt+ii].scratch[CDP_hw_last_intercept].u_val;
-                       if (isnan(value)) {
-                          fprintf(out_file, "\t\t\t<last_intercept> NaN </last_intercept>\n");
-                       } else {
-                          fprintf(out_file, "\t\t\t<last_intercept> %0.10e </last_intercept>\n", value);
-                       }
-               value = rrd.cdp_prep[i*rrd.stat_head->ds_cnt+ii].scratch[CDP_hw_slope].u_val;
-                       if (isnan(value)) {
-                          fprintf(out_file, "\t\t\t<slope> NaN </slope>\n");
-                       } else {
-                          fprintf(out_file, "\t\t\t<slope> %0.10e </slope>\n", value);
-                       }
-               value = rrd.cdp_prep[i*rrd.stat_head->ds_cnt+ii].scratch[CDP_hw_last_slope].u_val;
-                       if (isnan(value)) {
-                          fprintf(out_file, "\t\t\t<last_slope> NaN </last_slope>\n");
-                       } else {
-                          fprintf(out_file, "\t\t\t<last_slope> %0.10e </last_slope>\n", value);
-                       }
-                       ivalue = rrd.cdp_prep[i*rrd.stat_head->ds_cnt+ii].scratch[CDP_null_count].u_cnt;
-                       fprintf(out_file, "\t\t\t<nan_count> %lu </nan_count>\n", ivalue);
-                       ivalue = rrd.cdp_prep[i*rrd.stat_head->ds_cnt+ii].scratch[CDP_last_null_count].u_cnt;
-                       fprintf(out_file, "\t\t\t<last_nan_count> %lu </last_nan_count>\n", ivalue);
-                       break;
-               case CF_SEASONAL:
-               case CF_DEVSEASONAL:
-               value = rrd.cdp_prep[i*rrd.stat_head->ds_cnt+ii].scratch[CDP_hw_seasonal].u_val;
-                       if (isnan(value)) {
-                          fprintf(out_file, "\t\t\t<seasonal> NaN </seasonal>\n");
-                       } else {
-                          fprintf(out_file, "\t\t\t<seasonal> %0.10e </seasonal>\n", value);
-                       }
-               value = rrd.cdp_prep[i*rrd.stat_head->ds_cnt+ii].scratch[CDP_hw_last_seasonal].u_val;
-                       if (isnan(value)) {
-                          fprintf(out_file, "\t\t\t<last_seasonal> NaN </last_seasonal>\n");
-                       } else {
-                          fprintf(out_file, "\t\t\t<last_seasonal> %0.10e </last_seasonal>\n", value);
-                       }
-               ivalue = rrd.cdp_prep[i*rrd.stat_head->ds_cnt+ii].scratch[CDP_init_seasonal].u_cnt;
-                       fprintf(out_file, "\t\t\t<init_flag> %lu </init_flag>\n", ivalue);
-                       break;
-               case CF_DEVPREDICT:
-                       break;
-               case CF_FAILURES:
-                   {
-            unsigned short vidx;
-                       char *violations_array = (char *) ((void*) 
-                          rrd.cdp_prep[i*rrd.stat_head->ds_cnt+ii].scratch);
-                       fprintf(out_file, "\t\t\t<history> ");
-                       for (vidx = 0; vidx < rrd.rra_def[i].par[RRA_window_len].u_cnt; ++vidx)
-                       {
-                               fprintf(out_file, "%d",violations_array[vidx]);
-                       }
-                       fprintf(out_file, " </history>\n");
-                       }
-                       break;
-               case CF_AVERAGE:
-               case CF_MAXIMUM:
-               case CF_MINIMUM:
-               case CF_LAST:
-               default:
-               value = rrd.cdp_prep[i*rrd.stat_head->ds_cnt+ii].scratch[CDP_val].u_val;
-                       if (isnan(value)) {
-                          fprintf(out_file, "\t\t\t<value> NaN </value>\n");
-                       } else {
-                          fprintf(out_file, "\t\t\t<value> %0.10e </value>\n", value);
-                       }
-                   fprintf(out_file, "\t\t\t<unknown_datapoints> %lu </unknown_datapoints>\n",
-                      rrd.cdp_prep[i*rrd.stat_head->ds_cnt+ii].scratch[CDP_unkn_pdp_cnt].u_cnt);
-                       break;
-               }
-        fprintf(out_file, "\t\t\t</ds>\n");     
-    }
-       fprintf(out_file, "\t\t</cdp_prep>\n");
+    for (i = 0; i < rrd.stat_head->rra_cnt; i++) {
+
+        long      timer = 0;
+
+        rra_start = rra_next;
+        rra_next += (rrd.stat_head->ds_cnt
+                     * rrd.rra_def[i].row_cnt * sizeof(rrd_value_t));
+        fprintf(out_file, "\t<rra>\n");
+        fprintf(out_file, "\t\t<cf> %s </cf>\n", rrd.rra_def[i].cf_nam);
+        fprintf(out_file,
+                "\t\t<pdp_per_row> %lu </pdp_per_row> <!-- %lu seconds -->\n\n",
+                rrd.rra_def[i].pdp_cnt,
+                rrd.rra_def[i].pdp_cnt * rrd.stat_head->pdp_step);
+        /* support for RRA parameters */
+        fprintf(out_file, "\t\t<params>\n");
+        switch (cf_conv(rrd.rra_def[i].cf_nam)) {
+        case CF_HWPREDICT:
+        case CF_MHWPREDICT:
+            fprintf(out_file, "\t\t<hw_alpha> %0.10e </hw_alpha>\n",
+                    rrd.rra_def[i].par[RRA_hw_alpha].u_val);
+            fprintf(out_file, "\t\t<hw_beta> %0.10e </hw_beta>\n",
+                    rrd.rra_def[i].par[RRA_hw_beta].u_val);
+            fprintf(out_file,
+                    "\t\t<dependent_rra_idx> %lu </dependent_rra_idx>\n",
+                    rrd.rra_def[i].par[RRA_dependent_rra_idx].u_cnt);
+            break;
+        case CF_SEASONAL:
+        case CF_DEVSEASONAL:
+            fprintf(out_file,
+                    "\t\t<seasonal_gamma> %0.10e </seasonal_gamma>\n",
+                    rrd.rra_def[i].par[RRA_seasonal_gamma].u_val);
+            fprintf(out_file,
+                    "\t\t<seasonal_smooth_idx> %lu </seasonal_smooth_idx>\n",
+                    rrd.rra_def[i].par[RRA_seasonal_smooth_idx].u_cnt);
+            if (atoi(rrd.stat_head->version) >= 4) {
+                fprintf(out_file,
+                        "\t\t<smoothing_window> %0.10e </smoothing_window>\n",
+                        rrd.rra_def[i].par[RRA_seasonal_smoothing_window].
+                        u_val);
+            }
+            fprintf(out_file,
+                    "\t\t<dependent_rra_idx> %lu </dependent_rra_idx>\n",
+                    rrd.rra_def[i].par[RRA_dependent_rra_idx].u_cnt);
+            break;
+        case CF_FAILURES:
+            fprintf(out_file, "\t\t<delta_pos> %0.10e </delta_pos>\n",
+                    rrd.rra_def[i].par[RRA_delta_pos].u_val);
+            fprintf(out_file, "\t\t<delta_neg> %0.10e </delta_neg>\n",
+                    rrd.rra_def[i].par[RRA_delta_neg].u_val);
+            fprintf(out_file, "\t\t<window_len> %lu </window_len>\n",
+                    rrd.rra_def[i].par[RRA_window_len].u_cnt);
+            fprintf(out_file,
+                    "\t\t<failure_threshold> %lu </failure_threshold>\n",
+                    rrd.rra_def[i].par[RRA_failure_threshold].u_cnt);
+            /* fall thru */
+        case CF_DEVPREDICT:
+            fprintf(out_file,
+                    "\t\t<dependent_rra_idx> %lu </dependent_rra_idx>\n",
+                    rrd.rra_def[i].par[RRA_dependent_rra_idx].u_cnt);
+            break;
+        case CF_AVERAGE:
+        case CF_MAXIMUM:
+        case CF_MINIMUM:
+        case CF_LAST:
+        default:
+            fprintf(out_file, "\t\t<xff> %0.10e </xff>\n",
+                    rrd.rra_def[i].par[RRA_cdp_xff_val].u_val);
+            break;
+        }
+        fprintf(out_file, "\t\t</params>\n");
+        fprintf(out_file, "\t\t<cdp_prep>\n");
+        for (ii = 0; ii < rrd.stat_head->ds_cnt; ii++) {
+            unsigned long ivalue;
 
-       fprintf(out_file, "\t\t<database>\n");
-       fseek(in_file,(rra_start
-                      +(rrd.rra_ptr[i].cur_row+1)
-                      * rrd.stat_head->ds_cnt
-                      * sizeof(rrd_value_t)),SEEK_SET);
-       timer = - (rrd.rra_def[i].row_cnt-1);
-       ii=rrd.rra_ptr[i].cur_row;
-       for(ix=0;ix<rrd.rra_def[i].row_cnt;ix++){           
-           ii++;
-           if (ii>=rrd.rra_def[i].row_cnt) {
-               fseek(in_file,rra_start,SEEK_SET);
-               ii=0; /* wrap if max row cnt is reached */
-           }
-           now = (rrd.live_head->last_up 
-                  - rrd.live_head->last_up 
-                  % (rrd.rra_def[i].pdp_cnt*rrd.stat_head->pdp_step)) 
-               + (timer*rrd.rra_def[i].pdp_cnt*rrd.stat_head->pdp_step);
+            fprintf(out_file, "\t\t\t<ds>\n");
+            /* support for exporting all CDP parameters */
+            /* parameters common to all CFs */
+            /* primary_val and secondary_val do not need to be saved between updates
+             * so strictly speaking they could be omitted.
+             * However, they can be useful for diagnostic purposes, so are included here. */
+            value = rrd.cdp_prep[i * rrd.stat_head->ds_cnt
+                                 + ii].scratch[CDP_primary_val].u_val;
+            if (isnan(value)) {
+                fprintf(out_file,
+                        "\t\t\t<primary_value> NaN </primary_value>\n");
+            } else {
+                fprintf(out_file,
+                        "\t\t\t<primary_value> %0.10e </primary_value>\n",
+                        value);
+            }
+            value =
+                rrd.cdp_prep[i * rrd.stat_head->ds_cnt +
+                             ii].scratch[CDP_secondary_val].u_val;
+            if (isnan(value)) {
+                fprintf(out_file,
+                        "\t\t\t<secondary_value> NaN </secondary_value>\n");
+            } else {
+                fprintf(out_file,
+                        "\t\t\t<secondary_value> %0.10e </secondary_value>\n",
+                        value);
+            }
+            switch (cf_conv(rrd.rra_def[i].cf_nam)) {
+            case CF_HWPREDICT:
+            case CF_MHWPREDICT:
+                value =
+                    rrd.cdp_prep[i * rrd.stat_head->ds_cnt +
+                                 ii].scratch[CDP_hw_intercept].u_val;
+                if (isnan(value)) {
+                    fprintf(out_file, "\t\t\t<intercept> NaN </intercept>\n");
+                } else {
+                    fprintf(out_file,
+                            "\t\t\t<intercept> %0.10e </intercept>\n", value);
+                }
+                value =
+                    rrd.cdp_prep[i * rrd.stat_head->ds_cnt +
+                                 ii].scratch[CDP_hw_last_intercept].u_val;
+                if (isnan(value)) {
+                    fprintf(out_file,
+                            "\t\t\t<last_intercept> NaN </last_intercept>\n");
+                } else {
+                    fprintf(out_file,
+                            "\t\t\t<last_intercept> %0.10e </last_intercept>\n",
+                            value);
+                }
+                value =
+                    rrd.cdp_prep[i * rrd.stat_head->ds_cnt +
+                                 ii].scratch[CDP_hw_slope].u_val;
+                if (isnan(value)) {
+                    fprintf(out_file, "\t\t\t<slope> NaN </slope>\n");
+                } else {
+                    fprintf(out_file, "\t\t\t<slope> %0.10e </slope>\n",
+                            value);
+                }
+                value =
+                    rrd.cdp_prep[i * rrd.stat_head->ds_cnt +
+                                 ii].scratch[CDP_hw_last_slope].u_val;
+                if (isnan(value)) {
+                    fprintf(out_file,
+                            "\t\t\t<last_slope> NaN </last_slope>\n");
+                } else {
+                    fprintf(out_file,
+                            "\t\t\t<last_slope> %0.10e </last_slope>\n",
+                            value);
+                }
+                ivalue =
+                    rrd.cdp_prep[i * rrd.stat_head->ds_cnt +
+                                 ii].scratch[CDP_null_count].u_cnt;
+                fprintf(out_file, "\t\t\t<nan_count> %lu </nan_count>\n",
+                        ivalue);
+                ivalue =
+                    rrd.cdp_prep[i * rrd.stat_head->ds_cnt +
+                                 ii].scratch[CDP_last_null_count].u_cnt;
+                fprintf(out_file,
+                        "\t\t\t<last_nan_count> %lu </last_nan_count>\n",
+                        ivalue);
+                break;
+            case CF_SEASONAL:
+            case CF_DEVSEASONAL:
+                value =
+                    rrd.cdp_prep[i * rrd.stat_head->ds_cnt +
+                                 ii].scratch[CDP_hw_seasonal].u_val;
+                if (isnan(value)) {
+                    fprintf(out_file, "\t\t\t<seasonal> NaN </seasonal>\n");
+                } else {
+                    fprintf(out_file, "\t\t\t<seasonal> %0.10e </seasonal>\n",
+                            value);
+                }
+                value =
+                    rrd.cdp_prep[i * rrd.stat_head->ds_cnt +
+                                 ii].scratch[CDP_hw_last_seasonal].u_val;
+                if (isnan(value)) {
+                    fprintf(out_file,
+                            "\t\t\t<last_seasonal> NaN </last_seasonal>\n");
+                } else {
+                    fprintf(out_file,
+                            "\t\t\t<last_seasonal> %0.10e </last_seasonal>\n",
+                            value);
+                }
+                ivalue =
+                    rrd.cdp_prep[i * rrd.stat_head->ds_cnt +
+                                 ii].scratch[CDP_init_seasonal].u_cnt;
+                fprintf(out_file, "\t\t\t<init_flag> %lu </init_flag>\n",
+                        ivalue);
+                break;
+            case CF_DEVPREDICT:
+                break;
+            case CF_FAILURES:
+            {
+                unsigned short vidx;
+                char     *violations_array = (char *) ((void *)
+                                                       rrd.cdp_prep[i *
+                                                                    rrd.
+                                                                    stat_head->
+                                                                    ds_cnt +
+                                                                    ii].
+                                                       scratch);
+                fprintf(out_file, "\t\t\t<history> ");
+                for (vidx = 0;
+                     vidx < rrd.rra_def[i].par[RRA_window_len].u_cnt;
+                     ++vidx) {
+                    fprintf(out_file, "%d", violations_array[vidx]);
+                }
+                fprintf(out_file, " </history>\n");
+            }
+                break;
+            case CF_AVERAGE:
+            case CF_MAXIMUM:
+            case CF_MINIMUM:
+            case CF_LAST:
+            default:
+                value =
+                    rrd.cdp_prep[i * rrd.stat_head->ds_cnt +
+                                 ii].scratch[CDP_val].u_val;
+                if (isnan(value)) {
+                    fprintf(out_file, "\t\t\t<value> NaN </value>\n");
+                } else {
+                    fprintf(out_file, "\t\t\t<value> %0.10e </value>\n",
+                            value);
+                }
+                fprintf(out_file,
+                        "\t\t\t<unknown_datapoints> %lu </unknown_datapoints>\n",
+                        rrd.cdp_prep[i * rrd.stat_head->ds_cnt +
+                                     ii].scratch[CDP_unkn_pdp_cnt].u_cnt);
+                break;
+            }
+            fprintf(out_file, "\t\t\t</ds>\n");
+        }
+        fprintf(out_file, "\t\t</cdp_prep>\n");
 
-           timer++;
+        fprintf(out_file, "\t\t<database>\n");
+        rrd_seek(rrd_file, (rra_start + (rrd.rra_ptr[i].cur_row + 1)
+                            * rrd.stat_head->ds_cnt
+                            * sizeof(rrd_value_t)), SEEK_SET);
+        timer = -(rrd.rra_def[i].row_cnt - 1);
+        ii = rrd.rra_ptr[i].cur_row;
+        for (ix = 0; ix < rrd.rra_def[i].row_cnt; ix++) {
+            ii++;
+            if (ii >= rrd.rra_def[i].row_cnt) {
+                rrd_seek(rrd_file, rra_start, SEEK_SET);
+                ii = 0; /* wrap if max row cnt is reached */
+            }
+            now = (rrd.live_head->last_up
+                   - rrd.live_head->last_up
+                   % (rrd.rra_def[i].pdp_cnt * rrd.stat_head->pdp_step))
+                + (timer * rrd.rra_def[i].pdp_cnt * rrd.stat_head->pdp_step);
+
+            timer++;
 #if HAVE_STRFTIME
-           localtime_r(&now, &tm);
-           strftime(somestring,200,"%Y-%m-%d %H:%M:%S %Z", &tm);
+            localtime_r(&now, &tm);
+            strftime(somestring, 200, "%Y-%m-%d %H:%M:%S %Z", &tm);
 #else
 # error "Need strftime"
 #endif
-           fprintf(out_file, "\t\t\t<!-- %s / %d --> <row>",somestring,(int)now);
-           for(iii=0;iii<rrd.stat_head->ds_cnt;iii++){                  
-               fread(&my_cdp,sizeof(rrd_value_t),1,in_file);           
-               if (isnan(my_cdp)){
-                 fprintf(out_file, "<v> NaN </v>");
-               } else {
-                 fprintf(out_file, "<v> %0.10e </v>",my_cdp);
-               };
-           }
-           fprintf(out_file, "</row>\n");
-       }
-       fprintf(out_file, "\t\t</database>\n\t</rra>\n");
-       
+            fprintf(out_file, "\t\t\t<!-- %s / %d --> <row>", somestring,
+                    (int) now);
+            for (iii = 0; iii < rrd.stat_head->ds_cnt; iii++) {
+                rrd_read(rrd_file, &my_cdp, sizeof(rrd_value_t) * 1);
+                if (isnan(my_cdp)) {
+                    fprintf(out_file, "<v> NaN </v>");
+                } else {
+                    fprintf(out_file, "<v> %0.10e </v>", my_cdp);
+                };
+            }
+            fprintf(out_file, "</row>\n");
+        }
+        fprintf(out_file, "\t\t</database>\n\t</rra>\n");
+
     }
     fprintf(out_file, "</rrd>\n");
     rrd_free(&rrd);
-    fclose(in_file);
-    if (out_file != stdout)
-    {
-      fclose(out_file);
+    if (out_file != stdout) {
+        fclose(out_file);
     }
-    return(0);
+    return rrd_close(rrd_file);
+}
+
+/* backward compatibility with 1.2.x */
+int rrd_dump_r(
+    const char *filename,
+    char *outname)
+{
+    return rrd_dump_opt_r(filename,outname,0);    
 }
 
+int rrd_dump(
+    int argc,
+    char **argv)
+{
+    int       rc;
+    int       opt_noheader = 0;
+    /* init rrd clean */
+
+    optind = 0;
+    opterr = 0;         /* initialize getopt */
+    
+    while (42) {
+        int       opt;  
+        int       option_index = 0;
+        static struct option long_options[] = {
+            {"no-header", no_argument, 0, 'n'},
+            {0, 0, 0, 0}
+        };
+
+        opt = getopt_long(argc, argv, "n", long_options, &option_index);
 
+        if (opt == EOF)
+            break;
 
+        switch (opt) {
+        case 'n':
+            opt_noheader = 1;
+            break;
+
+        default: 
+            rrd_set_error("usage rrdtool %s [--no-header|-n] "
+                      "file.rrd [file.xml]", argv[0]);
+            return (-1);
+            break;
+        }
+    }                   /* while (42) */
+
+    if ((argc - optind) < 1 || (argc - optind) > 2) {
+        rrd_set_error("usage rrdtool %s [--no-header|-n] "
+                      "file.rrd [file.xml]", argv[0]);
+        return (-1);
+    }
+
+    if ((argc - optind) == 2) {
+        rc = rrd_dump_opt_r(argv[optind], argv[optind+1],opt_noheader);
+    } else {
+        rc = rrd_dump_opt_r(argv[optind], NULL,opt_noheader);
+    }
+
+    return rc;
+}
 
index 6aaf7f29fd6b07cc05feae00eb9cce4482ded506..bd8f4e7bc4affc7556c57367eeca7f70fef84992 100644 (file)
@@ -1,9 +1,9 @@
 /*****************************************************************************
- * RRDtool 1.2.27  Copyright by Tobi Oetiker, 1997-2008
+ * RRDtool 1.3rc4  Copyright by Tobi Oetiker, 1997-2008
  *****************************************************************************
  * rrd_error.c   Common Header File
  *****************************************************************************
- * $Id: rrd_error.c 1286 2008-02-17 10:08:10Z oetiker $
+ * $Id: rrd_error.c 1366 2008-05-18 13:06:44Z oetiker $
  * $Log$
  * Revision 1.4  2003/02/22 21:57:03  oetiker
  * a patch to avoid a memory leak and a Makefile.am patch to
 #define ERRBUFLEN 256
 #define CTX (rrd_get_context())
 
-void
-rrd_set_error(char *fmt, ...)
+void rrd_set_error(
+    char *fmt,
+    ...)
 {
-    va_list argp;
+    va_list   argp;
+
     rrd_clear_error();
     va_start(argp, fmt);
 #ifdef HAVE_VSNPRINTF
@@ -51,18 +53,21 @@ rrd_set_error(char *fmt, ...)
     va_end(argp);
 }
 
-int
-rrd_test_error(void) {
+int rrd_test_error(
+    void)
+{
     return CTX->rrd_error[0] != '\0';
 }
 
-void
-rrd_clear_error(void){
+void rrd_clear_error(
+    void)
+{
     CTX->rrd_error[0] = '\0';
 }
 
-char *
-rrd_get_error(void){
+char     *rrd_get_error(
+    void)
+{
     return CTX->rrd_error;
 }
 
@@ -72,74 +77,88 @@ rrd_get_error(void){
    operations on them... Then a single thread may use more than one
    context. Using these functions would require to change each and
    every function containing any of the non _r versions... */
-void
-rrd_set_error_r(struct rrd_context *rrd_ctx, char *fmt, ...)
+void rrd_set_error_r(
+    struct rrd_context *rrd_ctx,
+    char *fmt,
+    ...)
 {
-    va_list argp;
+    va_list   argp;
+
     rrd_clear_error_r(rrd_ctx);
     va_start(argp, fmt);
 #ifdef HAVE_VSNPRINTF
-    vsnprintf((char *)rrd_ctx->rrd_error, rrd_ctx->len, fmt, argp);
-    rrd_ctx->rrd_error[rrd_ctx->len]='\0';
+    vsnprintf((char *) rrd_ctx->rrd_error, rrd_ctx->len, fmt, argp);
+    rrd_ctx->rrd_error[rrd_ctx->len] = '\0';
 #else
-    vsprintf((char *)rrd_ctx->rrd_error, fmt, argp);
+    vsprintf((char *) rrd_ctx->rrd_error, fmt, argp);
 #endif
     va_end(argp);
 }
 
-int
-rrd_test_error_r(struct rrd_context *rrd_ctx) {
+int rrd_test_error_r(
+    struct rrd_context *rrd_ctx)
+{
     return rrd_ctx->rrd_error[0] != '\0';
 }
 
-void
-rrd_clear_error_r(struct rrd_context *rrd_ctx) {
+void rrd_clear_error_r(
+    struct rrd_context *rrd_ctx)
+{
     rrd_ctx->rrd_error[0] = '\0';
 }
 
-char *
-rrd_get_error_r(struct rrd_context *rrd_ctx) {
-    return (char *)rrd_ctx->rrd_error;
+char     *rrd_get_error_r(
+    struct rrd_context *rrd_ctx)
+{
+    return (char *) rrd_ctx->rrd_error;
 }
 #endif
 
 /* PS: Should we move this to some other file? It is not really error
    related. */
-struct rrd_context *
-rrd_new_context(void) {
-    struct rrd_context *rrd_ctx = 
-       (struct rrd_context *) malloc(sizeof(struct rrd_context));
+struct rrd_context *rrd_new_context(
+    void)
+{
+    struct rrd_context *rrd_ctx =
+        (struct rrd_context *) malloc(sizeof(struct rrd_context));
 
     if (rrd_ctx) {
-       rrd_ctx->rrd_error = malloc(MAXLEN+10);
-       rrd_ctx->lib_errstr = malloc(ERRBUFLEN+10);
-       if (rrd_ctx->rrd_error && rrd_ctx->lib_errstr) {
-           *rrd_ctx->rrd_error = 0;
-           *rrd_ctx->lib_errstr = 0;
-           rrd_ctx->len = MAXLEN;
-           rrd_ctx->errlen = ERRBUFLEN;
-           return rrd_ctx;
-       }
-       if (rrd_ctx->rrd_error) free(rrd_ctx->rrd_error);
-       if (rrd_ctx->lib_errstr) free(rrd_ctx->lib_errstr);
-       free(rrd_ctx);
+        rrd_ctx->rrd_error = malloc(MAXLEN + 10);
+        rrd_ctx->lib_errstr = malloc(ERRBUFLEN + 10);
+        if (rrd_ctx->rrd_error && rrd_ctx->lib_errstr) {
+            *rrd_ctx->rrd_error = 0;
+            *rrd_ctx->lib_errstr = 0;
+            rrd_ctx->len = MAXLEN;
+            rrd_ctx->errlen = ERRBUFLEN;
+            return rrd_ctx;
+        }
+        if (rrd_ctx->rrd_error)
+            free(rrd_ctx->rrd_error);
+        if (rrd_ctx->lib_errstr)
+            free(rrd_ctx->lib_errstr);
+        free(rrd_ctx);
     }
     return NULL;
 }
 
-void
-rrd_free_context(struct rrd_context *rrd_ctx) {
+void rrd_free_context(
+    struct rrd_context *rrd_ctx)
+{
     if (rrd_ctx) {
-       if (rrd_ctx->rrd_error) free(rrd_ctx->rrd_error);
-       if (rrd_ctx->lib_errstr) free(rrd_ctx->lib_errstr);
-       free(rrd_ctx);
+        if (rrd_ctx->rrd_error)
+            free(rrd_ctx->rrd_error);
+        if (rrd_ctx->lib_errstr)
+            free(rrd_ctx->lib_errstr);
+        free(rrd_ctx);
     }
 }
 
 #if 0
-void rrd_globalize_error(struct rrd_context *rrd_ctx) {
+void rrd_globalize_error(
+    struct rrd_context *rrd_ctx)
+{
     if (rrd_ctx) {
-       rrd_set_error(rrd_ctx->rrd_error);
+        rrd_set_error(rrd_ctx->rrd_error);
     }
 }
 #endif
index 82d35f374b75450175c5e9c34d2bbc4ab4b033a3..4fe64cbc3031ef90a9b8eda84981d02027071dad 100644 (file)
@@ -1,9 +1,9 @@
 /*****************************************************************************
- * RRDtool 1.2.27  Copyright by Tobi Oetiker, 1997-2008
+ * RRDtool 1.3rc4  Copyright by Tobi Oetiker, 1997-2008
  *****************************************************************************
  * rrd_fetch.c  read date from an rrd to use for further processing
  *****************************************************************************
- * $Id: rrd_fetch.c 1286 2008-02-17 10:08:10Z oetiker $
+ * $Id: rrd_fetch.c 1366 2008-05-18 13:06:44Z oetiker $
  * $Log$
  * Revision 1.8  2004/05/18 18:53:03  oetiker
  * big spell checking patch -- slif@bellsouth.net
 #include "rrd_is_thread_safe.h"
 /*#define DEBUG*/
 
-int
-rrd_fetch(int argc, 
-         char **argv,
-         time_t         *start,
-         time_t         *end,       /* which time frame do you want ?
-                                     * will be changed to represent reality */
-         unsigned long  *step,      /* which stepsize do you want? 
-                                     * will be changed to represent reality */
-         unsigned long  *ds_cnt,    /* number of data sources in file */
-         char           ***ds_namv,   /* names of data sources */
-         rrd_value_t    **data)     /* two dimensional array containing the data */
-{
-
-
-    long     step_tmp =1;
-    time_t   start_tmp=0, end_tmp=0;
+int rrd_fetch(
+    int argc,
+    char **argv,
+    time_t *start,
+    time_t *end,        /* which time frame do you want ?
+                         * will be changed to represent reality */
+    unsigned long *step,    /* which stepsize do you want? 
+                             * will be changed to represent reality */
+    unsigned long *ds_cnt,  /* number of data sources in file */
+    char ***ds_namv,    /* names of data sources */
+    rrd_value_t **data)
+{                       /* two dimensional array containing the data */
+    long      step_tmp = 1;
+    time_t    start_tmp = 0, end_tmp = 0;
     const char *cf;
 
     struct rrd_time_value start_tv, end_tv;
     char     *parsetime_error = NULL;
-    optind = 0; opterr = 0;  /* initialize getopt */
+    struct option long_options[] = {
+        {"resolution", required_argument, 0, 'r'},
+        {"start", required_argument, 0, 's'},
+        {"end", required_argument, 0, 'e'},
+        {0, 0, 0, 0}
+    };
+
+    optind = 0;
+    opterr = 0;         /* initialize getopt */
 
     /* init start and end time */
     parsetime("end-24h", &start_tv);
     parsetime("now", &end_tv);
 
-    while (1){
-       static struct option long_options[] =
-       {
-           {"resolution",      required_argument, 0, 'r'},
-           {"start",      required_argument, 0, 's'},
-           {"end",      required_argument, 0, 'e'},
-           {0,0,0,0}
-       };
-       int option_index = 0;
-       int opt;
-       opt = getopt_long(argc, argv, "r:s:e:", 
-                         long_options, &option_index);
-
-       if (opt == EOF)
-           break;
-
-       switch(opt) {
-       case 's':
+    while (1) {
+        int       option_index = 0;
+        int       opt;
+
+        opt = getopt_long(argc, argv, "r:s:e:", long_options, &option_index);
+
+        if (opt == EOF)
+            break;
+
+        switch (opt) {
+        case 's':
             if ((parsetime_error = parsetime(optarg, &start_tv))) {
-                rrd_set_error( "start time: %s", parsetime_error );
+                rrd_set_error("start time: %s", parsetime_error);
                 return -1;
-           }
-           break;
-       case 'e':
+            }
+            break;
+        case 'e':
             if ((parsetime_error = parsetime(optarg, &end_tv))) {
-                rrd_set_error( "end time: %s", parsetime_error );
+                rrd_set_error("end time: %s", parsetime_error);
                 return -1;
-           }
-           break;
-       case 'r':
-           step_tmp = atol(optarg);
-           break;
-       case '?':
-           rrd_set_error("unknown option '-%c'",optopt);
-           return(-1);
-       }
+            }
+            break;
+        case 'r':
+            step_tmp = atol(optarg);
+            break;
+        case '?':
+            rrd_set_error("unknown option '-%c'", optopt);
+            return (-1);
+        }
+    }
+
+
+    if (proc_start_end(&start_tv, &end_tv, &start_tmp, &end_tmp) == -1) {
+        return -1;
     }
 
-    
-    if (proc_start_end(&start_tv,&end_tv,&start_tmp,&end_tmp) == -1){
-       return -1;
-    }  
 
-    
-    if (start_tmp < 3600*24*365*10){
-       rrd_set_error("the first entry to fetch should be after 1980");
-       return(-1);
+    if (start_tmp < 3600 * 24 * 365 * 10) {
+        rrd_set_error("the first entry to fetch should be after 1980");
+        return (-1);
     }
-    
+
     if (end_tmp < start_tmp) {
-       rrd_set_error("start (%ld) should be less than end (%ld)", start_tmp, end_tmp);
-       return(-1);
+        rrd_set_error("start (%ld) should be less than end (%ld)", start_tmp,
+                      end_tmp);
+        return (-1);
     }
-    
+
     *start = start_tmp;
     *end = end_tmp;
 
     if (step_tmp < 1) {
-       rrd_set_error("step must be >= 1 second");
-       return -1;
+        rrd_set_error("step must be >= 1 second");
+        return -1;
     }
     *step = step_tmp;
-    
-    if (optind + 1 >= argc){
-       rrd_set_error("not enough arguments");
-       return -1;
+
+    if (optind + 1 >= argc) {
+        rrd_set_error("not enough arguments");
+        return -1;
     }
 
-    cf = argv[optind+1];
+    cf = argv[optind + 1];
 
-    if (rrd_fetch_r(argv[optind],cf,start,end,step,ds_cnt,ds_namv,data) == -1)
-       return(-1);
+    if (rrd_fetch_r(argv[optind], cf, start, end, step, ds_cnt, ds_namv, data)
+        != 0)
+        return (-1);
     return (0);
 }
 
-int
-rrd_fetch_r(
-    const char           *filename,  /* name of the rrd */
-    const char           *cf,        /* which consolidation function ?*/
-    time_t         *start,
-    time_t         *end,       /* which time frame do you want ?
-                                * will be changed to represent reality */
-    unsigned long  *step,      /* which stepsize do you want? 
-                                * will be changed to represent reality */
-    unsigned long  *ds_cnt,    /* number of data sources in file */
-    char           ***ds_namv, /* names of data_sources */
-    rrd_value_t    **data)     /* two dimensional array containing the data */
-{
-    enum     cf_en cf_idx;
-
-    if ((int)(cf_idx=cf_conv(cf)) == -1 ){
+int rrd_fetch_r(
+    const char *filename,   /* name of the rrd */
+    const char *cf,     /* which consolidation function ? */
+    time_t *start,
+    time_t *end,        /* which time frame do you want ?
+                         * will be changed to represent reality */
+    unsigned long *step,    /* which stepsize do you want? 
+                             * will be changed to represent reality */
+    unsigned long *ds_cnt,  /* number of data sources in file */
+    char ***ds_namv,    /* names of data_sources */
+    rrd_value_t **data)
+{                       /* two dimensional array containing the data */
+    enum cf_en cf_idx;
+
+    if ((int) (cf_idx = cf_conv(cf)) == -1) {
         return -1;
     }
 
-    return (rrd_fetch_fn(filename,cf_idx,start,end,step,ds_cnt,ds_namv,data));
+    return (rrd_fetch_fn
+            (filename, cf_idx, start, end, step, ds_cnt, ds_namv, data));
 }
 
-int
-rrd_fetch_fn(
-    const char     *filename,  /* name of the rrd */
-    enum cf_en     cf_idx,         /* which consolidation function ?*/
-    time_t         *start,
-    time_t         *end,       /* which time frame do you want ?
-                               * will be changed to represent reality */
-    unsigned long  *step,      /* which stepsize do you want? 
-                               * will be changed to represent reality */
-    unsigned long  *ds_cnt,    /* number of data sources in file */
-    char           ***ds_namv,   /* names of data_sources */
-    rrd_value_t    **data)     /* two dimensional array containing the data */
-{
-    long           i,ii;
-    FILE           *in_file;
-    time_t         cal_start,cal_end, rra_start_time,rra_end_time;
-    long  best_full_rra=0, best_part_rra=0, chosen_rra=0, rra_pointer=0;
-    long  best_full_step_diff=0, best_part_step_diff=0, tmp_step_diff=0, tmp_match=0, best_match=0;
-    long  full_match, rra_base;
-    long           start_offset, end_offset;
-    int            first_full = 1;
-    int            first_part = 1;
+int rrd_fetch_fn(
+    const char *filename,   /* name of the rrd */
+    enum cf_en cf_idx,  /* which consolidation function ? */
+    time_t *start,
+    time_t *end,        /* which time frame do you want ?
+                         * will be changed to represent reality */
+    unsigned long *step,    /* which stepsize do you want? 
+                             * will be changed to represent reality */
+    unsigned long *ds_cnt,  /* number of data sources in file */
+    char ***ds_namv,    /* names of data_sources */
+    rrd_value_t **data)
+{                       /* two dimensional array containing the data */
+    long      i, ii;
+    time_t    cal_start, cal_end, rra_start_time, rra_end_time;
+    long      best_full_rra = 0, best_part_rra = 0, chosen_rra =
+        0, rra_pointer = 0;
+    long      best_full_step_diff = 0, best_part_step_diff =
+        0, tmp_step_diff = 0, tmp_match = 0, best_match = 0;
+    long      full_match, rra_base;
+    long      start_offset, end_offset;
+    int       first_full = 1;
+    int       first_part = 1;
     rrd_t     rrd;
-    rrd_value_t    *data_ptr;
-    unsigned long  rows;
+    rrd_file_t *rrd_file;
+    rrd_value_t *data_ptr;
+    unsigned long rows;
 
 #ifdef DEBUG
-fprintf(stderr,"Entered rrd_fetch_fn() searching for the best match\n");
-fprintf(stderr,"Looking for: start %10lu end %10lu step %5lu\n",
-                                               *start,*end,*step);
+    fprintf(stderr, "Entered rrd_fetch_fn() searching for the best match\n");
+    fprintf(stderr, "Looking for: start %10lu end %10lu step %5lu\n",
+            *start, *end, *step);
 #endif
 
-    if(rrd_open(filename,&in_file,&rrd, RRD_READONLY)==-1)
-       return(-1);
-    
+    rrd_file = rrd_open(filename, &rrd, RRD_READONLY);
+    if (rrd_file == NULL)
+        goto err_free;
+
     /* when was the really last update of this file ? */
 
-    if (((*ds_namv) = (char **) malloc(rrd.stat_head->ds_cnt * sizeof(char*)))==NULL){
-       rrd_set_error("malloc fetch ds_namv array");
-       rrd_free(&rrd);
-       fclose(in_file);
-       return(-1);
+    if (((*ds_namv) =
+         (char **) malloc(rrd.stat_head->ds_cnt * sizeof(char *))) == NULL) {
+        rrd_set_error("malloc fetch ds_namv array");
+        goto err_close;
     }
-    
-    for(i=0;(unsigned long)i<rrd.stat_head->ds_cnt;i++){
-       if ((((*ds_namv)[i]) = malloc(sizeof(char) * DS_NAM_SIZE))==NULL){
-           rrd_set_error("malloc fetch ds_namv entry");
-           rrd_free(&rrd);
-           free(*ds_namv);
-           fclose(in_file);
-           return(-1);
-       }
-       strncpy((*ds_namv)[i],rrd.ds_def[i].ds_nam,DS_NAM_SIZE-1);
-       (*ds_namv)[i][DS_NAM_SIZE-1]='\0';
+
+    for (i = 0; (unsigned long) i < rrd.stat_head->ds_cnt; i++) {
+        if ((((*ds_namv)[i]) = malloc(sizeof(char) * DS_NAM_SIZE)) == NULL) {
+            rrd_set_error("malloc fetch ds_namv entry");
+            goto err_free_ds_namv;
+        }
+        strncpy((*ds_namv)[i], rrd.ds_def[i].ds_nam, DS_NAM_SIZE - 1);
+        (*ds_namv)[i][DS_NAM_SIZE - 1] = '\0';
 
     }
-    
+
     /* find the rra which best matches the requirements */
-    for(i=0;(unsigned)i<rrd.stat_head->rra_cnt;i++){
-       if(cf_conv(rrd.rra_def[i].cf_nam) == cf_idx){
-           
-           cal_end = (rrd.live_head->last_up - (rrd.live_head->last_up 
-                         % (rrd.rra_def[i].pdp_cnt 
-                            * rrd.stat_head->pdp_step)));
-           cal_start = (cal_end 
-                        - (rrd.rra_def[i].pdp_cnt 
-                           * rrd.rra_def[i].row_cnt
-                           * rrd.stat_head->pdp_step));
-
-           full_match = *end -*start;
-#ifdef DEBUG
-fprintf(stderr,"Considering: start %10lu end %10lu step %5lu ",
-                                                       cal_start,cal_end,
-                       rrd.stat_head->pdp_step * rrd.rra_def[i].pdp_cnt);
-#endif
-           /* we need step difference in either full or partial case */
-           tmp_step_diff = labs(*step - (rrd.stat_head->pdp_step
-                                          * rrd.rra_def[i].pdp_cnt));
-           /* best full match */
-           if(cal_end >= *end 
-              && cal_start <= *start){
-               if (first_full || (tmp_step_diff < best_full_step_diff)){
-                   first_full=0;
-                   best_full_step_diff = tmp_step_diff;
-                   best_full_rra=i;
+    for (i = 0; (unsigned) i < rrd.stat_head->rra_cnt; i++) {
+        if (cf_conv(rrd.rra_def[i].cf_nam) == cf_idx) {
+
+            cal_end = (rrd.live_head->last_up - (rrd.live_head->last_up
+                                                 % (rrd.rra_def[i].pdp_cnt
+                                                    *
+                                                    rrd.stat_head->
+                                                    pdp_step)));
+            cal_start =
+                (cal_end -
+                 (rrd.rra_def[i].pdp_cnt * rrd.rra_def[i].row_cnt *
+                  rrd.stat_head->pdp_step));
+
+            full_match = *end - *start;
 #ifdef DEBUG
-fprintf(stderr,"best full match so far\n");
+            fprintf(stderr, "Considering: start %10lu end %10lu step %5lu ",
+                    cal_start, cal_end,
+                    rrd.stat_head->pdp_step * rrd.rra_def[i].pdp_cnt);
 #endif
-               } else {
+            /* we need step difference in either full or partial case */
+            tmp_step_diff = labs(*step - (rrd.stat_head->pdp_step
+                                          * rrd.rra_def[i].pdp_cnt));
+            /* best full match */
+            if (cal_start <= *start) {
+                if (first_full || (tmp_step_diff < best_full_step_diff)) {
+                    first_full = 0;
+                    best_full_step_diff = tmp_step_diff;
+                    best_full_rra = i;
 #ifdef DEBUG
-fprintf(stderr,"full match, not best\n");
+                    fprintf(stderr, "best full match so far\n");
+                } else {
+                    fprintf(stderr, "full match, not best\n");
 #endif
-               }
-               
-           } else {
-               /* best partial match */
-               tmp_match = full_match;
-               if (cal_start>*start)
-                   tmp_match -= (cal_start-*start);
-               if (cal_end<*end)
-                   tmp_match -= (*end-cal_end);                
-               if (first_part ||
+                }
+
+            } else {
+                /* best partial match */
+                tmp_match = full_match;
+                if (cal_start > *start)
+                    tmp_match -= (cal_start - *start);
+                if (first_part ||
                     (best_match < tmp_match) ||
-                    (best_match == tmp_match && 
-                     tmp_step_diff < best_part_step_diff))
+                    (best_match == tmp_match &&
+                     tmp_step_diff < best_part_step_diff)) {
 #ifdef DEBUG
-fprintf(stderr,"best partial so far\n");
+                    fprintf(stderr, "best partial so far\n");
 #endif
-                   first_part=0;
-                   best_match = tmp_match;
-                   best_part_step_diff = tmp_step_diff;
-                   best_part_rra =i;
-               } else {
+                    first_part = 0;
+                    best_match = tmp_match;
+                    best_part_step_diff = tmp_step_diff;
+                    best_part_rra = i;
+                } else {
 #ifdef DEBUG
-fprintf(stderr,"partial match, not best\n");
+                    fprintf(stderr, "partial match, not best\n");
 #endif
-               }
-           }
-       }
+                }
+            }
+        }
     }
 
     /* lets see how the matching went. */
-    if (first_full==0)
-       chosen_rra = best_full_rra;
-    else if (first_part==0)
-       chosen_rra = best_part_rra;
+    if (first_full == 0)
+        chosen_rra = best_full_rra;
+    else if (first_part == 0)
+        chosen_rra = best_part_rra;
     else {
-       rrd_set_error("the RRD does not contain an RRA matching the chosen CF");
-       rrd_free(&rrd);
-       fclose(in_file);
-       return(-1);
+        rrd_set_error
+            ("the RRD does not contain an RRA matching the chosen CF");
+        goto err_free_all_ds_namv;
     }
-       
+
     /* set the wish parameters to their real values */
     *step = rrd.stat_head->pdp_step * rrd.rra_def[chosen_rra].pdp_cnt;
     *start -= (*start % *step);
@@ -320,8 +315,9 @@ fprintf(stderr,"partial match, not best\n");
     rows = (*end - *start) / *step + 1;
 
 #ifdef DEBUG
-    fprintf(stderr,"We found:    start %10lu end %10lu step %5lu rows  %lu\n",
-                                               *start,*end,*step,rows);
+    fprintf(stderr,
+            "We found:    start %10lu end %10lu step %5lu rows  %lu\n",
+            *start, *end, *step, rows);
 #endif
 
 /* Start and end are now multiples of the step size.  The amount of
@@ -330,143 +326,125 @@ fprintf(stderr,"partial match, not best\n");
 ** we need exactly ((t+s)-t)/s rows.  The row to collect from the
 ** database is the one with time stamp (t+s) which means t to t+s.
 */
-    *ds_cnt =   rrd.stat_head->ds_cnt; 
-    if (((*data) = malloc(*ds_cnt * rows * sizeof(rrd_value_t)))==NULL){
-       rrd_set_error("malloc fetch data area");
-       for (i=0;(unsigned long)i<*ds_cnt;i++)
-             free((*ds_namv)[i]);
-       free(*ds_namv);
-       rrd_free(&rrd);
-       fclose(in_file);
-       return(-1);
+    *ds_cnt = rrd.stat_head->ds_cnt;
+    if (((*data) = malloc(*ds_cnt * rows * sizeof(rrd_value_t))) == NULL) {
+        rrd_set_error("malloc fetch data area");
+        goto err_free_all_ds_namv;
     }
-    
-    data_ptr=(*data);
-    
+
+    data_ptr = (*data);
+
     /* find base address of rra */
-    rra_base=ftell(in_file);
-    for(i=0;i<chosen_rra;i++)
-       rra_base += ( *ds_cnt
-                     * rrd.rra_def[i].row_cnt
-                     * sizeof(rrd_value_t));
+    rra_base = rrd_file->header_len;
+    for (i = 0; i < chosen_rra; i++)
+        rra_base += (*ds_cnt * rrd.rra_def[i].row_cnt * sizeof(rrd_value_t));
 
     /* find start and end offset */
-    rra_end_time = (rrd.live_head->last_up 
-                   - (rrd.live_head->last_up % *step));
+    rra_end_time = (rrd.live_head->last_up
+                    - (rrd.live_head->last_up % *step));
     rra_start_time = (rra_end_time
-                - ( *step * (rrd.rra_def[chosen_rra].row_cnt-1)));
+                      - (*step * (rrd.rra_def[chosen_rra].row_cnt - 1)));
     /* here's an error by one if we don't be careful */
-    start_offset =(long)(*start + *step - rra_start_time) / (long)*step;
-    end_offset = (long)(rra_end_time - *end ) / (long)*step; 
+    start_offset = (long) (*start + *step - rra_start_time) / (long) *step;
+    end_offset = (long) (rra_end_time - *end) / (long) *step;
 #ifdef DEBUG
-    fprintf(stderr,"rra_start %lu, rra_end %lu, start_off %li, end_off %li\n",
-           rra_start_time,rra_end_time,start_offset,end_offset);
+    fprintf(stderr,
+            "rra_start %lu, rra_end %lu, start_off %li, end_off %li\n",
+            rra_start_time, rra_end_time, start_offset, end_offset);
 #endif
 
     /* fill the gap at the start if needs be */
 
     if (start_offset <= 0)
-       rra_pointer = rrd.rra_ptr[chosen_rra].cur_row+1;
-    else 
-       rra_pointer = rrd.rra_ptr[chosen_rra].cur_row+1+start_offset;
-    
-    if(fseek(in_file,(rra_base 
-                  + (rra_pointer
-                     * *ds_cnt
-                     * sizeof(rrd_value_t))),SEEK_SET) != 0){
-       rrd_set_error("seek error in RRA");
-       for (i=0;(unsigned)i<*ds_cnt;i++)
-             free((*ds_namv)[i]);
-       free(*ds_namv);
-       rrd_free(&rrd);
-       free(*data);
-       *data = NULL;
-       fclose(in_file);
-       return(-1);
-
+        rra_pointer = rrd.rra_ptr[chosen_rra].cur_row + 1;
+    else
+        rra_pointer = rrd.rra_ptr[chosen_rra].cur_row + 1 + start_offset;
+
+    if (rrd_seek(rrd_file, (rra_base + (rra_pointer * (*ds_cnt)
+                                        * sizeof(rrd_value_t))),
+                 SEEK_SET) != 0) {
+        rrd_set_error("seek error in RRA");
+        goto err_free_data;
     }
 #ifdef DEBUG
-    fprintf(stderr,"First Seek: rra_base %lu rra_pointer %lu\n",
-           rra_base, rra_pointer);
+    fprintf(stderr, "First Seek: rra_base %lu rra_pointer %lu\n",
+            rra_base, rra_pointer);
 #endif
     /* step trough the array */
 
-    for (i=start_offset;
-        i< (signed)rrd.rra_def[chosen_rra].row_cnt - end_offset;
-        i++){
-       /* no valid data yet */
-       if (i<0) {
+    for (i = start_offset;
+         i < (signed) rrd.rra_def[chosen_rra].row_cnt - end_offset; i++) {
+        /* no valid data yet */
+        if (i < 0) {
 #ifdef DEBUG
-           fprintf(stderr,"pre fetch %li -- ",i);
+            fprintf(stderr, "pre fetch %li -- ", i);
 #endif
-           for(ii=0;(unsigned)ii<*ds_cnt;ii++){
-               *(data_ptr++) = DNAN;
+            for (ii = 0; (unsigned) ii < *ds_cnt; ii++) {
+                *(data_ptr++) = DNAN;
 #ifdef DEBUG
-               fprintf(stderr,"%10.2f ",*(data_ptr-1));
+                fprintf(stderr, "%10.2f ", *(data_ptr - 1));
 #endif
-           }
-       } 
-       /* past the valid data area */
-       else if (i >= (signed)rrd.rra_def[chosen_rra].row_cnt) {
+            }
+        }
+        /* past the valid data area */
+        else if (i >= (signed) rrd.rra_def[chosen_rra].row_cnt) {
 #ifdef DEBUG
-           fprintf(stderr,"post fetch %li -- ",i);
+            fprintf(stderr, "past fetch %li -- ", i);
 #endif
-           for(ii=0;(unsigned)ii<*ds_cnt;ii++){
-               *(data_ptr++) = DNAN;
+            for (ii = 0; (unsigned) ii < *ds_cnt; ii++) {
+                *(data_ptr++) = DNAN;
 #ifdef DEBUG
-               fprintf(stderr,"%10.2f ",*(data_ptr-1));
+                fprintf(stderr, "%10.2f ", *(data_ptr - 1));
 #endif
-           }
-       } else {
-           /* OK we are inside the valid area but the pointer has to 
-            * be wrapped*/
-           if (rra_pointer >= (signed)rrd.rra_def[chosen_rra].row_cnt) {
-               rra_pointer -= rrd.rra_def[chosen_rra].row_cnt;
-               if(fseek(in_file,(rra_base+rra_pointer
-                              * *ds_cnt
-                              * sizeof(rrd_value_t)),SEEK_SET) != 0){
-                   rrd_set_error("wrap seek in RRA did fail");
-                   for (ii=0;(unsigned)ii<*ds_cnt;ii++)
-                       free((*ds_namv)[ii]);
-                   free(*ds_namv);
-                   rrd_free(&rrd);
-                   free(*data);
-                   *data = NULL;
-                   fclose(in_file);
-                   return(-1);
-               }
+            }
+        } else {
+            /* OK we are inside the valid area but the pointer has to 
+             * be wrapped*/
+            if (rra_pointer >= (signed) rrd.rra_def[chosen_rra].row_cnt) {
+                rra_pointer -= rrd.rra_def[chosen_rra].row_cnt;
+                if (rrd_seek(rrd_file, (rra_base + rra_pointer * (*ds_cnt)
+                                        * sizeof(rrd_value_t)),
+                             SEEK_SET) != 0) {
+                    rrd_set_error("wrap seek in RRA did fail");
+                    goto err_free_data;
+                }
 #ifdef DEBUG
-               fprintf(stderr,"wrap seek ...\n");
-#endif     
-           }
-           
-           if(fread(data_ptr,
-                    sizeof(rrd_value_t),
-                    *ds_cnt,in_file) != rrd.stat_head->ds_cnt){
-               rrd_set_error("fetching cdp from rra");
-               for (ii=0;(unsigned)ii<*ds_cnt;ii++)
-                   free((*ds_namv)[ii]);
-               free(*ds_namv);
-               rrd_free(&rrd);
-               free(*data);
-               *data = NULL;
-               fclose(in_file);
-               return(-1);
-           }
+                fprintf(stderr, "wrap seek ...\n");
+#endif
+            }
+
+            if (rrd_read(rrd_file, data_ptr, sizeof(rrd_value_t) * (*ds_cnt))
+                != (ssize_t) (sizeof(rrd_value_t) * (*ds_cnt))) {
+                rrd_set_error("fetching cdp from rra");
+                goto err_free_data;
+            }
 #ifdef DEBUG
-           fprintf(stderr,"post fetch %li -- ",i);
-           for(ii=0;ii<*ds_cnt;ii++)
-               fprintf(stderr,"%10.2f ",*(data_ptr+ii));
+            fprintf(stderr, "post fetch %li -- ", i);
+            for (ii = 0; ii < *ds_cnt; ii++)
+                fprintf(stderr, "%10.2f ", *(data_ptr + ii));
 #endif
-           data_ptr += *ds_cnt;
-           rra_pointer ++;
-       }
+            data_ptr += *ds_cnt;
+            rra_pointer++;
+        }
 #ifdef DEBUG
-           fprintf(stderr,"\n");
-#endif     
-       
+        fprintf(stderr, "\n");
+#endif
+
     }
+
+    rrd_close(rrd_file);
+    return (0);
+  err_free_data:
+    free(*data);
+    *data = NULL;
+  err_free_all_ds_namv:
+    for (i = 0; (unsigned long) i < rrd.stat_head->ds_cnt; ++i)
+        free((*ds_namv)[i]);
+  err_free_ds_namv:
+    free(*ds_namv);
+  err_close:
+    rrd_close(rrd_file);
+  err_free:
     rrd_free(&rrd);
-    fclose(in_file);
-    return(0);
+    return (-1);
 }
index eba83be375d19cdfafcd5ed4e267973756fce1c9..34692e74ec38e011eae3bbf6be71088ff0f5b4b3 100644 (file)
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * RRDtool 1.2.27  Copyright by Tobi Oetiker, 1997-2008
+ * RRDtool 1.3rc4  Copyright by Tobi Oetiker, 1997-2008
  *****************************************************************************
  * rrd_first Return
  *****************************************************************************
@@ -9,92 +9,88 @@
 #include "rrd_tool.h"
 
 
-time_t
-rrd_first(int argc, char **argv)
+time_t rrd_first(
+    int argc,
+    char **argv)
 {
-    int target_rraindex=0;
-    char *endptr;
-    optind = 0; opterr = 0;  /* initialize getopt */
+    int       target_rraindex = 0;
+    char     *endptr;
+    struct option long_options[] = {
+        {"rraindex", required_argument, 0, 129},
+        {0, 0, 0, 0}
+    };
+
+    optind = 0;
+    opterr = 0;         /* initialize getopt */
+
+    while (1) {
+        int       option_index = 0;
+        int       opt;
 
-    while (1){
-        static struct option long_options[] =
-        {
-            {"rraindex", required_argument, 0, 129},
-            {0,0,0,0}
-        };
-        int option_index = 0;
-        int opt;
         opt = getopt_long(argc, argv, "", long_options, &option_index);
 
-        if(opt == EOF)
+        if (opt == EOF)
             break;
 
-        switch(opt) {
-          case 129:
-            target_rraindex=strtol(optarg,&endptr,0);
-            if(target_rraindex < 0) {
+        switch (opt) {
+        case 129:
+            target_rraindex = strtol(optarg, &endptr, 0);
+            if (target_rraindex < 0) {
                 rrd_set_error("invalid rraindex number");
-                return(-1);
+                return (-1);
             }
             break;
-          default:
-            rrd_set_error("usage rrdtool %s [--rraindex number] file.rrd", argv[0]);
-            return(-1);
+        default:
+            rrd_set_error("usage rrdtool %s [--rraindex number] file.rrd",
+                          argv[0]);
+            return (-1);
         }
     }
 
-    if(optind >= argc){
+    if (optind >= argc) {
         rrd_set_error("not enough arguments");
-        return -1;       
-    }     
+        return -1;
+    }
 
-    return(rrd_first_r(argv[optind], target_rraindex));
+    return (rrd_first_r(argv[optind], target_rraindex));
 }
 
 
-time_t
-rrd_first_r(const char *filename, const int rraindex)
+time_t rrd_first_r(
+    const char *filename,
+    const int rraindex)
 {
-    long rra_start,
-         timer;
-    time_t then;
-    FILE *in_file;
-    rrd_t rrd;
-
-    if(rrd_open(filename,&in_file,&rrd, RRD_READONLY)==-1){
-        rrd_set_error("could not open RRD");
-        return(-1);
+    off_t     rra_start, timer;
+    time_t    then = -1;
+    rrd_t     rrd;
+    rrd_file_t *rrd_file;
+
+    rrd_file = rrd_open(filename, &rrd, RRD_READONLY);
+    if (rrd_file == NULL) {
+        goto err_free;
     }
 
-    if((rraindex < 0) || (rraindex >= (int)rrd.stat_head->rra_cnt)) {
+    if ((rraindex < 0) || (rraindex >= (int) rrd.stat_head->rra_cnt)) {
         rrd_set_error("invalid rraindex number");
-        rrd_free(&rrd);
-        fclose(in_file);
-        return(-1);
+        goto err_close;
     }
 
-    rra_start = ftell(in_file);    
-    fseek(in_file,
-          (rra_start +
-           (rrd.rra_ptr[rraindex].cur_row+1) *
-           rrd.stat_head->ds_cnt *
-           sizeof(rrd_value_t)),
-          SEEK_SET);
-    timer = - (rrd.rra_def[rraindex].row_cnt-1);
+    rra_start = rrd_file->header_len;
+    rrd_seek(rrd_file,
+             (rra_start +
+              (rrd.rra_ptr[rraindex].cur_row + 1) *
+              rrd.stat_head->ds_cnt * sizeof(rrd_value_t)), SEEK_SET);
+    timer = -(rrd.rra_def[rraindex].row_cnt - 1);
     if (rrd.rra_ptr[rraindex].cur_row + 1 > rrd.rra_def[rraindex].row_cnt) {
-      fseek(in_file,rra_start,SEEK_SET);
+        rrd_seek(rrd_file, rra_start, SEEK_SET);
     }
     then = (rrd.live_head->last_up -
             rrd.live_head->last_up %
-            (rrd.rra_def[rraindex].pdp_cnt*rrd.stat_head->pdp_step)) +
-           (timer * 
-            rrd.rra_def[rraindex].pdp_cnt*rrd.stat_head->pdp_step);
-
+            (rrd.rra_def[rraindex].pdp_cnt * rrd.stat_head->pdp_step)) +
+        (timer * rrd.rra_def[rraindex].pdp_cnt * rrd.stat_head->pdp_step);
+  err_close:
+    rrd_close(rrd_file);
+  err_free:
     rrd_free(&rrd);
-    fclose(in_file);
-    return(then);
+    return (then);
 }
-
-
-
-
index b7ca3a1eba756e03af4af6ac2fd3cba05d15a2d4..02abef43e761a3ada52c5a6b4ab070c9962b38e3 100644 (file)
@@ -1,9 +1,9 @@
 /*****************************************************************************
- * RRDtool 1.2.27  Copyright by Tobi Oetiker, 1997-2008
+ * RRDtool 1.3rc4  Copyright by Tobi Oetiker, 1997-2008
  *****************************************************************************
  * rrd_format.c  RRD Database Format helper functions
  *****************************************************************************
- * $Id: rrd_format.c 1286 2008-02-17 10:08:10Z oetiker $
+ * $Id: rrd_format.c 1366 2008-05-18 13:06:44Z oetiker $
  * $Log$
  * Revision 1.5  2004/05/18 18:53:03  oetiker
  * big spell checking patch -- slif@bellsouth.net
    if (strcmp(#VV, string) == 0) return VVV;
 
 /* conversion functions to allow symbolic entry of enumerations */
-enum dst_en dst_conv(char *string)
+enum dst_en dst_conv(
+    char *string)
 {
-    converter(COUNTER,DST_COUNTER)
-    converter(ABSOLUTE,DST_ABSOLUTE)
-    converter(GAUGE,DST_GAUGE)
-    converter(DERIVE,DST_DERIVE)
-    converter(COMPUTE,DST_CDEF)
-    rrd_set_error("unknown data acquisition function '%s'",string);
-    return(-1);
+    converter(COUNTER, DST_COUNTER)
+        converter(ABSOLUTE, DST_ABSOLUTE)
+        converter(GAUGE, DST_GAUGE)
+        converter(DERIVE, DST_DERIVE)
+        converter(COMPUTE, DST_CDEF)
+        rrd_set_error("unknown data acquisition function '%s'", string);
+    return (-1);
 }
 
 
-enum cf_en cf_conv(const char *string)
+enum cf_en cf_conv(
+    const char *string)
 {
 
-    converter(AVERAGE,CF_AVERAGE)
-    converter(MIN,CF_MINIMUM)
-    converter(MAX,CF_MAXIMUM)
-    converter(LAST,CF_LAST)
-    converter(HWPREDICT,CF_HWPREDICT)
-    converter(DEVPREDICT,CF_DEVPREDICT)
-    converter(SEASONAL,CF_SEASONAL)
-    converter(DEVSEASONAL,CF_DEVSEASONAL)
-    converter(FAILURES,CF_FAILURES)
-    rrd_set_error("unknown consolidation function '%s'",string);
-    return(-1);
+    converter(AVERAGE, CF_AVERAGE)
+        converter(MIN, CF_MINIMUM)
+        converter(MAX, CF_MAXIMUM)
+        converter(LAST, CF_LAST)
+        converter(HWPREDICT, CF_HWPREDICT)
+        converter(MHWPREDICT, CF_MHWPREDICT)
+        converter(DEVPREDICT, CF_DEVPREDICT)
+        converter(SEASONAL, CF_SEASONAL)
+        converter(DEVSEASONAL, CF_DEVSEASONAL)
+        converter(FAILURES, CF_FAILURES)
+        rrd_set_error("unknown consolidation function '%s'", string);
+    return (-1);
 }
 
-#undef converter       
+#undef converter
 
-long
-ds_match(rrd_t *rrd,char *ds_nam){
+long ds_match(
+    rrd_t *rrd,
+    char *ds_nam)
+{
     unsigned long i;
-    for(i=0;i<rrd->stat_head->ds_cnt;i++)
-       if ((strcmp(ds_nam,rrd->ds_def[i].ds_nam))==0)
-           return i;
-    rrd_set_error("unknown data source name '%s'",ds_nam);
+
+    for (i = 0; i < rrd->stat_head->ds_cnt; i++)
+        if ((strcmp(ds_nam, rrd->ds_def[i].ds_nam)) == 0)
+            return i;
+    rrd_set_error("unknown data source name '%s'", ds_nam);
     return -1;
 }
index b8c8a81c9968da0603b3556c4b9937e72db5c3ee..9deb5abf1f862f632505af1389047f6f5e46ba7d 100644 (file)
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * RRDtool 1.2.27  Copyright by Tobi Oetiker, 1997-2008
+ * RRDtool 1.3rc4  Copyright by Tobi Oetiker, 1997-2008
  *****************************************************************************
  * rrd_format.h  RRD Database Format header
  *****************************************************************************/
 #define RRD_COOKIE    "RRD"
 /* #define RRD_VERSION   "0002" */
 /* changed because microsecond precision requires another field */
-#define RRD_VERSION   "0003"
+#define RRD_VERSION   "0004"
+#define RRD_VERSION3  "0003"
 #define FLOAT_COOKIE  8.642135E130
 
-#include "rrd_nan_inf.h"
-
-typedef union unival { 
-    unsigned long u_cnt; 
-    rrd_value_t   u_val;
+typedef union unival {
+    unsigned long u_cnt;
+    rrd_value_t u_val;
 } unival;
 
 
@@ -101,21 +100,21 @@ typedef union unival {
 
 typedef struct stat_head_t {
 
-    /* Data Base Identification Section ***/
-    char             cookie[4];          /* RRD */
-    char             version[5];         /* version of the format */
-    double           float_cookie;       /* is it the correct double
-                                         * representation ?  */
-
-    /* Data Base Structure Definition *****/
-    unsigned long    ds_cnt;             /* how many different ds provide
-                                         * input to the rrd */
-    unsigned long    rra_cnt;            /* how many rras will be maintained
-                                         * in the rrd */
-    unsigned long    pdp_step;           /* pdp interval in seconds */
-
-    unival           par[10];            /* global parameters ... unused
-                                           at the moment */
+    /* Data Base Identification Section ** */
+    char      cookie[4];    /* RRD */
+    char      version[5];   /* version of the format */
+    double    float_cookie; /* is it the correct double
+                             * representation ?  */
+
+    /* Data Base Structure Definition **** */
+    unsigned long ds_cnt;   /* how many different ds provide
+                             * input to the rrd */
+    unsigned long rra_cnt;  /* how many rras will be maintained
+                             * in the rrd */
+    unsigned long pdp_step; /* pdp interval in seconds */
+
+    unival    par[10];  /* global parameters ... unused
+                           at the moment */
 } stat_head_t;
 
 
@@ -123,24 +122,26 @@ typedef struct stat_head_t {
  * POS 2: ds_def_t  (* ds_cnt)                        Data Source definitions
  ****************************************************************************/
 
-enum dst_en          { DST_COUNTER=0,     /* data source types available */
-                       DST_ABSOLUTE, 
-                       DST_GAUGE,
-                       DST_DERIVE,
-                                          DST_CDEF};
-
-enum ds_param_en {   DS_mrhb_cnt=0,       /* minimum required heartbeat. A
-                                          * data source must provide input at
-                                          * least every ds_mrhb seconds,
-                                          * otherwise it is regarded dead and
-                                          * will be set to UNKNOWN */             
-                    DS_min_val,          /* the processed input of a ds must */
-                     DS_max_val,      /* be between max_val and min_val
-                                          * both can be set to UNKNOWN if you
-                                          * do not care. Data outside the limits
-                                          * set to UNKNOWN */
-                     DS_cdef = DS_mrhb_cnt}; /* pointer to encoded rpn
-                                          * expression only applies to DST_CDEF */
+enum dst_en { DST_COUNTER = 0,  /* data source types available */
+    DST_ABSOLUTE,
+    DST_GAUGE,
+    DST_DERIVE,
+    DST_CDEF
+};
+
+enum ds_param_en { DS_mrhb_cnt = 0, /* minimum required heartbeat. A
+                                     * data source must provide input at
+                                     * least every ds_mrhb seconds,
+                                     * otherwise it is regarded dead and
+                                     * will be set to UNKNOWN */
+    DS_min_val,         /* the processed input of a ds must */
+    DS_max_val,         /* be between max_val and min_val
+                         * both can be set to UNKNOWN if you
+                         * do not care. Data outside the limits
+                         * set to UNKNOWN */
+    DS_cdef = DS_mrhb_cnt
+};                      /* pointer to encoded rpn
+                         * expression only applies to DST_CDEF */
 
 /* The magic number here is one less than DS_NAM_SIZE */
 #define DS_NAM_FMT    "%19[a-zA-Z0-9_-]"
@@ -150,89 +151,106 @@ enum ds_param_en {   DS_mrhb_cnt=0,       /* minimum required heartbeat. A
 #define DST_SIZE   20
 
 typedef struct ds_def_t {
-    char             ds_nam[DS_NAM_SIZE]; /* Name of the data source (null terminated)*/
-    char             dst[DST_SIZE];       /* Type of data source (null terminated)*/
-    unival           par[10];             /* index of this array see ds_param_en */
+    char      ds_nam[DS_NAM_SIZE];  /* Name of the data source (null terminated) */
+    char      dst[DST_SIZE];    /* Type of data source (null terminated) */
+    unival    par[10];  /* index of this array see ds_param_en */
 } ds_def_t;
 
 /****************************************************************************
  * POS 3: rra_def_t ( *  rra_cnt)         one for each store to be maintained
  ****************************************************************************/
-enum cf_en           { CF_AVERAGE=0,     /* data consolidation functions */ 
-                       CF_MINIMUM, 
-                       CF_MAXIMUM,
-                       CF_LAST,
-                      CF_HWPREDICT, 
-                                          /* An array of predictions using the seasonal 
-                                               * Holt-Winters algorithm. Requires an RRA of type
-                                               * CF_SEASONAL for this data source. */
-                                          CF_SEASONAL,
-                                          /* An array of seasonal effects. Requires an RRA of
-                                               * type CF_HWPREDICT for this data source. */
-                                          CF_DEVPREDICT,
-                                          /* An array of deviation predictions based upon
-                                               * smoothed seasonal deviations. Requires an RRA of
-                                               * type CF_DEVSEASONAL for this data source. */
-                                          CF_DEVSEASONAL,
-                                          /* An array of smoothed seasonal deviations. Requires
-                                               * an RRA of type CF_HWPREDICT for this data source.
-                                               * */
-                                          CF_FAILURES};
-                                          /* A binary array of failure indicators: 1 indicates
-                                               * that the number of violations in the prescribed
-                                               * window exceeded the prescribed threshold. */
+enum cf_en { CF_AVERAGE = 0,    /* data consolidation functions */
+    CF_MINIMUM,
+    CF_MAXIMUM,
+    CF_LAST,
+    CF_HWPREDICT,
+    /* An array of predictions using the seasonal 
+     * Holt-Winters algorithm. Requires an RRA of type
+     * CF_SEASONAL for this data source. */
+    CF_SEASONAL,
+    /* An array of seasonal effects. Requires an RRA of
+     * type CF_HWPREDICT for this data source. */
+    CF_DEVPREDICT,
+    /* An array of deviation predictions based upon
+     * smoothed seasonal deviations. Requires an RRA of
+     * type CF_DEVSEASONAL for this data source. */
+    CF_DEVSEASONAL,
+    /* An array of smoothed seasonal deviations. Requires
+     * an RRA of type CF_HWPREDICT for this data source.
+     * */
+    CF_FAILURES,
+    /* HWPREDICT that follows a moving baseline */
+    CF_MHWPREDICT
+        /* new entries must come last !!! */
+};
+
+                       /* A binary array of failure indicators: 1 indicates
+                        * that the number of violations in the prescribed
+                        * window exceeded the prescribed threshold. */
 
 #define MAX_RRA_PAR_EN 10
-enum rra_par_en {   RRA_cdp_xff_val=0,  /* what part of the consolidated
-                     * datapoint must be known, to produce a
-                                        * valid entry in the rra */
-                                       RRA_hw_alpha,
-                                       /* exponential smoothing parameter for the intercept in
-                                        * the Holt-Winters prediction algorithm. */
-                                       RRA_hw_beta,
-                                       /* exponential smoothing parameter for the slope in
-                                        * the Holt-Winters prediction algorithm. */
-                                       RRA_dependent_rra_idx,
-                                       /* For CF_HWPREDICT: index of the RRA with the seasonal 
-                                        * effects of the Holt-Winters algorithm (of type
-                                        * CF_SEASONAL).
-                                        * For CF_DEVPREDICT: index of the RRA with the seasonal
-                                        * deviation predictions (of type CF_DEVSEASONAL).
-                                        * For CF_SEASONAL: index of the RRA with the Holt-Winters
-                                        * intercept and slope coefficient (of type CF_HWPREDICT).
-                                        * For CF_DEVSEASONAL: index of the RRA with the 
-                                        * Holt-Winters prediction (of type CF_HWPREDICT).
-                                        * For CF_FAILURES: index of the CF_DEVSEASONAL array.
-                                        * */
-                                       RRA_seasonal_smooth_idx,
-                                       /* For CF_SEASONAL and CF_DEVSEASONAL:
-                                        * an integer between 0 and row_count - 1 which
-                                        * is index in the seasonal cycle for applying
-                                        * the period smoother. */
-                                   RRA_failure_threshold,
-                                       /* For CF_FAILURES, number of violations within the last
-                                        * window required to mark a failure. */
-                    RRA_seasonal_gamma = RRA_hw_alpha,
-                                       /* exponential smoothing parameter for seasonal effects.
-                                        * */
-                    RRA_delta_pos = RRA_hw_alpha,
-                    RRA_delta_neg = RRA_hw_beta,
-                                       /* confidence bound scaling parameters for the
-                                        * the FAILURES RRA. */
-                    RRA_window_len = RRA_seasonal_smooth_idx};
-                                       /* For CF_FAILURES, the length of the window for measuring
-                                        * failures. */
-                       
+enum rra_par_en { RRA_cdp_xff_val = 0,  /* what part of the consolidated
+                                         * datapoint must be known, to produce a
+                                         * valid entry in the rra */
+    /* CF_HWPREDICT: */
+    RRA_hw_alpha = 1,
+    /* exponential smoothing parameter for the intercept in
+     * the Holt-Winters prediction algorithm. */
+    RRA_hw_beta = 2,
+    /* exponential smoothing parameter for the slope in
+     * the Holt-Winters prediction algorithm. */
+
+    RRA_dependent_rra_idx = 3,
+    /* For CF_HWPREDICT: index of the RRA with the seasonal 
+     * effects of the Holt-Winters algorithm (of type
+     * CF_SEASONAL).
+     * For CF_DEVPREDICT: index of the RRA with the seasonal
+     * deviation predictions (of type CF_DEVSEASONAL).
+     * For CF_SEASONAL: index of the RRA with the Holt-Winters
+     * intercept and slope coefficient (of type CF_HWPREDICT).
+     * For CF_DEVSEASONAL: index of the RRA with the 
+     * Holt-Winters prediction (of type CF_HWPREDICT).
+     * For CF_FAILURES: index of the CF_DEVSEASONAL array.
+     * */
+
+    /* CF_SEASONAL and CF_DEVSEASONAL: */
+    RRA_seasonal_gamma = 1,
+    /* exponential smoothing parameter for seasonal effects. */
+
+    RRA_seasonal_smoothing_window = 2,
+    /* fraction of the season to include in the running average
+     * smoother */
+
+    /* RRA_dependent_rra_idx = 3, */
+
+    RRA_seasonal_smooth_idx = 4,
+    /* an integer between 0 and row_count - 1 which
+     * is index in the seasonal cycle for applying
+     * the period smoother. */
+
+    /* CF_FAILURES: */
+    RRA_delta_pos = 1,  /* confidence bound scaling parameters */
+    RRA_delta_neg = 2,
+    /* RRA_dependent_rra_idx = 3, */
+    RRA_window_len = 4,
+    RRA_failure_threshold = 5,
+    /* For CF_FAILURES, number of violations within the last
+     * window required to mark a failure. */
+};
+
+                    /* For CF_FAILURES, the length of the window for measuring
+                     * failures. */
+
 #define CF_NAM_FMT    "%19[A-Z]"
 #define CF_NAM_SIZE   20
 
 typedef struct rra_def_t {
-    char             cf_nam[CF_NAM_SIZE];/* consolidation function (null term) */
-    unsigned long    row_cnt;            /* number of entries in the store */
-    unsigned long    pdp_cnt;            /* how many primary data points are
-                                         * required for a consolidated data
-                                         * point?*/
-    unival           par[MAX_RRA_PAR_EN];            /* index see rra_param_en */
+    char      cf_nam[CF_NAM_SIZE];  /* consolidation function (null term) */
+    unsigned long row_cnt;  /* number of entries in the store */
+    unsigned long pdp_cnt;  /* how many primary data points are
+                             * required for a consolidated data
+                             * point?*/
+    unival    par[MAX_RRA_PAR_EN];  /* index see rra_param_en */
 
 } rra_def_t;
 
@@ -249,30 +267,31 @@ typedef struct rra_def_t {
  ****************************************************************************/
 
 typedef struct live_head_t {
-    time_t           last_up;            /* when was rrd last updated */
-    long            last_up_usec;       /* micro seconds part of the
-                                           update timestamp. Always >= 0 */
+    time_t    last_up;  /* when was rrd last updated */
+    long      last_up_usec; /* micro seconds part of the
+                               update timestamp. Always >= 0 */
 } live_head_t;
 
 
 /****************************************************************************
  * POS 5: pdp_prep_t  (* ds_cnt)                     here we prepare the pdps 
  ****************************************************************************/
-#define LAST_DS_LEN 30 /* DO NOT CHANGE THIS ... */
-
-enum pdp_par_en {   PDP_unkn_sec_cnt=0,  /* how many seconds of the current
-                                         * pdp value is unknown data? */
-
-                   PDP_val};            /* current value of the pdp.
-                                           this depends on dst */
-
-typedef struct pdp_prep_t{    
-    char last_ds[LAST_DS_LEN];           /* the last reading from the data
-                                         * source.  this is stored in ASCII
-                                         * to cater for very large counters
-                                         * we might encounter in connection
-                                         * with SNMP. */
-    unival          scratch[10];         /* contents according to pdp_par_en */
+#define LAST_DS_LEN 30  /* DO NOT CHANGE THIS ... */
+
+enum pdp_par_en { PDP_unkn_sec_cnt = 0, /* how many seconds of the current
+                                         * pdp value is unknown data? */
+
+    PDP_val
+};                      /* current value of the pdp.
+                           this depends on dst */
+
+typedef struct pdp_prep_t {
+    char      last_ds[LAST_DS_LEN]; /* the last reading from the data
+                                     * source.  this is stored in ASCII
+                                     * to cater for very large counters
+                                     * we might encounter in connection
+                                     * with SNMP. */
+    unival    scratch[10];  /* contents according to pdp_par_en */
 } pdp_prep_t;
 
 /* data is passed from pdp to cdp when seconds since epoch modulo pdp_step == 0
@@ -291,56 +310,58 @@ typedef struct pdp_prep_t{
  * POS 6: cdp_prep_t (* rra_cnt * ds_cnt )      data prep area for cdp values
  ****************************************************************************/
 #define MAX_CDP_PAR_EN 10
-#define MAX_CDP_FAILURES_IDX 8 
+#define MAX_CDP_FAILURES_IDX 8
 /* max CDP scratch entries avail to record violations for a FAILURES RRA */
 #define MAX_FAILURES_WINDOW_LEN 28
-enum cdp_par_en {  CDP_val=0,          
-                   /* the base_interval is always an
-                                       * average */
-                          CDP_unkn_pdp_cnt,       
-                                  /* how many unknown pdp were
-                           * integrated. This and the cdp_xff
-                                       * will decide if this is going to
-                                       * be a UNKNOWN or a valid value */
-                                  CDP_hw_intercept,
-                                  /* Current intercept coefficient for the Holt-Winters
-                                       * prediction algorithm. */
-                                  CDP_hw_last_intercept,
-                                  /* Last iteration intercept coefficient for the Holt-Winters
-                                       * prediction algorihtm. */
-                                  CDP_hw_slope,
-                                  /* Current slope coefficient for the Holt-Winters
-                                       * prediction algorithm. */
-                                  CDP_hw_last_slope,
-                                  /* Last iteration slope coeffient. */
-                                  CDP_null_count,
-                                  /* Number of sequential Unknown (DNAN) values + 1 preceding
-                                   * the current prediction.
-                                       * */
-                                  CDP_last_null_count,
-                                  /* Last iteration count of Unknown (DNAN) values. */
-                                  CDP_primary_val = 8,
-                                  /* optimization for bulk updates: the value of the first CDP
-                                       * value to be written in the bulk update. */
-                                  CDP_secondary_val = 9,
-                                  /* optimization for bulk updates: the value of subsequent
-                                       * CDP values to be written in the bulk update. */
-                   CDP_hw_seasonal = CDP_hw_intercept,
-                   /* Current seasonal coefficient for the Holt-Winters
-                    * prediction algorithm. This is stored in CDP prep to avoid
-                    * redundant seek operations. */
-                   CDP_hw_last_seasonal = CDP_hw_last_intercept,
-                   /* Last iteration seasonal coeffient. */
-                   CDP_seasonal_deviation = CDP_hw_intercept,
-                   CDP_last_seasonal_deviation = CDP_hw_last_intercept,
-                   CDP_init_seasonal = CDP_null_count};
+enum cdp_par_en { CDP_val = 0,
+    /* the base_interval is always an
+     * average */
+    CDP_unkn_pdp_cnt,
+    /* how many unknown pdp were
+     * integrated. This and the cdp_xff
+     * will decide if this is going to
+     * be a UNKNOWN or a valid value */
+    CDP_hw_intercept,
+    /* Current intercept coefficient for the Holt-Winters
+     * prediction algorithm. */
+    CDP_hw_last_intercept,
+    /* Last iteration intercept coefficient for the Holt-Winters
+     * prediction algorihtm. */
+    CDP_hw_slope,
+    /* Current slope coefficient for the Holt-Winters
+     * prediction algorithm. */
+    CDP_hw_last_slope,
+    /* Last iteration slope coeffient. */
+    CDP_null_count,
+    /* Number of sequential Unknown (DNAN) values + 1 preceding
+     * the current prediction.
+     * */
+    CDP_last_null_count,
+    /* Last iteration count of Unknown (DNAN) values. */
+    CDP_primary_val = 8,
+    /* optimization for bulk updates: the value of the first CDP
+     * value to be written in the bulk update. */
+    CDP_secondary_val = 9,
+    /* optimization for bulk updates: the value of subsequent
+     * CDP values to be written in the bulk update. */
+    CDP_hw_seasonal = CDP_hw_intercept,
+    /* Current seasonal coefficient for the Holt-Winters
+     * prediction algorithm. This is stored in CDP prep to avoid
+     * redundant seek operations. */
+    CDP_hw_last_seasonal = CDP_hw_last_intercept,
+    /* Last iteration seasonal coeffient. */
+    CDP_seasonal_deviation = CDP_hw_intercept,
+    CDP_last_seasonal_deviation = CDP_hw_last_intercept,
+    CDP_init_seasonal = CDP_null_count
+};
+
                    /* init_seasonal is a flag which when > 0, forces smoothing updates
                     * to occur when rra_ptr.cur_row == 0 */
 
-typedef struct cdp_prep_t{
-    unival         scratch[MAX_CDP_PAR_EN];          
-                                                                                /* contents according to cdp_par_en *
-                                          * init state should be NAN */
+typedef struct cdp_prep_t {
+    unival    scratch[MAX_CDP_PAR_EN];
+    /* contents according to cdp_par_en *
+     * init state should be NAN */
 
 } cdp_prep_t;
 
@@ -349,7 +370,7 @@ typedef struct cdp_prep_t{
  ****************************************************************************/
 
 typedef struct rra_ptr_t {
-    unsigned long    cur_row;            /* current row in the rra*/
+    unsigned long cur_row;  /* current row in the rra */
 } rra_ptr_t;
 
 
@@ -359,14 +380,14 @@ typedef struct rra_ptr_t {
  ****************************************************************************
  ****************************************************************************/
 typedef struct rrd_t {
-    stat_head_t      *stat_head;          /* the static header */
-    ds_def_t         *ds_def;             /* list of data source definitions */
-    rra_def_t        *rra_def;            /* list of round robin archive def */
-    live_head_t      *live_head;
-    pdp_prep_t       *pdp_prep;           /* pdp data prep area */  
-    cdp_prep_t       *cdp_prep;           /* cdp prep area */
-    rra_ptr_t        *rra_ptr;            /* list of rra pointers */
-    rrd_value_t      *rrd_value;          /* list of rrd values */
+    stat_head_t *stat_head; /* the static header */
+    ds_def_t *ds_def;   /* list of data source definitions */
+    rra_def_t *rra_def; /* list of round robin archive def */
+    live_head_t *live_head;
+    pdp_prep_t *pdp_prep;   /* pdp data prep area */
+    cdp_prep_t *cdp_prep;   /* cdp prep area */
+    rra_ptr_t *rra_ptr; /* list of rra pointers */
+    rrd_value_t *rrd_value; /* list of rrd values */
 } rrd_t;
 
 /****************************************************************************
@@ -392,7 +413,3 @@ typedef struct rrd_t {
 
 
 #endif
-
-
-
-
index b715ab0339d701efce02af16e45b1392e6765aaa..50a61e882ea76d13104285a6b30d9af92adff995 100644 (file)
 #define _NO_PROTO
 #endif
 
-#ifdef HAVE_CONFIG_H
-#include "../rrd_config.h"
-#endif
-
 #if !defined (__STDC__) || !__STDC__
 /* This is a separate conditional since some stdc systems
    reject `defined (const)'.  */
 #endif
 #endif
 
+
+#ifdef HAVE_CONFIG_H
+#include "../rrd_config.h"
+#endif
+
+#include "rrd_i18n.h"
+
+
 #include <stdio.h>
 
 /* Comment out all this code if we are using the GNU C Library, and are not
@@ -70,7 +74,7 @@
    contain conflicting prototypes for getopt.  */
 #include <stdlib.h>
 #include <unistd.h>
-#endif /* GNU C library.  */
+#endif                          /* GNU C library.  */
 
 #ifdef VMS
 #include <unixlib.h>
 #define getpid() GetCurrentProcessId()
 #endif
 
-#ifndef _
-/* This is for other GNU distributions with internationalized messages.
-   When compiling libc, the _ macro is predefined.  */
-#ifdef HAVE_LIBINTL_H
-# include <libintl.h>
-# define _(msgid)      gettext (msgid)
-#else
-# define _(msgid)      (msgid)
-#endif
-#endif
-
 /* This version of `getopt' appears to the caller like standard Unix `getopt'
    but it behaves differently for the user, since it allows the user
    to intersperse the options with the other arguments.
    Also, when `ordering' is RETURN_IN_ORDER,
    each non-option ARGV-element is returned here.  */
 
-char *optarg = NULL;
+char     *optarg = NULL;
 
 /* Index in ARGV of the next element to be scanned.
    This is used for communication to and from the caller
@@ -133,13 +126,13 @@ char *optarg = NULL;
    how much of ARGV has been scanned so far.  */
 
 /* 1003.2 says this must be 1 before any call.  */
-int optind = 1;
+int       optind = 1;
 
 /* Formerly, initialization of getopt depended on optind==0, which
    causes problems with re-calling getopt as programs generally don't
    know that. */
 
-int __getopt_initialized = 0;
+int       __getopt_initialized = 0;
 
 /* The next char to be scanned in the option-element
    in which the last option character we returned was found.
@@ -153,13 +146,13 @@ static char *nextchar;
 /* Callers store zero here to inhibit the error message
    for unrecognized options.  */
 
-int opterr = 1;
+int       opterr = 1;
 
 /* Set to an option character which was unrecognized.
    This must be initialized on some systems to avoid linking in the
    system's own getopt implementation.  */
 
-int optopt = '?';
+int       optopt = '?';
 
 /* Describe how to deal with options that follow non-option ARGV-elements.
 
@@ -190,9 +183,8 @@ int optopt = '?';
    of the value of `ordering'.  In the case of RETURN_IN_ORDER, only
    `--' can cause `getopt' to return -1 with `optind' != ARGC.  */
 
-static enum
-{
-  REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
+static enum {
+    REQUIRE_ORDER, PERMUTE, RETURN_IN_ORDER
 } ordering;
 
 /* Value of POSIXLY_CORRECT environment variable.  */
@@ -212,20 +204,21 @@ static char *posixly_correct;
 /* Avoid depending on library functions or files
    whose names are inconsistent.  */
 
-char *getenv ();
+char     *getenv(
+    );
 
-static char *
-my_index (str, chr)
-     const char *str;
-     int chr;
+static char *my_index(
+    str,
+    chr)
+    const char *str;
+    int chr;
 {
-  while (*str)
-    {
-      if (*str == chr)
-       return (char *) str;
-      str++;
+    while (*str) {
+        if (*str == chr)
+            return (char *) str;
+        str++;
     }
-  return 0;
+    return 0;
 }
 
 /* If using GCC, we can safely declare strlen this way.
@@ -236,11 +229,12 @@ my_index (str, chr)
 #if !defined (__STDC__) || !__STDC__
 /* gcc with -traditional declares the built-in strlen to return int,
    and has done so at least since version 2.4.5. -- rms.  */
-extern int strlen (const char *);
-#endif /* not __STDC__ */
-#endif /* __GNUC__ */
+extern int strlen(
+    const char *);
+#endif                          /* not __STDC__ */
+#endif                          /* __GNUC__ */
 
-#endif /* not __GNU_LIBRARY__ */
+#endif                          /* not __GNU_LIBRARY__ */
 \f
 /* Handle permutation of arguments.  */
 
@@ -264,16 +258,20 @@ static char *const *original_argv;
 /* Make sure the environment variable bash 2.0 puts in the environment
    is valid for the getopt call we must make sure that the ARGV passed
    to getopt is that one passed to the process.  */
-static void store_args (int argc, char *const *argv) __attribute__ ((unused));
-static void
-store_args (int argc, char *const *argv)
+static void store_args(
+    int argc,
+    char *const *argv) __attribute__ ((unused));
+static void store_args(
+    int argc,
+    char *const *argv)
 {
-  /* XXX This is no good solution.  We should rather copy the args so
-     that we can compare them later.  But we must not use malloc(3).  */
-  original_argc = argc;
-  original_argv = argv;
+    /* XXX This is no good solution.  We should rather copy the args so
+       that we can compare them later.  But we must not use malloc(3).  */
+    original_argc = argc;
+    original_argv = argv;
 }
-text_set_element (__libc_subinit, store_args);
+
+text_set_element(__libc_subinit, store_args);
 #endif
 
 /* Exchange two adjacent subsequences of ARGV.
@@ -286,124 +284,119 @@ text_set_element (__libc_subinit, store_args);
    the new indices of the non-options in ARGV after they are moved.  */
 
 #if defined (__STDC__) && __STDC__
-static void exchange (char **);
+static void exchange(
+    char **);
 #endif
 
-static void
-exchange (argv)
-     char **argv;
+static void exchange(
+    argv)
+    char    **argv;
 {
-  int bottom = first_nonopt;
-  int middle = last_nonopt;
-  int top = optind;
-  char *tem;
-
-  /* Exchange the shorter segment with the far end of the longer segment.
-     That puts the shorter segment into the right place.
-     It leaves the longer segment in the right place overall,
-     but it consists of two parts that need to be swapped next.  */
-
-  while (top > middle && middle > bottom)
-    {
-      if (top - middle > middle - bottom)
-       {
-         /* Bottom segment is the short one.  */
-         int len = middle - bottom;
-         register int i;
-
-         /* Swap it with the top part of the top segment.  */
-         for (i = 0; i < len; i++)
-           {
-             tem = argv[bottom + i];
-             argv[bottom + i] = argv[top - (middle - bottom) + i];
-             argv[top - (middle - bottom) + i] = tem;
-           }
-         /* Exclude the moved bottom segment from further swapping.  */
-         top -= len;
-       }
-      else
-       {
-         /* Top segment is the short one.  */
-         int len = top - middle;
-         register int i;
-
-         /* Swap it with the bottom part of the bottom segment.  */
-         for (i = 0; i < len; i++)
-           {
-             tem = argv[bottom + i];
-             argv[bottom + i] = argv[middle + i];
-             argv[middle + i] = tem;
-           }
-         /* Exclude the moved top segment from further swapping.  */
-         bottom += len;
-       }
+    int       bottom = first_nonopt;
+    int       middle = last_nonopt;
+    int       top = optind;
+    char     *tem;
+
+    /* Exchange the shorter segment with the far end of the longer segment.
+       That puts the shorter segment into the right place.
+       It leaves the longer segment in the right place overall,
+       but it consists of two parts that need to be swapped next.  */
+
+    while (top > middle && middle > bottom) {
+        if (top - middle > middle - bottom) {
+            /* Bottom segment is the short one.  */
+            int       len = middle - bottom;
+            register int i;
+
+            /* Swap it with the top part of the top segment.  */
+            for (i = 0; i < len; i++) {
+                tem = argv[bottom + i];
+                argv[bottom + i] = argv[top - (middle - bottom) + i];
+                argv[top - (middle - bottom) + i] = tem;
+            }
+            /* Exclude the moved bottom segment from further swapping.  */
+            top -= len;
+        } else {
+            /* Top segment is the short one.  */
+            int       len = top - middle;
+            register int i;
+
+            /* Swap it with the bottom part of the bottom segment.  */
+            for (i = 0; i < len; i++) {
+                tem = argv[bottom + i];
+                argv[bottom + i] = argv[middle + i];
+                argv[middle + i] = tem;
+            }
+            /* Exclude the moved top segment from further swapping.  */
+            bottom += len;
+        }
     }
 
-  /* Update records for the slots the non-options now occupy.  */
+    /* Update records for the slots the non-options now occupy.  */
 
-  first_nonopt += (optind - last_nonopt);
-  last_nonopt = optind;
+    first_nonopt += (optind - last_nonopt);
+    last_nonopt = optind;
 }
 
 /* Initialize the internal data when the first call is made.  */
 
 #if defined (__STDC__) && __STDC__
-static const char *_getopt_initialize (int, char *const *, const char *);
+static const char *_getopt_initialize(
+    int,
+    char *const *,
+    const char *);
 #endif
-static const char *
-_getopt_initialize (argc, argv, optstring)
-     int argc;
-     char *const *argv;
-     const char *optstring;
+static const char *_getopt_initialize(
+    argc,
+    argv,
+    optstring)
+    int argc;
+    char     *const *argv;
+    const char *optstring;
 {
-  /* Start processing options with ARGV-element 1 (since ARGV-element 0
-     is the program name); the sequence of previously skipped
-     non-option ARGV-elements is empty.  */
+    /* Start processing options with ARGV-element 1 (since ARGV-element 0
+       is the program name); the sequence of previously skipped
+       non-option ARGV-elements is empty.  */
 
-  first_nonopt = last_nonopt = optind = 1;
+    first_nonopt = last_nonopt = optind = 1;
 
-  nextchar = NULL;
+    nextchar = NULL;
 
-  posixly_correct = getenv ("POSIXLY_CORRECT");
+    posixly_correct = getenv("POSIXLY_CORRECT");
 
-  /* Determine how to handle the ordering of options and nonoptions.  */
+    /* Determine how to handle the ordering of options and nonoptions.  */
 
-  if (optstring[0] == '-')
-    {
-      ordering = RETURN_IN_ORDER;
-      ++optstring;
-    }
-  else if (optstring[0] == '+')
-    {
-      ordering = REQUIRE_ORDER;
-      ++optstring;
-    }
-  else if (posixly_correct != NULL)
-    ordering = REQUIRE_ORDER;
-  else
-    ordering = PERMUTE;
+    if (optstring[0] == '-') {
+        ordering = RETURN_IN_ORDER;
+        ++optstring;
+    } else if (optstring[0] == '+') {
+        ordering = REQUIRE_ORDER;
+        ++optstring;
+    } else if (posixly_correct != NULL)
+        ordering = REQUIRE_ORDER;
+    else
+        ordering = PERMUTE;
 
 #ifdef _LIBC
-  if (posixly_correct == NULL
-      && argc == original_argc && argv == original_argv)
-    {
-      /* Bash 2.0 puts a special variable in the environment for each
-        command it runs, specifying which ARGV elements are the results of
-        file name wildcard expansion and therefore should not be
-        considered as options.  */
-      char var[100];
-      sprintf (var, "_%d_GNU_nonoption_argv_flags_", getpid ());
-      nonoption_flags = getenv (var);
-      if (nonoption_flags == NULL)
-       nonoption_flags_len = 0;
-      else
-       nonoption_flags_len = strlen (nonoption_flags);
-    }
-  else
-    nonoption_flags_len = 0;
+    if (posixly_correct == NULL
+        && argc == original_argc && argv == original_argv) {
+        /* Bash 2.0 puts a special variable in the environment for each
+           command it runs, specifying which ARGV elements are the results of
+           file name wildcard expansion and therefore should not be
+           considered as options.  */
+        char      var[100];
+
+        sprintf(var, "_%d_GNU_nonoption_argv_flags_", getpid());
+        nonoption_flags = getenv(var);
+        if (nonoption_flags == NULL)
+            nonoption_flags_len = 0;
+        else
+            nonoption_flags_len = strlen(nonoption_flags);
+    } else
+        nonoption_flags_len = 0;
 #endif
 
-  return optstring;
+    return optstring;
 }
 \f
 /* Scan elements of ARGV (whose length is ARGC) for option characters
@@ -462,28 +455,32 @@ _getopt_initialize (argc, argv, optstring)
    If LONG_ONLY is nonzero, '-' as well as '--' can introduce
    long-named options.  */
 
-int
-_getopt_internal (argc, argv, optstring, longopts, longind, long_only)
-     int argc;
-     char *const *argv;
-     const char *optstring;
-     const struct option *longopts;
-     int *longind;
-     int long_only;
+int _getopt_internal(
+    argc,
+    argv,
+    optstring,
+    longopts,
+    longind,
+    long_only)
+    int argc;
+    char     *const *argv;
+    const char *optstring;
+    const struct option *longopts;
+    int      *longind;
+    int long_only;
 {
-  optarg = NULL;
+    optarg = NULL;
 
-  if (!__getopt_initialized || optind == 0)
-    {
-      optstring = _getopt_initialize (argc, argv, optstring);
-      optind = 1;              /* Don't scan ARGV[0], the program name.  */
-      __getopt_initialized = 1;
+    if (!__getopt_initialized || optind == 0) {
+        optstring = _getopt_initialize(argc, argv, optstring);
+        optind = 1;     /* Don't scan ARGV[0], the program name.  */
+        __getopt_initialized = 1;
     }
 
-  /* Test whether ARGV[optind] points to a non-option argument.
-     Either it does not have option syntax, or there is an environment flag
-     from the shell indicating it is not an option.  The later information
-     is only used when the used in the GNU libc.  */
+    /* Test whether ARGV[optind] points to a non-option argument.
+       Either it does not have option syntax, or there is an environment flag
+       from the shell indicating it is not an option.  The later information
+       is only used when the used in the GNU libc.  */
 #ifdef _LIBC
 #define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0'       \
                     || (optind < nonoption_flags_len                         \
@@ -492,511 +489,464 @@ _getopt_internal (argc, argv, optstring, longopts, longind, long_only)
 #define NONOPTION_P (argv[optind][0] != '-' || argv[optind][1] == '\0')
 #endif
 
-  if (nextchar == NULL || *nextchar == '\0')
-    {
-      /* Advance to the next ARGV-element.  */
-
-      /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been
-        moved back by the user (who may also have changed the arguments).  */
-      if (last_nonopt > optind)
-       last_nonopt = optind;
-      if (first_nonopt > optind)
-       first_nonopt = optind;
-
-      if (ordering == PERMUTE)
-       {
-         /* If we have just processed some options following some non-options,
-            exchange them so that the options come first.  */
-
-         if (first_nonopt != last_nonopt && last_nonopt != optind)
-           exchange ((char **) argv);
-         else if (last_nonopt != optind)
-           first_nonopt = optind;
-
-         /* Skip any additional non-options
-            and extend the range of non-options previously skipped.  */
-
-         while (optind < argc && NONOPTION_P)
-           optind++;
-         last_nonopt = optind;
-       }
-
-      /* The special ARGV-element `--' means premature end of options.
-        Skip it like a null option,
-        then exchange with previous non-options as if it were an option,
-        then skip everything else like a non-option.  */
-
-      if (optind != argc && !strcmp (argv[optind], "--"))
-       {
-         optind++;
-
-         if (first_nonopt != last_nonopt && last_nonopt != optind)
-           exchange ((char **) argv);
-         else if (first_nonopt == last_nonopt)
-           first_nonopt = optind;
-         last_nonopt = argc;
-
-         optind = argc;
-       }
-
-      /* If we have done all the ARGV-elements, stop the scan
-        and back over any non-options that we skipped and permuted.  */
-
-      if (optind == argc)
-       {
-         /* Set the next-arg-index to point at the non-options
-            that we previously skipped, so the caller will digest them.  */
-         if (first_nonopt != last_nonopt)
-           optind = first_nonopt;
-         return -1;
-       }
-
-      /* If we have come to a non-option and did not permute it,
-        either stop the scan or describe it to the caller and pass it by.  */
-
-      if (NONOPTION_P)
-       {
-         if (ordering == REQUIRE_ORDER)
-           return -1;
-         optarg = argv[optind++];
-         return 1;
-       }
-
-      /* We have found another option-ARGV-element.
-        Skip the initial punctuation.  */
-
-      nextchar = (argv[optind] + 1
-                 + (longopts != NULL && argv[optind][1] == '-'));
+    if (nextchar == NULL || *nextchar == '\0') {
+        /* Advance to the next ARGV-element.  */
+
+        /* Give FIRST_NONOPT & LAST_NONOPT rational values if OPTIND has been
+           moved back by the user (who may also have changed the arguments).  */
+        if (last_nonopt > optind)
+            last_nonopt = optind;
+        if (first_nonopt > optind)
+            first_nonopt = optind;
+
+        if (ordering == PERMUTE) {
+            /* If we have just processed some options following some non-options,
+               exchange them so that the options come first.  */
+
+            if (first_nonopt != last_nonopt && last_nonopt != optind)
+                exchange((char **) argv);
+            else if (last_nonopt != optind)
+                first_nonopt = optind;
+
+            /* Skip any additional non-options
+               and extend the range of non-options previously skipped.  */
+
+            while (optind < argc && NONOPTION_P)
+                optind++;
+            last_nonopt = optind;
+        }
+
+        /* The special ARGV-element `--' means premature end of options.
+           Skip it like a null option,
+           then exchange with previous non-options as if it were an option,
+           then skip everything else like a non-option.  */
+
+        if (optind != argc && !strcmp(argv[optind], "--")) {
+            optind++;
+
+            if (first_nonopt != last_nonopt && last_nonopt != optind)
+                exchange((char **) argv);
+            else if (first_nonopt == last_nonopt)
+                first_nonopt = optind;
+            last_nonopt = argc;
+
+            optind = argc;
+        }
+
+        /* If we have done all the ARGV-elements, stop the scan
+           and back over any non-options that we skipped and permuted.  */
+
+        if (optind == argc) {
+            /* Set the next-arg-index to point at the non-options
+               that we previously skipped, so the caller will digest them.  */
+            if (first_nonopt != last_nonopt)
+                optind = first_nonopt;
+            return -1;
+        }
+
+        /* If we have come to a non-option and did not permute it,
+           either stop the scan or describe it to the caller and pass it by.  */
+
+        if (NONOPTION_P) {
+            if (ordering == REQUIRE_ORDER)
+                return -1;
+            optarg = argv[optind++];
+            return 1;
+        }
+
+        /* We have found another option-ARGV-element.
+           Skip the initial punctuation.  */
+
+        nextchar = (argv[optind] + 1
+                    + (longopts != NULL && argv[optind][1] == '-'));
     }
 
-  /* Decode the current option-ARGV-element.  */
-
-  /* Check whether the ARGV-element is a long option.
-
-     If long_only and the ARGV-element has the form "-f", where f is
-     a valid short option, don't consider it an abbreviated form of
-     a long option that starts with f.  Otherwise there would be no
-     way to give the -f short option.
-
-     On the other hand, if there's a long option "fubar" and
-     the ARGV-element is "-fu", do consider that an abbreviation of
-     the long option, just like "--fu", and not "-f" with arg "u".
+    /* Decode the current option-ARGV-element.  */
+
+    /* Check whether the ARGV-element is a long option.
+
+       If long_only and the ARGV-element has the form "-f", where f is
+       a valid short option, don't consider it an abbreviated form of
+       a long option that starts with f.  Otherwise there would be no
+       way to give the -f short option.
+
+       On the other hand, if there's a long option "fubar" and
+       the ARGV-element is "-fu", do consider that an abbreviation of
+       the long option, just like "--fu", and not "-f" with arg "u".
+
+       This distinction seems to be the most useful approach.  */
+
+    if (longopts != NULL
+        && (argv[optind][1] == '-' || (long_only && (argv[optind][2]
+                                                     || !my_index(optstring,
+                                                                  argv[optind]
+                                                                  [1]))))) {
+        char     *nameend;
+        const struct option *p;
+        const struct option *pfound = NULL;
+        int       exact = 0;
+        int       ambig = 0;
+        int       indfound = -1;
+        int       option_index;
+
+        for (nameend = nextchar; *nameend && *nameend != '='; nameend++)
+            /* Do nothing.  */ ;
+
+        /* Test all long options for either exact match
+           or abbreviated matches.  */
+        for (p = longopts, option_index = 0; p->name; p++, option_index++)
+            if (!strncmp(p->name, nextchar, nameend - nextchar)) {
+                if ((unsigned int) (nameend - nextchar)
+                    == (unsigned int) strlen(p->name)) {
+                    /* Exact match found.  */
+                    pfound = p;
+                    indfound = option_index;
+                    exact = 1;
+                    break;
+                } else if (pfound == NULL) {
+                    /* First nonexact match found.  */
+                    pfound = p;
+                    indfound = option_index;
+                } else
+                    /* Second or later nonexact match found.  */
+                    ambig = 1;
+            }
+
+        if (ambig && !exact) {
+            if (opterr)
+                fprintf(stderr, _("%s: option `%s' is ambiguous\n"),
+                        argv[0], argv[optind]);
+            nextchar += strlen(nextchar);
+            optind++;
+            optopt = 0;
+            return '?';
+        }
+
+        if (pfound != NULL) {
+            option_index = indfound;
+            optind++;
+            if (*nameend) {
+                /* Don't test has_arg with >, because some C compilers don't
+                   allow it to be used on enums.  */
+                if (pfound->has_arg)
+                    optarg = nameend + 1;
+                else {
+                    if (opterr) {
+                        if (argv[optind - 1][1] == '-')
+                            /* --option */
+                            fprintf(stderr,
+                                    _
+                                    ("%s: option `--%s' doesn't allow an argument\n"),
+                                    argv[0], pfound->name);
+                        else
+                            /* +option or -option */
+                            fprintf(stderr,
+                                    _
+                                    ("%s: option `%c%s' doesn't allow an argument\n"),
+                                    argv[0], argv[optind - 1][0],
+                                    pfound->name);
+                    }
+                    nextchar += strlen(nextchar);
+
+                    optopt = pfound->val;
+                    return '?';
+                }
+            } else if (pfound->has_arg == 1) {
+                if (optind < argc)
+                    optarg = argv[optind++];
+                else {
+                    if (opterr)
+                        fprintf(stderr,
+                                _("%s: option `%s' requires an argument\n"),
+                                argv[0], argv[optind - 1]);
+                    nextchar += strlen(nextchar);
+                    optopt = pfound->val;
+                    return optstring[0] == ':' ? ':' : '?';
+                }
+            }
+            nextchar += strlen(nextchar);
+            if (longind != NULL)
+                *longind = option_index;
+            if (pfound->flag) {
+                *(pfound->flag) = pfound->val;
+                return 0;
+            }
+            return pfound->val;
+        }
+
+        /* Can't find it as a long option.  If this is not getopt_long_only,
+           or the option starts with '--' or is not a valid short
+           option, then it's an error.
+           Otherwise interpret it as a short option.  */
+        if (!long_only || argv[optind][1] == '-'
+            || my_index(optstring, *nextchar) == NULL) {
+            if (opterr) {
+                if (argv[optind][1] == '-')
+                    /* --option */
+                    fprintf(stderr, _("%s: unrecognized option `--%s'\n"),
+                            argv[0], nextchar);
+                else
+                    /* +option or -option */
+                    fprintf(stderr, _("%s: unrecognized option `%c%s'\n"),
+                            argv[0], argv[optind][0], nextchar);
+            }
+            nextchar = (char *) "";
+            optind++;
+            optopt = 0;
+            return '?';
+        }
+    }
 
-     This distinction seems to be the most useful approach.  */
+    /* Look at and handle the next short option-character.  */
 
-  if (longopts != NULL
-      && (argv[optind][1] == '-'
-         || (long_only && (argv[optind][2] || !my_index (optstring, argv[optind][1])))))
     {
-      char *nameend;
-      const struct option *p;
-      const struct option *pfound = NULL;
-      int exact = 0;
-      int ambig = 0;
-      int indfound = -1;
-      int option_index;
-
-      for (nameend = nextchar; *nameend && *nameend != '='; nameend++)
-       /* Do nothing.  */ ;
-
-      /* Test all long options for either exact match
-        or abbreviated matches.  */
-      for (p = longopts, option_index = 0; p->name; p++, option_index++)
-       if (!strncmp (p->name, nextchar, nameend - nextchar))
-         {
-           if ((unsigned int) (nameend - nextchar)
-               == (unsigned int) strlen (p->name))
-             {
-               /* Exact match found.  */
-               pfound = p;
-               indfound = option_index;
-               exact = 1;
-               break;
-             }
-           else if (pfound == NULL)
-             {
-               /* First nonexact match found.  */
-               pfound = p;
-               indfound = option_index;
-             }
-           else
-             /* Second or later nonexact match found.  */
-             ambig = 1;
-         }
-
-      if (ambig && !exact)
-       {
-         if (opterr)
-           fprintf (stderr, _("%s: option `%s' is ambiguous\n"),
-                    argv[0], argv[optind]);
-         nextchar += strlen (nextchar);
-         optind++;
-         optopt = 0;
-         return '?';
-       }
-
-      if (pfound != NULL)
-       {
-         option_index = indfound;
-         optind++;
-         if (*nameend)
-           {
-             /* Don't test has_arg with >, because some C compilers don't
-                allow it to be used on enums.  */
-             if (pfound->has_arg)
-               optarg = nameend + 1;
-             else
-               {
-                 if (opterr) {
-                  if (argv[optind - 1][1] == '-')
-                   /* --option */
-                   fprintf (stderr,
-                    _("%s: option `--%s' doesn't allow an argument\n"),
-                    argv[0], pfound->name);
-                  else
-                   /* +option or -option */
-                   fprintf (stderr,
-                    _("%s: option `%c%s' doesn't allow an argument\n"),
-                    argv[0], argv[optind - 1][0], pfound->name);
-                 }
-                 nextchar += strlen (nextchar);
-
-                 optopt = pfound->val;
-                 return '?';
-               }
-           }
-         else if (pfound->has_arg == 1)
-           {
-             if (optind < argc)
-               optarg = argv[optind++];
-             else
-               {
-                 if (opterr)
-                   fprintf (stderr,
-                          _("%s: option `%s' requires an argument\n"),
-                          argv[0], argv[optind - 1]);
-                 nextchar += strlen (nextchar);
-                 optopt = pfound->val;
-                 return optstring[0] == ':' ? ':' : '?';
-               }
-           }
-         nextchar += strlen (nextchar);
-         if (longind != NULL)
-           *longind = option_index;
-         if (pfound->flag)
-           {
-             *(pfound->flag) = pfound->val;
-             return 0;
-           }
-         return pfound->val;
-       }
-
-      /* Can't find it as a long option.  If this is not getopt_long_only,
-        or the option starts with '--' or is not a valid short
-        option, then it's an error.
-        Otherwise interpret it as a short option.  */
-      if (!long_only || argv[optind][1] == '-'
-         || my_index (optstring, *nextchar) == NULL)
-       {
-         if (opterr)
-           {
-             if (argv[optind][1] == '-')
-               /* --option */
-               fprintf (stderr, _("%s: unrecognized option `--%s'\n"),
-                        argv[0], nextchar);
-             else
-               /* +option or -option */
-               fprintf (stderr, _("%s: unrecognized option `%c%s'\n"),
-                        argv[0], argv[optind][0], nextchar);
-           }
-         nextchar = (char *) "";
-         optind++;
-         optopt = 0;
-         return '?';
-       }
+        char      c = *nextchar++;
+        char     *temp = my_index(optstring, c);
+
+        /* Increment `optind' when we start to process its last character.  */
+        if (*nextchar == '\0')
+            ++optind;
+
+        if (temp == NULL || c == ':') {
+            if (opterr) {
+                if (posixly_correct)
+                    /* 1003.2 specifies the format of this message.  */
+                    fprintf(stderr, _("%s: illegal option -- %c\n"),
+                            argv[0], c);
+                else
+                    fprintf(stderr, _("%s: invalid option -- %c\n"),
+                            argv[0], c);
+            }
+            optopt = c;
+            return '?';
+        }
+        /* Convenience. Treat POSIX -W foo same as long option --foo */
+        if (temp[0] == 'W' && temp[1] == ';') {
+            char     *nameend;
+            const struct option *p;
+            const struct option *pfound = NULL;
+            int       exact = 0;
+            int       ambig = 0;
+            int       indfound = 0;
+            int       option_index;
+
+            /* This is an option that requires an argument.  */
+            if (*nextchar != '\0') {
+                optarg = nextchar;
+                /* If we end this ARGV-element by taking the rest as an arg,
+                   we must advance to the next element now.  */
+                optind++;
+            } else if (optind == argc) {
+                if (opterr) {
+                    /* 1003.2 specifies the format of this message.  */
+                    fprintf(stderr,
+                            _("%s: option requires an argument -- %c\n"),
+                            argv[0], c);
+                }
+                optopt = c;
+                if (optstring[0] == ':')
+                    c = ':';
+                else
+                    c = '?';
+                return c;
+            } else
+                /* We already incremented `optind' once;
+                   increment it again when taking next ARGV-elt as argument.  */
+                optarg = argv[optind++];
+
+            /* optarg is now the argument, see if it's in the
+               table of longopts.  */
+
+            for (nextchar = nameend = optarg; *nameend && *nameend != '=';
+                 nameend++)
+                /* Do nothing.  */ ;
+
+            /* Test all long options for either exact match
+               or abbreviated matches.  */
+            for (p = longopts, option_index = 0; p->name; p++, option_index++)
+                if (!strncmp(p->name, nextchar, nameend - nextchar)) {
+                    if ((unsigned int) (nameend - nextchar) ==
+                        strlen(p->name)) {
+                        /* Exact match found.  */
+                        pfound = p;
+                        indfound = option_index;
+                        exact = 1;
+                        break;
+                    } else if (pfound == NULL) {
+                        /* First nonexact match found.  */
+                        pfound = p;
+                        indfound = option_index;
+                    } else
+                        /* Second or later nonexact match found.  */
+                        ambig = 1;
+                }
+            if (ambig && !exact) {
+                if (opterr)
+                    fprintf(stderr, _("%s: option `-W %s' is ambiguous\n"),
+                            argv[0], argv[optind]);
+                nextchar += strlen(nextchar);
+                optind++;
+                return '?';
+            }
+            if (pfound != NULL) {
+                option_index = indfound;
+                if (*nameend) {
+                    /* Don't test has_arg with >, because some C compilers don't
+                       allow it to be used on enums.  */
+                    if (pfound->has_arg)
+                        optarg = nameend + 1;
+                    else {
+                        if (opterr)
+                            fprintf(stderr, _("\
+%s: option `-W %s' doesn't allow an argument\n"), argv[0], pfound->name);
+
+                        nextchar += strlen(nextchar);
+                        return '?';
+                    }
+                } else if (pfound->has_arg == 1) {
+                    if (optind < argc)
+                        optarg = argv[optind++];
+                    else {
+                        if (opterr)
+                            fprintf(stderr,
+                                    _
+                                    ("%s: option `%s' requires an argument\n"),
+                                    argv[0], argv[optind - 1]);
+                        nextchar += strlen(nextchar);
+                        return optstring[0] == ':' ? ':' : '?';
+                    }
+                }
+                nextchar += strlen(nextchar);
+                if (longind != NULL)
+                    *longind = option_index;
+                if (pfound->flag) {
+                    *(pfound->flag) = pfound->val;
+                    return 0;
+                }
+                return pfound->val;
+            }
+            nextchar = NULL;
+            return 'W'; /* Let the application handle it.   */
+        }
+        if (temp[1] == ':') {
+            if (temp[2] == ':') {
+                /* This is an option that accepts an argument optionally.  */
+                if (*nextchar != '\0') {
+                    optarg = nextchar;
+                    optind++;
+                } else
+                    optarg = NULL;
+                nextchar = NULL;
+            } else {
+                /* This is an option that requires an argument.  */
+                if (*nextchar != '\0') {
+                    optarg = nextchar;
+                    /* If we end this ARGV-element by taking the rest as an arg,
+                       we must advance to the next element now.  */
+                    optind++;
+                } else if (optind == argc) {
+                    if (opterr) {
+                        /* 1003.2 specifies the format of this message.  */
+                        fprintf(stderr,
+                                _("%s: option requires an argument -- %c\n"),
+                                argv[0], c);
+                    }
+                    optopt = c;
+                    if (optstring[0] == ':')
+                        c = ':';
+                    else
+                        c = '?';
+                } else
+                    /* We already incremented `optind' once;
+                       increment it again when taking next ARGV-elt as argument.  */
+                    optarg = argv[optind++];
+                nextchar = NULL;
+            }
+        }
+        return c;
     }
-
-  /* Look at and handle the next short option-character.  */
-
-  {
-    char c = *nextchar++;
-    char *temp = my_index (optstring, c);
-
-    /* Increment `optind' when we start to process its last character.  */
-    if (*nextchar == '\0')
-      ++optind;
-
-    if (temp == NULL || c == ':')
-      {
-       if (opterr)
-         {
-           if (posixly_correct)
-             /* 1003.2 specifies the format of this message.  */
-             fprintf (stderr, _("%s: illegal option -- %c\n"),
-                      argv[0], c);
-           else
-             fprintf (stderr, _("%s: invalid option -- %c\n"),
-                      argv[0], c);
-         }
-       optopt = c;
-       return '?';
-      }
-    /* Convenience. Treat POSIX -W foo same as long option --foo */
-    if (temp[0] == 'W' && temp[1] == ';')
-      {
-       char *nameend;
-       const struct option *p;
-       const struct option *pfound = NULL;
-       int exact = 0;
-       int ambig = 0;
-       int indfound = 0;
-       int option_index;
-
-       /* This is an option that requires an argument.  */
-       if (*nextchar != '\0')
-         {
-           optarg = nextchar;
-           /* If we end this ARGV-element by taking the rest as an arg,
-              we must advance to the next element now.  */
-           optind++;
-         }
-       else if (optind == argc)
-         {
-           if (opterr)
-             {
-               /* 1003.2 specifies the format of this message.  */
-               fprintf (stderr, _("%s: option requires an argument -- %c\n"),
-                        argv[0], c);
-             }
-           optopt = c;
-           if (optstring[0] == ':')
-             c = ':';
-           else
-             c = '?';
-           return c;
-         }
-       else
-         /* We already incremented `optind' once;
-            increment it again when taking next ARGV-elt as argument.  */
-         optarg = argv[optind++];
-
-       /* optarg is now the argument, see if it's in the
-          table of longopts.  */
-
-       for (nextchar = nameend = optarg; *nameend && *nameend != '='; nameend++)
-         /* Do nothing.  */ ;
-
-       /* Test all long options for either exact match
-          or abbreviated matches.  */
-       for (p = longopts, option_index = 0; p->name; p++, option_index++)
-         if (!strncmp (p->name, nextchar, nameend - nextchar))
-           {
-             if ((unsigned int) (nameend - nextchar) == strlen (p->name))
-               {
-                 /* Exact match found.  */
-                 pfound = p;
-                 indfound = option_index;
-                 exact = 1;
-                 break;
-               }
-             else if (pfound == NULL)
-               {
-                 /* First nonexact match found.  */
-                 pfound = p;
-                 indfound = option_index;
-               }
-             else
-               /* Second or later nonexact match found.  */
-               ambig = 1;
-           }
-       if (ambig && !exact)
-         {
-           if (opterr)
-             fprintf (stderr, _("%s: option `-W %s' is ambiguous\n"),
-                      argv[0], argv[optind]);
-           nextchar += strlen (nextchar);
-           optind++;
-           return '?';
-         }
-       if (pfound != NULL)
-         {
-           option_index = indfound;
-           if (*nameend)
-             {
-               /* Don't test has_arg with >, because some C compilers don't
-                  allow it to be used on enums.  */
-               if (pfound->has_arg)
-                 optarg = nameend + 1;
-               else
-                 {
-                   if (opterr)
-                     fprintf (stderr, _("\
-%s: option `-W %s' doesn't allow an argument\n"),
-                              argv[0], pfound->name);
-
-                   nextchar += strlen (nextchar);
-                   return '?';
-                 }
-             }
-           else if (pfound->has_arg == 1)
-             {
-               if (optind < argc)
-                 optarg = argv[optind++];
-               else
-                 {
-                   if (opterr)
-                     fprintf (stderr,
-                              _("%s: option `%s' requires an argument\n"),
-                              argv[0], argv[optind - 1]);
-                   nextchar += strlen (nextchar);
-                   return optstring[0] == ':' ? ':' : '?';
-                 }
-             }
-           nextchar += strlen (nextchar);
-           if (longind != NULL)
-             *longind = option_index;
-           if (pfound->flag)
-             {
-               *(pfound->flag) = pfound->val;
-               return 0;
-             }
-           return pfound->val;
-         }
-         nextchar = NULL;
-         return 'W';   /* Let the application handle it.   */
-      }
-    if (temp[1] == ':')
-      {
-       if (temp[2] == ':')
-         {
-           /* This is an option that accepts an argument optionally.  */
-           if (*nextchar != '\0')
-             {
-               optarg = nextchar;
-               optind++;
-             }
-           else
-             optarg = NULL;
-           nextchar = NULL;
-         }
-       else
-         {
-           /* This is an option that requires an argument.  */
-           if (*nextchar != '\0')
-             {
-               optarg = nextchar;
-               /* If we end this ARGV-element by taking the rest as an arg,
-                  we must advance to the next element now.  */
-               optind++;
-             }
-           else if (optind == argc)
-             {
-               if (opterr)
-                 {
-                   /* 1003.2 specifies the format of this message.  */
-                   fprintf (stderr,
-                          _("%s: option requires an argument -- %c\n"),
-                          argv[0], c);
-                 }
-               optopt = c;
-               if (optstring[0] == ':')
-                 c = ':';
-               else
-                 c = '?';
-             }
-           else
-             /* We already incremented `optind' once;
-                increment it again when taking next ARGV-elt as argument.  */
-             optarg = argv[optind++];
-           nextchar = NULL;
-         }
-      }
-    return c;
-  }
 }
 
-int
-getopt (argc, argv, optstring)
-     int argc;
-     char *const *argv;
-     const char *optstring;
+int getopt(
+    argc,
+    argv,
+    optstring)
+    int argc;
+    char     *const *argv;
+    const char *optstring;
 {
-  return _getopt_internal (argc, argv, optstring,
-                          (const struct option *) 0,
-                          (int *) 0,
-                          0);
+    return _getopt_internal(argc, argv, optstring,
+                            (const struct option *) 0, (int *) 0, 0);
 }
 
-#endif /* Not ELIDE_CODE.  */
+#endif                          /* Not ELIDE_CODE.  */
 \f
 #ifdef TEST
 
 /* Compile with -DTEST to make an executable for use in testing
    the above definition of `getopt'.  */
 
-int
-main (argc, argv)
-     int argc;
-     char **argv;
+int main(
+    argc,
+    argv)
+    int argc;
+    char    **argv;
 {
-  int c;
-  int digit_optind = 0;
-
-  while (1)
-    {
-      int this_option_optind = optind ? optind : 1;
-
-      c = getopt (argc, argv, "abc:d:0123456789");
-      if (c == -1)
-       break;
-
-      switch (c)
-       {
-       case '0':
-       case '1':
-       case '2':
-       case '3':
-       case '4':
-       case '5':
-       case '6':
-       case '7':
-       case '8':
-       case '9':
-         if (digit_optind != 0 && digit_optind != this_option_optind)
-           printf ("digits occur in two different argv-elements.\n");
-         digit_optind = this_option_optind;
-         printf ("option %c\n", c);
-         break;
-
-       case 'a':
-         printf ("option a\n");
-         break;
-
-       case 'b':
-         printf ("option b\n");
-         break;
-
-       case 'c':
-         printf ("option c with value `%s'\n", optarg);
-         break;
-
-       case '?':
-         break;
-
-       default:
-         printf ("?? getopt returned character code 0%o ??\n", c);
-       }
+    int       c;
+    int       digit_optind = 0;
+
+    while (1) {
+        int       this_option_optind = optind ? optind : 1;
+
+        c = getopt(argc, argv, "abc:d:0123456789");
+        if (c == -1)
+            break;
+
+        switch (c) {
+        case '0':
+        case '1':
+        case '2':
+        case '3':
+        case '4':
+        case '5':
+        case '6':
+        case '7':
+        case '8':
+        case '9':
+            if (digit_optind != 0 && digit_optind != this_option_optind)
+                printf("digits occur in two different argv-elements.\n");
+            digit_optind = this_option_optind;
+            printf("option %c\n", c);
+            break;
+
+        case 'a':
+            printf("option a\n");
+            break;
+
+        case 'b':
+            printf("option b\n");
+            break;
+
+        case 'c':
+            printf("option c with value `%s'\n", optarg);
+            break;
+
+        case '?':
+            break;
+
+        default:
+            printf("?? getopt returned character code 0%o ??\n", c);
+        }
     }
 
-  if (optind < argc)
-    {
-      printf ("non-option ARGV-elements: ");
-      while (optind < argc)
-       printf ("%s ", argv[optind++]);
-      printf ("\n");
+    if (optind < argc) {
+        printf("non-option ARGV-elements: ");
+        while (optind < argc)
+            printf("%s ", argv[optind++]);
+        printf("\n");
     }
 
-  exit (0);
+    exit(0);
 }
 
-#endif /* TEST */
+#endif                          /* TEST */
index 7dad11b79ffe57d5beedbc1294d935859308d230..91906efe2dc7b7f9c635bb753c3c0d67b5947df1 100644 (file)
@@ -23,7 +23,7 @@
 #define _GETOPT_H 1
 
 #ifdef __cplusplus
-extern "C" {
+extern    "C" {
 #endif
 
 /* For communication from `getopt' to the caller.
@@ -32,7 +32,7 @@ extern "C" {
    Also, when `ordering' is RETURN_IN_ORDER,
    each non-option ARGV-element is returned here.  */
 
-extern char *optarg;
+    extern char *optarg;
 
 /* Index in ARGV of the next element to be scanned.
    This is used for communication to and from the caller
@@ -46,16 +46,16 @@ extern char *optarg;
    Otherwise, `optind' communicates from one call to the next
    how much of ARGV has been scanned so far.  */
 
-extern int optind;
+    extern int optind;
 
 /* Callers store zero here to inhibit the error message `getopt' prints
    for unrecognized options.  */
 
-extern int opterr;
+    extern int opterr;
 
 /* Set to an option character which was unrecognized.  */
 
-extern int optopt;
+    extern int optopt;
 
 /* Describe the long-named options requested by the application.
    The LONG_OPTIONS argument to getopt_long or getopt_long_only is a vector
@@ -78,19 +78,18 @@ extern int optopt;
    one).  For long options that have a zero `flag' field, `getopt'
    returns the contents of the `val' field.  */
 
-struct option
-{
+    struct option {
 #if defined (__STDC__) && __STDC__
-  const char *name;
+        const char *name;
 #else
-  char *name;
+        char     *name;
 #endif
-  /* has_arg can't be an enum because some compilers complain about
-     type mismatches in all the code that assumes it is an int.  */
-  int has_arg;
-  int *flag;
-  int val;
-};
+        /* has_arg can't be an enum because some compilers complain about
+           type mismatches in all the code that assumes it is an int.  */
+        int       has_arg;
+        int      *flag;
+        int       val;
+    };
 
 /* Names for the values of the `has_arg' field of `struct option'.  */
 
@@ -103,31 +102,48 @@ struct option
 /* Many other libraries have conflicting prototypes for getopt, with
    differences in the consts, in stdlib.h.  To avoid compilation
    errors, only prototype getopt for the GNU C library.  */
-extern int getopt (int argc, char *const *argv, const char *shortopts);
-#else /* not __GNU_LIBRARY__ */
-extern int getopt ();
-#endif /* __GNU_LIBRARY__ */
-extern int getopt_long (int argc, char *const *argv, const char *shortopts,
-                       const struct option *longopts, int *longind);
-extern int getopt_long_only (int argc, char *const *argv,
-                            const char *shortopts,
-                            const struct option *longopts, int *longind);
+    extern int getopt(
+    int argc,
+    char *const *argv,
+    const char *shortopts);
+#else                   /* not __GNU_LIBRARY__ */
+    extern int getopt(
+        );
+#endif                  /* __GNU_LIBRARY__ */
+    extern int getopt_long(
+    int argc,
+    char *const *argv,
+    const char *shortopts,
+    const struct option *longopts,
+    int *longind);
+    extern int getopt_long_only(
+    int argc,
+    char *const *argv,
+    const char *shortopts,
+    const struct option *longopts,
+    int *longind);
 
 /* Internal only.  Users should not call this directly.  */
-extern int _getopt_internal (int argc, char *const *argv,
-                            const char *shortopts,
-                            const struct option *longopts, int *longind,
-                            int long_only);
-#else /* not __STDC__ */
-extern int getopt ();
-extern int getopt_long ();
-extern int getopt_long_only ();
-
-extern int _getopt_internal ();
-#endif /* __STDC__ */
+    extern int _getopt_internal(
+    int argc,
+    char *const *argv,
+    const char *shortopts,
+    const struct option *longopts,
+    int *longind,
+    int long_only);
+#else                   /* not __STDC__ */
+    extern int getopt(
+        );
+    extern int getopt_long(
+        );
+    extern int getopt_long_only(
+        );
+
+    extern int _getopt_internal(
+        );
+#endif                  /* __STDC__ */
 
 #ifdef __cplusplus
 }
 #endif
-
-#endif /* _GETOPT_H */
+#endif                  /* _GETOPT_H */
index 14e1e885685699156ed730d82b6c963ce75ee39a..075bc8da48b79643af6794ddfc5c51270693982a 100644 (file)
    write to the Free Software Foundation, Inc., 59 Temple Place - Suite 330,
    Boston, MA 02111-1307, USA.  */
 \f
-#ifdef HAVE_CONFIG_H
-#include "../rrd_config.h"
-#endif
-
-#include "rrd_getopt.h"
 
 #if !defined (__STDC__) || !__STDC__
 /* This is a separate conditional since some stdc systems
 #endif
 #endif
 
+#ifdef HAVE_CONFIG_H
+#include "../rrd_config.h"
+#endif
+
+#include "rrd_getopt.h"
+
 #include <stdio.h>
 
 /* Comment out all this code if we are using the GNU C Library, and are not
 #define NULL 0
 #endif
 
-int
-getopt_long (argc, argv, options, long_options, opt_index)
-     int argc;
-     char *const *argv;
-     const char *options;
-     const struct option *long_options;
-     int *opt_index;
+int getopt_long(
+    argc,
+    argv,
+    options,
+    long_options,
+    opt_index)
+    int argc;
+    char     *const *argv;
+    const char *options;
+    const struct option *long_options;
+    int      *opt_index;
 {
-  return _getopt_internal (argc, argv, options, long_options, opt_index, 0);
+    return _getopt_internal(argc, argv, options, long_options, opt_index, 0);
 }
 
 /* Like getopt_long, but '-' as well as '--' can indicate a long option.
@@ -80,110 +85,111 @@ getopt_long (argc, argv, options, long_options, opt_index)
    but does match a short option, it is parsed as a short option
    instead.  */
 
-int
-getopt_long_only (argc, argv, options, long_options, opt_index)
-     int argc;
-     char *const *argv;
-     const char *options;
-     const struct option *long_options;
-     int *opt_index;
+int getopt_long_only(
+    argc,
+    argv,
+    options,
+    long_options,
+    opt_index)
+    int argc;
+    char     *const *argv;
+    const char *options;
+    const struct option *long_options;
+    int      *opt_index;
 {
-  return _getopt_internal (argc, argv, options, long_options, opt_index, 1);
+    return _getopt_internal(argc, argv, options, long_options, opt_index, 1);
 }
 
 
-#endif /* Not ELIDE_CODE.  */
+#endif                          /* Not ELIDE_CODE.  */
 \f
 #ifdef TEST
 
 #include <stdio.h>
 
-int
-main (argc, argv)
-     int argc;
-     char **argv;
+int main(
+    argc,
+    argv)
+    int argc;
+    char    **argv;
 {
-  int c;
-  int digit_optind = 0;
-
-  while (1)
-    {
-      int this_option_optind = optind ? optind : 1;
-      int option_index = 0;
-      static struct option long_options[] =
-      {
-       {"add", 1, 0, 0},
-       {"append", 0, 0, 0},
-       {"delete", 1, 0, 0},
-       {"verbose", 0, 0, 0},
-       {"create", 0, 0, 0},
-       {"file", 1, 0, 0},
-       {0, 0, 0, 0}
-      };
-
-      c = getopt_long (argc, argv, "abc:d:0123456789",
-                      long_options, &option_index);
-      if (c == -1)
-       break;
-
-      switch (c)
-       {
-       case 0:
-         printf ("option %s", long_options[option_index].name);
-         if (optarg)
-           printf (" with arg %s", optarg);
-         printf ("\n");
-         break;
-
-       case '0':
-       case '1':
-       case '2':
-       case '3':
-       case '4':
-       case '5':
-       case '6':
-       case '7':
-       case '8':
-       case '9':
-         if (digit_optind != 0 && digit_optind != this_option_optind)
-           printf ("digits occur in two different argv-elements.\n");
-         digit_optind = this_option_optind;
-         printf ("option %c\n", c);
-         break;
-
-       case 'a':
-         printf ("option a\n");
-         break;
-
-       case 'b':
-         printf ("option b\n");
-         break;
-
-       case 'c':
-         printf ("option c with value `%s'\n", optarg);
-         break;
-
-       case 'd':
-         printf ("option d with value `%s'\n", optarg);
-         break;
-
-       case '?':
-         break;
-
-       default:
-         printf ("?? getopt returned character code 0%o ??\n", c);
-       }
+    int       c;
+    int       digit_optind = 0;
+    struct option long_options[] = {
+        {"add", 1, 0, 0},
+        {"append", 0, 0, 0},
+        {"delete", 1, 0, 0},
+        {"verbose", 0, 0, 0},
+        {"create", 0, 0, 0},
+        {"file", 1, 0, 0},
+        {0, 0, 0, 0}
+    };
+
+    while (1) {
+        int       this_option_optind = optind ? optind : 1;
+        int       option_index = 0;
+
+        c = getopt_long(argc, argv, "abc:d:0123456789",
+                        long_options, &option_index);
+        if (c == -1)
+            break;
+
+        switch (c) {
+        case 0:
+            printf("option %s", long_options[option_index].name);
+            if (optarg)
+                printf(" with arg %s", optarg);
+            printf("\n");
+            break;
+
+        case '0':
+        case '1':
+        case '2':
+        case '3':
+        case '4':
+        case '5':
+        case '6':
+        case '7':
+        case '8':
+        case '9':
+            if (digit_optind != 0 && digit_optind != this_option_optind)
+                printf("digits occur in two different argv-elements.\n");
+            digit_optind = this_option_optind;
+            printf("option %c\n", c);
+            break;
+
+        case 'a':
+            printf("option a\n");
+            break;
+
+        case 'b':
+            printf("option b\n");
+            break;
+
+        case 'c':
+            printf("option c with value `%s'\n", optarg);
+            break;
+
+        case 'd':
+            printf("option d with value `%s'\n", optarg);
+            break;
+
+        case '?':
+            break;
+
+        default:
+            printf("?? getopt returned character code 0%o ??\n", c);
+        }
     }
 
-  if (optind < argc)
-    {
-      printf ("non-option ARGV-elements: ");
-      while (optind < argc)
-       printf ("%s ", argv[optind++]);
-      printf ("\n");
+    if (optind < argc) {
+        printf("non-option ARGV-elements: ");
+        while (optind < argc)
+            printf("%s ", argv[optind++]);
+        printf("\n");
     }
 
-  exit (0);
+    exit(0);
 }
 
-#endif /* TEST */
+#endif                          /* TEST */
index a94afbf1b08af0220e868fc91b4660978d2434eb..7ba93ca79400a4211e7c97aee9c843dfe47ee57f 100644 (file)
@@ -1,5 +1,5 @@
 /****************************************************************************
- * RRDtool 1.2.27  Copyright by Tobi Oetiker, 1997-2008
+ * RRDtool 1.3rc4  Copyright by Tobi Oetiker, 1997-2008
  ****************************************************************************
  * rrd_gfx.c  graphics wrapper for rrdtool
   **************************************************************************/
 /* stupid MSVC doesnt support variadic macros = no debug for now! */
 #ifdef _MSC_VER
 # define RRDPRINTF()
-#else 
+#else
 # ifdef DEBUG
 #  define RRDPRINTF(...)  fprintf(stderr, __VA_ARGS__);
 # else
 #  define RRDPRINTF(...)
-# endif /* DEBUG */
-#endif /* _MSC_VER */
-#include "rrd_tool.h"
-#include <png.h>
-#include <ft2build.h>
-#include FT_FREETYPE_H
-#include FT_GLYPH_H
-
-#include "rrd_gfx.h"
-#include "rrd_afm.h"
-#include "unused.h"
-
-/* lines are better drawn on the pixle than between pixles */
-#define LINEOFFSET 0.5
-
-#define USE_PDF_FAKE_ALPHA 1
-#define USE_EPS_FAKE_ALPHA 1
-
-typedef struct gfx_char_s *gfx_char;
-struct gfx_char_s {
-  FT_UInt     index;    /* glyph index */
-  FT_Vector   pos;      /* location from baseline in 26.6 */
-  FT_Glyph    image;    /* glyph bitmap */
-};
-
-typedef struct gfx_string_s *gfx_string;
-struct gfx_string_s {
-  unsigned int    width;
-  unsigned int    height;
-  int            count;  /* number of characters */
-  gfx_char        glyphs;
-  size_t          num_glyphs;
-  FT_BBox         bbox;
-  FT_Matrix       transform;
-};
-
-/* compute string bbox */
-static void compute_string_bbox(gfx_string string);
-
-/* create a freetype glyph string */
-gfx_string gfx_string_create ( gfx_canvas_t *canvas, FT_Face face,
-                               const char *text, int rotation, double tabwidth, double size);
-
-/* create a freetype glyph string */
-static void gfx_string_destroy ( gfx_string string );
+# endif                         /* DEBUG */
+#endif                          /* _MSC_VER */
 
-static
-gfx_node_t *gfx_new_node( gfx_canvas_t *canvas,enum gfx_en type){
-  gfx_node_t *node = art_new(gfx_node_t,1);
-  if (node == NULL) return NULL;
-  node->type = type;
-  node->color = 0x0;        /* color of element  0xRRGGBBAA  alpha 0xff is solid*/
-  node->size =0.0;         /* font size, line width */
-  node->path = NULL;        /* path */
-  node->points = 0;
-  node->points_max =0;
-  node->closed_path = 0;
-  node->filename = NULL;             /* font or image filename */
-  node->text = NULL;
-  node->x = 0.0;
-  node->y = 0.0;          /* position */
-  node->angle = 0;  
-  node->halign = GFX_H_NULL; /* text alignement */
-  node->valign = GFX_V_NULL; /* text alignement */
-  node->tabwidth = 0.0; 
-  node->next = NULL; 
-  if (canvas->lastnode != NULL){
-      canvas->lastnode->next = node;
-  }
-  if (canvas->firstnode == NULL){
-      canvas->firstnode = node;
-  }  
-  canvas->lastnode = node;
-  return node;
-}
+#include "rrd_tool.h"
+#include "rrd_graph.h"
 
-gfx_canvas_t *gfx_new_canvas (void) {
-    gfx_canvas_t *canvas = art_new(gfx_canvas_t,1);
-    canvas->firstnode = NULL;
-    canvas->lastnode = NULL;
-    canvas->imgformat = IF_PNG; /* we default to PNG output */
-    canvas->interlaced = 0;
-    canvas->zoom = 1.0;
-    canvas->font_aa_threshold = -1.0;
-    canvas->aa_type = AA_NORMAL;
-    return canvas;
-}
 
 /* create a new line */
-gfx_node_t  *gfx_new_line(gfx_canvas_t *canvas, 
-                          double X0, double Y0, 
-                          double X1, double Y1,
-                          double width, gfx_color_t color){
-  return gfx_new_dashed_line(canvas, X0, Y0, X1, Y1, width, color, 0, 0);
-}
-
-gfx_node_t  *gfx_new_dashed_line(gfx_canvas_t *canvas, 
-                          double X0, double Y0, 
-                          double X1, double Y1,
-                          double width, gfx_color_t color,
-                          double dash_on, double dash_off){
-
-  gfx_node_t *node;
-  ArtVpath *vec;
-  node = gfx_new_node(canvas,GFX_LINE);
-  if (node == NULL) return NULL;
-  vec = art_new(ArtVpath, 3);
-  if (vec == NULL) return NULL;
-  vec[0].code = ART_MOVETO_OPEN; vec[0].x=X0+LINEOFFSET; vec[0].y=Y0+LINEOFFSET;
-  vec[1].code = ART_LINETO; vec[1].x=X1+LINEOFFSET; vec[1].y=Y1+LINEOFFSET;
-  vec[2].code = ART_END; vec[2].x=0;vec[2].y=0;
-  
-  node->points = 3;
-  node->points_max = 3;
-  node->color = color;
-  node->size  = width;
-  node->dash_on = dash_on;
-  node->dash_off = dash_off;
-  node->path  = vec;
-  return node;
+void gfx_line(
+    image_desc_t *im,
+    double X0,
+    double Y0,
+    double X1,
+    double Y1,
+    double width,
+    gfx_color_t color)
+{
+    gfx_dashed_line(im, X0, Y0, X1, Y1, width, color, 0, 0);
+}
+
+void gfx_dashed_line(
+    image_desc_t *im,
+    double X0,
+    double Y0,
+    double X1,
+    double Y1,
+    double width,
+    gfx_color_t color,
+    double dash_on,
+    double dash_off)
+{
+    cairo_t  *cr = im->cr;
+    double    dashes[] = { dash_on, dash_off };
+    double    x = 0;
+    double    y = 0;
+
+    cairo_save(cr);
+    cairo_new_path(cr);
+    cairo_set_line_width(cr, width);
+    gfx_line_fit(im, &x, &y);
+    gfx_line_fit(im, &X0, &Y0);
+    cairo_move_to(cr, X0, Y0);
+    gfx_line_fit(im, &X1, &Y1);
+    cairo_line_to(cr, X1, Y1);
+    if (dash_on > 0 || dash_off > 0)
+        cairo_set_dash(cr, dashes, 2, x);
+    cairo_set_source_rgba(cr, color.red, color.green, color.blue,
+                          color.alpha);
+    cairo_stroke(cr);
+    cairo_restore(cr);
 }
 
 /* create a new area */
-gfx_node_t   *gfx_new_area   (gfx_canvas_t *canvas, 
-                             double X0, double Y0,
-                             double X1, double Y1,
-                             double X2, double Y2,
-                             gfx_color_t color) {
-
-  gfx_node_t *node;
-  ArtVpath *vec;
-  node = gfx_new_node(canvas,GFX_AREA);
-  if (node == NULL) return NULL;
-  vec = art_new(ArtVpath, 5);
-  if (vec == NULL) return NULL;
-  vec[0].code = ART_MOVETO; vec[0].x=X0; vec[0].y=Y0;
-  vec[1].code = ART_LINETO; vec[1].x=X1; vec[1].y=Y1;
-  vec[2].code = ART_LINETO; vec[2].x=X2; vec[2].y=Y2;
-  vec[3].code = ART_LINETO; vec[3].x=X0; vec[3].y=Y0;
-  vec[4].code = ART_END; vec[4].x=0; vec[4].y=0;
-  
-  node->points = 5;
-  node->points_max = 5;
-  node->color = color;
-  node->path  = vec;
-
-  return node;
+void gfx_new_area(
+    image_desc_t *im,
+    double X0,
+    double Y0,
+    double X1,
+    double Y1,
+    double X2,
+    double Y2,
+    gfx_color_t color)
+{
+    cairo_t  *cr = im->cr;
+
+    cairo_new_path(cr);
+    gfx_area_fit(im, &X0, &Y0);
+    cairo_move_to(cr, X0, Y0);
+    gfx_area_fit(im, &X1, &Y1);
+    cairo_line_to(cr, X1, Y1);
+    gfx_area_fit(im, &X2, &Y2);
+    cairo_line_to(cr, X2, Y2);
+    cairo_set_source_rgba(cr, color.red, color.green, color.blue,
+                          color.alpha);
 }
 
 /* add a point to a line or to an area */
-int           gfx_add_point  (gfx_node_t *node, 
-                             double x, double y){
-  if (node == NULL) return 1;
-  if (node->type == GFX_AREA) {
-    double X0 = node->path[0].x;
-    double Y0 = node->path[0].y;
-    node->points -= 2;
-    art_vpath_add_point (&(node->path),
-                         &(node->points),
-                         &(node->points_max),
-                         ART_LINETO,
-                         x,y);
-    art_vpath_add_point (&(node->path),
-                         &(node->points),
-                         &(node->points_max),
-                         ART_LINETO,
-                         X0,Y0);
-    art_vpath_add_point (&(node->path),
-                         &(node->points),
-                         &(node->points_max),
-                         ART_END,
-                         0,0);
-  } else if (node->type == GFX_LINE) {
-    node->points -= 1;
-    art_vpath_add_point (&(node->path),
-                         &(node->points),
-                         &(node->points_max),
-                         ART_LINETO,
-                         x+LINEOFFSET,y+LINEOFFSET);
-    art_vpath_add_point (&(node->path),
-                         &(node->points),
-                         &(node->points_max),
-                         ART_END,
-                         0,0);
-    
-  } else {
-    /* can only add point to areas and lines */
-    return 1;
-  }
-  return 0;
-}
-
-void           gfx_close_path  (gfx_node_t *node) {
-    node->closed_path = 1;
-    if (node->path[0].code == ART_MOVETO_OPEN)
-       node->path[0].code = ART_MOVETO;
-}
-
-/* create a text node */
-gfx_node_t   *gfx_new_text   (gfx_canvas_t *canvas,  
-                             double x, double y, gfx_color_t color,
-                             char* font, double size,                        
-                             double tabwidth, double angle,
-                             enum gfx_h_align_en h_align,
-                             enum gfx_v_align_en v_align,
-                              char* text){
-   gfx_node_t *node = gfx_new_node(canvas,GFX_TEXT);
-   
-   node->text = strdup(text);
-   node->size = size;
-   node->filename = strdup(font);
-   node->x = x;
-   node->y = y;
-   node->angle = angle;   
-   node->color = color;
-   node->tabwidth = tabwidth;
-   node->halign = h_align;
-   node->valign = v_align;
-#if 0
-  /* debugging: show text anchor
-     green is along x-axis, red is downward y-axis */
-   if (1) {
-     double a = 2 * M_PI * -node->angle / 360.0;
-     double cos_a = cos(a);
-     double sin_a = sin(a);
-     double len = 3;
-     gfx_new_line(canvas,
-        x, y,
-        x + len * cos_a, y - len * sin_a,
-        0.2, 0x00FF0000);
-     gfx_new_line(canvas,
-        x, y,
-        x + len * sin_a, y + len * cos_a,
-        0.2, 0xFF000000);
-   }
-#endif
-   return node;
-}
-
-int           gfx_render(gfx_canvas_t *canvas, 
-                             art_u32 width, art_u32 height, 
-                             gfx_color_t background, FILE *fp){
-  switch (canvas->imgformat) {
-  case IF_PNG: 
-    return gfx_render_png (canvas, width, height, background, fp);
-  case IF_SVG: 
-    return gfx_render_svg (canvas, width, height, background, fp);
-  case IF_EPS:
-    return gfx_render_eps (canvas, width, height, background, fp);
-  case IF_PDF:
-    return gfx_render_pdf (canvas, width, height, background, fp);
-  default:
-    return -1;
-  }
-}
-
-static void gfx_string_destroy ( gfx_string string ) {
-  unsigned int n;
-  if (string->glyphs) {
-    for (n=0; n<string->num_glyphs; ++n)
-      FT_Done_Glyph (string->glyphs[n].image);
-    free (string->glyphs);
-  }
-  free (string);
-}
-
-
-double gfx_get_text_width ( gfx_canvas_t *canvas,
-                           double start, char* font, double size,
-                           double tabwidth, char* text, int rotation){
-  switch (canvas->imgformat) {
-  case IF_PNG: 
-    return gfx_get_text_width_libart (canvas, start, font, size, tabwidth, text, rotation);
-  case IF_SVG: /* fall through */ 
-  case IF_EPS:
-  case IF_PDF:
-    return afm_get_text_width(start, font, size, tabwidth, text);
-  default:
-    return size * strlen(text);
-  }
-}
-
-double gfx_get_text_width_libart (
-                           gfx_canvas_t *canvas, double UNUSED(start), char* font, double size,
-                           double tabwidth, char* text, int rotation ){
-
-  int           error;
-  double        text_width=0;
-  FT_Face       face;
-  FT_Library    library=NULL;  
-  gfx_string    string;
-
-  FT_Init_FreeType( &library );
-  error = FT_New_Face( library, font, 0, &face );
-  if ( error ) {
-    FT_Done_FreeType(library);
-    return -1;
-  }
-  error = FT_Set_Char_Size(face,  size*64,size*64,  100,100);
-  if ( error ) {
-    FT_Done_FreeType(library);
-    return -1;
-  }
-  string = gfx_string_create( canvas, face, text, rotation, tabwidth, size );
-  text_width = string->width;
-  gfx_string_destroy(string);
-  FT_Done_FreeType(library);
-  return text_width/64;
-}
-
-static void gfx_libart_close_path(gfx_node_t *node, ArtVpath **vec)
-{
-    /* libart must have end==start for closed paths,
-       even if using ART_MOVETO and not ART_MOVETO_OPEN
-       so add extra point which is the same as the starting point */
-    int points_max = node->points; /* scaled array has exact size */
-    int points = node->points - 1;
-    art_vpath_add_point (vec, &points, &points_max, ART_LINETO,
-           (**vec).x, (**vec).y);
-    art_vpath_add_point (vec, &points, &points_max, ART_END, 0, 0);
-}
-
-
-/* find bbox of a string */
-static void compute_string_bbox(gfx_string string) {
-    unsigned int n;
-    FT_BBox bbox;
-
-    bbox.xMin = bbox.yMin = 32000;
-    bbox.xMax = bbox.yMax = -32000;
-    for ( n = 0; n < string->num_glyphs; n++ ) {
-      FT_BBox glyph_bbox;
-      FT_Glyph_Get_CBox( string->glyphs[n].image, ft_glyph_bbox_gridfit,
-       &glyph_bbox );
-      if (glyph_bbox.xMin < bbox.xMin) {
-         bbox.xMin = glyph_bbox.xMin;
-      }
-      if (glyph_bbox.yMin < bbox.yMin) {
-        bbox.yMin = glyph_bbox.yMin;
-      }
-      if (glyph_bbox.xMax > bbox.xMax) {
-         bbox.xMax = glyph_bbox.xMax;
-      }
-      if (glyph_bbox.yMax > bbox.yMax) {
-         bbox.yMax = glyph_bbox.yMax;
-      }
-    }
-    if ( bbox.xMin > bbox.xMax ) { 
-      bbox.xMin = 0;
-      bbox.yMin = 0;
-      bbox.xMax = 0;
-      bbox.yMax = 0;
-    }
-    string->bbox.xMin = bbox.xMin;
-    string->bbox.xMax = bbox.xMax;
-    string->bbox.yMin = bbox.yMin;
-    string->bbox.yMax = bbox.yMax;
-} 
-
-/* create a free type glyph string */
-gfx_string gfx_string_create(gfx_canvas_t *canvas, FT_Face face,const char *text,
-        int rotation, double tabwidth, double size )
-{
-
-  FT_GlyphSlot  slot = face->glyph;  /* a small shortcut */
-  FT_Bool       use_kerning;
-  FT_UInt       previous;
-  FT_Vector     ft_pen;
-
-  gfx_string    string = (gfx_string) malloc (sizeof(struct gfx_string_s));
-
-  gfx_char      glyph;          /* current glyph in table */
-  int          n;
-  int           error;
-  int        gottab = 0;    
-
-#ifdef HAVE_MBSTOWCS
-  wchar_t      *cstr;
-  size_t       clen = strlen(text)+1;
-  cstr = malloc(sizeof(wchar_t) * clen); /* yes we are allocating probably too much here, I know */
-  string->count=mbstowcs(cstr,text,clen);
-  if ( string->count == -1){
-  /* conversion did not work, so lets fall back to just use what we got */
-       string->count=clen-1;
-        for(n=0;text[n] != '\0';n++){
-            cstr[n]=(unsigned char)text[n];
-        }
-  }
-#else
-  char         *cstr = strdup(text);
-  string->count = strlen (text);
-#endif
-
-  ft_pen.x = 0;   /* start at (0,0) !! */
-  ft_pen.y = 0;
-
-
-  string->width = 0;
-  string->height = 0;
-  string->glyphs = (gfx_char) calloc (string->count,sizeof(struct gfx_char_s));
-  string->num_glyphs = 0;
-  string->transform.xx = (FT_Fixed)( cos(M_PI*(rotation)/180.0)*0x10000);
-  string->transform.xy = (FT_Fixed)(-sin(M_PI*(rotation)/180.0)*0x10000);
-  string->transform.yx = (FT_Fixed)( sin(M_PI*(rotation)/180.0)*0x10000);
-  string->transform.yy = (FT_Fixed)( cos(M_PI*(rotation)/180.0)*0x10000);
-
-  use_kerning = FT_HAS_KERNING(face);
-  previous    = 0;
-  glyph = string->glyphs;
-  for (n=0; n<string->count;glyph++,n++) {
-    FT_Vector   vec;
-    /* handle the tabs ...
-       have a witespace glyph inserted, but set its width such that the distance
-    of the new right edge is x times tabwidth from 0,0 where x is an integer. */    
-    unsigned int letter = cstr[n];
-       letter = afm_fix_osx_charset(letter); /* unsafe macro */
-          
-    gottab = 0;
-    if (letter == '\\' && n+1 < string->count && cstr[n+1] == 't'){
-            /* we have a tab here so skip the backslash and
-               set t to ' ' so that we get a white space */
-            gottab = 1;
-            n++;
-            letter  = ' ';            
-    }            
-    if (letter == '\t'){
-       letter = ' ';
-        gottab = 1 ;
-    }            
-    /* initialize each struct gfx_char_s */
-    glyph->index = 0;
-    glyph->pos.x = 0;
-    glyph->pos.y = 0;
-    glyph->image = NULL;
-    glyph->index = FT_Get_Char_Index( face, letter );
-
-    /* compute glyph origin */
-    if ( use_kerning && previous && glyph->index ) {
-      FT_Vector kerning;
-      FT_Get_Kerning (face, previous, glyph->index,
-          ft_kerning_default, &kerning);
-      ft_pen.x += kerning.x;
-      ft_pen.y += kerning.y;
-    }
-
-    /* load the glyph image (in its native format) */
-    /* for now, we take a monochrome glyph bitmap */
-    error = FT_Load_Glyph (face, glyph->index, size > canvas->font_aa_threshold ?
-                            canvas->aa_type == AA_NORMAL ? FT_LOAD_TARGET_NORMAL :
-                            canvas->aa_type == AA_LIGHT ? FT_LOAD_TARGET_LIGHT :
-                            FT_LOAD_TARGET_MONO : FT_LOAD_TARGET_MONO);
-    if (error) {
-      RRDPRINTF("couldn't load glyph:  %c\n", letter)
-      continue;
-    }
-    error = FT_Get_Glyph (slot, &glyph->image);
-    if (error) {
-      RRDPRINTF("couldn't get glyph %c from slot %d\n", letter, (int)slot)
-      continue;
-    }
-    /* if we are in tabbing mode, we replace the tab with a space and shift the position
-       of the space so that its left edge is where the tab was supposed to land us */
-    if (gottab){
-       /* we are in gridfitting mode so the calculations happen in 1/64 pixles */
-        ft_pen.x = tabwidth*64.0 * (float)(1 + (long)(ft_pen.x / (tabwidth * 64.0))) - slot->advance.x;
-    }
-    /* store current pen position */
-    glyph->pos.x = ft_pen.x;
-    glyph->pos.y = ft_pen.y;
-
-
-    ft_pen.x   += slot->advance.x;    
-    ft_pen.y   += slot->advance.y;
-
-    /* rotate glyph */
-    vec = glyph->pos;
-    FT_Vector_Transform (&vec, &string->transform);
-    error = FT_Glyph_Transform (glyph->image, &string->transform, &vec);
-    if (error) {
-      RRDPRINTF("couldn't transform glyph id %d\n", letter)
-      continue;
-    }
-
-    /* convert to a bitmap - destroy native image */
-    error = FT_Glyph_To_Bitmap (&glyph->image, size > canvas->font_aa_threshold ?
-                            canvas->aa_type == AA_NORMAL ? FT_RENDER_MODE_NORMAL :
-                            canvas->aa_type == AA_LIGHT ? FT_RENDER_MODE_LIGHT :
-                            FT_RENDER_MODE_MONO : FT_RENDER_MODE_MONO, 0, 1);
-    if (error) {
-      RRDPRINTF("couldn't convert glyph id %d to bitmap\n", letter)
-      continue;
-    }
-
-    /* increment number of glyphs */
-    previous = glyph->index;
-    string->num_glyphs++;
-  }
-  free(cstr);
-/*  printf ("number of glyphs = %d\n", string->num_glyphs);*/
-  compute_string_bbox( string );
-  /* the last character was a tab */  
-  /* if (gottab) { */
-      string->width = ft_pen.x;
-  /* } else {
-      string->width = string->bbox.xMax - string->bbox.xMin;
-  } */
-  string->height = string->bbox.yMax - string->bbox.yMin;
-  return string;
-}
-
-
-static int gfx_save_png (art_u8 *buffer, FILE *fp,
-                     long width, long height, long bytes_per_pixel);
-/* render grafics into png image */
-
-int           gfx_render_png (gfx_canvas_t *canvas, 
-                             art_u32 width, art_u32 height, 
-                             gfx_color_t background, FILE *fp){
-    
-    
-    FT_Library    library;
-    gfx_node_t *node = canvas->firstnode;    
-    /*
-    art_u8 red = background >> 24, green = (background >> 16) & 0xff;
-    art_u8 blue = (background >> 8) & 0xff, alpha = ( background & 0xff );
-    */
-    unsigned long pys_width = width * canvas->zoom;
-    unsigned long pys_height = height * canvas->zoom;
-    const int bytes_per_pixel = 4;
-    unsigned long rowstride = pys_width*bytes_per_pixel; /* bytes per pixel */
-    
-    /* fill that buffer with out background color */
-    gfx_color_t *buffp = art_new (gfx_color_t, pys_width*pys_height);
-    art_u8 *buffer = (art_u8 *)buffp;
-    unsigned long i;
-    for (i=0;i<pys_width*pys_height;
-        i++){
-       *(buffp++)=background;
-    }
-    FT_Init_FreeType( &library );
-    while(node){
-        switch (node->type) {
-        case GFX_LINE:
-        case GFX_AREA: {   
-            ArtVpath *vec;
-            double dst[6];     
-            ArtSVP *svp;
-            art_affine_scale(dst,canvas->zoom,canvas->zoom);
-            vec = art_vpath_affine_transform(node->path,dst);
-           if (node->closed_path)
-               gfx_libart_close_path(node, &vec);
-           /* gfx_round_scaled_coordinates(vec); */
-            /* pvec = art_vpath_perturb(vec);
-              art_free(vec); */
-            if(node->type == GFX_LINE){
-                svp = art_svp_vpath_stroke ( vec, ART_PATH_STROKE_JOIN_ROUND,
-                                             ART_PATH_STROKE_CAP_ROUND,
-                                             node->size*canvas->zoom,4,0.25);
-            } else {
-                svp  = art_svp_from_vpath ( vec );
-               /* this takes time and is unnecessary since we make
-                  sure elsewhere that the areas are going clock-whise */
-               /*  svpt = art_svp_uncross( svp );
-                    art_svp_free(svp);
-                   svp  = art_svp_rewind_uncrossed(svpt,ART_WIND_RULE_NONZERO); 
-                    art_svp_free(svpt);
-                 */
-            }
-            art_free(vec);
-           /* this is from gnome since libart does not have this yet */
-            gnome_print_art_rgba_svp_alpha (svp ,0,0, pys_width, pys_height,
-                                node->color, buffer, rowstride, NULL);
-            art_svp_free(svp);
-            break;
-        }
-        case GFX_TEXT: {
-            unsigned int  n;
-            int  error;
-            art_u8 fcolor[4],falpha;
-            FT_Face       face;
-            gfx_char      glyph;
-            gfx_string    string;
-            FT_Vector     vec;  /* 26.6 */
-
-            float pen_x = 0.0 , pen_y = 0.0;
-            /* double x,y; */
-            long   ix,iy;
-            
-            fcolor[0] = node->color >> 24;
-            fcolor[1] = (node->color >> 16) & 0xff;
-            fcolor[2] = (node->color >> 8) & 0xff;
-            falpha = node->color & 0xff;
-            error = FT_New_Face( library,
-                                 (char *)node->filename,
-                                 0,
-                                 &face );
-           if ( error ) {
-               rrd_set_error("failed to load %s",node->filename);
-               
-               break;
-           }
-            error = FT_Set_Char_Size(face,   /* handle to face object            */
-                                     (long)(node->size*64),
-                                     (long)(node->size*64),
-                                     (long)(100*canvas->zoom),
-                                     (long)(100*canvas->zoom));
-            if ( error ) {
-                FT_Done_Face(face);
-                break;
-            }
-            pen_x = node->x * canvas->zoom;
-            pen_y = node->y * canvas->zoom;
-
-            string = gfx_string_create (canvas, face, node->text, node->angle, node->tabwidth, node->size);
-            FT_Done_Face(face);
-
-            switch(node->halign){
-            case GFX_H_RIGHT:  vec.x = -string->bbox.xMax;
-                               break;          
-            case GFX_H_CENTER: vec.x = abs(string->bbox.xMax) >= abs(string->bbox.xMin) ?
-                                       -string->bbox.xMax/2:-string->bbox.xMin/2;
-                               break;          
-            case GFX_H_LEFT:   vec.x = -string->bbox.xMin;
-                              break;
-            case GFX_H_NULL:   vec.x = 0;
-                               break;          
-            }
-
-            switch(node->valign){
-            case GFX_V_TOP:    vec.y = string->bbox.yMax;
-                               break;
-            case GFX_V_CENTER: vec.y = abs(string->bbox.yMax) >= abs(string->bbox.yMin) ?
-                                       string->bbox.yMax/2:string->bbox.yMin/2;
-                               break;
-            case GFX_V_BOTTOM: vec.y = 0;
-                               break;
-            case GFX_V_NULL:   vec.y = 0;
-                               break;
-            }
-           pen_x += vec.x/64;
-           pen_y += vec.y/64;
-            glyph = string->glyphs;
-            for(n=0; n<string->num_glyphs; n++, glyph++) {
-                int gr;
-                FT_Glyph        image;
-                FT_BitmapGlyph  bit;
-               /* long buf_x,comp_n; */
-               /* make copy to transform */
-                if (! glyph->image) {
-                  RRDPRINTF("no image\n")
-                  continue;
-                }
-                error = FT_Glyph_Copy (glyph->image, &image);
-                if (error) {
-                  RRDPRINTF("couldn't copy image\n")
-                  continue;
-                }
-
-                /* transform it */
-                vec = glyph->pos;
-                FT_Vector_Transform (&vec, &string->transform);
-
-                bit = (FT_BitmapGlyph) image;
-                gr = bit->bitmap.num_grays -1;
-/* 
-               buf_x = (pen_x + 0.5) + (double)bit->left;
-               comp_n = buf_x + bit->bitmap.width > pys_width ? pys_width - buf_x : bit->bitmap.width;
-                if (buf_x < 0 || buf_x >= (long)pys_width) continue;
-               buf_x *=  bytes_per_pixel ;
-               for (iy=0; iy < bit->bitmap.rows; iy++){                    
-                   long buf_y = iy+(pen_y+0.5)-(double)bit->top;
-                   if (buf_y < 0 || buf_y >= (long)pys_height) continue;
-                    buf_y *= rowstride;
-                   for (ix=0;ix < bit->bitmap.width;ix++){             
-                       *(letter + (ix*bytes_per_pixel+3)) = *(bit->bitmap.buffer + iy * bit->bitmap.width + ix);
-                   }
-                   art_rgba_rgba_composite(buffer + buf_y + buf_x ,letter,comp_n);
-                }
-                art_free(letter);
-*/
-                switch ( bit->bitmap.pixel_mode ) {
-                    case FT_PIXEL_MODE_GRAY:
-                        for (iy=0; iy < bit->bitmap.rows; iy++){
-                            long buf_y = iy+(pen_y+0.5)-bit->top;
-                            if (buf_y < 0 || buf_y >= (long)pys_height) continue;
-                            buf_y *= rowstride;
-                            for (ix=0;ix < bit->bitmap.width;ix++){
-                                long buf_x = ix + (pen_x + 0.5) + (double)bit->left ;
-                                art_u8 font_alpha;
-
-                                if (buf_x < 0 || buf_x >= (long)pys_width) continue;
-                                buf_x *=  bytes_per_pixel ;
-                                font_alpha =  *(bit->bitmap.buffer + iy * bit->bitmap.pitch + ix);
-                    if (font_alpha > 0){
-                                    fcolor[3] =  (art_u8)((double)font_alpha / gr * falpha);
-                        art_rgba_rgba_composite(buffer + buf_y + buf_x ,fcolor,1);
-                                }
-                            }
-                        }
-                        break;
-
-                    case FT_PIXEL_MODE_MONO:
-                        for (iy=0; iy < bit->bitmap.rows; iy++){
-                            long buf_y = iy+(pen_y+0.5)-bit->top;
-                            if (buf_y < 0 || buf_y >= (long)pys_height) continue;
-                            buf_y *= rowstride;
-                            for (ix=0;ix < bit->bitmap.width;ix++){
-                                long buf_x = ix + (pen_x + 0.5) + (double)bit->left ;
-
-                                if (buf_x < 0 || buf_x >= (long)pys_width) continue;
-                                buf_x *=  bytes_per_pixel ;
-                                if ( (fcolor[3] = falpha * ((*(bit->bitmap.buffer + iy * bit->bitmap.pitch + ix/8) >> (7 - (ix % 8))) & 1)) > 0 )
-                                    art_rgba_rgba_composite(buffer + buf_y + buf_x ,fcolor,1);
-                            }
-                        }
-                        break;
-
-                        default:
-                            rrd_set_error("unknown freetype pixel mode: %d", bit->bitmap.pixel_mode);
-                            break;
-                }
-
-/*
-                for (iy=0; iy < bit->bitmap.rows; iy++){                   
-                    long buf_y = iy+(pen_y+0.5)-bit->top;
-                    if (buf_y < 0 || buf_y >= (long)pys_height) continue;
-                    buf_y *= rowstride;
-                    for (ix=0;ix < bit->bitmap.width;ix++){
-                        long buf_x = ix + (pen_x + 0.5) + (double)bit->left ;
-                        art_u8 font_alpha;
-                        
-                        if (buf_x < 0 || buf_x >= (long)pys_width) continue;
-                        buf_x *=  bytes_per_pixel ;
-                        font_alpha =  *(bit->bitmap.buffer + iy * bit->bitmap.width + ix);
-                        font_alpha =  (art_u8)((double)font_alpha / gr * falpha);
-                        for (iz = 0; iz < 3; iz++){
-                            art_u8 *orig = buffer + buf_y + buf_x + iz;
-                            *orig =  (art_u8)((double)*orig / gr * ( gr - font_alpha) +
-                                              (double)fcolor[iz] / gr * (font_alpha));
-                        }
-                    }
-                }
-*/
-                FT_Done_Glyph (image);
-            }
-            gfx_string_destroy(string);
-        }
-        }
-        node = node->next;
-    }  
-    gfx_save_png(buffer,fp , pys_width,pys_height,bytes_per_pixel);
-    art_free(buffer);
-    FT_Done_FreeType( library );
-    return 0;    
-}
-
-/* free memory used by nodes this will also remove memory required for
-   associated paths and svcs ... but not for text strings */
-int
-gfx_destroy    (gfx_canvas_t *canvas){  
-  gfx_node_t *next,*node = canvas->firstnode;
-  while(node){
-    next = node->next;
-    art_free(node->path);
-    free(node->text);
-    free(node->filename);
-    art_free(node);
-    node = next;
-  }
-  art_free(canvas);
-  return 0;
-}
-static int gfx_save_png (art_u8 *buffer, FILE *fp,  long width, long height, long bytes_per_pixel){
-  png_structp png_ptr = NULL;
-  png_infop   info_ptr = NULL;
-  int i;
-  png_bytep *row_pointers;
-  int rowstride = width * bytes_per_pixel;
-  png_text text[2];
-  
-  if (fp == NULL)
-    return (1);
-
-  png_ptr = png_create_write_struct(PNG_LIBPNG_VER_STRING,NULL,NULL,NULL);
-  if (png_ptr == NULL)
-   {
-      return (1);
-   }
-   row_pointers = (png_bytepp)png_malloc(png_ptr,
-                                     height*sizeof(png_bytep));
-
-  info_ptr = png_create_info_struct(png_ptr);
-
-  if (info_ptr == NULL)
-    {
-      png_free(png_ptr,row_pointers);
-      png_destroy_write_struct(&png_ptr,  (png_infopp)NULL);
-      return (1);
-    }
-
-  if (setjmp(png_jmpbuf(png_ptr)))
-    {
-      /* If we get here, we had a problem writing the file */
-      png_destroy_write_struct(&png_ptr, &info_ptr);
-      return (1);
-    }
-
-  png_init_io(png_ptr, fp);
-  png_set_IHDR (png_ptr, info_ptr,width, height,
-                8, PNG_COLOR_TYPE_RGB_ALPHA,
-                PNG_INTERLACE_NONE,
-                PNG_COMPRESSION_TYPE_DEFAULT,
-                PNG_FILTER_TYPE_DEFAULT);
-
-  text[0].key = "Software";
-  text[0].text = "RRDtool, Tobias Oetiker <tobi@oetiker.ch>, http://tobi.oetiker.ch";
-  text[0].compression = PNG_TEXT_COMPRESSION_NONE;
-  png_set_text (png_ptr, info_ptr, text, 1);
-
-  /* lets make this fast while ending up with some increass in image size */
-  png_set_filter(png_ptr,0,PNG_FILTER_NONE);
-  /* png_set_filter(png_ptr,0,PNG_FILTER_SUB); */
-  png_set_compression_level(png_ptr,1);
-  /* png_set_compression_strategy(png_ptr,Z_HUFFMAN_ONLY); */
-  /* 
-  png_set_filter(png_ptr,PNG_FILTER_TYPE_BASE,PNG_FILTER_SUB);
-  png_set_compression_strategy(png_ptr,Z_HUFFMAN_ONLY);
-  png_set_compression_level(png_ptr,Z_BEST_SPEED); */
-  
-  /* Write header data */
-  png_write_info (png_ptr, info_ptr);
-  for (i = 0; i < height; i++)
-    row_pointers[i] = (png_bytep) (buffer + i*rowstride);
-  
-  png_write_image(png_ptr, row_pointers);
-  png_write_end(png_ptr, info_ptr);
-  png_free(png_ptr,row_pointers);
-  png_destroy_write_struct(&png_ptr, &info_ptr);
-  return 1;
-}
-
-/* ----- COMMON ROUTINES for pdf, svg and eps */
-#define min3(a, b, c) (a < b ? (a < c ? a : c) : (b < c ? b : c))
-#define max3(a, b, c) (a > b ? (a > c ? a : c) : (b > c ? b : c))
-
-#define PDF_CALC_DEBUG 0
-
-typedef struct pdf_point
-{
-       double x, y;
-} pdf_point;
-
-typedef struct
-{
-       double ascender, descender, baselineY;
-       pdf_point sizep, minp, maxp;
-       double x, y, tdx, tdy;
-       double r, cos_r, sin_r;
-       double ma, mb, mc, md, mx, my; /* pdf coord matrix */
-       double tmx, tmy; /* last 2 coords of text coord matrix */
-#if PDF_CALC_DEBUG
-       int debug;
-#endif
-} pdf_coords;
-
-#if PDF_CALC_DEBUG
-static void pdf_dump_calc(gfx_node_t *node, pdf_coords *g)
-{
-       fprintf(stderr, "PDF CALC =============================\n");
-       fprintf(stderr, "   '%s' at %f pt\n", node->text, node->size);
-       fprintf(stderr, "   align h = %s, v = %s,  sizep = %f, %f\n",
-               (node->halign == GFX_H_RIGHT ? "r" :
-                       (node->halign == GFX_H_CENTER ? "c" :
-                               (node->halign == GFX_H_LEFT ? "l" : "N"))),
-               (node->valign == GFX_V_TOP ? "t" :
-                       (node->valign == GFX_V_CENTER ? "c" :
-                               (node->valign == GFX_V_BOTTOM ? "b" : "N"))),
-                       g->sizep.x, g->sizep.y);
-       fprintf(stderr, "   r = %f = %f, cos = %f, sin = %f\n",
-                       g->r, node->angle, g->cos_r, g->sin_r);
-       fprintf(stderr, "   ascender = %f, descender = %f, baselineY = %f\n",
-               g->ascender, g->descender, g->baselineY);
-       fprintf(stderr, "   sizep: %f, %f\n", g->sizep.x, g->sizep.y);
-       fprintf(stderr, "   minp: %f, %f     maxp = %f, %f\n", 
-                       g->minp.x, g->minp.y, g->maxp.x, g->maxp.y);
-       fprintf(stderr, "   x = %f, y = %f\n", g->x, g->y);
-       fprintf(stderr, "   tdx = %f, tdy = %f\n", g->tdx, g->tdy);
-       fprintf(stderr, "   GM = %f, %f, %f, %f, %f, %f\n",
-                       g->ma, g->mb, g->mc, g->md, g->mx, g->my);
-       fprintf(stderr, "   TM = %f, %f, %f, %f, %f, %f\n",
-                       g->ma, g->mb, g->mc, g->md, g->tmx, g->tmy);
-}
-#endif
-#if PDF_CALC_DEBUG
-#define PDF_DD(x) if (g->debug) x;
-#else
-#define PDF_DD(x)
-#endif
-
-static void pdf_rotate(pdf_coords *g, pdf_point *p)
-{
-    double x2 = g->cos_r * p->x - g->sin_r * p->y;
-    double y2 = g->sin_r * p->x + g->cos_r * p->y;
-       PDF_DD( fprintf(stderr, "  rotate(%f, %f) -> %f, %f\n", p->x, p->y, x2, y2))
-    p->x = x2;
-       p->y = y2;
-}
-
-
-static void pdf_calc(int page_height, gfx_node_t *node, pdf_coords *g)
+void gfx_add_point(
+    image_desc_t *im,
+    double x,
+    double y)
 {
-       pdf_point a, b, c;
-#if PDF_CALC_DEBUG
-       /* g->debug = !!strstr(node->text, "RevProxy-1") || !!strstr(node->text, "08:00"); */
-       g->debug = !!strstr(node->text, "sekunder") || !!strstr(node->text, "Web");
-#endif
-       g->x = node->x;
-       g->y = page_height - node->y;
-       if (node->angle) {
-               g->r = 2 * M_PI * node->angle / 360.0;
-               g->cos_r = cos(g->r);
-               g->sin_r = sin(g->r);
-       } else {
-               g->r = 0;
-               g->cos_r = 1;
-               g->sin_r = 0;
-       }
-       g->ascender = afm_get_ascender(node->filename, node->size);
-       g->descender = afm_get_descender(node->filename, node->size);
-       g->sizep.x = afm_get_text_width(0, node->filename, node->size, node->tabwidth, node->text);
-       /* seems like libart ignores the descender when doing vertial-align = bottom,
-          so we do that too, to get labels v-aligning properly */
-       g->sizep.y = -g->ascender; /* + afm_get_descender(font->ps_font, node->size); */
-       g->baselineY = -g->ascender - g->sizep.y / 2;
-       a.x = g->sizep.x; a.y = g->sizep.y;
-       b.x = g->sizep.x; b.y = 0;
-       c.x = 0; c.y = g->sizep.y;
-       if (node->angle) {
-               pdf_rotate(g, &a);
-               pdf_rotate(g, &b);
-               pdf_rotate(g, &c);
-       }
-       g->minp.x = min3(a.x, b.x, c.x);
-       g->minp.y = min3(a.y, b.y, c.y);
-       g->maxp.x = max3(a.x, b.x, c.x);
-       g->maxp.y = max3(a.y, b.y, c.y);
-  /* The alignment parameters in node->valign and node->halign
-     specifies the alignment in the non-rotated coordinate system
-     (very unlike pdf/postscript), which complicates matters.
-  */
-       switch (node->halign) {
-       case GFX_H_RIGHT:  g->tdx = -g->maxp.x; break;
-       case GFX_H_CENTER: g->tdx = -(g->maxp.x + g->minp.x) / 2; break;
-       case GFX_H_LEFT:   g->tdx = -g->minp.x; break;
-       case GFX_H_NULL:   g->tdx = 0; break;
-       }
-       switch(node->valign){
-       case GFX_V_TOP:    g->tdy = -g->maxp.y; break;
-       case GFX_V_CENTER: g->tdy = -(g->maxp.y + g->minp.y) / 2; break;
-       case GFX_V_BOTTOM: g->tdy = -g->minp.y; break;
-       case GFX_V_NULL:   g->tdy = 0; break;          
-       }
-       g->ma = g->cos_r;
-       g->mb = g->sin_r;
-       g->mc = -g->sin_r;
-       g->md = g->cos_r;
-       g->mx = g->x + g->tdx;
-       g->my = g->y + g->tdy;
-       g->tmx = g->mx - g->ascender * g->mc;
-       g->tmy = g->my - g->ascender * g->md;
-       PDF_DD(pdf_dump_calc(node, g))
-}
-
-/* ------- SVG -------
-   SVG reference:
-   http://www.w3.org/TR/SVG/
-*/
-static int svg_indent = 0;
-static int svg_single_line = 0;
-static const char *svg_default_font = "-dummy-";
-typedef struct svg_dash
-{
-  int dash_enable;
-  double dash_adjust, dash_len, dash_offset;
-  double adjusted_on, adjusted_off;
-} svg_dash;
+    cairo_t  *cr = im->cr;
 
-
-static void svg_print_indent(FILE *fp)
-{
-  int i;
-   for (i = svg_indent - svg_single_line; i > 0; i--) {
-     putc(' ', fp);
-     putc(' ', fp);
-   }
-}
-static void svg_start_tag(FILE *fp, const char *name)
-{
-   svg_print_indent(fp);
-   putc('<', fp);
-   fputs(name, fp);
-   svg_indent++;
-}
-static void svg_close_tag_single_line(FILE *fp)
-{
-   svg_single_line++;
-   putc('>', fp);
-}
-static void svg_close_tag(FILE *fp)
-{
-   putc('>', fp);
-   if (!svg_single_line)
-     putc('\n', fp);
-}
-static void svg_end_tag(FILE *fp, const char *name)
-{
-   /* name is NULL if closing empty-node tag */
-   svg_indent--;
-   if (svg_single_line)
-     svg_single_line--;
-   else if (name)
-     svg_print_indent(fp);
-   if (name != NULL) {
-     fputs("</", fp);
-     fputs(name, fp);
-   } else {
-     putc('/', fp);
-   }
-   svg_close_tag(fp);
-}
-static void svg_close_tag_empty_node(FILE *fp)
-{
-   svg_end_tag(fp, NULL);
-}
-static void svg_write_text(FILE *fp, const char *text)
-{
-#ifdef HAVE_MBSTOWCS
-    size_t clen;
-    wchar_t *p, *cstr, ch;
-    int text_count;
-    if (!text)
-       return;
-    clen = strlen(text) + 1;
-    cstr = malloc(sizeof(wchar_t) * clen);
-    text_count = mbstowcs(cstr, text, clen);
-    if (text_count == -1)
-       text_count = mbstowcs(cstr, "Enc-Err", 6);
-    p = cstr;
-#else
-    unsigned char *p = text;
-    unsigned char *cstr;
-    char ch;
-    if (!p)
-       return;
-#endif
-  while (1) {
-    ch = *p++;
-    ch = afm_fix_osx_charset(ch); /* unsafe macro */
-    switch (ch) {
-    case 0:
-#ifdef HAVE_MBSTOWCS
-    free(cstr);
-#endif
-    return;
-    case '&': fputs("&amp;", fp); break;
-    case '<': fputs("&lt;", fp); break;
-    case '>': fputs("&gt;", fp); break;
-    case '"': fputs("&quot;", fp); break;
-    default:
-        if (ch == 32) {
-#ifdef HAVE_MBSTOWCS
-            if (p <= cstr + 1 || !*p || *p == 32)
-                fputs("&#160;", fp); /* non-breaking space in unicode */
-            else
-#endif
-                fputc(32, fp);
-        } else if (ch < 32 || ch >= 127)
-       fprintf(fp, "&#%d;", (int)ch);
-      else
-       putc((char)ch, fp);
-     }
-   }
-}
-static void svg_format_number(char *buf, int bufsize, double d)
-{
-   /* omit decimals if integer to reduce filesize */
-   char *p;
-   snprintf(buf, bufsize, "%.2f", d);
-   p = buf; /* doesn't trust snprintf return value */
-   while (*p)
-     p++;
-   while (--p > buf) {
-     char ch = *p;
-     if (ch == '0') {
-       *p = '\0'; /* zap trailing zeros */
-       continue;
-     }
-     if (ch == '.')
-       *p = '\0'; /* zap trailing dot */
-     break;
-   }
-}
-static void svg_write_number(FILE *fp, double d)
-{
-   char buf[60];
-   svg_format_number(buf, sizeof(buf), d);
-   fputs(buf, fp);
-}
-
-static int svg_color_is_black(int c)
-{
-  /* gfx_color_t is RRGGBBAA */
-  return c == 0x000000FF;
-}
-static void svg_write_color(FILE *fp, gfx_color_t c, const char *attr)
-{
-  /* gfx_color_t is RRGGBBAA, svg can use #RRGGBB and #RGB like html */
-  gfx_color_t rrggbb = (int)((c >> 8) & 0xFFFFFF);
-  gfx_color_t opacity = c & 0xFF;
-  fprintf(fp, " %s=\"", attr);
-  if ((rrggbb & 0x0F0F0F) == ((rrggbb >> 4) & 0x0F0F0F)) {
-     /* css2 short form, #rgb is #rrggbb, not #r0g0b0 */
-    fprintf(fp, "#%03lX",
-          ( ((rrggbb >> 8) & 0xF00)
-          | ((rrggbb >> 4) & 0x0F0)
-          | ( rrggbb       & 0x00F)));
-   } else {
-    fprintf(fp, "#%06lX", rrggbb);
-   }
-  fputs("\"", fp);
-  if (opacity != 0xFF) {
-    fprintf(fp, " opacity=\"");
-    svg_write_number(fp, opacity / 255.0);
-    fputs("\"", fp);
- }
-}
-static void svg_get_dash(gfx_node_t *node, svg_dash *d)
-{
-  double offset;
-  int mult;
-  if (node->dash_on <= 0 || node->dash_off <= 0) {
-    d->dash_enable = 0;
-    return;
-  }
-  d->dash_enable = 1;
-  d->dash_len = node->dash_on + node->dash_off;
-  /* dash on/off adjustment due to round caps */
-  d->dash_adjust = 0.8 * node->size;
-  d->adjusted_on = node->dash_on - d->dash_adjust;
-  if (d->adjusted_on < 0.01)
-      d->adjusted_on = 0.01;
-  d->adjusted_off = d->dash_len - d->adjusted_on;
-  /* dash offset calc */
-  if (node->path[0].x == node->path[1].x) /* only good for horz/vert lines */
-    offset = node->path[0].y;
-  else
-    offset = node->path[0].x;
-  mult = (int)fabs(offset / d->dash_len);
-  d->dash_offset = offset - mult * d->dash_len;
-  if (node->path[0].x < node->path[1].x || node->path[0].y < node->path[1].y)
-    d->dash_offset = d->dash_len - d->dash_offset;
+    gfx_area_fit(im, &x, &y);
+    cairo_line_to(cr, x, y);
 }
 
-static int svg_dash_equal(svg_dash *a, svg_dash *b)
+void gfx_close_path(
+    image_desc_t *im)
 {
-  if (a->dash_enable != b->dash_enable)
-    return 0;
-  if (a->adjusted_on != b->adjusted_on)
-    return 0;
-  if (a->adjusted_off != b->adjusted_off)
-    return 0;
-  /* rest of properties will be the same when on+off are */
-  return 1;
-}
+    cairo_t  *cr = im->cr;
 
-static void svg_common_path_attributes(FILE *fp, gfx_node_t *node)
-{
-  svg_dash dash_info;
-  svg_get_dash(node, &dash_info);
-  fputs(" stroke-width=\"", fp);
-  svg_write_number(fp, node->size);
-  fputs("\"", fp);
-  svg_write_color(fp, node->color, "stroke");
-  fputs(" fill=\"none\"", fp);
-  if (dash_info.dash_enable) {
-    if (dash_info.dash_offset != 0) {
-      fputs(" stroke-dashoffset=\"", fp);
-      svg_write_number(fp, dash_info.dash_offset);
-      fputs("\"", fp);
-    }
-    fputs(" stroke-dasharray=\"", fp);
-    svg_write_number(fp, dash_info.adjusted_on);
-    fputs(",", fp);
-    svg_write_number(fp, dash_info.adjusted_off);
-    fputs("\"", fp);
-  }
+    cairo_close_path(cr);
+    cairo_fill(cr);
 }
 
-static int svg_is_int_step(double a, double b)
-{
-   double diff = fabs(a - b);
-   return floor(diff) == diff;
-}
-static int svg_path_straight_segment(FILE *fp,
-     double lastA, double currentA, double currentB,
-     gfx_node_t *node,
-     int segment_idx, int isx, char absChar, char relChar)
-{
-   if (!svg_is_int_step(lastA, currentA)) {
-     putc(absChar, fp);
-     svg_write_number(fp, currentA);
-     return 0;
-   }
-   if (segment_idx < node->points - 1) {
-     ArtVpath *vec = node->path + segment_idx + 1;
-     if (vec->code == ART_LINETO) {
-       double nextA = (isx ? vec->x : vec->y) - LINEOFFSET;
-       double nextB = (isx ? vec->y : vec->x) - LINEOFFSET;
-       if (nextB == currentB
-           && ((currentA >= lastA) == (nextA >= currentA))
-           && svg_is_int_step(currentA, nextA)) {
-         return 1; /* skip to next as it is a straight line  */
-       }
-     }
-   }
-   putc(relChar, fp);
-   svg_write_number(fp, currentA - lastA);
-   return 0;
-}
-static void svg_path(FILE *fp, gfx_node_t *node, int multi)
-{
-   int i;
-   double lastX = 0, lastY = 0;
-   /* for straight lines <path..> tags take less space than
-      <line..> tags because of the efficient packing
-      in the 'd' attribute */
-   svg_start_tag(fp, "path");
-  if (!multi)
-    svg_common_path_attributes(fp, node);
-   fputs(" d=\"", fp);
-   /* specification of the 'd' attribute: */
-   /* http://www.w3.org/TR/SVG/paths.html#PathDataGeneralInformation */
-   for (i = 0; i < node->points; i++) {
-     ArtVpath *vec = node->path + i;
-     double x = vec->x - LINEOFFSET;
-     double y = vec->y - LINEOFFSET;
-     switch (vec->code) {
-     case ART_MOVETO_OPEN: /* fall-through */
-     case ART_MOVETO:
-       putc('M', fp);
-       svg_write_number(fp, x);
-       putc(',', fp);
-       svg_write_number(fp, y);
-       break;
-     case ART_LINETO:
-       /* try optimize filesize by using minimal lineto commands */
-       /* without introducing rounding errors. */
-       if (x == lastX) {
-         if (svg_path_straight_segment(fp, lastY, y, x, node, i, 0, 'V', 'v'))
-           continue;
-       } else if (y == lastY) {
-         if (svg_path_straight_segment(fp, lastX, x, y, node, i, 1, 'H', 'h'))
-           continue;
-       } else {
-         putc('L', fp);
-         svg_write_number(fp, x);
-         putc(',', fp);
-         svg_write_number(fp, y);
-       }
-       break;
-     case ART_CURVETO: break; /* unsupported */
-     case ART_END: break; /* nop */
-     }
-     lastX = x;
-     lastY = y;
-   }
-  if (node->closed_path)
-    fputs(" Z", fp);
-   fputs("\"", fp);
-   svg_close_tag_empty_node(fp);
-}
-static void svg_multi_path(FILE *fp, gfx_node_t **nodeR)
-{
-   /* optimize for multiple paths with the same color, penwidth, etc. */
-   int num = 1;
-   gfx_node_t *node = *nodeR;
-   gfx_node_t *next = node->next;
-   while (next) {
-     if (next->type != node->type
-         || next->size != node->size
-        || next->color != node->color
-        || next->dash_on != node->dash_on
-        || next->dash_off != node->dash_off)
-       break;
-     next = next->next;
-     num++;
-   }
-   if (num == 1) {
-     svg_path(fp, node, 0);
-     return;
-   }
-   svg_start_tag(fp, "g");
-  svg_common_path_attributes(fp, node);
-   svg_close_tag(fp);
-   while (num && node) {
-     svg_path(fp, node, 1);
-     if (!--num)
-       break;
-     node = node->next;
-     *nodeR = node;
-   }
-   svg_end_tag(fp, "g");
-}
-static void svg_area(FILE *fp, gfx_node_t *node)
-{
-   int i;
-   double startX = 0, startY = 0;
-   svg_start_tag(fp, "polygon");
-  fputs(" ", fp);
-  svg_write_color(fp, node->color, "fill");
-  fputs(" points=\"", fp);
-   for (i = 0; i < node->points; i++) {
-     ArtVpath *vec = node->path + i;
-     double x = vec->x - LINEOFFSET;
-     double y = vec->y - LINEOFFSET;
-     switch (vec->code) {
-       case ART_MOVETO_OPEN: /* fall-through */
-       case ART_MOVETO:
-         svg_write_number(fp, x);
-         putc(',', fp);
-         svg_write_number(fp, y);
-         startX = x;
-         startY = y;
-         break;
-       case ART_LINETO:
-         if (i == node->points - 2
-                       && node->path[i + 1].code == ART_END
-             && fabs(x - startX) < 0.001 && fabs(y - startY) < 0.001) {
-           break; /* poly area always closed, no need for last point */
-         }
-         putc(' ', fp);
-         svg_write_number(fp, x);
-         putc(',', fp);
-         svg_write_number(fp, y);
-         break;
-       case ART_CURVETO: break; /* unsupported */
-       case ART_END: break; /* nop */
-     }
-   }
-   fputs("\"", fp);
-   svg_close_tag_empty_node(fp);
-}
-static void svg_text(FILE *fp, gfx_node_t *node)
-{
-   pdf_coords g;
-   const char *fontname;
-   /* as svg has 0,0 in top-left corner (like most screens) instead of
-         bottom-left corner like pdf and eps, we have to fake the coords
-         using offset and inverse sin(r) value */
-   int page_height = 1000;
-   pdf_calc(page_height, node, &g);
-   if (node->angle != 0) {
-     svg_start_tag(fp, "g");
-        /* can't use svg_write_number as 2 decimals is far from enough to avoid
-               skewed text */
-     fprintf(fp, " transform=\"matrix(%f,%f,%f,%f,%f,%f)\"",
-                        g.ma, -g.mb, -g.mc, g.md, g.tmx, page_height - g.tmy);
-     svg_close_tag(fp);
-   }
-   svg_start_tag(fp, "text");
-   if (!node->angle) {
-     fputs(" x=\"", fp);
-     svg_write_number(fp, g.tmx);
-     fputs("\" y=\"", fp);
-     svg_write_number(fp, page_height - g.tmy);
-     fputs("\"", fp);
-   }
-   fontname = afm_get_font_name(node->filename);
-   if (strcmp(fontname, svg_default_font))
-     fprintf(fp, " font-family=\"%s\"", fontname);
-   fputs(" font-size=\"", fp);
-   svg_write_number(fp, node->size);
-   fputs("\"", fp);
-  if (!svg_color_is_black(node->color))
-    svg_write_color(fp, node->color, "fill");
-   svg_close_tag_single_line(fp);
-   /* support for node->tabwidth missing */
-   svg_write_text(fp, node->text);
-   svg_end_tag(fp, "text");
-   if (node->angle != 0)
-     svg_end_tag(fp, "g");
-}
-int       gfx_render_svg (gfx_canvas_t *canvas,
-                 art_u32 width, art_u32 height,
-                 gfx_color_t background, FILE *fp){
-   gfx_node_t *node = canvas->firstnode;
-   /* Find the first font used, and assume it is the mostly used
-         one. It reduces the number of font-familty attributes. */
-   while (node) {
-          if (node->type == GFX_TEXT && node->filename) {
-                  svg_default_font = afm_get_font_name(node->filename);
-                  break;
-          }
-          node = node->next;
-   }
-   fputs(
-"<?xml version=\"1.0\" standalone=\"no\"?>\n"
-"<!DOCTYPE svg PUBLIC \"-//W3C//DTD SVG 1.0//EN\"\n"
-"   \"http://www.w3.org/TR/2001/REC-SVG-20010904/DTD/svg10.dtd\">\n"
-"<!--\n"
-"   SVG file created by\n"
-"        RRDtool " PACKAGE_VERSION " Tobias Oetiker, http://tobi.oetiker.ch\n"
-"\n"
-"   The width/height attributes in the outhermost svg node\n"
-"   are just default sizes for the browser which is used\n"
-"   if the svg file is openened directly without being\n"
-"   embedded in an html file.\n"
-"   The viewBox is the local coord system for rrdtool.\n"
-"-->\n", fp);
-   svg_start_tag(fp, "svg");
-   fputs(" width=\"", fp);
-   svg_write_number(fp, width * canvas->zoom);
-   fputs("\" height=\"", fp);
-   svg_write_number(fp, height * canvas->zoom);
-   fputs("\" x=\"0\" y=\"0\" viewBox=\"", fp);
-   svg_write_number(fp, -LINEOFFSET);
-   fputs(" ", fp);
-   svg_write_number(fp, -LINEOFFSET);
-   fputs(" ", fp);
-   svg_write_number(fp, width - LINEOFFSET);
-   fputs(" ", fp);
-   svg_write_number(fp, height - LINEOFFSET);
-   fputs("\" preserveAspectRatio=\"xMidYMid\"", fp);
-   fprintf(fp, " font-family=\"%s\"", svg_default_font); /* default font */
-   fputs(" stroke-linecap=\"round\" stroke-linejoin=\"round\"", fp);
-   fputs(" xmlns=\"http://www.w3.org/2000/svg\"", fp);
-   fputs(" xmlns:xlink=\"http://www.w3.org/1999/xlink\"", fp);
-   svg_close_tag(fp);
-   svg_start_tag(fp, "rect");
-   fprintf(fp, " x=\"0\" y=\"0\" width=\"%d\" height=\"%d\"", width, height);
-  svg_write_color(fp, background, "fill");
-   svg_close_tag_empty_node(fp);
-   node = canvas->firstnode;
-   while (node) {
-     switch (node->type) {
-     case GFX_LINE:
-       svg_multi_path(fp, &node);
-       break;
-     case GFX_AREA:
-       svg_area(fp, node);
-       break;
-     case GFX_TEXT:
-       svg_text(fp, node);
-     }
-     node = node->next;
-   }
-   svg_end_tag(fp, "svg");
-   return 0;
-}
-
-/* ------- EPS -------
-   EPS and Postscript references:
-   http://partners.adobe.com/asn/developer/technotes/postscript.html
-*/
-
-typedef struct eps_font
-{
-  const char *ps_font;
-  int id;
-  struct eps_font *next;
-} eps_font;
-
-typedef struct eps_state
-{
-  FILE *fp;
-  gfx_canvas_t *canvas;
-  art_u32 page_width, page_height;
-  eps_font *font_list;
-  /*--*/
-  gfx_color_t color;
-  const char *font;
-  double font_size;
-  double line_width;
-  int linecap, linejoin;
-  int has_dash;
-} eps_state;
-
-static void eps_set_color(eps_state *state, gfx_color_t color)
-{
-#if USE_EPS_FAKE_ALPHA
-   double a1, a2;
-#endif
-   /* gfx_color_t is RRGGBBAA */
-  if (state->color == color)
-    return;
-#if USE_EPS_FAKE_ALPHA
-  a1 = (color & 255) / 255.0;
-  a2 = 255 * (1 - a1);
-#define eps_color_calc(x) (int)( ((x) & 255) * a1 + a2)
-#else
-#define eps_color_calc(x) (int)( (x) & 255)
-#endif
-   /* gfx_color_t is RRGGBBAA */
-  if (state->color == color)
-    return;
-  fprintf(state->fp, "%d %d %d Rgb\n",
-      eps_color_calc(color >> 24),
-      eps_color_calc(color >> 16),
-      eps_color_calc(color >>  8));
-  state->color = color;
-}
-
-static int eps_add_font(eps_state *state, gfx_node_t *node)
-{
-  /* The fonts list could be postponed to the end using
-     (atend), but let's be nice and have them in the header. */
-  const char *ps_font = afm_get_font_postscript_name(node->filename);
-  eps_font *ef;
-  for (ef = state->font_list; ef; ef = ef->next) {
-    if (!strcmp(ps_font, ef->ps_font))
-      return 0;
-  }
-  ef = malloc(sizeof(eps_font));
-  if (ef == NULL) {
-    rrd_set_error("malloc for eps_font");
-    return -1;
-  }
-  ef->next = state->font_list;
-  ef->ps_font = ps_font;
-  state->font_list = ef;
-  return 0;
-}
-
-static void eps_list_fonts(eps_state *state, const char *dscName)
-{
-  eps_font *ef;
-  int lineLen = strlen(dscName);
-  if (!state->font_list)
-    return;
-  fputs(dscName, state->fp);
-  for (ef = state->font_list; ef; ef = ef->next) {
-    int nameLen = strlen(ef->ps_font);
-    if (lineLen + nameLen > 100 && lineLen) {
-      fputs("\n", state->fp);
-      fputs("%%- \n", state->fp);
-      lineLen = 5;
-    } else {
-      fputs(" ", state->fp);
-      lineLen++;
-    }
-    fputs(ef->ps_font, state->fp);
-    lineLen += nameLen;
-  }
-  fputs("\n", state->fp);
-}
-
-static void eps_define_fonts(eps_state *state)
-{
-  eps_font *ef;
-  if (!state->font_list)
-    return;
-  for (ef = state->font_list; ef; ef = ef->next) {
-    /* PostScript¨ LANGUAGE REFERENCE third edition
-       page 349 */
-    fprintf(state->fp,
-        "%%\n"
-        "/%s findfont dup length dict begin\n"
-        "{ 1 index /FID ne {def} {pop pop} ifelse } forall\n"
-        "/Encoding ISOLatin1Encoding def\n"
-        "currentdict end\n"
-        "/%s-ISOLatin1 exch definefont pop\n"
-        "/SetFont-%s { /%s-ISOLatin1 findfont exch scalefont setfont } bd\n",
-        ef->ps_font, ef->ps_font, ef->ps_font, ef->ps_font);
-  }
-}
-
-static int eps_prologue(eps_state *state)
-{
-  gfx_node_t *node;
-  fputs(
-    "%!PS-Adobe-3.0 EPSF-3.0\n"
-    "%%Creator: RRDtool " PACKAGE_VERSION " Tobias Oetiker, http://tobi.oetiker.ch\n"
-    /* can't like weird chars here */
-    "%%Title: (RRDtool output)\n"
-    "%%DocumentData: Clean7Bit\n"
-    "", state->fp);
-  fprintf(state->fp, "%%%%BoundingBox: 0 0 %d %d\n",
-    state->page_width, state->page_height);
-  for (node = state->canvas->firstnode; node; node = node->next) {
-    if (node->type == GFX_TEXT && eps_add_font(state, node) == -1)
-      return -1;
-  }
-  eps_list_fonts(state, "%%DocumentFonts:");
-  eps_list_fonts(state, "%%DocumentNeededFonts:");
-  fputs(
-      "%%EndComments\n"
-      "%%BeginProlog\n"
-      "%%EndProlog\n" /* must have, or BoundingBox is ignored */
-      "/bd { bind def } bind def\n"
-      "", state->fp);
-  fprintf(state->fp, "/X { %.2f add } bd\n", LINEOFFSET);
-  fputs(
-      "/X2 {X exch X exch} bd\n"
-      "/M {X2 moveto} bd\n"
-      "/L {X2 lineto} bd\n"
-      "/m {moveto} bd\n"
-      "/l {lineto} bd\n"
-      "/S {stroke} bd\n"
-      "/CP {closepath} bd\n"
-      "/WS {setlinewidth stroke} bd\n"
-      "/F {fill} bd\n"
-      "/T1 {gsave} bd\n"
-      "/T2 {concat 0 0 moveto show grestore} bd\n"
-      "/T   {moveto show} bd\n"
-      "/Rgb { 255.0 div 3 1 roll\n"
-      "       255.0 div 3 1 roll \n"
-      "       255.0 div 3 1 roll setrgbcolor } bd\n"
-      "", state->fp);
-  eps_define_fonts(state);
-  return 0;
-}
-
-static void eps_clear_dash(eps_state *state)
-{
-  if (!state->has_dash)
-    return;
-  state->has_dash = 0;
-  fputs("[1 0] 0 setdash\n", state->fp);
-}
-
-static void eps_write_linearea(eps_state *state, gfx_node_t *node)
-{
-  int i;
-  FILE *fp = state->fp;
-  int useOffset = 0;
-  int clearDashIfAny = 1;
-  eps_set_color(state, node->color);
-  if (node->type == GFX_LINE) {
-    svg_dash dash_info;
-    if (state->linecap != 1) {
-      fputs("1 setlinecap\n", fp);
-      state->linecap = 1;
-    }
-    if (state->linejoin != 1) {
-      fputs("1 setlinejoin\n", fp);
-      state->linejoin = 1;
-    }
-    svg_get_dash(node, &dash_info);
-    if (dash_info.dash_enable) {
-      clearDashIfAny = 0;
-      state->has_dash = 1;
-      fputs("[", fp);
-      svg_write_number(fp, dash_info.adjusted_on);
-      fputs(" ", fp);
-      svg_write_number(fp, dash_info.adjusted_off);
-      fputs("] ", fp);
-      svg_write_number(fp, dash_info.dash_offset);
-      fputs(" setdash\n", fp);
-    }
-  }
-  if (clearDashIfAny)
-    eps_clear_dash(state);
-  for (i = 0; i < node->points; i++) {
-    ArtVpath *vec = node->path + i;
-    double x = vec->x;
-    double y = state->page_height - vec->y;
-    if (vec->code == ART_MOVETO_OPEN || vec->code == ART_MOVETO)
-      useOffset = (fabs(x - floor(x) - 0.5) < 0.01 && fabs(y - floor(y) - 0.5) < 0.01);
-    if (useOffset) {
-      x -= LINEOFFSET;
-      y -= LINEOFFSET;
-    }
-    switch (vec->code) {
-    case ART_MOVETO_OPEN: /* fall-through */
-    case ART_MOVETO:
-      svg_write_number(fp, x);
-      fputc(' ', fp);
-      svg_write_number(fp, y);
-      fputc(' ', fp);
-      fputs(useOffset ? "M\n" : "m\n", fp);
-      break;
-    case ART_LINETO:
-      svg_write_number(fp, x);
-      fputc(' ', fp);
-      svg_write_number(fp, y);
-      fputc(' ', fp);
-      fputs(useOffset ? "L\n" : "l\n", fp);
-      break;
-    case ART_CURVETO: break; /* unsupported */
-    case ART_END: break; /* nop */
-    }
-  }
-  if (node->type == GFX_LINE) {
-    if (node->closed_path)
-      fputs("CP ", fp);
-    if (node->size != state->line_width) {
-      state->line_width = node->size;
-      svg_write_number(fp, state->line_width);
-      fputs(" WS\n", fp);
-    } else {
-      fputs("S\n", fp);
-    }
-   } else {
-    fputs("F\n", fp);
-   }
-}
-
-static void eps_write_text(eps_state *state, gfx_node_t *node)
-{
-  FILE *fp = state->fp;
-  const char *ps_font = afm_get_font_postscript_name(node->filename);
-  int lineLen = 0;
-  pdf_coords g;
-#ifdef HAVE_MBSTOWCS
-    size_t clen;
-    wchar_t *p, *cstr, ch;
-    int text_count;
-    if (!node->text)
-       return;
-    clen = strlen(node->text) + 1;
-    cstr = malloc(sizeof(wchar_t) * clen);
-    text_count = mbstowcs(cstr, node->text, clen);
-    if (text_count == -1)
-       text_count = mbstowcs(cstr, "Enc-Err", 6);
-    p = cstr;
-#else
-    const unsigned char *p = node->text;
-    unsigned char ch;
-    if (!p)
-       return;
-#endif
-  pdf_calc(state->page_height, node, &g);
-  eps_set_color(state, node->color);
-  if (strcmp(ps_font, state->font) || node->size != state->font_size) {
-    state->font = ps_font;
-    state->font_size = node->size;
-    svg_write_number(fp, state->font_size);
-    fprintf(fp, " SetFont-%s\n", state->font);
-  }
-  if (node->angle)
-         fputs("T1 ", fp);
-  fputs("(", fp);
-  lineLen = 20;
-  while (1) {
-    ch = *p;
-    if (!ch)
-      break;
-       ch = afm_fix_osx_charset(ch); /* unsafe macro */
-    if (++lineLen > 70) {
-      fputs("\\\n", fp); /* backslash and \n */
-      lineLen = 0;
-    }
-    switch (ch) {
-      case '%':
-      case '(':
-      case ')':
-      case '\\':
-        fputc('\\', fp);
-        fputc(ch, fp);
+/* create a text node */
+static PangoLayout *gfx_prep_text(
+    image_desc_t *im,
+    double x,
+    gfx_color_t color,
+    char *font,
+    double size,
+    double tabwidth,
+    const char *text)
+{
+    PangoLayout *layout;
+    PangoFontDescription *font_desc;
+    cairo_t  *cr = im->cr;
+
+    /* for performance reasons we might
+       want todo that only once ... tabs will always
+       be the same */
+    long      i;
+    long      tab_count = strlen(text);
+    long      tab_shift = fmod(x, tabwidth);
+
+    PangoTabArray *tab_array;
+    PangoContext *pango_context;
+
+    tab_array = pango_tab_array_new(tab_count, (gboolean) (1));
+    for (i = 1; i <= tab_count; i++) {
+        pango_tab_array_set_tab(tab_array,
+                                i, PANGO_TAB_LEFT, tabwidth * i - tab_shift);
+    }
+    cairo_new_path(cr);
+    cairo_set_source_rgba(cr, color.red, color.green, color.blue,
+                          color.alpha);
+    layout = pango_cairo_create_layout(cr);
+    pango_context = pango_layout_get_context(layout);
+    pango_cairo_context_set_font_options(pango_context, im->font_options);
+    pango_cairo_context_set_resolution(pango_context, 100);
+
+/*     pango_cairo_update_context(cr, pango_context); */
+
+    pango_layout_set_tabs(layout, tab_array);
+    font_desc = pango_font_description_from_string(font);
+    pango_font_description_set_size(font_desc, size * PANGO_SCALE);
+    pango_layout_set_font_description(layout, font_desc);
+    pango_layout_set_markup(layout, text, -1);
+    return layout;
+}
+
+/* Size Text Node */
+double gfx_get_text_width(
+    image_desc_t *im,
+    double start,
+    char *font,
+    double size,
+    double tabwidth,
+    char *text)
+{
+    PangoLayout *layout;
+    PangoRectangle log_rect;
+    gfx_color_t color = { 0, 0, 0, 0 };
+    char     *tab;
+
+    /* turn \\t into tab */
+    while ((tab = strstr(text, "\\t"))) {
+        memmove(tab + 1, tab + 2, strlen(tab + 2));
+        tab[0] = (char) 9;
+    }
+    layout = gfx_prep_text(im, start, color, font, size, tabwidth, text);
+    pango_layout_get_pixel_extents(layout, NULL, &log_rect);
+    pango_tab_array_free(pango_layout_get_tabs(layout));
+    g_object_unref(layout);
+    return log_rect.width;
+}
+
+void gfx_text(
+    image_desc_t *im,
+    double x,
+    double y,
+    gfx_color_t color,
+    char *font,
+    double size,
+    double tabwidth,
+    double angle,
+    enum gfx_h_align_en h_align,
+    enum gfx_v_align_en v_align,
+    const char *text)
+{
+    PangoLayout *layout;
+    PangoRectangle log_rect;
+    PangoRectangle ink_rect;
+    cairo_t  *cr = im->cr;
+    double    sx = 0;
+    double    sy = 0;
+
+    cairo_save(cr);
+    cairo_translate(cr, x, y);
+/*    gfx_line(cr,-2,0,2,0,1,color);
+    gfx_line(cr,0,-2,0,2,1,color); */
+    layout = gfx_prep_text(im, x, color, font, size, tabwidth, text);
+    pango_layout_get_pixel_extents(layout, &ink_rect, &log_rect);
+    cairo_rotate(cr, -angle * G_PI / 180.0);
+    sx = log_rect.x;
+    switch (h_align) {
+    case GFX_H_RIGHT:
+        sx -= log_rect.width;
         break;
-      case '\n':
-        fputs("\\n", fp);
+    case GFX_H_CENTER:
+        sx -= log_rect.width / 2;
         break;
-      case '\r':
-        fputs("\\r", fp);
+    case GFX_H_LEFT:
         break;
-      case '\t':
-        fputs("\\t", fp);
+    case GFX_H_NULL:
         break;
-      default:
-        if (ch > 255) {
-            fputc('?', fp);
-        } else if (ch >= 126 || ch < 32) {
-          fprintf(fp, "\\%03o", (unsigned int)ch);
-          lineLen += 3;
-        } else {
-          fputc(ch, fp);
-        }
-      }
-      p++;
-  }
-#ifdef HAVE_MBSTOWCS
-  free(cstr);
-#endif
-  if (node->angle) {
-        /* can't use svg_write_number as 2 decimals is far from enough to avoid
-               skewed text */
-         fprintf(fp, ") [%f %f %f %f %f %f] T2\n",
-                         g.ma, g.mb, g.mc, g.md, g.tmx, g.tmy);
-  } else {
-         fputs(") ", fp);
-         svg_write_number(fp, g.tmx);
-         fputs(" ", fp);
-         svg_write_number(fp, g.tmy);
-         fputs(" T\n", fp);
-  }
-}
-
-static int eps_write_content(eps_state *state)
-{
-  gfx_node_t *node;
-  fputs("%\n", state->fp);
-  for (node = state->canvas->firstnode; node; node = node->next) {
-    switch (node->type) {
-    case GFX_LINE:
-    case GFX_AREA:
-      eps_write_linearea(state, node);
-      break;
-    case GFX_TEXT:
-      eps_write_text(state, node);
-      break;
     }
-  }
-  return 0;
-}
-
-int       gfx_render_eps (gfx_canvas_t *canvas,
-                 art_u32 width, art_u32 height,
-                 gfx_color_t background, FILE *fp){
-  struct eps_state state;
-  state.fp = fp;
-  state.canvas = canvas;
-  state.page_width = width;
-  state.page_height = height;
-  state.font = "no-default-font";
-  state.font_size = -1;
-  state.color = 0; /* black */
-  state.font_list = NULL;
-  state.linecap = -1;
-  state.linejoin = -1;
-  state.has_dash = 0;
-  state.line_width = 1;
-  if (eps_prologue(&state) == -1)
-    return -1;
-  eps_set_color(&state, background);
-  fprintf(fp, "0 0 M 0 %d L %d %d L %d 0 L fill\n",
-      height, width, height, width);
-  if (eps_write_content(&state) == -1)
-    return 0;
-  fputs("showpage\n", fp);
-  fputs("%%EOF\n", fp);
-  while (state.font_list) {
-    eps_font *next = state.font_list->next;
-    free(state.font_list);
-    state.font_list = next;
-  }
-  return 0;
-}
-
-/* ------- PDF -------
-   PDF references page:
-   http://partners.adobe.com/public/developer/pdf/index_reference.html
-*/
-
-typedef struct pdf_buffer
-{
-  int id, is_obj, is_dict, is_stream, pdf_file_pos;
-  char *data;
-  int alloc_size, current_size;
-  struct pdf_buffer *previous_buffer, *next_buffer;
-  struct pdf_state *state;
-} pdf_buffer;
-
-typedef struct pdf_font
-{
-  const char *ps_font;
-  pdf_buffer obj;
-  struct pdf_font *next;
-} pdf_font;
-
-typedef struct pdf_state
-{
-  FILE *fp;
-  gfx_canvas_t *canvas;
-  art_u32 page_width, page_height;
-  pdf_font *font_list;
-  pdf_buffer *first_buffer, *last_buffer;
-  int pdf_file_pos;
-  int has_failed;
-  /*--*/
-  gfx_color_t stroke_color, fill_color;
-  int font_id;
-  double font_size;
-  double line_width;
-  svg_dash dash;
-  int linecap, linejoin;
-  int last_obj_id;
-  /*--*/
-  pdf_buffer pdf_header;
-  pdf_buffer info_obj, catalog_obj, pages_obj, page1_obj;
-  pdf_buffer fontsdict_obj;
-  pdf_buffer graph_stream;
-} pdf_state;
-
-static void pdf_init_buffer(pdf_state *state, pdf_buffer *buf)
-{
-  int initial_size = 32;
-  buf->state = state;
-  buf->id = -42;
-  buf->alloc_size = 0;
-  buf->current_size = 0;
-  buf->data = (char*)malloc(initial_size);
-  buf->is_obj = 0;
-  buf->previous_buffer = NULL;
-  buf->next_buffer = NULL;
-  if (buf->data == NULL) {
-    rrd_set_error("malloc for pdf_buffer data");
-    state->has_failed = 1;
-    return;
-  }
-  buf->alloc_size = initial_size;
-  if (state->last_buffer)
-    state->last_buffer->next_buffer = buf;
-  if (state->first_buffer == NULL)
-    state->first_buffer = buf;
-  buf->previous_buffer = state->last_buffer;
-  state->last_buffer = buf;
-}
-
-static void pdf_put(pdf_buffer *buf, const char *text, int len)
-{
-  if (len <= 0)
-    return;
-  if (buf->alloc_size < buf->current_size + len) {
-    int new_size = buf->alloc_size;
-    char *new_buf;
-    while (new_size < buf->current_size + len)
-      new_size *= 4;
-    new_buf = (char*)malloc(new_size);
-    if (new_buf == NULL) {
-      rrd_set_error("re-malloc for pdf_buffer data");
-      buf->state->has_failed = 1;
-      return;
-    }
-    memcpy(new_buf, buf->data, buf->current_size);
-    free(buf->data);
-    buf->data = new_buf;
-    buf->alloc_size = new_size;
-  }
-  memcpy(buf->data + buf->current_size, text, len);
-  buf->current_size += len;
-}
-
-static void pdf_put_char(pdf_buffer *buf, char c)
-{
-    if (buf->alloc_size >= buf->current_size + 1) {
-       buf->data[buf->current_size++] = c;
-    } else {
-       char tmp[1];
-       tmp[0] = (char)c;
-       pdf_put(buf, tmp, 1);
-    }
-}
-
-static void pdf_puts(pdf_buffer *buf, const char *text)
-{
-  pdf_put(buf, text, strlen(text));
-}
-
-static void pdf_indent(pdf_buffer *buf)
-{
-  pdf_puts(buf, "\t");
-}
-
-static void pdf_putsi(pdf_buffer *buf, const char *text)
-{
-  pdf_indent(buf);
-  pdf_puts(buf, text);
-}
-
-static void pdf_putint(pdf_buffer *buf, int i)
-{
-  char tmp[20];
-  sprintf(tmp, "%d", i);
-  pdf_puts(buf, tmp);
-}
-
-static void pdf_putnumber(pdf_buffer *buf, double d)
-{
-  char tmp[50];
-  svg_format_number(tmp, sizeof(tmp), d);
-  pdf_puts(buf, tmp);
-}
-
-static void pdf_put_string_contents_wide(pdf_buffer *buf, const afm_char *text)
-{
-    const afm_char *p = text;
-    while (1) {
-       afm_char ch = *p;
-       ch = afm_fix_osx_charset(ch); /* unsafe macro */
-       switch (ch) {
-           case 0:
-               return;
-           case '(':
-               pdf_puts(buf, "\\(");
-               break;
-           case ')':
-               pdf_puts(buf, "\\)");
-               break;
-           case '\\':
-               pdf_puts(buf, "\\\\");
-               break;
-           case '\n':
-               pdf_puts(buf, "\\n");
-               break;
-           case '\r':
-               pdf_puts(buf, "\\r");
-               break;
-           case '\t':
-               pdf_puts(buf, "\\t");
-               break;
-           default:
-               if (ch > 255) {
-                   pdf_put_char(buf, '?');
-               } else if (ch > 125 || ch < 32) {
-                   pdf_put_char(buf, ch);
-               } else {
-                   char tmp[10];
-                   snprintf(tmp, sizeof(tmp), "\\%03o", (int)ch);
-                   pdf_puts(buf, tmp);
-               }
-       }
-       p++;
-    }
-}
-
-static void pdf_put_string_contents(pdf_buffer *buf, const char *text)
-{
-#ifdef HAVE_MBSTOWCS
-    size_t clen = strlen(text) + 1;
-    wchar_t *cstr = malloc(sizeof(wchar_t) * clen);
-    int text_count = mbstowcs(cstr, text, clen);
-    if (text_count == -1)
-       text_count = mbstowcs(cstr, "Enc-Err", 6);
-    pdf_put_string_contents_wide(buf, cstr);
-#if 0
-    if (*text == 'W') {
-       fprintf(stderr, "Decoding utf8 for '%s'\n", text);
-       wchar_t *p = cstr;
-       char *pp = text;
-       fprintf(stderr, "sz wc = %d\n", sizeof(wchar_t));
-       while (*p) {
-           fprintf(stderr, "  %d = %c  versus %d = %c\n", *p, (char)*p, 255 & (int)*pp, *pp);
-           p++;
-           pp++;
-       }
-    }
-#endif
-    free(cstr);
-#else
-    pdf_put_string_contents_wide(buf, text);
-#endif
-}
-
-static void pdf_init_object(pdf_state *state, pdf_buffer *buf)
-{
-  pdf_init_buffer(state, buf);
-  buf->id = ++state->last_obj_id;
-  buf->is_obj = 1;
-  buf->is_stream = 0;
-}
-
-static void pdf_init_dict(pdf_state *state, pdf_buffer *buf)
-{
-  pdf_init_object(state, buf);
-  buf->is_dict = 1;
-}
-
-static void pdf_set_color(pdf_buffer *buf, gfx_color_t color,
-       gfx_color_t *current_color, const char *op)
-{
-#if USE_PDF_FAKE_ALPHA
-   double a1, a2;
-#endif
-   /* gfx_color_t is RRGGBBAA */
-  if (*current_color == color)
-    return;
-#if USE_PDF_FAKE_ALPHA
-  a1 = (color & 255) / 255.0;
-  a2 = 1 - a1;
-#define pdf_color_calc(x) ( ((x)  & 255) / 255.0 * a1 + a2)
-#else
-#define pdf_color_calc(x) ( ((x)  & 255) / 255.0)
-#endif
-  pdf_putnumber(buf, pdf_color_calc(color >> 24));
-  pdf_puts(buf, " ");
-  pdf_putnumber(buf, pdf_color_calc(color >> 16));
-  pdf_puts(buf, " ");
-  pdf_putnumber(buf, pdf_color_calc(color >>  8));
-  pdf_puts(buf, " ");
-  pdf_puts(buf, op);
-  pdf_puts(buf, "\n");
-  *current_color = color;
-}
-
-static void pdf_set_stroke_color(pdf_buffer *buf, gfx_color_t color)
-{
-    pdf_set_color(buf, color, &buf->state->stroke_color, "RG");
-}
-
-static void pdf_set_fill_color(pdf_buffer *buf, gfx_color_t color)
-{
-    pdf_set_color(buf, color, &buf->state->fill_color, "rg");
-}
-
-static pdf_font *pdf_find_font(pdf_state *state, gfx_node_t *node)
-{
-  const char *ps_font = afm_get_font_postscript_name(node->filename);
-  pdf_font *ef;
-  for (ef = state->font_list; ef; ef = ef->next) {
-    if (!strcmp(ps_font, ef->ps_font))
-      return ef;
-  }
-  return NULL;
-}
-
-static void pdf_add_font(pdf_state *state, gfx_node_t *node)
-{
-  pdf_font *ef = pdf_find_font(state, node);
-  if (ef)
-    return;
-  ef = malloc(sizeof(pdf_font));
-  if (ef == NULL) {
-    rrd_set_error("malloc for pdf_font");
-    state->has_failed = 1;
-    return;
-  }
-  pdf_init_dict(state, &ef->obj);
-  ef->next = state->font_list;
-  ef->ps_font = afm_get_font_postscript_name(node->filename);
-  state->font_list = ef;
-  /* fonts dict */
-  pdf_putsi(&state->fontsdict_obj, "/F");
-  pdf_putint(&state->fontsdict_obj, ef->obj.id);
-  pdf_puts(&state->fontsdict_obj, " ");
-  pdf_putint(&state->fontsdict_obj, ef->obj.id);
-  pdf_puts(&state->fontsdict_obj, " 0 R\n");
-  /* fonts def */
-  pdf_putsi(&ef->obj, "/Type /Font\n");
-  pdf_putsi(&ef->obj, "/Subtype /Type1\n");
-  pdf_putsi(&ef->obj, "/Name /F");
-  pdf_putint(&ef->obj, ef->obj.id);
-  pdf_puts(&ef->obj, "\n");
-  pdf_putsi(&ef->obj, "/BaseFont /");
-  pdf_puts(&ef->obj, ef->ps_font);
-  pdf_puts(&ef->obj, "\n");
-  pdf_putsi(&ef->obj, "/Encoding /WinAnsiEncoding\n");
-  /*  'Cp1252' (this is latin 1 extended with 27 characters;
-      the encoding is also known as 'winansi')
-      http://www.lowagie.com/iText/tutorial/ch09.html */
-}
-
-static void pdf_create_fonts(pdf_state *state)
-{
-  gfx_node_t *node;
-  for (node = state->canvas->firstnode; node; node = node->next) {
-    if (node->type == GFX_TEXT)
-      pdf_add_font(state, node);
-  }
-}
-
-static void pdf_write_linearea(pdf_state *state, gfx_node_t *node)
-{
-  int i;
-  pdf_buffer *s = &state->graph_stream;
-  if (node->type == GFX_LINE) {
-    svg_dash dash_info;
-    svg_get_dash(node, &dash_info);
-    if (!svg_dash_equal(&dash_info, &state->dash)) {
-      state->dash = dash_info;
-      if (dash_info.dash_enable) {
-       pdf_puts(s, "[");
-       pdf_putnumber(s, dash_info.adjusted_on);
-       pdf_puts(s, " ");
-       pdf_putnumber(s, dash_info.adjusted_off);
-       pdf_puts(s, "] ");
-       pdf_putnumber(s, dash_info.dash_offset);
-       pdf_puts(s, " d\n");
-      } else {
-       pdf_puts(s, "[] 0 d\n");
-      }
-    }
-    pdf_set_stroke_color(s, node->color);
-    if (state->linecap != 1) {
-      pdf_puts(s, "1 j\n");
-      state->linecap = 1;
-    }
-    if (state->linejoin != 1) {
-      pdf_puts(s, "1 J\n");
-      state->linejoin = 1;
-    }
-    if (node->size != state->line_width) {
-      state->line_width = node->size;
-      pdf_putnumber(s, state->line_width);
-      pdf_puts(s, " w\n");
-    }
-  } else {
-    pdf_set_fill_color(s, node->color);
-  }
-  for (i = 0; i < node->points; i++) {
-    ArtVpath *vec = node->path + i;
-    double x = vec->x;
-    double y = state->page_height - vec->y;
-    if (node->type == GFX_AREA) {
-      x += LINEOFFSET; /* adjust for libart handling of areas */
-      y -= LINEOFFSET;
-    }
-    switch (vec->code) {
-    case ART_MOVETO_OPEN: /* fall-through */
-    case ART_MOVETO:
-      pdf_putnumber(s, x);
-      pdf_puts(s, " ");
-      pdf_putnumber(s, y);
-      pdf_puts(s, " m\n");
-      break;
-    case ART_LINETO:
-      pdf_putnumber(s, x);
-      pdf_puts(s, " ");
-      pdf_putnumber(s, y);
-      pdf_puts(s, " l\n");
-      break;
-    case ART_CURVETO: break; /* unsupported */
-    case ART_END: break; /* nop */
+    sy = log_rect.y;
+    switch (v_align) {
+    case GFX_V_TOP:
+        break;
+    case GFX_V_CENTER:
+        sy -= log_rect.height / 2;
+        break;
+    case GFX_V_BOTTOM:
+        sy -= log_rect.height;
+        break;
+    case GFX_V_NULL:
+        break;
     }
-  }
-  if (node->type == GFX_LINE) {
-    pdf_puts(s, node->closed_path ? "s\n" : "S\n");
-   } else {
-    pdf_puts(s, "f\n");
-   }
-}
+    pango_cairo_update_layout(cr, layout);
+    cairo_move_to(cr, sx, sy);
+    pango_cairo_show_layout(cr, layout);
+    pango_tab_array_free(pango_layout_get_tabs(layout));
+    g_object_unref(layout);
+    cairo_restore(cr);
 
-
-static void pdf_write_matrix(pdf_state *state, gfx_node_t *node, pdf_coords *g, int useTM)
-{
-       char tmp[150];
-       pdf_buffer *s = &state->graph_stream;
-       if (node->angle == 0) {
-               pdf_puts(s, "1 0 0 1 ");
-               pdf_putnumber(s, useTM ? g->tmx : g->mx);
-               pdf_puts(s, " ");
-               pdf_putnumber(s, useTM ? g->tmy : g->my);
-       } else {
-                /* can't use svg_write_number as 2 decimals is far from enough to avoid
-                       skewed text */
-               sprintf(tmp, "%f %f %f %f %f %f",
-                               g->ma, g->mb, g->mc, g->md, 
-                               useTM ? g->tmx : g->mx,
-                               useTM ? g->tmy : g->my);
-               pdf_puts(s, tmp);
-       }
 }
 
-static void pdf_write_text(pdf_state *state, gfx_node_t *node, 
-    int last_was_text, int next_is_text)
+/* convert color */
+struct gfx_color_t gfx_hex_to_col(
+    long unsigned int color)
 {
-  pdf_coords g;
-  pdf_buffer *s = &state->graph_stream;
-  pdf_font *font = pdf_find_font(state, node);
-  if (font == NULL) {
-    rrd_set_error("font disappeared");
-    state->has_failed = 1;
-    return;
-  }
-  pdf_calc(state->page_height, node, &g);
-#if PDF_CALC_DEBUG
-  pdf_puts(s, "q % debug green box\n");
-  pdf_write_matrix(state, node, &g, 0);
-  pdf_puts(s, " cm\n");
-  pdf_set_fill_color(s, 0x90FF9000);
-  pdf_puts(s, "0 0.4 0 rg\n");
-  pdf_puts(s, "0 0 ");
-  pdf_putnumber(s, g.sizep.x);
-  pdf_puts(s, " ");
-  pdf_putnumber(s, g.sizep.y);
-  pdf_puts(s, " re\n");
-  pdf_puts(s, "f\n");
-  pdf_puts(s, "Q\n");
-#endif
-  pdf_set_fill_color(s, node->color);
-  if (PDF_CALC_DEBUG || !last_was_text)
-    pdf_puts(s, "BT\n");
-  if (state->font_id != font->obj.id || node->size != state->font_size) {
-    state->font_id = font->obj.id;
-    state->font_size = node->size;
-    pdf_puts(s, "/F");
-    pdf_putint(s, font->obj.id);
-    pdf_puts(s, " ");
-    pdf_putnumber(s, node->size);
-    pdf_puts(s, " Tf\n");
-  }
-  pdf_write_matrix(state, node, &g, 1);
-  pdf_puts(s, " Tm\n");
-  pdf_puts(s, "(");
-  pdf_put_string_contents(s, node->text);
-  pdf_puts(s, ") Tj\n");
-  if (PDF_CALC_DEBUG || !next_is_text)
-    pdf_puts(s, "ET\n");
-}
-static void pdf_write_content(pdf_state *state)
-{
-  gfx_node_t *node;
-  int last_was_text = 0, next_is_text;
-  for (node = state->canvas->firstnode; node; node = node->next) {
-    switch (node->type) {
-    case GFX_LINE:
-    case GFX_AREA:
-      pdf_write_linearea(state, node);
-      break;
-    case GFX_TEXT:
-      next_is_text = node->next && node->next->type == GFX_TEXT;
-      pdf_write_text(state, node, last_was_text, next_is_text);
-      break;
-    }
-    last_was_text = node->type == GFX_TEXT;
-  }
-}
+    struct gfx_color_t gfx_color;
 
-static void pdf_init_document(pdf_state *state)
-{
-  pdf_init_buffer(state, &state->pdf_header);
-  pdf_init_dict(state, &state->catalog_obj);
-  pdf_init_dict(state, &state->info_obj);
-  pdf_init_dict(state, &state->pages_obj);
-  pdf_init_dict(state, &state->page1_obj);
-  pdf_init_dict(state, &state->fontsdict_obj);
-  pdf_create_fonts(state);
-  if (state->has_failed)
-    return;
-  /* make stream last object in file */
-  pdf_init_object(state, &state->graph_stream);
-  state->graph_stream.is_stream = 1;
+    gfx_color.red = 1.0 / 255.0 * ((color & 0xff000000) >> (3 * 8));
+    gfx_color.green = 1.0 / 255.0 * ((color & 0x00ff0000) >> (2 * 8));
+    gfx_color.blue = 1.0 / 255.0 * ((color & 0x0000ff00) >> (1 * 8));
+    gfx_color.alpha = 1.0 / 255.0 * (color & 0x000000ff);
+    return gfx_color;
 }
 
-static void pdf_setup_document(pdf_state *state)
-{
-  const char *creator = "RRDtool " PACKAGE_VERSION " Tobias Oetiker, http://tobi.oetiker.ch";
-  /* all objects created by now, so init code can reference them */
-  /* HEADER */
-  pdf_puts(&state->pdf_header, "%PDF-1.3\n");
-  /* following 8 bit comment is recommended by Adobe for
-     indicating binary file to file transfer applications */
-  pdf_puts(&state->pdf_header, "%\xE2\xE3\xCF\xD3\n");
-  /* INFO */
-  pdf_putsi(&state->info_obj, "/Creator (");
-  pdf_put_string_contents(&state->info_obj, creator);
-  pdf_puts(&state->info_obj, ")\n");
-  /* CATALOG */
-  pdf_putsi(&state->catalog_obj, "/Type /Catalog\n");
-  pdf_putsi(&state->catalog_obj, "/Pages ");
-  pdf_putint(&state->catalog_obj, state->pages_obj.id);
-  pdf_puts(&state->catalog_obj, " 0 R\n");
-  /* PAGES */
-  pdf_putsi(&state->pages_obj, "/Type /Pages\n");
-  pdf_putsi(&state->pages_obj, "/Kids [");
-  pdf_putint(&state->pages_obj, state->page1_obj.id);
-  pdf_puts(&state->pages_obj, " 0 R]\n");
-  pdf_putsi(&state->pages_obj, "/Count 1\n");
-  /* PAGE 1 */
-  pdf_putsi(&state->page1_obj, "/Type /Page\n");
-  pdf_putsi(&state->page1_obj, "/Parent ");
-  pdf_putint(&state->page1_obj, state->pages_obj.id);
-  pdf_puts(&state->page1_obj, " 0 R\n");
-  pdf_putsi(&state->page1_obj, "/MediaBox [0 0 ");
-  pdf_putint(&state->page1_obj, state->page_width);
-  pdf_puts(&state->page1_obj, " ");
-  pdf_putint(&state->page1_obj, state->page_height);
-  pdf_puts(&state->page1_obj, "]\n");
-  pdf_putsi(&state->page1_obj, "/Contents ");
-  pdf_putint(&state->page1_obj, state->graph_stream.id);
-  pdf_puts(&state->page1_obj, " 0 R\n");
-  pdf_putsi(&state->page1_obj, "/Resources << /Font ");
-  pdf_putint(&state->page1_obj, state->fontsdict_obj.id);
-  pdf_puts(&state->page1_obj, " 0 R >>\n");
-}
+/* gridfit_lines */
 
-static void pdf_write_string_to_file(pdf_state *state, const char *text)
+void gfx_line_fit(
+    image_desc_t *im,
+    double *x,
+    double *y)
 {
-    fputs(text, state->fp);
-    state->pdf_file_pos += strlen(text);
-}
+    cairo_t  *cr = im->cr;
+    double    line_width;
+    double    line_height;
 
-static void pdf_write_buf_to_file(pdf_state *state, pdf_buffer *buf)
-{
-  char tmp[40];
-  buf->pdf_file_pos = state->pdf_file_pos;
-  if (buf->is_obj) {
-    snprintf(tmp, sizeof(tmp), "%d 0 obj\n", buf->id);
-    pdf_write_string_to_file(state, tmp);
-  }
-  if (buf->is_dict)
-    pdf_write_string_to_file(state, "<<\n");
-  if (buf->is_stream) {
-    snprintf(tmp, sizeof(tmp), "<< /Length %d >>\n", buf->current_size);
-    pdf_write_string_to_file(state, tmp);
-    pdf_write_string_to_file(state, "stream\n");
-  }
-  fwrite(buf->data, 1, buf->current_size, state->fp);
-  state->pdf_file_pos += buf->current_size;
-  if (buf->is_stream)
-    pdf_write_string_to_file(state, "endstream\n");
-  if (buf->is_dict)
-    pdf_write_string_to_file(state, ">>\n");
-  if (buf->is_obj)
-    pdf_write_string_to_file(state, "endobj\n");
+    if (!im->gridfit)
+        return;
+    cairo_user_to_device(cr, x, y);
+    line_width = cairo_get_line_width(cr);
+    line_height = line_width;
+    cairo_user_to_device_distance(cr, &line_width, &line_height);
+    line_width = line_width / 2.0 - (long) (line_width / 2.0);
+    line_height = line_height / 2.0 - (long) (line_height / 2.0);
+    *x = (double) ((long) (*x + 0.5)) - line_width;
+    *y = (double) ((long) (*y + 0.5)) + line_height;
+    cairo_device_to_user(cr, x, y);
 }
 
-static void pdf_write_to_file(pdf_state *state)
-{
-  pdf_buffer *buf = state->first_buffer;
-  int xref_pos;
-  state->pdf_file_pos = 0;
-  pdf_write_buf_to_file(state, &state->pdf_header);
-  while (buf) {
-    if (buf->is_obj)
-      pdf_write_buf_to_file(state, buf);
-    buf = buf->next_buffer;
-  }
-  xref_pos = state->pdf_file_pos;
-  fprintf(state->fp, "xref\n");
-  fprintf(state->fp, "%d %d\n", 0, state->last_obj_id + 1);
-  /* TOC lines must be exactly 20 bytes including \n */
-  fprintf(state->fp, "%010d %05d f\x20\n", 0, 65535);
-  for (buf = state->first_buffer; buf; buf = buf->next_buffer) {
-    if (buf->is_obj)
-      fprintf(state->fp, "%010d %05d n\x20\n", buf->pdf_file_pos, 0);
-  }
-  fprintf(state->fp, "trailer\n");
-  fprintf(state->fp, "<<\n");
-  fprintf(state->fp, "\t/Size %d\n", state->last_obj_id + 1);
-  fprintf(state->fp, "\t/Root %d 0 R\n", state->catalog_obj.id);
-  fprintf(state->fp, "\t/Info %d 0 R\n", state->info_obj.id);
-  fprintf(state->fp, ">>\n");
-  fprintf(state->fp, "startxref\n");
-  fprintf(state->fp, "%d\n", xref_pos);
-  fputs("%%EOF\n", state->fp);
-}
+/* gridfit_areas */
 
-static void pdf_free_resources(pdf_state *state)
+void gfx_area_fit(
+    image_desc_t *im,
+    double *x,
+    double *y)
 {
-  pdf_buffer *buf = state->first_buffer;
-  while (buf) {
-    free(buf->data);
-    buf->data = NULL;
-    buf->alloc_size = buf->current_size = 0;
-    buf = buf->next_buffer;
-  }
-  while (state->font_list) {
-    pdf_font *next = state->font_list->next;
-    free(state->font_list);
-    state->font_list = next;
-  }
-}
+    cairo_t  *cr = im->cr;
 
-int       gfx_render_pdf (gfx_canvas_t *canvas,
-                 art_u32 width, art_u32 height,
-                 gfx_color_t UNUSED(background), FILE *fp){
-  struct pdf_state state;
-  memset(&state, 0, sizeof(pdf_state));
-  state.fp = fp;
-  state.canvas = canvas;
-  state.page_width = width;
-  state.page_height = height;
-  state.font_id = -1;
-  state.font_size = -1;
-  state.font_list = NULL;
-  state.linecap = -1;
-  state.linejoin = -1;
-  pdf_init_document(&state);
-  /*
-  pdf_set_color(&state, background);
-  fprintf(fp, "0 0 M 0 %d L %d %d L %d 0 L fill\n",
-      height, width, height, width);
-  */
-  if (!state.has_failed)
-    pdf_write_content(&state);
-  if (!state.has_failed)
-    pdf_setup_document(&state);
-  if (!state.has_failed)
-    pdf_write_to_file(&state);
-  pdf_free_resources(&state);
-  return state.has_failed ? -1 : 0;
+    if (!im->gridfit)
+        return;
+    cairo_user_to_device(cr, x, y);
+    *x = (double) ((long) (*x + 0.5));
+    *y = (double) ((long) (*y + 0.5));
+    cairo_device_to_user(cr, x, y);
 }
-
diff --git a/src/rrd_gfx.h b/src/rrd_gfx.h
deleted file mode 100644 (file)
index 15680a1..0000000
+++ /dev/null
@@ -1,135 +0,0 @@
-/****************************************************************************
- * RRDtool 1.2.27  Copyright by Tobi Oetiker, 1997-2008
- ****************************************************************************
- * rrd_gfx.h generic graphics adapter library
- ****************************************************************************/
-
-#ifndef  RRD_GFX_H
-#define RRD_GFX_H
-#define LIBART_COMPILATION
-
-#define y0 libart_y0
-#define y1 libart_y1
-#define gamma libart_gamma
-#include <libart_lgpl/libart.h>
-#include <libart_lgpl/art_rgba.h>
-#include "art_rgba_svp.h"
-#undef gamma
-#undef y0
-#undef y1
-
-
-enum gfx_if_en {IF_PNG=0,IF_SVG,IF_EPS,IF_PDF};
-enum gfx_en { GFX_LINE=0,GFX_AREA,GFX_TEXT };
-enum gfx_h_align_en { GFX_H_NULL=0, GFX_H_LEFT, GFX_H_RIGHT, GFX_H_CENTER };
-enum gfx_v_align_en { GFX_V_NULL=0, GFX_V_TOP,  GFX_V_BOTTOM, GFX_V_CENTER };
-enum gfx_aa_type_en {AA_NORMAL=0,AA_LIGHT,AA_NONE};
-typedef unsigned long gfx_color_t;
-
-typedef struct  gfx_node_t {
-  enum gfx_en   type;         /* type of graph element */
-  gfx_color_t   color;        /* color of element  0xRRGGBBAA  alpha 0xff is solid*/
-  double        size;         /* font size, line width */
-  double        dash_on, dash_off; /* dash line fragments lengths */
-  int           closed_path;
-  int           points;
-  int           points_max;
-  char *filename;             /* font or image filename */
-  char *text;
-  ArtVpath      *path;        /* path */
-  double        x,y;          /* position */
-  double        angle;        /* text angle */
-  enum gfx_h_align_en halign; /* text alignement */
-  enum gfx_v_align_en valign; /* text alignement */
-  double        tabwidth; 
-  struct gfx_node_t  *next; 
-} gfx_node_t;
-
-
-typedef struct gfx_canvas_t 
-{
-    struct gfx_node_t *firstnode;
-    struct gfx_node_t *lastnode;
-    enum gfx_if_en imgformat;      /* image format */
-    int            interlaced;     /* will the graph be interlaced? */
-    double         zoom;           /* zoom for graph */
-    double         font_aa_threshold; /* no anti-aliasing for sizes <= */
-    enum gfx_aa_type_en aa_type;   /* anti-aliasing type (normal/light/none) */
-} gfx_canvas_t;
-
-gfx_canvas_t *gfx_new_canvas (void);
-
-/* create a new line */
-gfx_node_t   *gfx_new_line   (gfx_canvas_t *canvas, 
-                             double X0, double Y0, 
-                             double X1, double Y1,
-                             double width, gfx_color_t color);
-
-gfx_node_t   *gfx_new_dashed_line   (gfx_canvas_t *canvas, 
-                             double X0, double Y0, 
-                             double X1, double Y1,
-                             double width, gfx_color_t color,
-                             double dash_on, double dash_off);
-
-/* create a new area */
-gfx_node_t   *gfx_new_area   (gfx_canvas_t *canvas, 
-                             double X0, double Y0,
-                             double X1, double Y1,
-                             double X2, double Y2,
-                             gfx_color_t  color);
-
-/* add a point to a line or to an area */
-int           gfx_add_point  (gfx_node_t *node, double x, double y);
-
-/* close current path so it ends at the same point as it started */
-void          gfx_close_path  (gfx_node_t *node);
-
-
-/* create a text node */
-gfx_node_t   *gfx_new_text   (gfx_canvas_t *canvas,  
-                             double x, double y, gfx_color_t color,
-                             char* font, double size,                        
-                             double tabwidth, double angle,
-                             enum gfx_h_align_en h_align,
-                             enum gfx_v_align_en v_align,
-                              char* text);
-
-/* measure width of a text string */
-double gfx_get_text_width ( gfx_canvas_t *canvas,
-                           double start, char* font, double size,
-                           double tabwidth, char* text, int rotation);
-
-/* save image to file */
-int       gfx_render (gfx_canvas_t *canvas,
-                              art_u32 width, art_u32 height,
-                              gfx_color_t background, FILE *fo);
-
-/* free memory used by nodes this will also remove memory required for
-   node chain and associated material */
-int           gfx_destroy    (gfx_canvas_t *canvas); 
-
-
-/* PNG support*/
-int       gfx_render_png (gfx_canvas_t *canvas,
-                              art_u32 width, art_u32 height,
-                              gfx_color_t background, FILE *fo);
-double gfx_get_text_width_libart ( gfx_canvas_t *canvas, double start, 
-                char* font, double size, double tabwidth, 
-                char* text, int rotation );
-
-/* SVG support */
-int       gfx_render_svg (gfx_canvas_t *canvas,
-                              art_u32 width, art_u32 height,
-                              gfx_color_t background, FILE *fo);
-
-/* EPS support */
-int       gfx_render_eps (gfx_canvas_t *canvas,
-                              art_u32 width, art_u32 height,
-                              gfx_color_t background, FILE *fo);
-
-/* PDF support */
-int       gfx_render_pdf (gfx_canvas_t *canvas,
-                              art_u32 width, art_u32 height,
-                              gfx_color_t background, FILE *fo);
-
-#endif
index deb23cf4723fc017671321f39c24e3d3fff46bfc..abebde707c94040e0571518e91631dfd8e4d300c 100644 (file)
@@ -1,5 +1,5 @@
 /****************************************************************************
- * RRDtool 1.2.27  Copyright by Tobi Oetiker, 1997-2008
+ * RRDtool 1.3rc4  Copyright by Tobi Oetiker, 1997-2008
  ****************************************************************************
  * rrd__graph.c  produce graphs from data in rrdfiles
  ****************************************************************************/
 
 #ifndef RRD_DEFAULT_FONT
 /* there is special code later to pick Cour.ttf when running on windows */
-#define RRD_DEFAULT_FONT "DejaVuSansMono-Roman.ttf"
+#define RRD_DEFAULT_FONT "DejaVu Sans Mono,Bitstream Vera Sans Mono,monospace,Courier"
 #endif
 
-text_prop_t text_prop[] = {   
-     { 8.0, RRD_DEFAULT_FONT }, /* default */
-     { 9.0, RRD_DEFAULT_FONT }, /* title */
-     { 7.0,  RRD_DEFAULT_FONT }, /* axis */
-     { 8.0, RRD_DEFAULT_FONT }, /* unit */
-     { 8.0, RRD_DEFAULT_FONT }  /* legend */
+text_prop_t text_prop[] = {
+    {8.0, RRD_DEFAULT_FONT}
+    ,                   /* default */
+    {9.0, RRD_DEFAULT_FONT}
+    ,                   /* title */
+    {7.0, RRD_DEFAULT_FONT}
+    ,                   /* axis */
+    {8.0, RRD_DEFAULT_FONT}
+    ,                   /* unit */
+    {8.0, RRD_DEFAULT_FONT} /* legend */
 };
 
-xlab_t xlab[] = {
-    {0,                 0,   TMT_SECOND,30, TMT_MINUTE,5,  TMT_MINUTE,5,         0,"%H:%M"},
-    {2,                 0,   TMT_MINUTE,1,  TMT_MINUTE,5,  TMT_MINUTE,5,         0,"%H:%M"},
-    {5,                 0,   TMT_MINUTE,2,  TMT_MINUTE,10, TMT_MINUTE,10,        0,"%H:%M"},
-    {10,                0,   TMT_MINUTE,5,  TMT_MINUTE,20, TMT_MINUTE,20,        0,"%H:%M"},
-    {30,                0,   TMT_MINUTE,10, TMT_HOUR,1,    TMT_HOUR,1,           0,"%H:%M"},
-    {60,                0,   TMT_MINUTE,30, TMT_HOUR,2,    TMT_HOUR,2,           0,"%H:%M"},
-    {60,          24*3600,   TMT_MINUTE,30, TMT_HOUR,2,    TMT_HOUR,6,           0,"%a %H:%M"},
-    {180,               0,   TMT_HOUR,1,    TMT_HOUR,6,    TMT_HOUR,6,           0,"%H:%M"},
-    {180,         24*3600,   TMT_HOUR,1,    TMT_HOUR,6,    TMT_HOUR,12,          0,"%a %H:%M"},
-    /*{300,             0,   TMT_HOUR,3,    TMT_HOUR,12,   TMT_HOUR,12,    12*3600,"%a %p"},  this looks silly*/
-    {600,               0,   TMT_HOUR,6,    TMT_DAY,1,     TMT_DAY,1,      24*3600,"%a"},
-    {1200,               0,   TMT_HOUR,6,    TMT_DAY,1,     TMT_DAY,1,      24*3600,"%d"},
-    {1800,              0,   TMT_HOUR,12,   TMT_DAY,1,     TMT_DAY,2,      24*3600,"%a %d"},
-    {2400,              0,   TMT_HOUR,12,   TMT_DAY,1,     TMT_DAY,2,      24*3600,"%a"},
-    {3600,              0,   TMT_DAY,1,     TMT_WEEK,1,    TMT_WEEK,1,   7*24*3600,"Week %V"},
-    {3*3600,            0,   TMT_WEEK,1,    TMT_MONTH,1,   TMT_WEEK,2,   7*24*3600,"Week %V"},
-    {6*3600,            0,   TMT_MONTH,1,   TMT_MONTH,1,   TMT_MONTH,1, 30*24*3600,"%b"},
-    {48*3600,           0,   TMT_MONTH,1,   TMT_MONTH,3,   TMT_MONTH,3, 30*24*3600,"%b"},
-    {315360,            0,   TMT_MONTH,3,   TMT_YEAR,1,    TMT_YEAR,1,  365*24*3600,"%Y"},
-    {10*24*3600,        0,   TMT_YEAR,1,  TMT_YEAR,1,    TMT_YEAR,1, 365*24*3600,"%y"},
-    {-1,0,TMT_MONTH,0,TMT_MONTH,0,TMT_MONTH,0,0,""}
+xlab_t    xlab[] = {
+    {0, 0, TMT_SECOND, 30, TMT_MINUTE, 5, TMT_MINUTE, 5, 0, "%H:%M"}
+    ,
+    {2, 0, TMT_MINUTE, 1, TMT_MINUTE, 5, TMT_MINUTE, 5, 0, "%H:%M"}
+    ,
+    {5, 0, TMT_MINUTE, 2, TMT_MINUTE, 10, TMT_MINUTE, 10, 0, "%H:%M"}
+    ,
+    {10, 0, TMT_MINUTE, 5, TMT_MINUTE, 20, TMT_MINUTE, 20, 0, "%H:%M"}
+    ,
+    {30, 0, TMT_MINUTE, 10, TMT_HOUR, 1, TMT_HOUR, 1, 0, "%H:%M"}
+    ,
+    {60, 0, TMT_MINUTE, 30, TMT_HOUR, 2, TMT_HOUR, 2, 0, "%H:%M"}
+    ,
+    {60, 24 * 3600, TMT_MINUTE, 30, TMT_HOUR, 2, TMT_HOUR, 6, 0, "%a %H:%M"}
+    ,
+    {180, 0, TMT_HOUR, 1, TMT_HOUR, 6, TMT_HOUR, 6, 0, "%H:%M"}
+    ,
+    {180, 24 * 3600, TMT_HOUR, 1, TMT_HOUR, 6, TMT_HOUR, 12, 0, "%a %H:%M"}
+    ,
+    /*{300,             0,   TMT_HOUR,3,    TMT_HOUR,12,   TMT_HOUR,12,    12*3600,"%a %p"},  this looks silly */
+    {600, 0, TMT_HOUR, 6, TMT_DAY, 1, TMT_DAY, 1, 24 * 3600, "%a"}
+    ,
+    {1200, 0, TMT_HOUR, 6, TMT_DAY, 1, TMT_DAY, 1, 24 * 3600, "%d"}
+    ,
+    {1800, 0, TMT_HOUR, 12, TMT_DAY, 1, TMT_DAY, 2, 24 * 3600, "%a %d"}
+    ,
+    {2400, 0, TMT_HOUR, 12, TMT_DAY, 1, TMT_DAY, 2, 24 * 3600, "%a"}
+    ,
+    {3600, 0, TMT_DAY, 1, TMT_WEEK, 1, TMT_WEEK, 1, 7 * 24 * 3600, "Week %V"}
+    ,
+    {3 * 3600, 0, TMT_WEEK, 1, TMT_MONTH, 1, TMT_WEEK, 2, 7 * 24 * 3600,
+     "Week %V"}
+    ,
+    {6 * 3600, 0, TMT_MONTH, 1, TMT_MONTH, 1, TMT_MONTH, 1, 30 * 24 * 3600,
+     "%b"}
+    ,
+    {48 * 3600, 0, TMT_MONTH, 1, TMT_MONTH, 3, TMT_MONTH, 3, 30 * 24 * 3600,
+     "%b"}
+    ,
+    {315360, 0, TMT_MONTH, 3, TMT_YEAR, 1, TMT_YEAR, 1, 365 * 24 * 3600, "%Y"}
+    ,
+    {10 * 24 * 3600, 0, TMT_YEAR, 1, TMT_YEAR, 1, TMT_YEAR, 1,
+     365 * 24 * 3600, "%y"}
+    ,
+    {-1, 0, TMT_MONTH, 0, TMT_MONTH, 0, TMT_MONTH, 0, 0, ""}
 };
 
 /* sensible y label intervals ...*/
 
-ylab_t ylab[]= {
-    {0.1, {1,2, 5,10}},
-    {0.2, {1,5,10,20}},
-    {0.5, {1,2, 4,10}},
-    {1.0,   {1,2, 5,10}},
-    {2.0,   {1,5,10,20}},
-    {5.0,   {1,2, 4,10}},
-    {10.0,  {1,2, 5,10}},
-    {20.0,  {1,5,10,20}},
-    {50.0,  {1,2, 4,10}},
-    {100.0, {1,2, 5,10}},
-    {200.0, {1,5,10,20}},
-    {500.0, {1,2, 4,10}},
-    {0.0,   {0,0,0,0}}};
+ylab_t    ylab[] = {
+    {0.1, {1, 2, 5, 10}
+     }
+    ,
+    {0.2, {1, 5, 10, 20}
+     }
+    ,
+    {0.5, {1, 2, 4, 10}
+     }
+    ,
+    {1.0, {1, 2, 5, 10}
+     }
+    ,
+    {2.0, {1, 5, 10, 20}
+     }
+    ,
+    {5.0, {1, 2, 4, 10}
+     }
+    ,
+    {10.0, {1, 2, 5, 10}
+     }
+    ,
+    {20.0, {1, 5, 10, 20}
+     }
+    ,
+    {50.0, {1, 2, 4, 10}
+     }
+    ,
+    {100.0, {1, 2, 5, 10}
+     }
+    ,
+    {200.0, {1, 5, 10, 20}
+     }
+    ,
+    {500.0, {1, 2, 4, 10}
+     }
+    ,
+    {0.0, {0, 0, 0, 0}
+     }
+};
 
 
 gfx_color_t graph_col[] =   /* default colors */
-{    0xFFFFFFFF,   /* canvas     */
-     0xF0F0F0FF,   /* background */
-     0xD0D0D0FF,   /* shade A    */
-     0xA0A0A0FF,   /* shade B    */
-     0x90909080,   /* grid       */
-     0xE0505080,   /* major grid */
-     0x000000FF,   /* font       */ 
-     0x802020FF,   /* arrow      */
-     0x202020FF,   /* axis       */
-     0x000000FF    /* frame      */ 
-};     
+{
+    {1.00, 1.00, 1.00, 1.00},   /* canvas     */
+    {0.95, 0.95, 0.95, 1.00},   /* background */
+    {0.81, 0.81, 0.81, 1.00},   /* shade A    */
+    {0.62, 0.62, 0.62, 1.00},   /* shade B    */
+    {0.56, 0.56, 0.56, 0.75},   /* grid       */
+    {0.87, 0.31, 0.31, 0.60},   /* major grid */
+    {0.00, 0.00, 0.00, 1.00},   /* font       */
+    {0.50, 0.12, 0.12, 1.00},   /* arrow      */
+    {0.12, 0.12, 0.12, 1.00},   /* axis       */
+    {0.00, 0.00, 0.00, 1.00}    /* frame      */
+};
 
 
 /* #define DEBUG */
@@ -110,47 +164,53 @@ gfx_color_t graph_col[] =   /* default colors */
 
 
 /* initialize with xtr(im,0); */
-int
-xtr(image_desc_t *im,time_t mytime){
+int xtr(
+    image_desc_t *im,
+    time_t mytime)
+{
     static double pixie;
-    if (mytime==0){
-        pixie = (double) im->xsize / (double)(im->end - im->start);
+
+    if (mytime == 0) {
+        pixie = (double) im->xsize / (double) (im->end - im->start);
         return im->xorigin;
     }
-    return (int)((double)im->xorigin 
-                 + pixie * ( mytime - im->start ) );
+    return (int) ((double) im->xorigin + pixie * (mytime - im->start));
 }
 
 /* translate data values into y coordinates */
-double
-ytr(image_desc_t *im, double value){
+double ytr(
+    image_desc_t *im,
+    double value)
+{
     static double pixie;
-    double yval;
-    if (isnan(value)){
-      if(!im->logarithmic)
-        pixie = (double) im->ysize / (im->maxval - im->minval);
-      else 
-        pixie = (double) im->ysize / (log10(im->maxval) - log10(im->minval));
-      yval = im->yorigin;
-    } else if(!im->logarithmic) {
-      yval = im->yorigin - pixie * (value - im->minval);
-    } else {
-      if (value < im->minval) {
+    double    yval;
+
+    if (isnan(value)) {
+        if (!im->logarithmic)
+            pixie = (double) im->ysize / (im->maxval - im->minval);
+        else
+            pixie =
+                (double) im->ysize / (log10(im->maxval) - log10(im->minval));
         yval = im->yorigin;
-      } else {
-        yval = im->yorigin - pixie * (log10(value) - log10(im->minval));
-      }
+    } else if (!im->logarithmic) {
+        yval = im->yorigin - pixie * (value - im->minval);
+    } else {
+        if (value < im->minval) {
+            yval = im->yorigin;
+        } else {
+            yval = im->yorigin - pixie * (log10(value) - log10(im->minval));
+        }
     }
     /* make sure we don't return anything too unreasonable. GD lib can
        get terribly slow when drawing lines outside its scope. This is 
        especially problematic in connection with the rigid option */
-    if (! im->rigid) {
-      /* keep yval as-is */
+    if (!im->rigid) {
+        /* keep yval as-is */
     } else if (yval > im->yorigin) {
-      yval = im->yorigin +0.00001;
-    } else if (yval < im->yorigin - im->ysize){
-      yval = im->yorigin - im->ysize - 0.00001;
-    } 
+        yval = im->yorigin + 0.00001;
+    } else if (yval < im->yorigin - im->ysize) {
+        yval = im->yorigin - im->ysize - 0.00001;
+    }
     return yval;
 }
 
@@ -162,175 +222,203 @@ ytr(image_desc_t *im, double value){
 #define conv_if(VV,VVV) \
    if (strcmp(#VV, string) == 0) return VVV ;
 
-enum gf_en gf_conv(char *string){
-    
-    conv_if(PRINT,GF_PRINT)
-    conv_if(GPRINT,GF_GPRINT)
-    conv_if(COMMENT,GF_COMMENT)
-    conv_if(HRULE,GF_HRULE)
-    conv_if(VRULE,GF_VRULE)
-    conv_if(LINE,GF_LINE)
-    conv_if(AREA,GF_AREA)
-    conv_if(STACK,GF_STACK) 
-    conv_if(TICK,GF_TICK)
-    conv_if(DEF,GF_DEF)
-    conv_if(CDEF,GF_CDEF)
-    conv_if(VDEF,GF_VDEF)
-#ifdef WITH_PIECHART
-    conv_if(PART,GF_PART)
-#endif
-    conv_if(XPORT,GF_XPORT)
-    conv_if(SHIFT,GF_SHIFT)
-    
+enum gf_en gf_conv(
+    char *string)
+{
+
+    conv_if(PRINT, GF_PRINT);
+    conv_if(GPRINT, GF_GPRINT);
+    conv_if(COMMENT, GF_COMMENT);
+    conv_if(HRULE, GF_HRULE);
+    conv_if(VRULE, GF_VRULE);
+    conv_if(LINE, GF_LINE);
+    conv_if(AREA, GF_AREA);
+    conv_if(STACK, GF_STACK);
+    conv_if(TICK, GF_TICK);
+    conv_if(TEXTALIGN, GF_TEXTALIGN);
+    conv_if(DEF, GF_DEF);
+    conv_if(CDEF, GF_CDEF);
+    conv_if(VDEF, GF_VDEF);
+    conv_if(XPORT, GF_XPORT);
+    conv_if(SHIFT, GF_SHIFT);
+
     return (-1);
 }
 
-enum gfx_if_en if_conv(char *string){
-    
-    conv_if(PNG,IF_PNG)
-    conv_if(SVG,IF_SVG)
-    conv_if(EPS,IF_EPS)
-    conv_if(PDF,IF_PDF)
+enum gfx_if_en if_conv(
+    char *string)
+{
+
+    conv_if(PNG, IF_PNG);
+    conv_if(SVG, IF_SVG);
+    conv_if(EPS, IF_EPS);
+    conv_if(PDF, IF_PDF);
 
     return (-1);
 }
 
-enum tmt_en tmt_conv(char *string){
+enum tmt_en tmt_conv(
+    char *string)
+{
 
-    conv_if(SECOND,TMT_SECOND)
-    conv_if(MINUTE,TMT_MINUTE)
-    conv_if(HOUR,TMT_HOUR)
-    conv_if(DAY,TMT_DAY)
-    conv_if(WEEK,TMT_WEEK)
-    conv_if(MONTH,TMT_MONTH)
-    conv_if(YEAR,TMT_YEAR)
+    conv_if(SECOND, TMT_SECOND);
+    conv_if(MINUTE, TMT_MINUTE);
+    conv_if(HOUR, TMT_HOUR);
+    conv_if(DAY, TMT_DAY);
+    conv_if(WEEK, TMT_WEEK);
+    conv_if(MONTH, TMT_MONTH);
+    conv_if(YEAR, TMT_YEAR);
     return (-1);
 }
 
-enum grc_en grc_conv(char *string){
+enum grc_en grc_conv(
+    char *string)
+{
 
-    conv_if(BACK,GRC_BACK)
-    conv_if(CANVAS,GRC_CANVAS)
-    conv_if(SHADEA,GRC_SHADEA)
-    conv_if(SHADEB,GRC_SHADEB)
-    conv_if(GRID,GRC_GRID)
-    conv_if(MGRID,GRC_MGRID)
-    conv_if(FONT,GRC_FONT)
-    conv_if(ARROW,GRC_ARROW)
-    conv_if(AXIS,GRC_AXIS)
-    conv_if(FRAME,GRC_FRAME)
+    conv_if(BACK, GRC_BACK);
+    conv_if(CANVAS, GRC_CANVAS);
+    conv_if(SHADEA, GRC_SHADEA);
+    conv_if(SHADEB, GRC_SHADEB);
+    conv_if(GRID, GRC_GRID);
+    conv_if(MGRID, GRC_MGRID);
+    conv_if(FONT, GRC_FONT);
+    conv_if(ARROW, GRC_ARROW);
+    conv_if(AXIS, GRC_AXIS);
+    conv_if(FRAME, GRC_FRAME);
 
-    return -1;        
+    return -1;
 }
 
-enum text_prop_en text_prop_conv(char *string){
-      
-    conv_if(DEFAULT,TEXT_PROP_DEFAULT)
-    conv_if(TITLE,TEXT_PROP_TITLE)
-    conv_if(AXIS,TEXT_PROP_AXIS)
-    conv_if(UNIT,TEXT_PROP_UNIT)
-    conv_if(LEGEND,TEXT_PROP_LEGEND)
+enum text_prop_en text_prop_conv(
+    char *string)
+{
+
+    conv_if(DEFAULT, TEXT_PROP_DEFAULT);
+    conv_if(TITLE, TEXT_PROP_TITLE);
+    conv_if(AXIS, TEXT_PROP_AXIS);
+    conv_if(UNIT, TEXT_PROP_UNIT);
+    conv_if(LEGEND, TEXT_PROP_LEGEND);
     return -1;
 }
 
 
 #undef conv_if
 
-int
-im_free(image_desc_t *im)
+int im_free(
+    image_desc_t *im)
 {
-    unsigned long        i,ii;
-
-    if (im == NULL) return 0;
-    for(i=0;i<(unsigned)im->gdes_c;i++){
-      if (im->gdes[i].data_first){
-        /* careful here, because a single pointer can occur several times */
-          free (im->gdes[i].data);
-          if (im->gdes[i].ds_namv){
-              for (ii=0;ii<im->gdes[i].ds_cnt;ii++)
-                  free(im->gdes[i].ds_namv[ii]);
-              free(im->gdes[i].ds_namv);
-          }
-      }
-      free (im->gdes[i].p_data);
-      free (im->gdes[i].rpnp);
+    unsigned long i, ii;
+    cairo_status_t status = 0;
+
+    if (im == NULL)
+        return 0;
+    for (i = 0; i < (unsigned) im->gdes_c; i++) {
+        if (im->gdes[i].data_first) {
+            /* careful here, because a single pointer can occur several times */
+            free(im->gdes[i].data);
+            if (im->gdes[i].ds_namv) {
+                for (ii = 0; ii < im->gdes[i].ds_cnt; ii++)
+                    free(im->gdes[i].ds_namv[ii]);
+                free(im->gdes[i].ds_namv);
+            }
+        }
+        /* free allocated memory used for dashed lines */
+        if (im->gdes[i].p_dashes != NULL)
+            free(im->gdes[i].p_dashes);
+
+        free(im->gdes[i].p_data);
+        free(im->gdes[i].rpnp);
     }
     free(im->gdes);
-    gfx_destroy(im->canvas);
+    if (im->font_options)
+        cairo_font_options_destroy(im->font_options);
+
+    if (im->cr) {
+        status = cairo_status(im->cr);
+        cairo_destroy(im->cr);
+    }
+    if (im->rendered_image) {
+        free(im->rendered_image);
+    }
+    if (im->surface)
+        cairo_surface_destroy(im->surface);
+    if (status)
+        fprintf(stderr, "OOPS: Cairo has issues it can't even die: %s\n",
+                cairo_status_to_string(status));
+
     return 0;
 }
 
 /* find SI magnitude symbol for the given number*/
-void
-auto_scale(
-           image_desc_t *im,   /* image description */
-           double *value,
-           char **symb_ptr,
-           double *magfact
-           )
+void auto_scale(
+    image_desc_t *im,   /* image description */
+    double *value,
+    char **symb_ptr,
+    double *magfact)
 {
-        
-    char *symbol[] = {"a", /* 10e-18 Atto */
-                      "f", /* 10e-15 Femto */
-                      "p", /* 10e-12 Pico */
-                      "n", /* 10e-9  Nano */
-                      "u", /* 10e-6  Micro */
-                      "m", /* 10e-3  Milli */
-                      " ", /* Base */
-                      "k", /* 10e3   Kilo */
-                      "M", /* 10e6   Mega */
-                      "G", /* 10e9   Giga */
-                      "T", /* 10e12  Tera */
-                      "P", /* 10e15  Peta */
-                      "E"};/* 10e18  Exa */
-
-    int symbcenter = 6;
-    int sindex;  
-
-    if (*value == 0.0 || isnan(*value) ) {
+
+    char     *symbol[] = { "a", /* 10e-18 Atto */
+        "f",            /* 10e-15 Femto */
+        "p",            /* 10e-12 Pico */
+        "n",            /* 10e-9  Nano */
+        "u",            /* 10e-6  Micro */
+        "m",            /* 10e-3  Milli */
+        " ",            /* Base */
+        "k",            /* 10e3   Kilo */
+        "M",            /* 10e6   Mega */
+        "G",            /* 10e9   Giga */
+        "T",            /* 10e12  Tera */
+        "P",            /* 10e15  Peta */
+        "E"
+    };                  /* 10e18  Exa */
+
+    int       symbcenter = 6;
+    int       sindex;
+
+    if (*value == 0.0 || isnan(*value)) {
         sindex = 0;
         *magfact = 1.0;
     } else {
-        sindex = floor(log(fabs(*value))/log((double)im->base)); 
-        *magfact = pow((double)im->base, (double)sindex);
+        sindex = floor(log(fabs(*value)) / log((double) im->base));
+        *magfact = pow((double) im->base, (double) sindex);
         (*value) /= (*magfact);
     }
-    if ( sindex <= symbcenter && sindex >= -symbcenter) {
-        (*symb_ptr) = symbol[sindex+symbcenter];
-    }
-    else {
+    if (sindex <= symbcenter && sindex >= -symbcenter) {
+        (*symb_ptr) = symbol[sindex + symbcenter];
+    } else {
         (*symb_ptr) = "?";
     }
 }
 
 
 static char si_symbol[] = {
-                     'a', /* 10e-18 Atto */ 
-                     'f', /* 10e-15 Femto */
-                     'p', /* 10e-12 Pico */
-                     'n', /* 10e-9  Nano */
-                     'u', /* 10e-6  Micro */
-                     'm', /* 10e-3  Milli */
-                     ' ', /* Base */
-                     'k', /* 10e3   Kilo */
-                     'M', /* 10e6   Mega */
-                     'G', /* 10e9   Giga */
-                     'T', /* 10e12  Tera */
-                     'P', /* 10e15  Peta */
-                     'E', /* 10e18  Exa */
+    'a',                /* 10e-18 Atto */
+    'f',                /* 10e-15 Femto */
+    'p',                /* 10e-12 Pico */
+    'n',                /* 10e-9  Nano */
+    'u',                /* 10e-6  Micro */
+    'm',                /* 10e-3  Milli */
+    ' ',                /* Base */
+    'k',                /* 10e3   Kilo */
+    'M',                /* 10e6   Mega */
+    'G',                /* 10e9   Giga */
+    'T',                /* 10e12  Tera */
+    'P',                /* 10e15  Peta */
+    'E',                /* 10e18  Exa */
 };
 static const int si_symbcenter = 6;
 
 /* find SI magnitude symbol for the numbers on the y-axis*/
-void 
-si_unit(
-    image_desc_t *im   /* image description */
-)
+void si_unit(
+    image_desc_t *im    /* image description */
+    )
 {
 
-    double digits,viewdigits=0;  
-    
-    digits = floor( log( max( fabs(im->minval),fabs(im->maxval)))/log((double)im->base)); 
+    double    digits, viewdigits = 0;
+
+    digits =
+        floor(log(max(fabs(im->minval), fabs(im->maxval))) /
+              log((double) im->base));
 
     if (im->unitsexponent != 9999) {
         /* unitsexponent = 9, 6, 3, 0, -3, -6, -9, etc */
@@ -339,352 +427,365 @@ si_unit(
         viewdigits = digits;
     }
 
-    im->magfact = pow((double)im->base , digits);
-    
+    im->magfact = pow((double) im->base, digits);
+
 #ifdef DEBUG
-    printf("digits %6.3f  im->magfact %6.3f\n",digits,im->magfact);
+    printf("digits %6.3f  im->magfact %6.3f\n", digits, im->magfact);
 #endif
 
-    im->viewfactor = im->magfact / pow((double)im->base , viewdigits);
+    im->viewfactor = im->magfact / pow((double) im->base, viewdigits);
 
-    if ( ((viewdigits+si_symbcenter) < sizeof(si_symbol)) &&
-                    ((viewdigits+si_symbcenter) >= 0) )
-        im->symbol = si_symbol[(int)viewdigits+si_symbcenter];
+    if (((viewdigits + si_symbcenter) < sizeof(si_symbol)) &&
+        ((viewdigits + si_symbcenter) >= 0))
+        im->symbol = si_symbol[(int) viewdigits + si_symbcenter];
     else
         im->symbol = '?';
- }
+}
 
 /*  move min and max values around to become sensible */
 
-void 
-expand_range(image_desc_t *im)
+void expand_range(
+    image_desc_t *im)
 {
-    double sensiblevalues[] ={1000.0,900.0,800.0,750.0,700.0,
-                              600.0,500.0,400.0,300.0,250.0,
-                              200.0,125.0,100.0,90.0,80.0,
-                              75.0,70.0,60.0,50.0,40.0,30.0,
-                              25.0,20.0,10.0,9.0,8.0,
-                              7.0,6.0,5.0,4.0,3.5,3.0,
-                              2.5,2.0,1.8,1.5,1.2,1.0,
-                              0.8,0.7,0.6,0.5,0.4,0.3,0.2,0.1,0.0,-1};
-    
-    double scaled_min,scaled_max;  
-    double adj;
-    int i;
-    
-
-    
+    double    sensiblevalues[] = { 1000.0, 900.0, 800.0, 750.0, 700.0,
+        600.0, 500.0, 400.0, 300.0, 250.0,
+        200.0, 125.0, 100.0, 90.0, 80.0,
+        75.0, 70.0, 60.0, 50.0, 40.0, 30.0,
+        25.0, 20.0, 10.0, 9.0, 8.0,
+        7.0, 6.0, 5.0, 4.0, 3.5, 3.0,
+        2.5, 2.0, 1.8, 1.5, 1.2, 1.0,
+        0.8, 0.7, 0.6, 0.5, 0.4, 0.3, 0.2, 0.1, 0.0, -1
+    };
+
+    double    scaled_min, scaled_max;
+    double    adj;
+    int       i;
+
+
+
 #ifdef DEBUG
     printf("Min: %6.2f Max: %6.2f MagFactor: %6.2f\n",
-           im->minval,im->maxval,im->magfact);
+           im->minval, im->maxval, im->magfact);
 #endif
 
-    if (isnan(im->ygridstep)){
-        if(im->extra_flags & ALTAUTOSCALE) {
+    if (isnan(im->ygridstep)) {
+        if (im->extra_flags & ALTAUTOSCALE) {
             /* measure the amplitude of the function. Make sure that
                graph boundaries are slightly higher then max/min vals
                so we can see amplitude on the graph */
-              double delt, fact;
-
-              delt = im->maxval - im->minval;
-              adj = delt * 0.1;
-              fact = 2.0 * pow(10.0,
-                    floor(log10(max(fabs(im->minval), fabs(im->maxval))/im->magfact)) - 2);
-              if (delt < fact) {
+            double    delt, fact;
+
+            delt = im->maxval - im->minval;
+            adj = delt * 0.1;
+            fact = 2.0 * pow(10.0,
+                             floor(log10
+                                   (max(fabs(im->minval), fabs(im->maxval)) /
+                                    im->magfact)) - 2);
+            if (delt < fact) {
                 adj = (fact - delt) * 0.55;
 #ifdef DEBUG
-              printf("Min: %6.2f Max: %6.2f delt: %6.2f fact: %6.2f adj: %6.2f\n", im->minval, im->maxval, delt, fact, adj);
+                printf
+                    ("Min: %6.2f Max: %6.2f delt: %6.2f fact: %6.2f adj: %6.2f\n",
+                     im->minval, im->maxval, delt, fact, adj);
 #endif
-              }
-              im->minval -= adj;
-              im->maxval += adj;
-        }
-       else if(im->extra_flags & ALTAUTOSCALE_MIN) {
-           /* measure the amplitude of the function. Make sure that
-              graph boundaries are slightly lower than min vals
-              so we can see amplitude on the graph */
-             adj = (im->maxval - im->minval) * 0.1;
-             im->minval -= adj;
-       }
-        else if(im->extra_flags & ALTAUTOSCALE_MAX) {
+            }
+            im->minval -= adj;
+            im->maxval += adj;
+        } else if (im->extra_flags & ALTAUTOSCALE_MIN) {
+            /* measure the amplitude of the function. Make sure that
+               graph boundaries are slightly lower than min vals
+               so we can see amplitude on the graph */
+            adj = (im->maxval - im->minval) * 0.1;
+            im->minval -= adj;
+        } else if (im->extra_flags & ALTAUTOSCALE_MAX) {
             /* measure the amplitude of the function. Make sure that
                graph boundaries are slightly higher than max vals
                so we can see amplitude on the graph */
-              adj = (im->maxval - im->minval) * 0.1;
-              im->maxval += adj;
-        }
-        else {
+            adj = (im->maxval - im->minval) * 0.1;
+            im->maxval += adj;
+        } else {
             scaled_min = im->minval / im->magfact;
             scaled_max = im->maxval / im->magfact;
-            
-            for (i=1; sensiblevalues[i] > 0; i++){
-                if (sensiblevalues[i-1]>=scaled_min &&
-                    sensiblevalues[i]<=scaled_min)        
-                    im->minval = sensiblevalues[i]*(im->magfact);
-                
-                if (-sensiblevalues[i-1]<=scaled_min &&
-                    -sensiblevalues[i]>=scaled_min)
-                    im->minval = -sensiblevalues[i-1]*(im->magfact);
-                
-                if (sensiblevalues[i-1] >= scaled_max &&
+
+            for (i = 1; sensiblevalues[i] > 0; i++) {
+                if (sensiblevalues[i - 1] >= scaled_min &&
+                    sensiblevalues[i] <= scaled_min)
+                    im->minval = sensiblevalues[i] * (im->magfact);
+
+                if (-sensiblevalues[i - 1] <= scaled_min &&
+                    -sensiblevalues[i] >= scaled_min)
+                    im->minval = -sensiblevalues[i - 1] * (im->magfact);
+
+                if (sensiblevalues[i - 1] >= scaled_max &&
                     sensiblevalues[i] <= scaled_max)
-                    im->maxval = sensiblevalues[i-1]*(im->magfact);
-                
-                if (-sensiblevalues[i-1]<=scaled_max &&
-                    -sensiblevalues[i] >=scaled_max)
-                    im->maxval = -sensiblevalues[i]*(im->magfact);
+                    im->maxval = sensiblevalues[i - 1] * (im->magfact);
+
+                if (-sensiblevalues[i - 1] <= scaled_max &&
+                    -sensiblevalues[i] >= scaled_max)
+                    im->maxval = -sensiblevalues[i] * (im->magfact);
             }
         }
     } else {
         /* adjust min and max to the grid definition if there is one */
-        im->minval = (double)im->ylabfact * im->ygridstep * 
-            floor(im->minval / ((double)im->ylabfact * im->ygridstep));
-        im->maxval = (double)im->ylabfact * im->ygridstep * 
-            ceil(im->maxval /( (double)im->ylabfact * im->ygridstep));
+        im->minval = (double) im->ylabfact * im->ygridstep *
+            floor(im->minval / ((double) im->ylabfact * im->ygridstep));
+        im->maxval = (double) im->ylabfact * im->ygridstep *
+            ceil(im->maxval / ((double) im->ylabfact * im->ygridstep));
     }
-    
+
 #ifdef DEBUG
-    fprintf(stderr,"SCALED Min: %6.2f Max: %6.2f Factor: %6.2f\n",
-           im->minval,im->maxval,im->magfact);
+    fprintf(stderr, "SCALED Min: %6.2f Max: %6.2f Factor: %6.2f\n",
+            im->minval, im->maxval, im->magfact);
 #endif
 }
 
-void
-apply_gridfit(image_desc_t *im)
+
+void apply_gridfit(
+    image_desc_t *im)
 {
-  if (isnan(im->minval) || isnan(im->maxval))
-    return;
-  ytr(im,DNAN);
-  if (im->logarithmic) {
-    double ya, yb, ypix, ypixfrac;
-    double log10_range = log10(im->maxval) - log10(im->minval);
-    ya = pow((double)10, floor(log10(im->minval)));
-    while (ya < im->minval)
-      ya *= 10;
-    if (ya > im->maxval)
-      return; /* don't have y=10^x gridline */
-    yb = ya * 10;
-    if (yb <= im->maxval) {
-      /* we have at least 2 y=10^x gridlines.
-         Make sure distance between them in pixels
-         are an integer by expanding im->maxval */
-      double y_pixel_delta = ytr(im, ya) - ytr(im, yb);
-      double factor = y_pixel_delta / floor(y_pixel_delta);
-      double new_log10_range = factor * log10_range;
-      double new_ymax_log10 = log10(im->minval) + new_log10_range;
-      im->maxval = pow(10, new_ymax_log10);
-      ytr(im,DNAN); /* reset precalc */
-      log10_range = log10(im->maxval) - log10(im->minval);
-    }
-    /* make sure first y=10^x gridline is located on 
-       integer pixel position by moving scale slightly 
-       downwards (sub-pixel movement) */
-    ypix = ytr(im, ya) + im->ysize; /* add im->ysize so it always is positive */
-    ypixfrac = ypix - floor(ypix);
-    if (ypixfrac > 0 && ypixfrac < 1) {
-      double yfrac = ypixfrac / im->ysize;
-      im->minval = pow(10, log10(im->minval) - yfrac * log10_range);
-      im->maxval = pow(10, log10(im->maxval) - yfrac * log10_range);
-      ytr(im,DNAN); /* reset precalc */
-    }
-  } else {
-    /* Make sure we have an integer pixel distance between
-       each minor gridline */
-    double ypos1 = ytr(im, im->minval);
-    double ypos2 = ytr(im, im->minval + im->ygrid_scale.gridstep);
-    double y_pixel_delta = ypos1 - ypos2;
-    double factor = y_pixel_delta / floor(y_pixel_delta);
-    double new_range = factor * (im->maxval - im->minval);
-    double gridstep = im->ygrid_scale.gridstep;
-    double minor_y, minor_y_px, minor_y_px_frac;
-
-
-    if (im->maxval > 0.0)
-      im->maxval = im->minval + new_range;
-    else
-      im->minval = im->maxval - new_range;
-    ytr(im,DNAN); /* reset precalc */
-
-    /* make sure first minor gridline is on integer pixel y coord */
-    minor_y = gridstep * floor(im->minval / gridstep);
-    while (minor_y < im->minval)
-      minor_y += gridstep;
-    minor_y_px = ytr(im, minor_y) + im->ysize; /* ensure > 0 by adding ysize */
-    minor_y_px_frac = minor_y_px - floor(minor_y_px);
-    if (minor_y_px_frac > 0 && minor_y_px_frac < 1) {
-      double yfrac = minor_y_px_frac / im->ysize;
-      double range = im->maxval - im->minval;
-      im->minval = im->minval - yfrac * range;
-      im->maxval = im->maxval - yfrac * range;
-      ytr(im,DNAN); /* reset precalc */
-    }
-    calc_horizontal_grid(im); /* recalc with changed im->maxval */
-  }
+    if (isnan(im->minval) || isnan(im->maxval))
+        return;
+    ytr(im, DNAN);
+    if (im->logarithmic) {
+        double    ya, yb, ypix, ypixfrac;
+        double    log10_range = log10(im->maxval) - log10(im->minval);
+
+        ya = pow((double) 10, floor(log10(im->minval)));
+        while (ya < im->minval)
+            ya *= 10;
+        if (ya > im->maxval)
+            return;     /* don't have y=10^x gridline */
+        yb = ya * 10;
+        if (yb <= im->maxval) {
+            /* we have at least 2 y=10^x gridlines.
+               Make sure distance between them in pixels
+               are an integer by expanding im->maxval */
+            double    y_pixel_delta = ytr(im, ya) - ytr(im, yb);
+            double    factor = y_pixel_delta / floor(y_pixel_delta);
+            double    new_log10_range = factor * log10_range;
+            double    new_ymax_log10 = log10(im->minval) + new_log10_range;
+
+            im->maxval = pow(10, new_ymax_log10);
+            ytr(im, DNAN);  /* reset precalc */
+            log10_range = log10(im->maxval) - log10(im->minval);
+        }
+        /* make sure first y=10^x gridline is located on 
+           integer pixel position by moving scale slightly 
+           downwards (sub-pixel movement) */
+        ypix = ytr(im, ya) + im->ysize; /* add im->ysize so it always is positive */
+        ypixfrac = ypix - floor(ypix);
+        if (ypixfrac > 0 && ypixfrac < 1) {
+            double    yfrac = ypixfrac / im->ysize;
+
+            im->minval = pow(10, log10(im->minval) - yfrac * log10_range);
+            im->maxval = pow(10, log10(im->maxval) - yfrac * log10_range);
+            ytr(im, DNAN);  /* reset precalc */
+        }
+    } else {
+        /* Make sure we have an integer pixel distance between
+           each minor gridline */
+        double    ypos1 = ytr(im, im->minval);
+        double    ypos2 = ytr(im, im->minval + im->ygrid_scale.gridstep);
+        double    y_pixel_delta = ypos1 - ypos2;
+        double    factor = y_pixel_delta / floor(y_pixel_delta);
+        double    new_range = factor * (im->maxval - im->minval);
+        double    gridstep = im->ygrid_scale.gridstep;
+        double    minor_y, minor_y_px, minor_y_px_frac;
+
+        if (im->maxval > 0.0)
+            im->maxval = im->minval + new_range;
+        else
+            im->minval = im->maxval - new_range;
+        ytr(im, DNAN);  /* reset precalc */
+        /* make sure first minor gridline is on integer pixel y coord */
+        minor_y = gridstep * floor(im->minval / gridstep);
+        while (minor_y < im->minval)
+            minor_y += gridstep;
+        minor_y_px = ytr(im, minor_y) + im->ysize;  /* ensure > 0 by adding ysize */
+        minor_y_px_frac = minor_y_px - floor(minor_y_px);
+        if (minor_y_px_frac > 0 && minor_y_px_frac < 1) {
+            double    yfrac = minor_y_px_frac / im->ysize;
+            double    range = im->maxval - im->minval;
+
+            im->minval = im->minval - yfrac * range;
+            im->maxval = im->maxval - yfrac * range;
+            ytr(im, DNAN);  /* reset precalc */
+        }
+        calc_horizontal_grid(im);   /* recalc with changed im->maxval */
+    }
 }
 
 /* reduce data reimplementation by Alex */
 
-void
-reduce_data(
-    enum cf_en     cf,         /* which consolidation function ?*/
-    unsigned long  cur_step,   /* step the data currently is in */
-    time_t         *start,     /* start, end and step as requested ... */
-    time_t         *end,       /* ... by the application will be   ... */
-    unsigned long  *step,      /* ... adjusted to represent reality    */
-    unsigned long  *ds_cnt,    /* number of data sources in file */
-    rrd_value_t    **data)     /* two dimensional array containing the data */
-{
-    int i,reduce_factor = ceil((double)(*step) / (double)cur_step);
-    unsigned long col,dst_row,row_cnt,start_offset,end_offset,skiprows=0;
-    rrd_value_t    *srcptr,*dstptr;
-
-    (*step) = cur_step*reduce_factor; /* set new step size for reduced data */
+void reduce_data(
+    enum cf_en cf,      /* which consolidation function ? */
+    unsigned long cur_step, /* step the data currently is in */
+    time_t *start,      /* start, end and step as requested ... */
+    time_t *end,        /* ... by the application will be   ... */
+    unsigned long *step,    /* ... adjusted to represent reality    */
+    unsigned long *ds_cnt,  /* number of data sources in file */
+    rrd_value_t **data)
+{                       /* two dimensional array containing the data */
+    int       i, reduce_factor = ceil((double) (*step) / (double) cur_step);
+    unsigned long col, dst_row, row_cnt, start_offset, end_offset, skiprows =
+        0;
+    rrd_value_t *srcptr, *dstptr;
+
+    (*step) = cur_step * reduce_factor; /* set new step size for reduced data */
     dstptr = *data;
     srcptr = *data;
-    row_cnt = ((*end)-(*start))/cur_step;
+    row_cnt = ((*end) - (*start)) / cur_step;
 
 #ifdef DEBUG
 #define DEBUG_REDUCE
 #endif
 #ifdef DEBUG_REDUCE
-printf("Reducing %lu rows with factor %i time %lu to %lu, step %lu\n",
-                        row_cnt,reduce_factor,*start,*end,cur_step);
-for (col=0;col<row_cnt;col++) {
-    printf("time %10lu: ",*start+(col+1)*cur_step);
-    for (i=0;i<*ds_cnt;i++)
-        printf(" %8.2e",srcptr[*ds_cnt*col+i]);
-    printf("\n");
-}
+    printf("Reducing %lu rows with factor %i time %lu to %lu, step %lu\n",
+           row_cnt, reduce_factor, *start, *end, cur_step);
+    for (col = 0; col < row_cnt; col++) {
+        printf("time %10lu: ", *start + (col + 1) * cur_step);
+        for (i = 0; i < *ds_cnt; i++)
+            printf(" %8.2e", srcptr[*ds_cnt * col + i]);
+        printf("\n");
+    }
 #endif
 
     /* We have to combine [reduce_factor] rows of the source
-    ** into one row for the destination.  Doing this we also
-    ** need to take care to combine the correct rows.  First
-    ** alter the start and end time so that they are multiples
-    ** of the new step time.  We cannot reduce the amount of
-    ** time so we have to move the end towards the future and
-    ** the start towards the past.
-    */
+     ** into one row for the destination.  Doing this we also
+     ** need to take care to combine the correct rows.  First
+     ** alter the start and end time so that they are multiples
+     ** of the new step time.  We cannot reduce the amount of
+     ** time so we have to move the end towards the future and
+     ** the start towards the past.
+     */
     end_offset = (*end) % (*step);
     start_offset = (*start) % (*step);
 
     /* If there is a start offset (which cannot be more than
-    ** one destination row), skip the appropriate number of
-    ** source rows and one destination row.  The appropriate
-    ** number is what we do know (start_offset/cur_step) of
-    ** the new interval (*step/cur_step aka reduce_factor).
-    */
+     ** one destination row), skip the appropriate number of
+     ** source rows and one destination row.  The appropriate
+     ** number is what we do know (start_offset/cur_step) of
+     ** the new interval (*step/cur_step aka reduce_factor).
+     */
 #ifdef DEBUG_REDUCE
-printf("start_offset: %lu  end_offset: %lu\n",start_offset,end_offset);
-printf("row_cnt before:  %lu\n",row_cnt);
+    printf("start_offset: %lu  end_offset: %lu\n", start_offset, end_offset);
+    printf("row_cnt before:  %lu\n", row_cnt);
 #endif
     if (start_offset) {
-        (*start) = (*start)-start_offset;
-        skiprows=reduce_factor-start_offset/cur_step;
-        srcptr+=skiprows* *ds_cnt;
-        for (col=0;col<(*ds_cnt);col++) *dstptr++ = DNAN;
-        row_cnt-=skiprows;
+        (*start) = (*start) - start_offset;
+        skiprows = reduce_factor - start_offset / cur_step;
+        srcptr += skiprows * *ds_cnt;
+        for (col = 0; col < (*ds_cnt); col++)
+            *dstptr++ = DNAN;
+        row_cnt -= skiprows;
     }
 #ifdef DEBUG_REDUCE
-printf("row_cnt between: %lu\n",row_cnt);
+    printf("row_cnt between: %lu\n", row_cnt);
 #endif
 
     /* At the end we have some rows that are not going to be
-    ** used, the amount is end_offset/cur_step
-    */
+     ** used, the amount is end_offset/cur_step
+     */
     if (end_offset) {
-        (*end) = (*end)-end_offset+(*step);
-        skiprows = end_offset/cur_step;
-        row_cnt-=skiprows;
+        (*end) = (*end) - end_offset + (*step);
+        skiprows = end_offset / cur_step;
+        row_cnt -= skiprows;
     }
 #ifdef DEBUG_REDUCE
-printf("row_cnt after:   %lu\n",row_cnt);
+    printf("row_cnt after:   %lu\n", row_cnt);
 #endif
 
 /* Sanity check: row_cnt should be multiple of reduce_factor */
 /* if this gets triggered, something is REALLY WRONG ... we die immediately */
 
-    if (row_cnt%reduce_factor) {
+    if (row_cnt % reduce_factor) {
         printf("SANITY CHECK: %lu rows cannot be reduced by %i \n",
-                                row_cnt,reduce_factor);
+               row_cnt, reduce_factor);
         printf("BUG in reduce_data()\n");
         exit(1);
     }
 
     /* Now combine reduce_factor intervals at a time
-    ** into one interval for the destination.
-    */
+     ** into one interval for the destination.
+     */
 
-    for (dst_row=0;(long int)row_cnt>=reduce_factor;dst_row++) {
-        for (col=0;col<(*ds_cnt);col++) {
-            rrd_value_t newval=DNAN;
-            unsigned long validval=0;
+    for (dst_row = 0; (long int) row_cnt >= reduce_factor; dst_row++) {
+        for (col = 0; col < (*ds_cnt); col++) {
+            rrd_value_t newval = DNAN;
+            unsigned long validval = 0;
 
-            for (i=0;i<reduce_factor;i++) {
-                if (isnan(srcptr[i*(*ds_cnt)+col])) {
+            for (i = 0; i < reduce_factor; i++) {
+                if (isnan(srcptr[i * (*ds_cnt) + col])) {
                     continue;
                 }
                 validval++;
-                if (isnan(newval)) newval = srcptr[i*(*ds_cnt)+col];
+                if (isnan(newval))
+                    newval = srcptr[i * (*ds_cnt) + col];
                 else {
                     switch (cf) {
-                        case CF_HWPREDICT:
-                        case CF_DEVSEASONAL:
-                        case CF_DEVPREDICT:
-                        case CF_SEASONAL:
-                        case CF_AVERAGE:
-                            newval += srcptr[i*(*ds_cnt)+col];
-                            break;
-                        case CF_MINIMUM:
-                            newval = min (newval,srcptr[i*(*ds_cnt)+col]);
-                            break;
-                        case CF_FAILURES: 
-                        /* an interval contains a failure if any subintervals contained a failure */
-                        case CF_MAXIMUM:
-                            newval = max (newval,srcptr[i*(*ds_cnt)+col]);
-                            break;
-                        case CF_LAST:
-                            newval = srcptr[i*(*ds_cnt)+col];
-                            break;
-                    }
-                }
-            }
-            if (validval == 0){newval = DNAN;} else{
-                switch (cf) {
                     case CF_HWPREDICT:
-                case CF_DEVSEASONAL:
+                    case CF_MHWPREDICT:
+                    case CF_DEVSEASONAL:
                     case CF_DEVPREDICT:
                     case CF_SEASONAL:
-                    case CF_AVERAGE:                
-                       newval /= validval;
+                    case CF_AVERAGE:
+                        newval += srcptr[i * (*ds_cnt) + col];
                         break;
                     case CF_MINIMUM:
+                        newval = min(newval, srcptr[i * (*ds_cnt) + col]);
+                        break;
                     case CF_FAILURES:
-                     case CF_MAXIMUM:
+                        /* an interval contains a failure if any subintervals contained a failure */
+                    case CF_MAXIMUM:
+                        newval = max(newval, srcptr[i * (*ds_cnt) + col]);
+                        break;
                     case CF_LAST:
+                        newval = srcptr[i * (*ds_cnt) + col];
                         break;
+                    }
+                }
+            }
+            if (validval == 0) {
+                newval = DNAN;
+            } else {
+                switch (cf) {
+                case CF_HWPREDICT:
+                case CF_MHWPREDICT:
+                case CF_DEVSEASONAL:
+                case CF_DEVPREDICT:
+                case CF_SEASONAL:
+                case CF_AVERAGE:
+                    newval /= validval;
+                    break;
+                case CF_MINIMUM:
+                case CF_FAILURES:
+                case CF_MAXIMUM:
+                case CF_LAST:
+                    break;
                 }
             }
-            *dstptr++=newval;
+            *dstptr++ = newval;
         }
-        srcptr+=(*ds_cnt)*reduce_factor;
-        row_cnt-=reduce_factor;
+        srcptr += (*ds_cnt) * reduce_factor;
+        row_cnt -= reduce_factor;
     }
     /* If we had to alter the endtime, we didn't have enough
-    ** source rows to fill the last row. Fill it with NaN.
-    */
-    if (end_offset) for (col=0;col<(*ds_cnt);col++) *dstptr++ = DNAN;
+     ** source rows to fill the last row. Fill it with NaN.
+     */
+    if (end_offset)
+        for (col = 0; col < (*ds_cnt); col++)
+            *dstptr++ = DNAN;
 #ifdef DEBUG_REDUCE
-    row_cnt = ((*end)-(*start))/ *step;
+    row_cnt = ((*end) - (*start)) / *step;
     srcptr = *data;
     printf("Done reducing. Currently %lu rows, time %lu to %lu, step %lu\n",
-                                row_cnt,*start,*end,*step);
-for (col=0;col<row_cnt;col++) {
-    printf("time %10lu: ",*start+(col+1)*(*step));
-    for (i=0;i<*ds_cnt;i++)
-        printf(" %8.2e",srcptr[*ds_cnt*col+i]);
-    printf("\n");
-}
+           row_cnt, *start, *end, *step);
+    for (col = 0; col < row_cnt; col++) {
+        printf("time %10lu: ", *start + (col + 1) * (*step));
+        for (i = 0; i < *ds_cnt; i++)
+            printf(" %8.2e", srcptr[*ds_cnt * col + i]);
+        printf("\n");
+    }
 #endif
 }
 
@@ -692,83 +793,83 @@ for (col=0;col<row_cnt;col++) {
 /* get the data required for the graphs from the 
    relevant rrds ... */
 
-int
-data_fetch(image_desc_t *im )
+int data_fetch(
+    image_desc_t *im)
 {
-    int i,ii;
-    int                skip;
+    int       i, ii;
+    int       skip;
 
     /* pull the data from the rrd files ... */
-    for (i=0;i< (int)im->gdes_c;i++){
+    for (i = 0; i < (int) im->gdes_c; i++) {
         /* only GF_DEF elements fetch data */
-        if (im->gdes[i].gf != GF_DEF) 
+        if (im->gdes[i].gf != GF_DEF)
             continue;
 
-        skip=0;
-        /* do we have it already ?*/
-        for (ii=0;ii<i;ii++) {
-            if (im->gdes[ii].gf != GF_DEF) 
+        skip = 0;
+        /* do we have it already ? */
+        for (ii = 0; ii < i; ii++) {
+            if (im->gdes[ii].gf != GF_DEF)
                 continue;
             if ((strcmp(im->gdes[i].rrd, im->gdes[ii].rrd) == 0)
-                        && (im->gdes[i].cf    == im->gdes[ii].cf)
-                        && (im->gdes[i].cf_reduce == im->gdes[ii].cf_reduce)
-                        && (im->gdes[i].start_orig == im->gdes[ii].start_orig)
-                        && (im->gdes[i].end_orig   == im->gdes[ii].end_orig)
-                        && (im->gdes[i].step_orig  == im->gdes[ii].step_orig)) {
+                && (im->gdes[i].cf == im->gdes[ii].cf)
+                && (im->gdes[i].cf_reduce == im->gdes[ii].cf_reduce)
+                && (im->gdes[i].start_orig == im->gdes[ii].start_orig)
+                && (im->gdes[i].end_orig == im->gdes[ii].end_orig)
+                && (im->gdes[i].step_orig == im->gdes[ii].step_orig)) {
                 /* OK, the data is already there.
-                ** Just copy the header portion
-                */
+                 ** Just copy the header portion
+                 */
                 im->gdes[i].start = im->gdes[ii].start;
                 im->gdes[i].end = im->gdes[ii].end;
                 im->gdes[i].step = im->gdes[ii].step;
                 im->gdes[i].ds_cnt = im->gdes[ii].ds_cnt;
-                im->gdes[i].ds_namv = im->gdes[ii].ds_namv;                
+                im->gdes[i].ds_namv = im->gdes[ii].ds_namv;
                 im->gdes[i].data = im->gdes[ii].data;
                 im->gdes[i].data_first = 0;
-                skip=1;
+                skip = 1;
             }
-            if (skip) 
+            if (skip)
                 break;
         }
-        if (! skip) {
-            unsigned long  ft_step = im->gdes[i].step ; /* ft_step will record what we got from fetch */
-            
-            if((rrd_fetch_fn(im->gdes[i].rrd,
-                             im->gdes[i].cf,
-                             &im->gdes[i].start,
-                             &im->gdes[i].end,
-                             &ft_step,
-                             &im->gdes[i].ds_cnt,
-                             &im->gdes[i].ds_namv,
-                             &im->gdes[i].data)) == -1){                
+        if (!skip) {
+            unsigned long ft_step = im->gdes[i].step;   /* ft_step will record what we got from fetch */
+
+            if ((rrd_fetch_fn(im->gdes[i].rrd,
+                              im->gdes[i].cf,
+                              &im->gdes[i].start,
+                              &im->gdes[i].end,
+                              &ft_step,
+                              &im->gdes[i].ds_cnt,
+                              &im->gdes[i].ds_namv,
+                              &im->gdes[i].data)) == -1) {
                 return -1;
             }
-            im->gdes[i].data_first = 1;            
-        
+            im->gdes[i].data_first = 1;
+
             if (ft_step < im->gdes[i].step) {
                 reduce_data(im->gdes[i].cf_reduce,
                             ft_step,
                             &im->gdes[i].start,
                             &im->gdes[i].end,
                             &im->gdes[i].step,
-                            &im->gdes[i].ds_cnt,
-                            &im->gdes[i].data);
+                            &im->gdes[i].ds_cnt, &im->gdes[i].data);
             } else {
                 im->gdes[i].step = ft_step;
             }
         }
-        
+
         /* lets see if the required data source is really there */
-        for(ii=0;ii<(int)im->gdes[i].ds_cnt;ii++){
-            if(strcmp(im->gdes[i].ds_namv[ii],im->gdes[i].ds_nam) == 0){
-                im->gdes[i].ds=ii; }
+        for (ii = 0; ii < (int) im->gdes[i].ds_cnt; ii++) {
+            if (strcmp(im->gdes[i].ds_namv[ii], im->gdes[i].ds_nam) == 0) {
+                im->gdes[i].ds = ii;
+            }
         }
-        if (im->gdes[i].ds== -1){
+        if (im->gdes[i].ds == -1) {
             rrd_set_error("No DS called '%s' in '%s'",
-                          im->gdes[i].ds_nam,im->gdes[i].rrd);
-            return -1; 
+                          im->gdes[i].ds_nam, im->gdes[i].rrd);
+            return -1;
         }
-        
+
     }
     return 0;
 }
@@ -779,243 +880,258 @@ data_fetch(image_desc_t *im )
  * CDEF stuff 
  *************************************************************/
 
-long
-find_var_wrapper(void *arg1, char *key)
+long find_var_wrapper(
+    void *arg1,
+    char *key)
 {
-   return find_var((image_desc_t *) arg1, key);
+    return find_var((image_desc_t *) arg1, key);
 }
 
 /* find gdes containing var*/
-long
-find_var(image_desc_t *im, char *key){
-    long ii;
-    for(ii=0;ii<im->gdes_c-1;ii++){
-        if((im->gdes[ii].gf == GF_DEF 
-            || im->gdes[ii].gf == GF_VDEF
-            || im->gdes[ii].gf == GF_CDEF) 
-           && (strcmp(im->gdes[ii].vname,key) == 0)){
-            return ii; 
-        }           
-    }                        
+long find_var(
+    image_desc_t *im,
+    char *key)
+{
+    long      ii;
+
+    for (ii = 0; ii < im->gdes_c - 1; ii++) {
+        if ((im->gdes[ii].gf == GF_DEF
+             || im->gdes[ii].gf == GF_VDEF || im->gdes[ii].gf == GF_CDEF)
+            && (strcmp(im->gdes[ii].vname, key) == 0)) {
+            return ii;
+        }
+    }
     return -1;
 }
 
 /* find the largest common denominator for all the numbers
    in the 0 terminated num array */
-long
-lcd(long *num){
-    long rest;
-    int i;
-    for (i=0;num[i+1]!=0;i++){
-        do { 
-            rest=num[i] % num[i+1];
-            num[i]=num[i+1]; num[i+1]=rest;
-        } while (rest!=0);
-        num[i+1] = num[i];
+long lcd(
+    long *num)
+{
+    long      rest;
+    int       i;
+
+    for (i = 0; num[i + 1] != 0; i++) {
+        do {
+            rest = num[i] % num[i + 1];
+            num[i] = num[i + 1];
+            num[i + 1] = rest;
+        } while (rest != 0);
+        num[i + 1] = num[i];
     }
 /*    return i==0?num[i]:num[i-1]; */
-      return num[i];
+    return num[i];
 }
 
 /* run the rpn calculator on all the VDEF and CDEF arguments */
-int
-data_calc( image_desc_t *im){
+int data_calc(
+    image_desc_t *im)
+{
 
     int       gdi;
     int       dataidx;
-    long      *steparray, rpi;
+    long     *steparray, rpi;
     int       stepcnt;
     time_t    now;
     rpnstack_t rpnstack;
 
     rpnstack_init(&rpnstack);
 
-    for (gdi=0;gdi<im->gdes_c;gdi++){
+    for (gdi = 0; gdi < im->gdes_c; gdi++) {
         /* Look for GF_VDEF and GF_CDEF in the same loop,
          * so CDEFs can use VDEFs and vice versa
          */
         switch (im->gdes[gdi].gf) {
-            case GF_XPORT:
-              break;
-            case GF_SHIFT: {
-                graph_desc_t        *vdp = &im->gdes[im->gdes[gdi].vidx];
-                
-                /* remove current shift */
-                vdp->start -= vdp->shift;
-                vdp->end -= vdp->shift;
-                
-                /* vdef */
-                if (im->gdes[gdi].shidx >= 0) 
-                        vdp->shift = im->gdes[im->gdes[gdi].shidx].vf.val;
-                /* constant */
-                else
-                        vdp->shift = im->gdes[gdi].shval;
+        case GF_XPORT:
+            break;
+        case GF_SHIFT:{
+            graph_desc_t *vdp = &im->gdes[im->gdes[gdi].vidx];
 
-                /* normalize shift to multiple of consolidated step */
-                vdp->shift = (vdp->shift / (long)vdp->step) * (long)vdp->step;
+            /* remove current shift */
+            vdp->start -= vdp->shift;
+            vdp->end -= vdp->shift;
 
-                /* apply shift */
-                vdp->start += vdp->shift;
-                vdp->end += vdp->shift;
-                break;
+            /* vdef */
+            if (im->gdes[gdi].shidx >= 0)
+                vdp->shift = im->gdes[im->gdes[gdi].shidx].vf.val;
+            /* constant */
+            else
+                vdp->shift = im->gdes[gdi].shval;
+
+            /* normalize shift to multiple of consolidated step */
+            vdp->shift = (vdp->shift / (long) vdp->step) * (long) vdp->step;
+
+            /* apply shift */
+            vdp->start += vdp->shift;
+            vdp->end += vdp->shift;
+            break;
+        }
+        case GF_VDEF:
+            /* A VDEF has no DS.  This also signals other parts
+             * of rrdtool that this is a VDEF value, not a CDEF.
+             */
+            im->gdes[gdi].ds_cnt = 0;
+            if (vdef_calc(im, gdi)) {
+                rrd_set_error("Error processing VDEF '%s'",
+                              im->gdes[gdi].vname);
+                rpnstack_free(&rpnstack);
+                return -1;
             }
-            case GF_VDEF:
-                /* A VDEF has no DS.  This also signals other parts
-                 * of rrdtool that this is a VDEF value, not a CDEF.
-                 */
-                im->gdes[gdi].ds_cnt = 0;
-                if (vdef_calc(im,gdi)) {
-                    rrd_set_error("Error processing VDEF '%s'"
-                        ,im->gdes[gdi].vname
-                        );
-                    rpnstack_free(&rpnstack);
-                    return -1;
-                }
-                break;
-            case GF_CDEF:
-                im->gdes[gdi].ds_cnt = 1;
-                im->gdes[gdi].ds = 0;
-                im->gdes[gdi].data_first = 1;
-                im->gdes[gdi].start = 0;
-                im->gdes[gdi].end = 0;
-                steparray=NULL;
-                stepcnt = 0;
-                dataidx=-1;
-
-                /* Find the variables in the expression.
-                 * - VDEF variables are substituted by their values
-                 *   and the opcode is changed into OP_NUMBER.
-                 * - CDEF variables are analized for their step size,
-                 *   the lowest common denominator of all the step
-                 *   sizes of the data sources involved is calculated
-                 *   and the resulting number is the step size for the
-                 *   resulting data source.
-                 */
-                for(rpi=0;im->gdes[gdi].rpnp[rpi].op != OP_END;rpi++){
-                    if(im->gdes[gdi].rpnp[rpi].op == OP_VARIABLE  ||
-                        im->gdes[gdi].rpnp[rpi].op == OP_PREV_OTHER){
-                        long ptr = im->gdes[gdi].rpnp[rpi].ptr;
-                        if (im->gdes[ptr].ds_cnt == 0) { /* this is a VDEF data source */
+            break;
+        case GF_CDEF:
+            im->gdes[gdi].ds_cnt = 1;
+            im->gdes[gdi].ds = 0;
+            im->gdes[gdi].data_first = 1;
+            im->gdes[gdi].start = 0;
+            im->gdes[gdi].end = 0;
+            steparray = NULL;
+            stepcnt = 0;
+            dataidx = -1;
+
+            /* Find the variables in the expression.
+             * - VDEF variables are substituted by their values
+             *   and the opcode is changed into OP_NUMBER.
+             * - CDEF variables are analized for their step size,
+             *   the lowest common denominator of all the step
+             *   sizes of the data sources involved is calculated
+             *   and the resulting number is the step size for the
+             *   resulting data source.
+             */
+            for (rpi = 0; im->gdes[gdi].rpnp[rpi].op != OP_END; rpi++) {
+                if (im->gdes[gdi].rpnp[rpi].op == OP_VARIABLE ||
+                    im->gdes[gdi].rpnp[rpi].op == OP_PREV_OTHER) {
+                    long      ptr = im->gdes[gdi].rpnp[rpi].ptr;
+
+                    if (im->gdes[ptr].ds_cnt == 0) {    /* this is a VDEF data source */
 #if 0
-                            printf("DEBUG: inside CDEF '%s' processing VDEF '%s'\n",
-                               im->gdes[gdi].vname,
-                               im->gdes[ptr].vname);
-                            printf("DEBUG: value from vdef is %f\n",im->gdes[ptr].vf.val);
+                        printf
+                            ("DEBUG: inside CDEF '%s' processing VDEF '%s'\n",
+                             im->gdes[gdi].vname, im->gdes[ptr].vname);
+                        printf("DEBUG: value from vdef is %f\n",
+                               im->gdes[ptr].vf.val);
 #endif
-                            im->gdes[gdi].rpnp[rpi].val = im->gdes[ptr].vf.val;
-                            im->gdes[gdi].rpnp[rpi].op  = OP_NUMBER;
-                        } else { /* normal variables and PREF(variables) */
-
-                            /* add one entry to the array that keeps track of the step sizes of the
-                             * data sources going into the CDEF. */
-                            if ((steparray =
-                                 rrd_realloc(steparray,
-                                                         (++stepcnt+1)*sizeof(*steparray)))==NULL){
-                                  rrd_set_error("realloc steparray");
-                                  rpnstack_free(&rpnstack);
-                                 return -1;
-                            };
+                        im->gdes[gdi].rpnp[rpi].val = im->gdes[ptr].vf.val;
+                        im->gdes[gdi].rpnp[rpi].op = OP_NUMBER;
+                    } else {    /* normal variables and PREF(variables) */
+
+                        /* add one entry to the array that keeps track of the step sizes of the
+                         * data sources going into the CDEF. */
+                        if ((steparray =
+                             rrd_realloc(steparray,
+                                         (++stepcnt +
+                                          1) * sizeof(*steparray))) == NULL) {
+                            rrd_set_error("realloc steparray");
+                            rpnstack_free(&rpnstack);
+                            return -1;
+                        };
+
+                        steparray[stepcnt - 1] = im->gdes[ptr].step;
+
+                        /* adjust start and end of cdef (gdi) so
+                         * that it runs from the latest start point
+                         * to the earliest endpoint of any of the
+                         * rras involved (ptr)
+                         */
 
-                            steparray[stepcnt-1] = im->gdes[ptr].step;
-
-                            /* adjust start and end of cdef (gdi) so
-                             * that it runs from the latest start point
-                             * to the earliest endpoint of any of the
-                             * rras involved (ptr)
-                             */
-
-                            if(im->gdes[gdi].start < im->gdes[ptr].start)
-                                im->gdes[gdi].start = im->gdes[ptr].start;
-
-                            if(im->gdes[gdi].end == 0 ||
-                                        im->gdes[gdi].end > im->gdes[ptr].end)
-                                im->gdes[gdi].end = im->gdes[ptr].end;
-                
-                            /* store pointer to the first element of
-                             * the rra providing data for variable,
-                             * further save step size and data source
-                             * count of this rra
-                             */ 
-                            im->gdes[gdi].rpnp[rpi].data   = im->gdes[ptr].data + im->gdes[ptr].ds;
-                            im->gdes[gdi].rpnp[rpi].step   = im->gdes[ptr].step;
-                            im->gdes[gdi].rpnp[rpi].ds_cnt = im->gdes[ptr].ds_cnt;
-
-                            /* backoff the *.data ptr; this is done so
-                             * rpncalc() function doesn't have to treat
-                             * the first case differently
-                             */
-                        } /* if ds_cnt != 0 */
-                    } /* if OP_VARIABLE */
-                } /* loop through all rpi */
-
-                /* move the data pointers to the correct period */
-                for(rpi=0;im->gdes[gdi].rpnp[rpi].op != OP_END;rpi++){
-                    if(im->gdes[gdi].rpnp[rpi].op == OP_VARIABLE ||
-                        im->gdes[gdi].rpnp[rpi].op == OP_PREV_OTHER){
-                        long ptr  = im->gdes[gdi].rpnp[rpi].ptr;
-                        long diff = im->gdes[gdi].start - im->gdes[ptr].start;
-
-                        if(diff > 0)
-                            im->gdes[gdi].rpnp[rpi].data += (diff / im->gdes[ptr].step) * im->gdes[ptr].ds_cnt;
-                     }
-                }
+                        if (im->gdes[gdi].start < im->gdes[ptr].start)
+                            im->gdes[gdi].start = im->gdes[ptr].start;
 
-                if(steparray == NULL){
-                    rrd_set_error("rpn expressions without DEF"
-                                " or CDEF variables are not supported");
-                    rpnstack_free(&rpnstack);
-                    return -1;    
+                        if (im->gdes[gdi].end == 0 ||
+                            im->gdes[gdi].end > im->gdes[ptr].end)
+                            im->gdes[gdi].end = im->gdes[ptr].end;
+
+                        /* store pointer to the first element of
+                         * the rra providing data for variable,
+                         * further save step size and data source
+                         * count of this rra
+                         */
+                        im->gdes[gdi].rpnp[rpi].data =
+                            im->gdes[ptr].data + im->gdes[ptr].ds;
+                        im->gdes[gdi].rpnp[rpi].step = im->gdes[ptr].step;
+                        im->gdes[gdi].rpnp[rpi].ds_cnt = im->gdes[ptr].ds_cnt;
+
+                        /* backoff the *.data ptr; this is done so
+                         * rpncalc() function doesn't have to treat
+                         * the first case differently
+                         */
+                    }   /* if ds_cnt != 0 */
+                }       /* if OP_VARIABLE */
+            }           /* loop through all rpi */
+
+            /* move the data pointers to the correct period */
+            for (rpi = 0; im->gdes[gdi].rpnp[rpi].op != OP_END; rpi++) {
+                if (im->gdes[gdi].rpnp[rpi].op == OP_VARIABLE ||
+                    im->gdes[gdi].rpnp[rpi].op == OP_PREV_OTHER) {
+                    long      ptr = im->gdes[gdi].rpnp[rpi].ptr;
+                    long      diff =
+                        im->gdes[gdi].start - im->gdes[ptr].start;
+
+                    if (diff > 0)
+                        im->gdes[gdi].rpnp[rpi].data +=
+                            (diff / im->gdes[ptr].step) *
+                            im->gdes[ptr].ds_cnt;
                 }
-                steparray[stepcnt]=0;
-                /* Now find the resulting step.  All steps in all
-                 * used RRAs have to be visited
+            }
+
+            if (steparray == NULL) {
+                rrd_set_error("rpn expressions without DEF"
+                              " or CDEF variables are not supported");
+                rpnstack_free(&rpnstack);
+                return -1;
+            }
+            steparray[stepcnt] = 0;
+            /* Now find the resulting step.  All steps in all
+             * used RRAs have to be visited
+             */
+            im->gdes[gdi].step = lcd(steparray);
+            free(steparray);
+            if ((im->gdes[gdi].data = malloc(((im->gdes[gdi].end -
+                                               im->gdes[gdi].start)
+                                              / im->gdes[gdi].step)
+                                             * sizeof(double))) == NULL) {
+                rrd_set_error("malloc im->gdes[gdi].data");
+                rpnstack_free(&rpnstack);
+                return -1;
+            }
+
+            /* Step through the new cdef results array and
+             * calculate the values
+             */
+            for (now = im->gdes[gdi].start + im->gdes[gdi].step;
+                 now <= im->gdes[gdi].end; now += im->gdes[gdi].step) {
+                rpnp_t   *rpnp = im->gdes[gdi].rpnp;
+
+                /* 3rd arg of rpn_calc is for OP_VARIABLE lookups;
+                 * in this case we are advancing by timesteps;
+                 * we use the fact that time_t is a synonym for long
                  */
-                im->gdes[gdi].step = lcd(steparray);
-                free(steparray);
-                if((im->gdes[gdi].data = malloc((
-                                (im->gdes[gdi].end-im->gdes[gdi].start) 
-                                    / im->gdes[gdi].step)
-                                    * sizeof(double)))==NULL){
-                    rrd_set_error("malloc im->gdes[gdi].data");
+                if (rpn_calc(rpnp, &rpnstack, (long) now,
+                             im->gdes[gdi].data, ++dataidx) == -1) {
+                    /* rpn_calc sets the error string */
                     rpnstack_free(&rpnstack);
                     return -1;
                 }
-        
-                /* Step through the new cdef results array and
-                 * calculate the values
-                 */
-                for (now = im->gdes[gdi].start + im->gdes[gdi].step;
-                                now<=im->gdes[gdi].end;
-                                now += im->gdes[gdi].step)
-                {
-                    rpnp_t  *rpnp = im -> gdes[gdi].rpnp;
-
-                    /* 3rd arg of rpn_calc is for OP_VARIABLE lookups;
-                     * in this case we are advancing by timesteps;
-                     * we use the fact that time_t is a synonym for long
-                     */
-                    if (rpn_calc(rpnp,&rpnstack,(long) now, 
-                                im->gdes[gdi].data,++dataidx) == -1) {
-                        /* rpn_calc sets the error string */
-                        rpnstack_free(&rpnstack); 
-                        return -1;
-                    } 
-                } /* enumerate over time steps within a CDEF */
-                break;
-            default:
-                continue;
+            }           /* enumerate over time steps within a CDEF */
+            break;
+        default:
+            continue;
         }
-    } /* enumerate over CDEFs */
+    }                   /* enumerate over CDEFs */
     rpnstack_free(&rpnstack);
     return 0;
 }
 
-static int AlmostEqual2sComplement (float A, float B, int maxUlps)
+static int AlmostEqual2sComplement(
+    float A,
+    float B,
+    int maxUlps)
 {
 
-    int aInt = *(int*)&A;
-    int bInt = *(int*)&B;
-    int intDiff;
+    int       aInt = *(int *) &A;
+    int       bInt = *(int *) &B;
+    int       intDiff;
+
     /* Make sure maxUlps is non-negative and small enough that the
        default NAN won't compare as equal to anything.  */
 
@@ -1040,88 +1156,96 @@ static int AlmostEqual2sComplement (float A, float B, int maxUlps)
 }
 
 /* massage data so, that we get one value for each x coordinate in the graph */
-int
-data_proc( image_desc_t *im ){
-    long i,ii;
-    double pixstep = (double)(im->end-im->start)
-        /(double)im->xsize; /* how much time 
-                               passes in one pixel */
-    double paintval;
-    double minval=DNAN,maxval=DNAN;
-    
-    unsigned long gr_time;    
+int data_proc(
+    image_desc_t *im)
+{
+    long      i, ii;
+    double    pixstep = (double) (im->end - im->start)
+        / (double) im->xsize;   /* how much time 
+                                   passes in one pixel */
+    double    paintval;
+    double    minval = DNAN, maxval = DNAN;
+
+    unsigned long gr_time;
 
     /* memory for the processed data */
-    for(i=0;i<im->gdes_c;i++) {
-        if((im->gdes[i].gf==GF_LINE) ||
-                (im->gdes[i].gf==GF_AREA) ||
-                (im->gdes[i].gf==GF_TICK)) {
-            if((im->gdes[i].p_data = malloc((im->xsize +1)
-                                        * sizeof(rrd_value_t)))==NULL){
+    for (i = 0; i < im->gdes_c; i++) {
+        if ((im->gdes[i].gf == GF_LINE) ||
+            (im->gdes[i].gf == GF_AREA) || (im->gdes[i].gf == GF_TICK)) {
+            if ((im->gdes[i].p_data = malloc((im->xsize + 1)
+                                             * sizeof(rrd_value_t))) == NULL) {
                 rrd_set_error("malloc data_proc");
                 return -1;
             }
         }
     }
 
-    for (i=0;i<im->xsize;i++) {        /* for each pixel */
-        long vidx;
-        gr_time = im->start+pixstep*i; /* time of the current step */
-        paintval=0.0;
-        
-        for (ii=0;ii<im->gdes_c;ii++) {
-            double value;
-            switch (im->gdes[ii].gf) {
-                case GF_LINE:
-                case GF_AREA:
-                case GF_TICK:
-                    if (!im->gdes[ii].stack)
-                        paintval = 0.0;
-                    value = im->gdes[ii].yrule;
-                    if (isnan(value) || (im->gdes[ii].gf == GF_TICK)) {
-                        /* The time of the data doesn't necessarily match
-                        ** the time of the graph. Beware.
-                        */
-                        vidx = im->gdes[ii].vidx;
-                        if (im->gdes[vidx].gf == GF_VDEF) {
-                            value = im->gdes[vidx].vf.val;
-                        } else if (((long int)gr_time >= (long int)im->gdes[vidx].start) &&
-                                   ((long int)gr_time <= (long int)im->gdes[vidx].end) ) {
-                            value = im->gdes[vidx].data[
-                                (unsigned long) floor(
-                                    (double)(gr_time - im->gdes[vidx].start)
-                                                / im->gdes[vidx].step)
-                                * im->gdes[vidx].ds_cnt
-                                + im->gdes[vidx].ds
-                            ];
-                        } else {
-                            value = DNAN;
-                        }
-                    };
+    for (i = 0; i < im->xsize; i++) {   /* for each pixel */
+        long      vidx;
 
-                    if (! isnan(value)) {
-                        paintval += value;
-                        im->gdes[ii].p_data[i] = paintval;
-                        /* GF_TICK: the data values are not
-                        ** relevant for min and max
-                        */
-                        if (finite(paintval) && im->gdes[ii].gf != GF_TICK ) {
-                            if ((isnan(minval) || paintval <  minval ) &&
-                              ! (im->logarithmic && paintval <= 0.0)) 
-                                        minval = paintval;
-                            if (isnan(maxval) || paintval >  maxval)
-                                maxval = paintval;
-                        }
+        gr_time = im->start + pixstep * i;  /* time of the current step */
+        paintval = 0.0;
+
+        for (ii = 0; ii < im->gdes_c; ii++) {
+            double    value;
+
+            switch (im->gdes[ii].gf) {
+            case GF_LINE:
+            case GF_AREA:
+            case GF_TICK:
+                if (!im->gdes[ii].stack)
+                    paintval = 0.0;
+                value = im->gdes[ii].yrule;
+                if (isnan(value) || (im->gdes[ii].gf == GF_TICK)) {
+                    /* The time of the data doesn't necessarily match
+                     ** the time of the graph. Beware.
+                     */
+                    vidx = im->gdes[ii].vidx;
+                    if (im->gdes[vidx].gf == GF_VDEF) {
+                        value = im->gdes[vidx].vf.val;
+                    } else
+                        if (((long int) gr_time >=
+                             (long int) im->gdes[vidx].start)
+                            && ((long int) gr_time <=
+                                (long int) im->gdes[vidx].end)) {
+                        value = im->gdes[vidx].data[(unsigned long)
+                                                    floor((double)
+                                                          (gr_time -
+                                                           im->gdes[vidx].
+                                                           start)
+                                                          /
+                                                          im->gdes[vidx].step)
+                                                    * im->gdes[vidx].ds_cnt +
+                                                    im->gdes[vidx].ds];
                     } else {
-                        im->gdes[ii].p_data[i] = DNAN;
+                        value = DNAN;
                     }
-                    break;
-                case GF_STACK:
-                    rrd_set_error("STACK should already be turned into LINE or AREA here");
-                    return -1;
-                    break;
-                default:
-                    break;
+                };
+
+                if (!isnan(value)) {
+                    paintval += value;
+                    im->gdes[ii].p_data[i] = paintval;
+                    /* GF_TICK: the data values are not
+                     ** relevant for min and max
+                     */
+                    if (finite(paintval) && im->gdes[ii].gf != GF_TICK) {
+                        if ((isnan(minval) || paintval < minval) &&
+                            !(im->logarithmic && paintval <= 0.0))
+                            minval = paintval;
+                        if (isnan(maxval) || paintval > maxval)
+                            maxval = paintval;
+                    }
+                } else {
+                    im->gdes[ii].p_data[i] = DNAN;
+                }
+                break;
+            case GF_STACK:
+                rrd_set_error
+                    ("STACK should already be turned into LINE or AREA here");
+                return -1;
+                break;
+            default:
+                break;
             }
         }
     }
@@ -1131,25 +1255,33 @@ data_proc( image_desc_t *im ){
        lets set these to dummy values then ... */
 
     if (im->logarithmic) {
-        if (isnan(minval)) minval = 0.2;
-        if (isnan(maxval)) maxval = 5.1;
-    }
-    else {
-        if (isnan(minval)) minval = 0.0;
-        if (isnan(maxval)) maxval = 1.0;
+        if (isnan(minval) || isnan(maxval) || maxval <= 0) {
+            minval = 0.0; /* catching this right away below */
+            maxval = 5.1;
+        }
+        /* in logarithm mode, where minval is smaller or equal 
+           to 0 make the beast just way smaller than maxval */
+        if (minval <= 0) {
+            minval = maxval / 10e8;
+        }
+    } else {
+        if (isnan(minval) || isnan(maxval)) {
+            minval = 0.0;
+            maxval = 1.0;
+        }
     }
-    
-    /* adjust min and max values */
-    if (isnan(im->minval) 
-        /* don't adjust low-end with log scale */ /* why not? */
+
+    /* adjust min and max values given by the user*/
+    /* for logscale we add something on top */
+    if (isnan(im->minval)
         || ((!im->rigid) && im->minval > minval)
         ) {
         if (im->logarithmic)
-            im->minval = minval * 0.5;
+            im->minval = minval / 2.0;
         else
             im->minval = minval;
     }
-    if (isnan(im->maxval) 
+    if (isnan(im->maxval)
         || (!im->rigid && im->maxval < maxval)
         ) {
         if (im->logarithmic)
@@ -1157,29 +1289,24 @@ data_proc( image_desc_t *im ){
         else
             im->maxval = maxval;
     }
+
     /* make sure min is smaller than max */
-    if (im->minval > im->maxval ) {             
-        if (im->maxval > 0)
+    if (im->minval > im->maxval) {
+        if (im->minval > 0)
             im->minval = 0.99 * im->maxval;
-        else 
+        else
             im->minval = 1.01 * im->maxval;
     }
-                      
+
     /* make sure min and max are not equal */
-   if (  AlmostEqual2sComplement(im->minval,im->maxval,4)) {
+    if (AlmostEqual2sComplement(im->minval, im->maxval, 4)) {
         if (im->maxval > 0)
-           im->maxval *= 1.01; 
-        else 
-           im->maxval *= 0.99;
+            im->maxval *= 1.01;
+        else
+            im->maxval *= 0.99;
 
-        if (! im->logarithmic) {
-            if (im->minval > 0)
-               im->minval *= 0.99;
-            else 
-               im->minval *= 1.01;
-        }
         /* make sure min and max are not both zero */
-        if (AlmostEqual2sComplement(im->maxval,0,4)) {
+        if (AlmostEqual2sComplement(im->maxval, 0, 4)) {
             im->maxval = 1.0;
         }
     }
@@ -1190,227 +1317,257 @@ data_proc( image_desc_t *im ){
 
 /* identify the point where the first gridline, label ... gets placed */
 
-time_t
-find_first_time(
-    time_t   start, /* what is the initial time */
-    enum tmt_en baseint,  /* what is the basic interval */
-    long     basestep /* how many if these do we jump a time */
+time_t find_first_time(
+    time_t start,       /* what is the initial time */
+    enum tmt_en baseint,    /* what is the basic interval */
+    long basestep       /* how many if these do we jump a time */
     )
 {
     struct tm tm;
+
     localtime_r(&start, &tm);
-    switch(baseint){
+
+    switch (baseint) {
     case TMT_SECOND:
-        tm.tm_sec -= tm.tm_sec % basestep; break;
-    case TMT_MINUTE: 
-        tm.tm_sec=0;
-        tm.tm_min -= tm.tm_min % basestep; 
+        tm.       tm_sec -= tm.tm_sec % basestep;
+
+        break;
+    case TMT_MINUTE:
+        tm.       tm_sec = 0;
+        tm.       tm_min -= tm.tm_min % basestep;
+
         break;
     case TMT_HOUR:
-        tm.tm_sec=0;
-        tm.tm_min = 0;
-        tm.tm_hour -= tm.tm_hour % basestep; break;
+        tm.       tm_sec = 0;
+        tm.       tm_min = 0;
+        tm.       tm_hour -= tm.tm_hour % basestep;
+
+        break;
     case TMT_DAY:
         /* we do NOT look at the basestep for this ... */
-        tm.tm_sec=0;
-        tm.tm_min = 0;
-        tm.tm_hour = 0; break;
+        tm.       tm_sec = 0;
+        tm.       tm_min = 0;
+        tm.       tm_hour = 0;
+
+        break;
     case TMT_WEEK:
         /* we do NOT look at the basestep for this ... */
-        tm.tm_sec=0;
-        tm.tm_min = 0;
-        tm.tm_hour = 0;
-        tm.tm_mday -= tm.tm_wday -1;        /* -1 because we want the monday */
-        if (tm.tm_wday==0) tm.tm_mday -= 7; /* we want the *previous* monday */
+        tm.       tm_sec = 0;
+        tm.       tm_min = 0;
+        tm.       tm_hour = 0;
+        tm.       tm_mday -= tm.tm_wday - 1;    /* -1 because we want the monday */
+
+        if (tm.tm_wday == 0)
+            tm.       tm_mday -= 7; /* we want the *previous* monday */
+
         break;
     case TMT_MONTH:
-        tm.tm_sec=0;
-        tm.tm_min = 0;
-        tm.tm_hour = 0;
-        tm.tm_mday = 1;
-        tm.tm_mon -= tm.tm_mon % basestep; break;
+        tm.       tm_sec = 0;
+        tm.       tm_min = 0;
+        tm.       tm_hour = 0;
+        tm.       tm_mday = 1;
+        tm.       tm_mon -= tm.tm_mon % basestep;
+
+        break;
 
     case TMT_YEAR:
-        tm.tm_sec=0;
-        tm.tm_min = 0;
-        tm.tm_hour = 0;
-        tm.tm_mday = 1;
-        tm.tm_mon = 0;
-        tm.tm_year -= (tm.tm_year+1900) % basestep;
-        
+        tm.       tm_sec = 0;
+        tm.       tm_min = 0;
+        tm.       tm_hour = 0;
+        tm.       tm_mday = 1;
+        tm.       tm_mon = 0;
+        tm.       tm_year -= (
+    tm.tm_year + 1900) %basestep;
+
     }
     return mktime(&tm);
 }
+
 /* identify the point where the next gridline, label ... gets placed */
-time_t 
-find_next_time(
-    time_t   current, /* what is the initial time */
-    enum tmt_en baseint,  /* what is the basic interval */
-    long     basestep /* how many if these do we jump a time */
+time_t find_next_time(
+    time_t current,     /* what is the initial time */
+    enum tmt_en baseint,    /* what is the basic interval */
+    long basestep       /* how many if these do we jump a time */
     )
 {
     struct tm tm;
-    time_t madetime;
+    time_t    madetime;
+
     localtime_r(&current, &tm);
+
     do {
-        switch(baseint){
+        switch (baseint) {
         case TMT_SECOND:
-            tm.tm_sec += basestep; break;
-        case TMT_MINUTE: 
-            tm.tm_min += basestep; break;
+            tm.       tm_sec += basestep;
+
+            break;
+        case TMT_MINUTE:
+            tm.       tm_min += basestep;
+
+            break;
         case TMT_HOUR:
-            tm.tm_hour += basestep; break;
+            tm.       tm_hour += basestep;
+
+            break;
         case TMT_DAY:
-            tm.tm_mday += basestep; break;
+            tm.       tm_mday += basestep;
+
+            break;
         case TMT_WEEK:
-            tm.tm_mday += 7*basestep; break;
+            tm.       tm_mday += 7 * basestep;
+
+            break;
         case TMT_MONTH:
-            tm.tm_mon += basestep; break;
+            tm.       tm_mon += basestep;
+
+            break;
         case TMT_YEAR:
-            tm.tm_year += basestep;        
+            tm.       tm_year += basestep;
         }
         madetime = mktime(&tm);
-    } while (madetime == -1); /* this is necessary to skip impssible times
-                                 like the daylight saving time skips */
+    } while (madetime == -1);   /* this is necessary to skip impssible times
+                                   like the daylight saving time skips */
     return madetime;
-          
+
 }
 
 
 /* calculate values required for PRINT and GPRINT functions */
 
-int
-print_calc(image_desc_t *im, char ***prdata) 
+int print_calc(
+    image_desc_t *im)
 {
-    long i,ii,validsteps;
-    double printval;
+    long      i, ii, validsteps;
+    double    printval;
     struct tm tmvdef;
-    int graphelement = 0;
-    long vidx;
-    int max_ii;        
-    double magfact = -1;
-    char *si_symb = "";
-    char *percent_s;
-    int prlines = 1;
+    int       graphelement = 0;
+    long      vidx;
+    int       max_ii;
+    double    magfact = -1;
+    char     *si_symb = "";
+    char     *percent_s;
+    int       prline_cnt = 0;
+
     /* wow initializing tmvdef is quite a task :-) */
-    time_t now = time(NULL);
-    localtime_r(&now,&tmvdef);
-    if (im->imginfo) prlines++;
-    for(i=0;i<im->gdes_c;i++){
-            vidx = im->gdes[i].vidx;
-        switch(im->gdes[i].gf){
+    time_t    now = time(NULL);
+
+    localtime_r(&now, &tmvdef);
+    for (i = 0; i < im->gdes_c; i++) {
+        vidx = im->gdes[i].vidx;
+        switch (im->gdes[i].gf) {
         case GF_PRINT:
-            prlines++;
-            if(((*prdata) = rrd_realloc((*prdata),prlines*sizeof(char *)))==NULL){
-                rrd_set_error("realloc prdata");
-                return 0;
-            }
         case GF_GPRINT:
             /* PRINT and GPRINT can now print VDEF generated values.
              * There's no need to do any calculations on them as these
              * calculations were already made.
              */
-            if (im->gdes[vidx].gf==GF_VDEF) { /* simply use vals */
+            if (im->gdes[vidx].gf == GF_VDEF) { /* simply use vals */
                 printval = im->gdes[vidx].vf.val;
-                localtime_r(&im->gdes[vidx].vf.when,&tmvdef);
-            } else { /* need to calculate max,min,avg etcetera */
-                max_ii =((im->gdes[vidx].end 
-                        - im->gdes[vidx].start)
-                        / im->gdes[vidx].step
-                        * im->gdes[vidx].ds_cnt);
+                localtime_r(&im->gdes[vidx].vf.when, &tmvdef);
+            } else {    /* need to calculate max,min,avg etcetera */
+                max_ii = ((im->gdes[vidx].end - im->gdes[vidx].start)
+                          / im->gdes[vidx].step * im->gdes[vidx].ds_cnt);
                 printval = DNAN;
                 validsteps = 0;
-                for(        ii=im->gdes[vidx].ds;
-                        ii < max_ii;
-                        ii+=im->gdes[vidx].ds_cnt){
-                    if (! finite(im->gdes[vidx].data[ii]))
+                for (ii = im->gdes[vidx].ds;
+                     ii < max_ii; ii += im->gdes[vidx].ds_cnt) {
+                    if (!finite(im->gdes[vidx].data[ii]))
                         continue;
-                    if (isnan(printval)){
+                    if (isnan(printval)) {
                         printval = im->gdes[vidx].data[ii];
                         validsteps++;
                         continue;
                     }
 
-                    switch (im->gdes[i].cf){
-                        case CF_HWPREDICT:
-                        case CF_DEVPREDICT:
-                        case CF_DEVSEASONAL:
-                        case CF_SEASONAL:
-                        case CF_AVERAGE:
-                            validsteps++;
-                            printval += im->gdes[vidx].data[ii];
-                            break;
-                        case CF_MINIMUM:
-                            printval = min( printval, im->gdes[vidx].data[ii]);
-                            break;
-                        case CF_FAILURES:
-                        case CF_MAXIMUM:
-                            printval = max( printval, im->gdes[vidx].data[ii]);
-                            break;
-                        case CF_LAST:
-                            printval = im->gdes[vidx].data[ii];
+                    switch (im->gdes[i].cf) {
+                    case CF_HWPREDICT:
+                    case CF_MHWPREDICT:
+                    case CF_DEVPREDICT:
+                    case CF_DEVSEASONAL:
+                    case CF_SEASONAL:
+                    case CF_AVERAGE:
+                        validsteps++;
+                        printval += im->gdes[vidx].data[ii];
+                        break;
+                    case CF_MINIMUM:
+                        printval = min(printval, im->gdes[vidx].data[ii]);
+                        break;
+                    case CF_FAILURES:
+                    case CF_MAXIMUM:
+                        printval = max(printval, im->gdes[vidx].data[ii]);
+                        break;
+                    case CF_LAST:
+                        printval = im->gdes[vidx].data[ii];
                     }
                 }
-                if (im->gdes[i].cf==CF_AVERAGE || im->gdes[i].cf > CF_LAST) {
+                if (im->gdes[i].cf == CF_AVERAGE || im->gdes[i].cf > CF_LAST) {
                     if (validsteps > 1) {
                         printval = (printval / validsteps);
                     }
                 }
-            } /* prepare printval */
+            }           /* prepare printval */
 
-            if ((percent_s = strstr(im->gdes[i].format,"%S")) != NULL) {
+            if ((percent_s = strstr(im->gdes[i].format, "%S")) != NULL) {
                 /* Magfact is set to -1 upon entry to print_calc.  If it
                  * is still less than 0, then we need to run auto_scale.
                  * Otherwise, put the value into the correct units.  If
                  * the value is 0, then do not set the symbol or magnification
                  * so next the calculation will be performed again. */
                 if (magfact < 0.0) {
-                    auto_scale(im,&printval,&si_symb,&magfact);
+                    auto_scale(im, &printval, &si_symb, &magfact);
                     if (printval == 0.0)
                         magfact = -1.0;
                 } else {
                     printval /= magfact;
                 }
                 *(++percent_s) = 's';
-            } else if (strstr(im->gdes[i].format,"%s") != NULL) {
-                auto_scale(im,&printval,&si_symb,&magfact);
+            } else if (strstr(im->gdes[i].format, "%s") != NULL) {
+                auto_scale(im, &printval, &si_symb, &magfact);
             }
 
-            if (im->gdes[i].gf == GF_PRINT){
-                (*prdata)[prlines-2] = malloc((FMT_LEG_LEN+2)*sizeof(char));
-                (*prdata)[prlines-1] = NULL;
-                if (im->gdes[i].strftm){
-                        strftime((*prdata)[prlines-2],FMT_LEG_LEN,im->gdes[i].format,&tmvdef);
+            if (im->gdes[i].gf == GF_PRINT) {
+                infoval   prline;
+
+                if (im->gdes[i].strftm) {
+                    prline.u_str = malloc((FMT_LEG_LEN + 2) * sizeof(char));
+                    strftime(prline.u_str,
+                             FMT_LEG_LEN, im->gdes[i].format, &tmvdef);
+                } else if (bad_format(im->gdes[i].format)) {
+                    rrd_set_error
+                        ("bad format for PRINT in '%s'", im->gdes[i].format);
+                    return -1;
                 } else {
-                     if (bad_format(im->gdes[i].format)) {
-                          rrd_set_error("bad format for PRINT in '%s'", im->gdes[i].format);
-                        return -1;
-                  }
+                    prline.u_str =
+                        sprintf_alloc(im->gdes[i].format, printval, si_symb);
+                }
+                grinfo_push(im,
+                            sprintf_alloc
+                            ("print[%ld]", prline_cnt++), RD_I_STR, prline);
+                free(prline.u_str);
+            } else {
+                /* GF_GPRINT */
 
-#ifdef HAVE_SNPRINTF
-                  snprintf((*prdata)[prlines-2],FMT_LEG_LEN,im->gdes[i].format,printval,si_symb);
-#else
-                  sprintf((*prdata)[prlines-2],im->gdes[i].format,printval,si_symb);
-#endif
-               }
-             } else {
-                /* GF_GPRINT */
-
-                if (im->gdes[i].strftm){
-                        strftime(im->gdes[i].legend,FMT_LEG_LEN,im->gdes[i].format,&tmvdef);
+                if (im->gdes[i].strftm) {
+                    strftime(im->gdes[i].legend,
+                             FMT_LEG_LEN, im->gdes[i].format, &tmvdef);
                 } else {
                     if (bad_format(im->gdes[i].format)) {
-                        rrd_set_error("bad format for GPRINT in '%s'", im->gdes[i].format);
+                        rrd_set_error
+                            ("bad format for GPRINT in '%s'",
+                             im->gdes[i].format);
                         return -1;
-                  }
+                    }
 #ifdef HAVE_SNPRINTF
-                  snprintf(im->gdes[i].legend,FMT_LEG_LEN-2,im->gdes[i].format,printval,si_symb);
+                    snprintf(im->gdes[i].legend,
+                             FMT_LEG_LEN - 2,
+                             im->gdes[i].format, printval, si_symb);
 #else
-                  sprintf(im->gdes[i].legend,im->gdes[i].format,printval,si_symb);
+                    sprintf(im->gdes[i].legend,
+                            im->gdes[i].format, printval, si_symb);
 #endif
                 }
-                graphelement = 1;               
-            }            
+                graphelement = 1;
+            }
             break;
         case GF_LINE:
         case GF_AREA:
@@ -1418,21 +1575,22 @@ print_calc(image_desc_t *im, char ***prdata)
             graphelement = 1;
             break;
         case GF_HRULE:
-            if(isnan(im->gdes[i].yrule)) { /* we must set this here or the legend printer can not decide to print the legend */
-               im->gdes[i].yrule=im->gdes[vidx].vf.val;
+            if (isnan(im->gdes[i].yrule)) { /* we must set this here or the legend printer can not decide to print the legend */
+                im->gdes[i].yrule = im->gdes[vidx].vf.val;
             };
             graphelement = 1;
             break;
         case GF_VRULE:
-            if(im->gdes[i].xrule == 0) { /* again ... the legend printer needs it*/
-              im->gdes[i].xrule = im->gdes[vidx].vf.when;
+            if (im->gdes[i].xrule == 0) {   /* again ... the legend printer needs it */
+                im->gdes[i].xrule = im->gdes[vidx].vf.when;
             };
             graphelement = 1;
             break;
         case GF_COMMENT:
+        case GF_TEXTALIGN:
         case GF_DEF:
-        case GF_CDEF:            
-        case GF_VDEF:            
+        case GF_CDEF:
+        case GF_VDEF:
 #ifdef WITH_PIECHART
         case GF_PART:
 #endif
@@ -1440,7 +1598,8 @@ print_calc(image_desc_t *im, char ***prdata)
         case GF_XPORT:
             break;
         case GF_STACK:
-            rrd_set_error("STACK should already be turned into LINE or AREA here");
+            rrd_set_error
+                ("STACK should already be turned into LINE or AREA here");
             return -1;
             break;
         }
@@ -1450,163 +1609,214 @@ print_calc(image_desc_t *im, char ***prdata)
 
 
 /* place legends with color spots */
-int
-leg_place(image_desc_t *im)
+int leg_place(
+    image_desc_t *im,
+    int *gY)
 {
     /* graph labels */
-    int   interleg = im->text_prop[TEXT_PROP_LEGEND].size*2.0;
-    int   border = im->text_prop[TEXT_PROP_LEGEND].size*2.0;
-    int   fill=0, fill_last;
-    int   leg_c = 0;
-    int   leg_x = border, leg_y = im->yimg;
-    int   leg_y_prev = im->yimg;
-    int   leg_cc;
-    int   glue = 0;
-    int   i,ii, mark = 0;
-    char  prt_fctn; /*special printfunctions */
-    int  *legspace;
-
-  if( !(im->extra_flags & NOLEGEND) & !(im->extra_flags & ONLY_GRAPH) ) {
-    if ((legspace = malloc(im->gdes_c*sizeof(int)))==NULL){
-       rrd_set_error("malloc for legspace");
-       return -1;
-    }
-
-    for(i=0;i<im->gdes_c;i++){
-        fill_last = fill;
-        
-        /* hid legends for rules which are not displayed */
-        
-        if(!(im->extra_flags & FORCE_RULES_LEGEND)) {
-                if (im->gdes[i].gf == GF_HRULE &&
-                    (im->gdes[i].yrule < im->minval || im->gdes[i].yrule > im->maxval))
-                    im->gdes[i].legend[0] = '\0';
+    int       interleg = im->text_prop[TEXT_PROP_LEGEND].size * 2.0;
+    int       border = im->text_prop[TEXT_PROP_LEGEND].size * 2.0;
+    int       fill = 0, fill_last;
+    int       leg_c = 0;
+    int       leg_x = border, leg_y = im->yimg;
+    int       leg_y_prev = im->yimg;
+    int       leg_cc;
+    int       glue = 0;
+    int       i, ii, mark = 0;
+    char      prt_fctn; /*special printfunctions */
+    char      default_txtalign = TXA_JUSTIFIED; /*default line orientation */
+    int      *legspace;
+
+    if (!(im->extra_flags & NOLEGEND) & !(im->extra_flags & ONLY_GRAPH)) {
+        if ((legspace = malloc(im->gdes_c * sizeof(int))) == NULL) {
+            rrd_set_error("malloc for legspace");
+            return -1;
+        }
+
+        if (im->extra_flags & FULL_SIZE_MODE)
+            leg_y = leg_y_prev =
+                leg_y - (int) (im->text_prop[TEXT_PROP_LEGEND].size * 1.8);
+        for (i = 0; i < im->gdes_c; i++) {
+            fill_last = fill;
+            /* hide legends for rules which are not displayed */
+            if (im->gdes[i].gf == GF_TEXTALIGN) {
+                default_txtalign = im->gdes[i].txtalign;
+            }
 
-                if (im->gdes[i].gf == GF_VRULE &&
-                    (im->gdes[i].xrule < im->start || im->gdes[i].xrule > im->end))
+            if (!(im->extra_flags & FORCE_RULES_LEGEND)) {
+                if (im->gdes[i].gf == GF_HRULE
+                    && (im->gdes[i].yrule <
+                        im->minval || im->gdes[i].yrule > im->maxval))
                     im->gdes[i].legend[0] = '\0';
-        }
+                if (im->gdes[i].gf == GF_VRULE
+                    && (im->gdes[i].xrule <
+                        im->start || im->gdes[i].xrule > im->end))
+                    im->gdes[i].legend[0] = '\0';
+            }
+
+            leg_cc = strlen(im->gdes[i].legend);
+            /* is there a controle code ant the end of the legend string ? */
+            /* and it is not a tab \\t */
+            if (leg_cc >= 2
+                && im->gdes[i].legend[leg_cc -
+                                      2] == '\\'
+                && im->gdes[i].legend[leg_cc - 1] != 't') {
+                prt_fctn = im->gdes[i].legend[leg_cc - 1];
+                leg_cc -= 2;
+                im->gdes[i].legend[leg_cc] = '\0';
+            } else {
+                prt_fctn = '\0';
+            }
+            /* only valid control codes */
+            if (prt_fctn != 'l' && prt_fctn != 'n' &&   /* a synonym for l */
+                prt_fctn != 'r' &&
+                prt_fctn != 'j' &&
+                prt_fctn != 'c' &&
+                prt_fctn != 's' &&
+                prt_fctn != 't' && prt_fctn != '\0' && prt_fctn != 'g') {
+                free(legspace);
+                rrd_set_error
+                    ("Unknown control code at the end of '%s\\%c'",
+                     im->gdes[i].legend, prt_fctn);
+                return -1;
+            }
+            /* \n -> \l */
+            if (prt_fctn == 'n') {
+                prt_fctn = 'l';
+            }
+
+            /* remove exess space from the end of the legend for \g */
+            while (prt_fctn == 'g' &&
+                   leg_cc > 0 && im->gdes[i].legend[leg_cc - 1] == ' ') {
+                leg_cc--;
+                im->gdes[i].legend[leg_cc] = '\0';
+            }
+
+            if (leg_cc != 0) {
 
-        leg_cc = strlen(im->gdes[i].legend);
-        
-        /* is there a controle code ant the end of the legend string ? */ 
-        /* and it is not a tab \\t */
-        if (leg_cc >= 2 && im->gdes[i].legend[leg_cc-2] == '\\' && im->gdes[i].legend[leg_cc-1] != 't') {
-            prt_fctn = im->gdes[i].legend[leg_cc-1];
-            leg_cc -= 2;
-            im->gdes[i].legend[leg_cc] = '\0';
-        } else {
-            prt_fctn = '\0';
-        }
-        /* only valid control codes */
-        if (prt_fctn != 'l' && 
-            prt_fctn != 'n' && /* a synonym for l */
-            prt_fctn != 'r' &&
-            prt_fctn != 'j' &&
-            prt_fctn != 'c' &&
-            prt_fctn != 's' &&
-            prt_fctn != 't' &&
-            prt_fctn != '\0' &&
-            prt_fctn != 'g' ) {
-               free(legspace);
-               rrd_set_error("Unknown control code at the end of '%s\\%c'",im->gdes[i].legend,prt_fctn);
-                      return -1;
-
-        }
-
-        /* remove exess space */
-        if ( prt_fctn == 'n' ){
-            prt_fctn='l';
-        }
-
-        while (prt_fctn=='g' && 
-               leg_cc > 0 && 
-               im->gdes[i].legend[leg_cc-1]==' '){
-           leg_cc--;
-           im->gdes[i].legend[leg_cc]='\0';
-        }
-        if (leg_cc != 0 ){
-           legspace[i]=(prt_fctn=='g' ? 0 : interleg);
-           
-           if (fill > 0){ 
                 /* no interleg space if string ends in \g */
-               fill += legspace[i];
-            }
-           fill += gfx_get_text_width(im->canvas, fill+border,
-                                      im->text_prop[TEXT_PROP_LEGEND].font,
-                                      im->text_prop[TEXT_PROP_LEGEND].size,
-                                      im->tabwidth,
-                                      im->gdes[i].legend, 0);
-            leg_c++;
-        } else {
-           legspace[i]=0;
-        }
-        /* who said there was a special tag ... ?*/
-        if (prt_fctn=='g') {    
-           prt_fctn = '\0';
-        }
-        if (prt_fctn == '\0') {
-            if (i == im->gdes_c -1 ) prt_fctn ='l';
-            
-            /* is it time to place the legends ? */
-            if (fill > im->ximg - 2*border){
-                if (leg_c > 1) {
-                    /* go back one */
-                    i--; 
-                    fill = fill_last;
-                    leg_c--;
-                    prt_fctn = 'j';
-                } else {
+                legspace[i] = (prt_fctn == 'g' ? 0 : interleg);
+                if (fill > 0) {
+                    fill += legspace[i];
+                }
+                fill +=
+                    gfx_get_text_width(im,
+                                       fill + border,
+                                       im->
+                                       text_prop
+                                       [TEXT_PROP_LEGEND].
+                                       font,
+                                       im->
+                                       text_prop
+                                       [TEXT_PROP_LEGEND].
+                                       size,
+                                       im->tabwidth, im->gdes[i].legend);
+                leg_c++;
+            } else {
+                legspace[i] = 0;
+            }
+            /* who said there was a special tag ... ? */
+            if (prt_fctn == 'g') {
+                prt_fctn = '\0';
+            }
+
+            if (prt_fctn == '\0') {
+                if (i == im->gdes_c - 1 || fill > im->ximg - 2 * border) {
+                    /* just one legend item is left right or center */
+                    switch (default_txtalign) {
+                    case TXA_RIGHT:
+                        prt_fctn = 'r';
+                        break;
+                    case TXA_CENTER:
+                        prt_fctn = 'c';
+                        break;
+                    case TXA_JUSTIFIED:
+                        prt_fctn = 'j';
+                        break;
+                    default:
+                        prt_fctn = 'l';
+                        break;
+                    }
+                }
+                /* is it time to place the legends ? */
+                if (fill > im->ximg - 2 * border) {
+                    if (leg_c > 1) {
+                        /* go back one */
+                        i--;
+                        fill = fill_last;
+                        leg_c--;
+                    }
+                }
+                if (leg_c == 1 && prt_fctn == 'j') {
                     prt_fctn = 'l';
                 }
-                
             }
-        }
 
 
-        if (prt_fctn != '\0'){        
-            leg_x = border;
-            if (leg_c >= 2 && prt_fctn == 'j') {
-                glue = (im->ximg - fill - 2* border) / (leg_c-1);
-            } else {
-                glue = 0;
-            }
-            if (prt_fctn =='c') leg_x =  (im->ximg - fill) / 2.0;
-            if (prt_fctn =='r') leg_x =  im->ximg - fill - border;
-
-            for(ii=mark;ii<=i;ii++){
-                if(im->gdes[ii].legend[0]=='\0')
-                    continue; /* skip empty legends */
-                im->gdes[ii].leg_x = leg_x;
-                im->gdes[ii].leg_y = leg_y;
-                leg_x += 
-                 gfx_get_text_width(im->canvas, leg_x,
-                                      im->text_prop[TEXT_PROP_LEGEND].font,
-                                      im->text_prop[TEXT_PROP_LEGEND].size,
-                                      im->tabwidth,
-                                      im->gdes[ii].legend, 0) 
-                   + legspace[ii]
-                   + glue;
-            }                        
-            leg_y_prev = leg_y;
-            /* only add y space if there was text on the line */
-            if (leg_x > border || prt_fctn == 's')            
-               leg_y += im->text_prop[TEXT_PROP_LEGEND].size*1.8;
-            if (prt_fctn == 's')
-               leg_y -=  im->text_prop[TEXT_PROP_LEGEND].size;           
-            fill = 0;
-            leg_c = 0;
-            mark = ii;
-        }           
-    }
-    im->yimg = leg_y_prev;
-    /* if we did place some legends we have to add vertical space */
-    if (leg_y != im->yimg){
-        im->yimg += im->text_prop[TEXT_PROP_LEGEND].size*1.8;
-    }
-    free(legspace);
-  }
-  return 0;
+            if (prt_fctn != '\0') {
+                leg_x = border;
+                if (leg_c >= 2 && prt_fctn == 'j') {
+                    glue = (im->ximg - fill - 2 * border) / (leg_c - 1);
+                } else {
+                    glue = 0;
+                }
+                if (prt_fctn == 'c')
+                    leg_x = (im->ximg - fill) / 2.0;
+                if (prt_fctn == 'r')
+                    leg_x = im->ximg - fill - border;
+                for (ii = mark; ii <= i; ii++) {
+                    if (im->gdes[ii].legend[0] == '\0')
+                        continue;   /* skip empty legends */
+                    im->gdes[ii].leg_x = leg_x;
+                    im->gdes[ii].leg_y = leg_y;
+                    leg_x +=
+                        gfx_get_text_width(im, leg_x,
+                                           im->
+                                           text_prop
+                                           [TEXT_PROP_LEGEND].
+                                           font,
+                                           im->
+                                           text_prop
+                                           [TEXT_PROP_LEGEND].
+                                           size,
+                                           im->tabwidth, im->gdes[ii].legend)
+                        + legspace[ii]
+                        + glue;
+                }
+                leg_y_prev = leg_y;
+                if (im->extra_flags & FULL_SIZE_MODE) {
+                    /* only add y space if there was text on the line */
+                    if (leg_x > border || prt_fctn == 's')
+                        leg_y -= im->text_prop[TEXT_PROP_LEGEND].size * 1.8;
+                    if (prt_fctn == 's')
+                        leg_y += im->text_prop[TEXT_PROP_LEGEND].size;
+                } else {
+                    if (leg_x > border || prt_fctn == 's')
+                        leg_y += im->text_prop[TEXT_PROP_LEGEND].size * 1.8;
+                    if (prt_fctn == 's')
+                        leg_y -= im->text_prop[TEXT_PROP_LEGEND].size;
+                }
+                fill = 0;
+                leg_c = 0;
+                mark = ii;
+            }
+        }
+
+        if (im->extra_flags & FULL_SIZE_MODE) {
+            if (leg_y != leg_y_prev) {
+                *gY = leg_y - im->text_prop[TEXT_PROP_LEGEND].size * 1.8;
+                im->yorigin =
+                    leg_y - im->text_prop[TEXT_PROP_LEGEND].size * 1.8;
+            }
+        } else {
+            im->yimg = leg_y_prev;
+            /* if we did place some legends we have to add vertical space */
+            if (leg_y != im->yimg)
+                im->yimg += im->text_prop[TEXT_PROP_LEGEND].size * 1.8;
+        }
+        free(legspace);
+    }
+    return 0;
 }
 
 /* create a grid on the graph. it determines what to do
@@ -1617,78 +1827,92 @@ leg_place(image_desc_t *im)
 
 
 
-int
-calc_horizontal_grid(image_desc_t   *im)
+int calc_horizontal_grid(
+    image_desc_t
+    *im)
 {
-    double   range;
-    double   scaledrange;
-    int      pixel,i;
-    int      gridind=0;
-    int      decimals, fractionals;
-
-    im->ygrid_scale.labfact=2;
-    range =  im->maxval - im->minval;
+    double    range;
+    double    scaledrange;
+    int       pixel, i;
+    int       gridind = 0;
+    int       decimals, fractionals;
+
+    im->ygrid_scale.labfact = 2;
+    range = im->maxval - im->minval;
     scaledrange = range / im->magfact;
-
-        /* does the scale of this graph make it impossible to put lines
-           on it? If so, give up. */
-        if (isnan(scaledrange)) {
-                return 0;
-        }
+    /* does the scale of this graph make it impossible to put lines
+       on it? If so, give up. */
+    if (isnan(scaledrange)) {
+        return 0;
+    }
 
     /* find grid spaceing */
-    pixel=1;
-    if(isnan(im->ygridstep)){
-        if(im->extra_flags & ALTYGRID) {
+    pixel = 1;
+    if (isnan(im->ygridstep)) {
+        if (im->extra_flags & ALTYGRID) {
             /* find the value with max number of digits. Get number of digits */
-            decimals = ceil(log10(max(fabs(im->maxval), fabs(im->minval))*im->viewfactor/im->magfact));
-            if(decimals <= 0) /* everything is small. make place for zero */
+            decimals =
+                ceil(log10
+                     (max(fabs(im->maxval), fabs(im->minval)) *
+                      im->viewfactor / im->magfact));
+            if (decimals <= 0)  /* everything is small. make place for zero */
                 decimals = 1;
-            
-            im->ygrid_scale.gridstep = pow((double)10, floor(log10(range*im->viewfactor/im->magfact)))/im->viewfactor*im->magfact;
-            
-            if(im->ygrid_scale.gridstep == 0) /* range is one -> 0.1 is reasonable scale */
+            im->ygrid_scale.gridstep =
+                pow((double) 10,
+                    floor(log10(range * im->viewfactor / im->magfact))) /
+                im->viewfactor * im->magfact;
+            if (im->ygrid_scale.gridstep == 0)  /* range is one -> 0.1 is reasonable scale */
                 im->ygrid_scale.gridstep = 0.1;
             /* should have at least 5 lines but no more then 15 */
-            if(range/im->ygrid_scale.gridstep < 5)
+            if (range / im->ygrid_scale.gridstep < 5)
                 im->ygrid_scale.gridstep /= 10;
-            if(range/im->ygrid_scale.gridstep > 15)
+            if (range / im->ygrid_scale.gridstep > 15)
                 im->ygrid_scale.gridstep *= 10;
-            if(range/im->ygrid_scale.gridstep > 5) {
+            if (range / im->ygrid_scale.gridstep > 5) {
                 im->ygrid_scale.labfact = 1;
-                if(range/im->ygrid_scale.gridstep > 8)
+                if (range / im->ygrid_scale.gridstep > 8)
                     im->ygrid_scale.labfact = 2;
-            }
-            else {
+            } else {
                 im->ygrid_scale.gridstep /= 5;
                 im->ygrid_scale.labfact = 5;
             }
-            fractionals = floor(log10(im->ygrid_scale.gridstep*(double)im->ygrid_scale.labfact*im->viewfactor/im->magfact));
-            if(fractionals < 0) { /* small amplitude. */
-                int len = decimals - fractionals + 1;
-                if (im->unitslength < len+2) im->unitslength = len+2;
-                sprintf(im->ygrid_scale.labfmt, "%%%d.%df%s", len, -fractionals,(im->symbol != ' ' ? " %c" : ""));
+            fractionals =
+                floor(log10
+                      (im->ygrid_scale.gridstep *
+                       (double) im->ygrid_scale.labfact * im->viewfactor /
+                       im->magfact));
+            if (fractionals < 0) {  /* small amplitude. */
+                int       len = decimals - fractionals + 1;
+
+                if (im->unitslength < len + 2)
+                    im->unitslength = len + 2;
+                sprintf(im->ygrid_scale.labfmt,
+                        "%%%d.%df%s", len,
+                        -fractionals, (im->symbol != ' ' ? " %c" : ""));
             } else {
-                int len = decimals + 1;
-                if (im->unitslength < len+2) im->unitslength = len+2;
-                sprintf(im->ygrid_scale.labfmt, "%%%d.0f%s", len, ( im->symbol != ' ' ? " %c" : "" ));
+                int       len = decimals + 1;
+
+                if (im->unitslength < len + 2)
+                    im->unitslength = len + 2;
+                sprintf(im->ygrid_scale.labfmt,
+                        "%%%d.0f%s", len, (im->symbol != ' ' ? " %c" : ""));
             }
-        }
-        else {
-            for(i=0;ylab[i].grid > 0;i++){
+        } else {
+            for (i = 0; ylab[i].grid > 0; i++) {
                 pixel = im->ysize / (scaledrange / ylab[i].grid);
-                   gridind = i;
+                gridind = i;
                 if (pixel > 7)
                     break;
             }
-            
-            for(i=0; i<4;i++) {
-               if (pixel * ylab[gridind].lfac[i] >=  2.5 * im->text_prop[TEXT_PROP_AXIS].size) {
-                  im->ygrid_scale.labfact =  ylab[gridind].lfac[i];
-                  break;
-               }
-            } 
-            
+
+            for (i = 0; i < 4; i++) {
+                if (pixel * ylab[gridind].lfac[i] >=
+                    2.5 * im->text_prop[TEXT_PROP_AXIS].size) {
+                    im->ygrid_scale.labfact = ylab[gridind].lfac[i];
+                    break;
+                }
+            }
+
             im->ygrid_scale.gridstep = ylab[gridind].grid * im->magfact;
         }
     } else {
@@ -1698,88 +1922,126 @@ calc_horizontal_grid(image_desc_t   *im)
     return 1;
 }
 
-int draw_horizontal_grid(image_desc_t *im)
+int draw_horizontal_grid(
+    image_desc_t
+    *im)
 {
-    int      i;
-    double   scaledstep;
-    char     graph_label[100];
-    int      nlabels=0;
-    double X0=im->xorigin;
-    double X1=im->xorigin+im->xsize;
-   
-    int sgrid = (int)( im->minval / im->ygrid_scale.gridstep - 1);
-    int egrid = (int)( im->maxval / im->ygrid_scale.gridstep + 1);
-    double MaxY;
-    scaledstep = im->ygrid_scale.gridstep/(double)im->magfact*(double)im->viewfactor;
-    MaxY = scaledstep*(double)egrid;
-    for (i = sgrid; i <= egrid; i++){
-       double Y0=ytr(im,im->ygrid_scale.gridstep*i);
-       double YN=ytr(im,im->ygrid_scale.gridstep*(i+1));
-       if ( floor(Y0+0.5) >= im->yorigin-im->ysize 
-            && floor(Y0+0.5) <= im->yorigin){       
+    int       i;
+    double    scaledstep;
+    char      graph_label[100];
+    int       nlabels = 0;
+    double    X0 = im->xorigin;
+    double    X1 = im->xorigin + im->xsize;
+    int       sgrid = (int) (im->minval / im->ygrid_scale.gridstep - 1);
+    int       egrid = (int) (im->maxval / im->ygrid_scale.gridstep + 1);
+    double    MaxY;
+
+    scaledstep =
+        im->ygrid_scale.gridstep /
+        (double) im->magfact * (double) im->viewfactor;
+    MaxY = scaledstep * (double) egrid;
+    for (i = sgrid; i <= egrid; i++) {
+        double    Y0 = ytr(im,
+                           im->ygrid_scale.gridstep * i);
+        double    YN = ytr(im,
+                           im->ygrid_scale.gridstep * (i + 1));
+
+        if (floor(Y0 + 0.5) >=
+            im->yorigin - im->ysize && floor(Y0 + 0.5) <= im->yorigin) {
             /* Make sure at least 2 grid labels are shown, even if it doesn't agree
                with the chosen settings. Add a label if required by settings, or if
                there is only one label so far and the next grid line is out of bounds. */
-            if(i % im->ygrid_scale.labfact == 0 || ( nlabels==1 && (YN < im->yorigin-im->ysize || YN > im->yorigin) )){                
+            if (i % im->ygrid_scale.labfact == 0
+                || (nlabels == 1
+                    && (YN < im->yorigin - im->ysize || YN > im->yorigin))) {
                 if (im->symbol == ' ') {
-                     if(im->extra_flags & ALTYGRID) {
-                        sprintf(graph_label,im->ygrid_scale.labfmt,scaledstep*(double)i);
+                    if (im->extra_flags & ALTYGRID) {
+                        sprintf(graph_label,
+                                im->ygrid_scale.labfmt,
+                                scaledstep * (double) i);
                     } else {
-                        if(MaxY < 10) {
-                           sprintf(graph_label,"%4.1f",scaledstep*(double)i);
-                          } else {
-                           sprintf(graph_label,"%4.0f",scaledstep*(double)i);
+                        if (MaxY < 10) {
+                            sprintf(graph_label, "%4.1f",
+                                    scaledstep * (double) i);
+                        } else {
+                            sprintf(graph_label, "%4.0f",
+                                    scaledstep * (double) i);
                         }
                     }
-                }else {
-                    char sisym = ( i == 0  ? ' ' : im->symbol);
-                     if(im->extra_flags & ALTYGRID) {
-                        sprintf(graph_label,im->ygrid_scale.labfmt,scaledstep*(double)i,sisym);
+                } else {
+                    char      sisym = (i == 0 ? ' ' : im->symbol);
+
+                    if (im->extra_flags & ALTYGRID) {
+                        sprintf(graph_label,
+                                im->ygrid_scale.labfmt,
+                                scaledstep * (double) i, sisym);
                     } else {
-                          if(MaxY < 10){
-                             sprintf(graph_label,"%4.1f %c",scaledstep*(double)i, sisym);
+                        if (MaxY < 10) {
+                            sprintf(graph_label, "%4.1f %c",
+                                    scaledstep * (double) i, sisym);
                         } else {
-                             sprintf(graph_label,"%4.0f %c",scaledstep*(double)i, sisym);
+                            sprintf(graph_label, "%4.0f %c",
+                                    scaledstep * (double) i, sisym);
                         }
                     }
                 }
                 nlabels++;
-
-               gfx_new_text ( im->canvas,
-                              X0-im->text_prop[TEXT_PROP_AXIS].size, Y0,
-                              im->graph_col[GRC_FONT],
-                              im->text_prop[TEXT_PROP_AXIS].font,
-                              im->text_prop[TEXT_PROP_AXIS].size,
-                              im->tabwidth, 0.0, GFX_H_RIGHT, GFX_V_CENTER,
-                              graph_label );
-               gfx_new_dashed_line ( im->canvas,
-                              X0-2,Y0,
-                              X1+2,Y0,
-                              MGRIDWIDTH, im->graph_col[GRC_MGRID],
-                              im->grid_dash_on, im->grid_dash_off);               
-               
-            } else if (!(im->extra_flags & NOMINOR)) {                
-               gfx_new_dashed_line ( im->canvas,
-                              X0-1,Y0,
-                              X1+1,Y0,
-                              GRIDWIDTH, im->graph_col[GRC_GRID],
-                              im->grid_dash_on, im->grid_dash_off);               
-               
-            }            
-        }        
-    } 
+                gfx_text(im,
+                         X0 -
+                         im->
+                         text_prop[TEXT_PROP_AXIS].
+                         size, Y0,
+                         im->graph_col[GRC_FONT],
+                         im->
+                         text_prop[TEXT_PROP_AXIS].
+                         font,
+                         im->
+                         text_prop[TEXT_PROP_AXIS].
+                         size, im->tabwidth, 0.0,
+                         GFX_H_RIGHT, GFX_V_CENTER, graph_label);
+                gfx_line(im, X0 - 2, Y0, X0, Y0,
+                         MGRIDWIDTH, im->graph_col[GRC_MGRID]);
+                gfx_line(im, X1, Y0, X1 + 2, Y0,
+                         MGRIDWIDTH, im->graph_col[GRC_MGRID]);
+                gfx_dashed_line(im, X0 - 2, Y0,
+                                X1 + 2, Y0,
+                                MGRIDWIDTH,
+                                im->
+                                graph_col
+                                [GRC_MGRID],
+                                im->grid_dash_on, im->grid_dash_off);
+            } else if (!(im->extra_flags & NOMINOR)) {
+                gfx_line(im,
+                         X0 - 2, Y0,
+                         X0, Y0, GRIDWIDTH, im->graph_col[GRC_GRID]);
+                gfx_line(im, X1, Y0, X1 + 2, Y0,
+                         GRIDWIDTH, im->graph_col[GRC_GRID]);
+                gfx_dashed_line(im, X0 - 1, Y0,
+                                X1 + 1, Y0,
+                                GRIDWIDTH,
+                                im->
+                                graph_col[GRC_GRID],
+                                im->grid_dash_on, im->grid_dash_off);
+            }
+        }
+    }
     return 1;
 }
 
 /* this is frexp for base 10 */
-double frexp10(double, double *);
-double frexp10(double x, double *e) {
-    double mnt;
-    int iexp;
+double    frexp10(
+    double,
+    double *);
+double frexp10(
+    double x,
+    double *e)
+{
+    double    mnt;
+    int       iexp;
 
     iexp = floor(log(fabs(x)) / log(10));
     mnt = x / pow(10.0, iexp);
-    if(mnt >= 10.0) {
+    if (mnt >= 10.0) {
         iexp++;
         mnt = x / pow(10.0, iexp);
     }
@@ -1787,212 +2049,265 @@ double frexp10(double x, double *e) {
     return mnt;
 }
 
+/* from http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm */
+/* yes we are loosing precision by doing tos with floats instead of doubles
+   but it seems more stable this way. */
+
 
 /* logaritmic horizontal grid */
-int
-horizontal_log_grid(image_desc_t   *im)   
+int horizontal_log_grid(
+    image_desc_t
+    *im)
 {
-    double yloglab[][10] = {
-        {1.0, 10., 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
-        {1.0, 5.0, 10., 0.0, 0.0, 0.0, 0.0, 0.0, 0.0, 0.0},
-        {1.0, 2.0, 5.0, 7.0, 10., 0.0, 0.0, 0.0, 0.0, 0.0},
-        {1.0, 2.0, 4.0, 6.0, 8.0, 10., 0.0, 0.0, 0.0, 0.0},
-        {1.0, 2.0, 3.0, 4.0, 5.0, 6.0, 7.0, 8.0, 9.0, 10.},
-        {0,0,0,0,0, 0,0,0,0,0} /* last line */ };
-
-    int i, j, val_exp, min_exp;
-    double nex;                /* number of decades in data */
-    double logscale;        /* scale in logarithmic space */
-    int exfrac = 1;        /* decade spacing */
-    int mid = -1;        /* row in yloglab for major grid */
-    double mspac;        /* smallest major grid spacing (pixels) */
-    int flab;                /* first value in yloglab to use */
-    double value, tmp, pre_value;
-    double X0,X1,Y0;   
-    char graph_label[100];
+    double    yloglab[][10] = {
+        {
+         1.0, 10., 0.0, 0.0, 0.0, 0.0, 0.0,
+         0.0, 0.0, 0.0}, {
+                          1.0, 5.0, 10., 0.0, 0.0, 0.0, 0.0,
+                          0.0, 0.0, 0.0}, {
+                                           1.0, 2.0, 5.0, 7.0, 10., 0.0, 0.0,
+                                           0.0, 0.0, 0.0}, {
+                                                            1.0, 2.0, 4.0,
+                                                            6.0, 8.0, 10.,
+                                                            0.0,
+                                                            0.0, 0.0, 0.0}, {
+                                                                             1.0,
+                                                                             2.0,
+                                                                             3.0,
+                                                                             4.0,
+                                                                             5.0,
+                                                                             6.0,
+                                                                             7.0,
+                                                                             8.0,
+                                                                             9.0,
+                                                                             10.},
+        {
+         0, 0, 0, 0, 0, 0, 0, 0, 0, 0}  /* last line */
+    };
+    int       i, j, val_exp, min_exp;
+    double    nex;      /* number of decades in data */
+    double    logscale; /* scale in logarithmic space */
+    int       exfrac = 1;   /* decade spacing */
+    int       mid = -1; /* row in yloglab for major grid */
+    double    mspac;    /* smallest major grid spacing (pixels) */
+    int       flab;     /* first value in yloglab to use */
+    double    value, tmp, pre_value;
+    double    X0, X1, Y0;
+    char      graph_label[100];
 
     nex = log10(im->maxval / im->minval);
     logscale = im->ysize / nex;
-
     /* major spacing for data with high dynamic range */
-    while(logscale * exfrac < 3 * im->text_prop[TEXT_PROP_LEGEND].size) {
-        if(exfrac == 1) exfrac = 3;
-        else exfrac += 3;
+    while (logscale * exfrac < 3 * im->text_prop[TEXT_PROP_LEGEND].size) {
+        if (exfrac == 1)
+            exfrac = 3;
+        else
+            exfrac += 3;
     }
 
     /* major spacing for less dynamic data */
     do {
         /* search best row in yloglab */
         mid++;
-        for(i = 0; yloglab[mid][i + 1] < 10.0; i++);
+        for (i = 0; yloglab[mid][i + 1] < 10.0; i++);
         mspac = logscale * log10(10.0 / yloglab[mid][i]);
-    } while(mspac > 2 * im->text_prop[TEXT_PROP_LEGEND].size && yloglab[mid][0] > 0);
-    if(mid) mid--;
-
+    }
+    while (mspac >
+           2 * im->text_prop[TEXT_PROP_LEGEND].size && yloglab[mid][0] > 0);
+    if (mid)
+        mid--;
     /* find first value in yloglab */
-    for(flab = 0; yloglab[mid][flab] < 10 && frexp10(im->minval, &tmp) > yloglab[mid][flab] ; flab++);
-    if(yloglab[mid][flab] == 10.0) {
+    for (flab = 0;
+         yloglab[mid][flab] < 10
+         && frexp10(im->minval, &tmp) > yloglab[mid][flab]; flab++);
+    if (yloglab[mid][flab] == 10.0) {
         tmp += 1.0;
         flab = 0;
     }
     val_exp = tmp;
-    if(val_exp % exfrac) val_exp += abs(-val_exp % exfrac);
-
-    X0=im->xorigin;
-    X1=im->xorigin+im->xsize;
-
+    if (val_exp % exfrac)
+        val_exp += abs(-val_exp % exfrac);
+    X0 = im->xorigin;
+    X1 = im->xorigin + im->xsize;
     /* draw grid */
     pre_value = DNAN;
-    while(1) {       
+    while (1) {
 
         value = yloglab[mid][flab] * pow(10.0, val_exp);
-        if (  AlmostEqual2sComplement(value,pre_value,4) ) break; /* it seems we are not converging */
-
+        if (AlmostEqual2sComplement(value, pre_value, 4))
+            break;      /* it seems we are not converging */
         pre_value = value;
-
         Y0 = ytr(im, value);
-        if(floor(Y0+0.5) <= im->yorigin - im->ysize) break;
-
+        if (floor(Y0 + 0.5) <= im->yorigin - im->ysize)
+            break;
         /* major grid line */
-        gfx_new_dashed_line ( im->canvas,
-            X0-2,Y0,
-            X1+2,Y0,
-            MGRIDWIDTH, im->graph_col[GRC_MGRID],
-            im->grid_dash_on, im->grid_dash_off);
-
+        gfx_line(im,
+                 X0 - 2, Y0, X0, Y0, MGRIDWIDTH, im->graph_col[GRC_MGRID]);
+        gfx_line(im, X1, Y0, X1 + 2, Y0,
+                 MGRIDWIDTH, im->graph_col[GRC_MGRID]);
+        gfx_dashed_line(im, X0 - 2, Y0,
+                        X1 + 2, Y0,
+                        MGRIDWIDTH,
+                        im->
+                        graph_col
+                        [GRC_MGRID], im->grid_dash_on, im->grid_dash_off);
         /* label */
         if (im->extra_flags & FORCE_UNITS_SI) {
-            int scale;
-            double pvalue;
-            char symbol;
+            int       scale;
+            double    pvalue;
+            char      symbol;
 
             scale = floor(val_exp / 3.0);
-            if( value >= 1.0 ) pvalue = pow(10.0, val_exp % 3);
-            else pvalue = pow(10.0, ((val_exp + 1) % 3) + 2);
+            if (value >= 1.0)
+                pvalue = pow(10.0, val_exp % 3);
+            else
+                pvalue = pow(10.0, ((val_exp + 1) % 3) + 2);
             pvalue *= yloglab[mid][flab];
-
-            if ( ((scale+si_symbcenter) < (int)sizeof(si_symbol)) &&
-                ((scale+si_symbcenter) >= 0) )
-                symbol = si_symbol[scale+si_symbcenter];
+            if (((scale + si_symbcenter) < (int) sizeof(si_symbol))
+                && ((scale + si_symbcenter) >= 0))
+                symbol = si_symbol[scale + si_symbcenter];
             else
                 symbol = '?';
-
-                sprintf(graph_label,"%3.0f %c", pvalue, symbol);
+            sprintf(graph_label, "%3.0f %c", pvalue, symbol);
         } else
-            sprintf(graph_label,"%3.0e", value);
-        gfx_new_text ( im->canvas,
-            X0-im->text_prop[TEXT_PROP_AXIS].size, Y0,
-            im->graph_col[GRC_FONT],
-            im->text_prop[TEXT_PROP_AXIS].font,
-            im->text_prop[TEXT_PROP_AXIS].size,
-            im->tabwidth,0.0, GFX_H_RIGHT, GFX_V_CENTER,
-            graph_label );
-
+            sprintf(graph_label, "%3.0e", value);
+        gfx_text(im,
+                 X0 -
+                 im->
+                 text_prop[TEXT_PROP_AXIS].
+                 size, Y0,
+                 im->graph_col[GRC_FONT],
+                 im->
+                 text_prop[TEXT_PROP_AXIS].
+                 font,
+                 im->
+                 text_prop[TEXT_PROP_AXIS].
+                 size, im->tabwidth, 0.0,
+                 GFX_H_RIGHT, GFX_V_CENTER, graph_label);
         /* minor grid */
-        if(mid < 4 && exfrac == 1) {
+        if (mid < 4 && exfrac == 1) {
             /* find first and last minor line behind current major line
              * i is the first line and j tha last */
-            if(flab == 0) {
+            if (flab == 0) {
                 min_exp = val_exp - 1;
-                for(i = 1; yloglab[mid][i] < 10.0; i++);
+                for (i = 1; yloglab[mid][i] < 10.0; i++);
                 i = yloglab[mid][i - 1] + 1;
                 j = 10;
-            }
-            else {
+            } else {
                 min_exp = val_exp;
                 i = yloglab[mid][flab - 1] + 1;
                 j = yloglab[mid][flab];
             }
 
             /* draw minor lines below current major line */
-            for(; i < j; i++) {
+            for (; i < j; i++) {
 
                 value = i * pow(10.0, min_exp);
-                if(value < im->minval) continue;
-
+                if (value < im->minval)
+                    continue;
                 Y0 = ytr(im, value);
-                if(floor(Y0+0.5) <= im->yorigin - im->ysize) break;
-
+                if (floor(Y0 + 0.5) <= im->yorigin - im->ysize)
+                    break;
                 /* draw lines */
-                gfx_new_dashed_line ( im->canvas,
-                    X0-1,Y0,
-                    X1+1,Y0,
-                    GRIDWIDTH, im->graph_col[GRC_GRID],
-                    im->grid_dash_on, im->grid_dash_off);
+                gfx_line(im,
+                         X0 - 2, Y0,
+                         X0, Y0, GRIDWIDTH, im->graph_col[GRC_GRID]);
+                gfx_line(im, X1, Y0, X1 + 2, Y0,
+                         GRIDWIDTH, im->graph_col[GRC_GRID]);
+                gfx_dashed_line(im, X0 - 1, Y0,
+                                X1 + 1, Y0,
+                                GRIDWIDTH,
+                                im->
+                                graph_col[GRC_GRID],
+                                im->grid_dash_on, im->grid_dash_off);
             }
-        }
-        else if(exfrac > 1) {
-            for(i = val_exp - exfrac / 3 * 2; i < val_exp; i += exfrac / 3) {
+        } else if (exfrac > 1) {
+            for (i = val_exp - exfrac / 3 * 2; i < val_exp; i += exfrac / 3) {
                 value = pow(10.0, i);
-                if(value < im->minval) continue;
-
+                if (value < im->minval)
+                    continue;
                 Y0 = ytr(im, value);
-                if(floor(Y0+0.5) <= im->yorigin - im->ysize) break;
-
+                if (floor(Y0 + 0.5) <= im->yorigin - im->ysize)
+                    break;
                 /* draw lines */
-                gfx_new_dashed_line ( im->canvas,
-                    X0-1,Y0,
-                    X1+1,Y0,
-                    GRIDWIDTH, im->graph_col[GRC_GRID],
-                    im->grid_dash_on, im->grid_dash_off);
+                gfx_line(im,
+                         X0 - 2, Y0,
+                         X0, Y0, GRIDWIDTH, im->graph_col[GRC_GRID]);
+                gfx_line(im, X1, Y0, X1 + 2, Y0,
+                         GRIDWIDTH, im->graph_col[GRC_GRID]);
+                gfx_dashed_line(im, X0 - 1, Y0,
+                                X1 + 1, Y0,
+                                GRIDWIDTH,
+                                im->
+                                graph_col[GRC_GRID],
+                                im->grid_dash_on, im->grid_dash_off);
             }
         }
 
         /* next decade */
-        if(yloglab[mid][++flab] == 10.0) {
+        if (yloglab[mid][++flab] == 10.0) {
             flab = 0;
             val_exp += exfrac;
         }
     }
 
     /* draw minor lines after highest major line */
-    if(mid < 4 && exfrac == 1) {
+    if (mid < 4 && exfrac == 1) {
         /* find first and last minor line below current major line
          * i is the first line and j tha last */
-        if(flab == 0) {
+        if (flab == 0) {
             min_exp = val_exp - 1;
-            for(i = 1; yloglab[mid][i] < 10.0; i++);
+            for (i = 1; yloglab[mid][i] < 10.0; i++);
             i = yloglab[mid][i - 1] + 1;
             j = 10;
-        }
-        else {
+        } else {
             min_exp = val_exp;
             i = yloglab[mid][flab - 1] + 1;
             j = yloglab[mid][flab];
         }
 
         /* draw minor lines below current major line */
-        for(; i < j; i++) {
+        for (; i < j; i++) {
 
             value = i * pow(10.0, min_exp);
-            if(value < im->minval) continue;
-
+            if (value < im->minval)
+                continue;
             Y0 = ytr(im, value);
-            if(floor(Y0+0.5) <= im->yorigin - im->ysize) break;
-
+            if (floor(Y0 + 0.5) <= im->yorigin - im->ysize)
+                break;
             /* draw lines */
-            gfx_new_dashed_line ( im->canvas,
-                X0-1,Y0,
-                X1+1,Y0,
-                GRIDWIDTH, im->graph_col[GRC_GRID],
-                im->grid_dash_on, im->grid_dash_off);
+            gfx_line(im,
+                     X0 - 2, Y0, X0, Y0, GRIDWIDTH, im->graph_col[GRC_GRID]);
+            gfx_line(im, X1, Y0, X1 + 2, Y0,
+                     GRIDWIDTH, im->graph_col[GRC_GRID]);
+            gfx_dashed_line(im, X0 - 1, Y0,
+                            X1 + 1, Y0,
+                            GRIDWIDTH,
+                            im->
+                            graph_col[GRC_GRID],
+                            im->grid_dash_on, im->grid_dash_off);
         }
     }
     /* fancy minor gridlines */
-    else if(exfrac > 1) {
-        for(i = val_exp - exfrac / 3 * 2; i < val_exp; i += exfrac / 3) {
+    else if (exfrac > 1) {
+        for (i = val_exp - exfrac / 3 * 2; i < val_exp; i += exfrac / 3) {
             value = pow(10.0, i);
-            if(value < im->minval) continue;
-
+            if (value < im->minval)
+                continue;
             Y0 = ytr(im, value);
-            if(floor(Y0+0.5) <= im->yorigin - im->ysize) break;
-
+            if (floor(Y0 + 0.5) <= im->yorigin - im->ysize)
+                break;
             /* draw lines */
-            gfx_new_dashed_line ( im->canvas,
-                X0-1,Y0,
-                X1+1,Y0,
-                GRIDWIDTH, im->graph_col[GRC_GRID],
-                im->grid_dash_on, im->grid_dash_off);
+            gfx_line(im,
+                     X0 - 2, Y0, X0, Y0, GRIDWIDTH, im->graph_col[GRC_GRID]);
+            gfx_line(im, X1, Y0, X1 + 2, Y0,
+                     GRIDWIDTH, im->graph_col[GRC_GRID]);
+            gfx_dashed_line(im, X0 - 1, Y0,
+                            X1 + 1, Y0,
+                            GRIDWIDTH,
+                            im->
+                            graph_col[GRC_GRID],
+                            im->grid_dash_on, im->grid_dash_off);
         }
     }
 
@@ -2000,28 +2315,30 @@ horizontal_log_grid(image_desc_t   *im)
 }
 
 
-void
-vertical_grid(
-    image_desc_t   *im )
-{   
-    int xlab_sel;                /* which sort of label and grid ? */
-    time_t ti, tilab, timajor;
-    long factor;
-    char graph_label[100];
-    double X0,Y0,Y1; /* points for filled graph and more*/
+void vertical_grid(
+    image_desc_t *im)
+{
+    int       xlab_sel; /* which sort of label and grid ? */
+    time_t    ti, tilab, timajor;
+    long      factor;
+    char      graph_label[100];
+    double    X0, Y0, Y1;   /* points for filled graph and more */
     struct tm tm;
 
     /* the type of time grid is determined by finding
        the number of seconds per pixel in the graph */
-    
-    
-    if(im->xlab_user.minsec == -1){
-        factor=(im->end - im->start)/im->xsize;
-        xlab_sel=0;
-        while ( xlab[xlab_sel+1].minsec != -1 
-                && xlab[xlab_sel+1].minsec <= factor) { xlab_sel++; }        /* pick the last one */
-        while ( xlab[xlab_sel-1].minsec == xlab[xlab_sel].minsec
-                && xlab[xlab_sel].length > (im->end - im->start)) { xlab_sel--; }        /* go back to the smallest size */
+    if (im->xlab_user.minsec == -1) {
+        factor = (im->end - im->start) / im->xsize;
+        xlab_sel = 0;
+        while (xlab[xlab_sel + 1].minsec !=
+               -1 && xlab[xlab_sel + 1].minsec <= factor) {
+            xlab_sel++;
+        }               /* pick the last one */
+        while (xlab[xlab_sel - 1].minsec ==
+               xlab[xlab_sel].minsec
+               && xlab[xlab_sel].length > (im->end - im->start)) {
+            xlab_sel--;
+        }               /* go back to the smallest size */
         im->xlab_user.gridtm = xlab[xlab_sel].gridtm;
         im->xlab_user.gridst = xlab[xlab_sel].gridst;
         im->xlab_user.mgridtm = xlab[xlab_sel].mgridtm;
@@ -2031,260 +2348,323 @@ vertical_grid(
         im->xlab_user.precis = xlab[xlab_sel].precis;
         im->xlab_user.stst = xlab[xlab_sel].stst;
     }
-    
+
     /* y coords are the same for every line ... */
     Y0 = im->yorigin;
-    Y1 = im->yorigin-im->ysize;
-   
-
+    Y1 = im->yorigin - im->ysize;
     /* paint the minor grid */
-    if (!(im->extra_flags & NOMINOR))
-    {
-        for(ti = find_first_time(im->start,
-                                im->xlab_user.gridtm,
-                                im->xlab_user.gridst),
-            timajor = find_first_time(im->start,
-                                im->xlab_user.mgridtm,
-                                im->xlab_user.mgridst);
-            ti < im->end; 
-            ti = find_next_time(ti,im->xlab_user.gridtm,im->xlab_user.gridst)
-            ){
+    if (!(im->extra_flags & NOMINOR)) {
+        for (ti = find_first_time(im->start,
+                                  im->
+                                  xlab_user.
+                                  gridtm,
+                                  im->
+                                  xlab_user.
+                                  gridst),
+             timajor =
+             find_first_time(im->start,
+                             im->xlab_user.
+                             mgridtm,
+                             im->xlab_user.
+                             mgridst);
+             ti < im->end;
+             ti =
+             find_next_time(ti, im->xlab_user.gridtm, im->xlab_user.gridst)
+            ) {
             /* are we inside the graph ? */
-            if (ti < im->start || ti > im->end) continue;
+            if (ti < im->start || ti > im->end)
+                continue;
             while (timajor < ti) {
                 timajor = find_next_time(timajor,
-                        im->xlab_user.mgridtm, im->xlab_user.mgridst);
+                                         im->
+                                         xlab_user.
+                                         mgridtm, im->xlab_user.mgridst);
             }
-            if (ti == timajor) continue; /* skip as falls on major grid line */
-           X0 = xtr(im,ti);       
-           gfx_new_dashed_line(im->canvas,X0,Y0+1, X0,Y1-1,GRIDWIDTH,
-               im->graph_col[GRC_GRID],
-               im->grid_dash_on, im->grid_dash_off);
-           
+            if (ti == timajor)
+                continue;   /* skip as falls on major grid line */
+            X0 = xtr(im, ti);
+            gfx_line(im, X0, Y1 - 2, X0, Y1,
+                     GRIDWIDTH, im->graph_col[GRC_GRID]);
+            gfx_line(im, X0, Y0, X0, Y0 + 2,
+                     GRIDWIDTH, im->graph_col[GRC_GRID]);
+            gfx_dashed_line(im, X0, Y0 + 1, X0,
+                            Y1 - 1, GRIDWIDTH,
+                            im->
+                            graph_col[GRC_GRID],
+                            im->grid_dash_on, im->grid_dash_off);
         }
     }
 
     /* paint the major grid */
-    for(ti = find_first_time(im->start,
-                            im->xlab_user.mgridtm,
-                            im->xlab_user.mgridst);
-        ti < im->end; 
-        ti = find_next_time(ti,im->xlab_user.mgridtm,im->xlab_user.mgridst)
-        ){
+    for (ti = find_first_time(im->start,
+                              im->
+                              xlab_user.
+                              mgridtm,
+                              im->
+                              xlab_user.
+                              mgridst);
+         ti < im->end;
+         ti = find_next_time(ti, im->xlab_user.mgridtm, im->xlab_user.mgridst)
+        ) {
         /* are we inside the graph ? */
-        if (ti < im->start || ti > im->end) continue;
-       X0 = xtr(im,ti);
-       gfx_new_dashed_line(im->canvas,X0,Y0+3, X0,Y1-2,MGRIDWIDTH,
-           im->graph_col[GRC_MGRID],
-           im->grid_dash_on, im->grid_dash_off);
-       
+        if (ti < im->start || ti > im->end)
+            continue;
+        X0 = xtr(im, ti);
+        gfx_line(im, X0, Y1 - 2, X0, Y1,
+                 MGRIDWIDTH, im->graph_col[GRC_MGRID]);
+        gfx_line(im, X0, Y0, X0, Y0 + 3,
+                 MGRIDWIDTH, im->graph_col[GRC_MGRID]);
+        gfx_dashed_line(im, X0, Y0 + 3, X0,
+                        Y1 - 2, MGRIDWIDTH,
+                        im->
+                        graph_col
+                        [GRC_MGRID], im->grid_dash_on, im->grid_dash_off);
     }
     /* paint the labels below the graph */
-    for(ti = find_first_time(im->start - im->xlab_user.precis/2,
-                            im->xlab_user.labtm,
-                            im->xlab_user.labst);
-        ti <= im->end - im->xlab_user.precis/2; 
-        ti = find_next_time(ti,im->xlab_user.labtm,im->xlab_user.labst)
-        ){
-        tilab= ti + im->xlab_user.precis/2; /* correct time for the label */
+    for (ti =
+         find_first_time(im->start -
+                         im->xlab_user.
+                         precis / 2,
+                         im->xlab_user.
+                         labtm,
+                         im->xlab_user.
+                         labst);
+         ti <=
+         im->end -
+         im->xlab_user.precis / 2;
+         ti = find_next_time(ti, im->xlab_user.labtm, im->xlab_user.labst)
+        ) {
+        tilab = ti + im->xlab_user.precis / 2;  /* correct time for the label */
         /* are we inside the graph ? */
-        if (tilab < im->start || tilab > im->end) continue;
-
+        if (tilab < im->start || tilab > im->end)
+            continue;
 #if HAVE_STRFTIME
         localtime_r(&tilab, &tm);
-        strftime(graph_label,99,im->xlab_user.stst, &tm);
+        strftime(graph_label, 99, im->xlab_user.stst, &tm);
 #else
 # error "your libc has no strftime I guess we'll abort the exercise here."
 #endif
-       gfx_new_text ( im->canvas,
-                      xtr(im,tilab), Y0+im->text_prop[TEXT_PROP_AXIS].size*1.4+5,
-                      im->graph_col[GRC_FONT],
-                      im->text_prop[TEXT_PROP_AXIS].font,
-                      im->text_prop[TEXT_PROP_AXIS].size,
-                      im->tabwidth, 0.0, GFX_H_CENTER, GFX_V_BOTTOM,
-                      graph_label );
-       
+        gfx_text(im,
+                 xtr(im, tilab),
+                 Y0 + 3,
+                 im->graph_col[GRC_FONT],
+                 im->
+                 text_prop[TEXT_PROP_AXIS].
+                 font,
+                 im->
+                 text_prop[TEXT_PROP_AXIS].
+                 size, im->tabwidth, 0.0,
+                 GFX_H_CENTER, GFX_V_TOP, graph_label);
     }
 
 }
 
 
-void 
-axis_paint(
-   image_desc_t   *im
-           )
-{   
+void axis_paint(
+    image_desc_t *im)
+{
     /* draw x and y axis */
-    /* gfx_new_line ( im->canvas, im->xorigin+im->xsize,im->yorigin,
-                      im->xorigin+im->xsize,im->yorigin-im->ysize,
-                      GRIDWIDTH, im->graph_col[GRC_AXIS]);
-       
-       gfx_new_line ( im->canvas, im->xorigin,im->yorigin-im->ysize,
-                         im->xorigin+im->xsize,im->yorigin-im->ysize,
-                         GRIDWIDTH, im->graph_col[GRC_AXIS]); */
-   
-       gfx_new_line ( im->canvas, im->xorigin-4,im->yorigin,
-                         im->xorigin+im->xsize+4,im->yorigin,
-                         MGRIDWIDTH, im->graph_col[GRC_AXIS]);
-   
-       gfx_new_line ( im->canvas, im->xorigin,im->yorigin+4,
-                         im->xorigin,im->yorigin-im->ysize-4,
-                         MGRIDWIDTH, im->graph_col[GRC_AXIS]);
-   
-    
+    /* gfx_line ( im->canvas, im->xorigin+im->xsize,im->yorigin,
+       im->xorigin+im->xsize,im->yorigin-im->ysize,
+       GRIDWIDTH, im->graph_col[GRC_AXIS]);
+
+       gfx_line ( im->canvas, im->xorigin,im->yorigin-im->ysize,
+       im->xorigin+im->xsize,im->yorigin-im->ysize,
+       GRIDWIDTH, im->graph_col[GRC_AXIS]); */
+
+    gfx_line(im, im->xorigin - 4,
+             im->yorigin,
+             im->xorigin + im->xsize +
+             4, im->yorigin, MGRIDWIDTH, im->graph_col[GRC_AXIS]);
+    gfx_line(im, im->xorigin,
+             im->yorigin + 4,
+             im->xorigin,
+             im->yorigin - im->ysize -
+             4, MGRIDWIDTH, im->graph_col[GRC_AXIS]);
     /* arrow for X and Y axis direction */
-    gfx_new_area ( im->canvas, 
-                   im->xorigin+im->xsize+2,  im->yorigin-2,
-                   im->xorigin+im->xsize+2,  im->yorigin+3,
-                   im->xorigin+im->xsize+7,  im->yorigin+0.5, /* LINEOFFSET */
-                   im->graph_col[GRC_ARROW]);
-
-    gfx_new_area ( im->canvas, 
-                   im->xorigin-2,  im->yorigin-im->ysize-2,
-                   im->xorigin+3,  im->yorigin-im->ysize-2,
-                   im->xorigin+0.5,    im->yorigin-im->ysize-7, /* LINEOFFSET */
-                   im->graph_col[GRC_ARROW]);
-
+    gfx_new_area(im, im->xorigin + im->xsize + 2, im->yorigin - 3, im->xorigin + im->xsize + 2, im->yorigin + 3, im->xorigin + im->xsize + 7, im->yorigin,  /* horyzontal */
+                 im->graph_col[GRC_ARROW]);
+    gfx_close_path(im);
+    gfx_new_area(im, im->xorigin - 3, im->yorigin - im->ysize - 2, im->xorigin + 3, im->yorigin - im->ysize - 2, im->xorigin, im->yorigin - im->ysize - 7,  /* vertical */
+                 im->graph_col[GRC_ARROW]);
+    gfx_close_path(im);
 }
 
-void
-grid_paint(image_desc_t   *im)
-{   
-    long i;
-    int res=0;
-    double X0,Y0; /* points for filled graph and more*/
-    gfx_node_t *node;
+void grid_paint(
+    image_desc_t *im)
+{
+    long      i;
+    int       res = 0;
+    double    X0, Y0;   /* points for filled graph and more */
+    struct gfx_color_t water_color;
 
     /* draw 3d border */
-    node = gfx_new_area (im->canvas, 0,im->yimg,
-                                 2,im->yimg-2,
-                                 2,2,im->graph_col[GRC_SHADEA]);
-    gfx_add_point( node , im->ximg - 2, 2 );
-    gfx_add_point( node , im->ximg, 0 );
-    gfx_add_point( node , 0,0 );
-/*    gfx_add_point( node , 0,im->yimg ); */
-   
-    node =  gfx_new_area (im->canvas, 2,im->yimg-2,
-                                  im->ximg-2,im->yimg-2,
-                                  im->ximg - 2, 2,
-                                 im->graph_col[GRC_SHADEB]);
-    gfx_add_point( node ,   im->ximg,0);
-    gfx_add_point( node ,   im->ximg,im->yimg);
-    gfx_add_point( node ,   0,im->yimg);
-/*    gfx_add_point( node , 0,im->yimg ); */
-   
-   
-    if (im->draw_x_grid == 1 )
-      vertical_grid(im);
-    
-    if (im->draw_y_grid == 1){
-        if(im->logarithmic){
-                res = horizontal_log_grid(im);
+    gfx_new_area(im, 0, im->yimg,
+                 2, im->yimg - 2, 2, 2, im->graph_col[GRC_SHADEA]);
+    gfx_add_point(im, im->ximg - 2, 2);
+    gfx_add_point(im, im->ximg, 0);
+    gfx_add_point(im, 0, 0);
+    gfx_close_path(im);
+    gfx_new_area(im, 2, im->yimg - 2,
+                 im->ximg - 2,
+                 im->yimg - 2, im->ximg - 2, 2, im->graph_col[GRC_SHADEB]);
+    gfx_add_point(im, im->ximg, 0);
+    gfx_add_point(im, im->ximg, im->yimg);
+    gfx_add_point(im, 0, im->yimg);
+    gfx_close_path(im);
+    if (im->draw_x_grid == 1)
+        vertical_grid(im);
+    if (im->draw_y_grid == 1) {
+        if (im->logarithmic) {
+            res = horizontal_log_grid(im);
         } else {
-                res = draw_horizontal_grid(im);
+            res = draw_horizontal_grid(im);
         }
-        
+
         /* dont draw horizontal grid if there is no min and max val */
-        if (! res ) {
-          char *nodata = "No Data found";
-           gfx_new_text(im->canvas,im->ximg/2, (2*im->yorigin-im->ysize) / 2,
-                        im->graph_col[GRC_FONT],
-                        im->text_prop[TEXT_PROP_AXIS].font,
-                        im->text_prop[TEXT_PROP_AXIS].size,
-                        im->tabwidth, 0.0, GFX_H_CENTER, GFX_V_CENTER,
-                        nodata );           
+        if (!res) {
+            char     *nodata = "No Data found";
+
+            gfx_text(im, im->ximg / 2,
+                     (2 * im->yorigin -
+                      im->ysize) / 2,
+                     im->graph_col[GRC_FONT],
+                     im->
+                     text_prop[TEXT_PROP_AXIS].
+                     font,
+                     im->
+                     text_prop[TEXT_PROP_AXIS].
+                     size, im->tabwidth, 0.0,
+                     GFX_H_CENTER, GFX_V_CENTER, nodata);
         }
     }
 
     /* yaxis unit description */
-    gfx_new_text( im->canvas,
-                  10, (im->yorigin - im->ysize/2),
-                  im->graph_col[GRC_FONT],
-                  im->text_prop[TEXT_PROP_UNIT].font,
-                  im->text_prop[TEXT_PROP_UNIT].size, im->tabwidth, 
-                  RRDGRAPH_YLEGEND_ANGLE,
-                  GFX_H_LEFT, GFX_V_CENTER,
-                  im->ylegend);
-
+    gfx_text(im,
+             10,
+             (im->yorigin -
+              im->ysize / 2),
+             im->graph_col[GRC_FONT],
+             im->
+             text_prop[TEXT_PROP_UNIT].
+             font,
+             im->
+             text_prop[TEXT_PROP_UNIT].
+             size, im->tabwidth,
+             RRDGRAPH_YLEGEND_ANGLE, GFX_H_CENTER, GFX_V_CENTER, im->ylegend);
     /* graph title */
-    gfx_new_text( im->canvas,
-                  im->ximg/2, im->text_prop[TEXT_PROP_TITLE].size*1.3+4,
-                  im->graph_col[GRC_FONT],
-                  im->text_prop[TEXT_PROP_TITLE].font,
-                  im->text_prop[TEXT_PROP_TITLE].size, im->tabwidth, 0.0,
-                  GFX_H_CENTER, GFX_V_CENTER,
-                  im->title);
+    gfx_text(im,
+             im->ximg / 2, 6,
+             im->graph_col[GRC_FONT],
+             im->
+             text_prop[TEXT_PROP_TITLE].
+             font,
+             im->
+             text_prop[TEXT_PROP_TITLE].
+             size, im->tabwidth, 0.0, GFX_H_CENTER, GFX_V_TOP, im->title);
     /* rrdtool 'logo' */
-    gfx_new_text( im->canvas,
-                  im->ximg-7, 7,
-                  ( im->graph_col[GRC_FONT] & 0xffffff00 ) | 0x00000044,
-                  im->text_prop[TEXT_PROP_AXIS].font,
-                  5.5, im->tabwidth, 270,
-                  GFX_H_RIGHT, GFX_V_TOP,
-                  "RRDTOOL / TOBI OETIKER");
-
+    water_color = im->graph_col[GRC_FONT];
+    water_color.alpha = 0.3;
+    gfx_text(im, im->ximg - 4, 5,
+             water_color,
+             im->
+             text_prop[TEXT_PROP_AXIS].
+             font, 5.5, im->tabwidth,
+             -90, GFX_H_LEFT, GFX_V_TOP, "RRDTOOL / TOBI OETIKER");
     /* graph watermark */
-    if(im->watermark[0] != '\0') {
-        gfx_new_text( im->canvas,
-                  im->ximg/2, im->yimg-6,
-                  ( im->graph_col[GRC_FONT] & 0xffffff00 ) | 0x00000044,
-                  im->text_prop[TEXT_PROP_AXIS].font,
-                  5.5, im->tabwidth, 0,
-                  GFX_H_CENTER, GFX_V_BOTTOM,
-                  im->watermark);
-    }
-    
+    if (im->watermark[0] != '\0') {
+        gfx_text(im,
+                 im->ximg / 2, im->yimg - 6,
+                 water_color,
+                 im->
+                 text_prop[TEXT_PROP_AXIS].
+                 font, 5.5, im->tabwidth, 0,
+                 GFX_H_CENTER, GFX_V_BOTTOM, im->watermark);
+    }
+
     /* graph labels */
-    if( !(im->extra_flags & NOLEGEND) & !(im->extra_flags & ONLY_GRAPH) ) {
-            for(i=0;i<im->gdes_c;i++){
-                    if(im->gdes[i].legend[0] =='\0')
-                            continue;
-                    
-                    /* im->gdes[i].leg_y is the bottom of the legend */
-                    X0 = im->gdes[i].leg_x;
-                    Y0 = im->gdes[i].leg_y;
-                    gfx_new_text ( im->canvas, X0, Y0,
-                                   im->graph_col[GRC_FONT],
-                                   im->text_prop[TEXT_PROP_LEGEND].font,
-                                   im->text_prop[TEXT_PROP_LEGEND].size,
-                                   im->tabwidth,0.0, GFX_H_LEFT, GFX_V_BOTTOM,
-                                   im->gdes[i].legend );
-                    /* The legend for GRAPH items starts with "M " to have
-                       enough space for the box */
-                    if (           im->gdes[i].gf != GF_PRINT &&
-                                   im->gdes[i].gf != GF_GPRINT &&
-                                   im->gdes[i].gf != GF_COMMENT) {
-                            int boxH, boxV;
-                            
-                            boxH = gfx_get_text_width(im->canvas, 0,
-                                                      im->text_prop[TEXT_PROP_LEGEND].font,
-                                                      im->text_prop[TEXT_PROP_LEGEND].size,
-                                                      im->tabwidth,"o", 0) * 1.2;
-                            boxV = boxH*1.1;
-                            
-                            /* make sure transparent colors show up the same way as in the graph */
-                             node = gfx_new_area(im->canvas,
-                                                X0,Y0-boxV,
-                                                X0,Y0,
-                                                X0+boxH,Y0,
-                                                im->graph_col[GRC_BACK]);
-                            gfx_add_point ( node, X0+boxH, Y0-boxV );
-
-                            node = gfx_new_area(im->canvas,
-                                                X0,Y0-boxV,
-                                                X0,Y0,
-                                                X0+boxH,Y0,
-                                                im->gdes[i].col);
-                            gfx_add_point ( node, X0+boxH, Y0-boxV );
-                            node = gfx_new_line(im->canvas,
-                                                X0,Y0-boxV,
-                                                X0,Y0,
-                                                1.0,im->graph_col[GRC_FRAME]);
-                            gfx_add_point(node,X0+boxH,Y0);
-                            gfx_add_point(node,X0+boxH,Y0-boxV);
-                            gfx_close_path(node);
-                    }
+    if (!(im->extra_flags & NOLEGEND) & !(im->extra_flags & ONLY_GRAPH)) {
+        for (i = 0; i < im->gdes_c; i++) {
+            if (im->gdes[i].legend[0] == '\0')
+                continue;
+            /* im->gdes[i].leg_y is the bottom of the legend */
+            X0 = im->gdes[i].leg_x;
+            Y0 = im->gdes[i].leg_y;
+            gfx_text(im, X0, Y0,
+                     im->graph_col[GRC_FONT],
+                     im->
+                     text_prop
+                     [TEXT_PROP_LEGEND].font,
+                     im->
+                     text_prop
+                     [TEXT_PROP_LEGEND].size,
+                     im->tabwidth, 0.0,
+                     GFX_H_LEFT, GFX_V_BOTTOM, im->gdes[i].legend);
+            /* The legend for GRAPH items starts with "M " to have
+               enough space for the box */
+            if (im->gdes[i].gf != GF_PRINT &&
+                im->gdes[i].gf != GF_GPRINT && im->gdes[i].gf != GF_COMMENT) {
+                double    boxH, boxV;
+                double    X1, Y1;
+
+                boxH = gfx_get_text_width(im, 0,
+                                          im->
+                                          text_prop
+                                          [TEXT_PROP_LEGEND].
+                                          font,
+                                          im->
+                                          text_prop
+                                          [TEXT_PROP_LEGEND].
+                                          size, im->tabwidth, "o") * 1.2;
+                boxV = boxH;
+                /* shift the box up a bit */
+                Y0 -= boxV * 0.4;
+                /* make sure transparent colors show up the same way as in the graph */
+                gfx_new_area(im,
+                             X0, Y0 - boxV,
+                             X0, Y0, X0 + boxH, Y0, im->graph_col[GRC_BACK]);
+                gfx_add_point(im, X0 + boxH, Y0 - boxV);
+                gfx_close_path(im);
+                gfx_new_area(im, X0, Y0 - boxV, X0,
+                             Y0, X0 + boxH, Y0, im->gdes[i].col);
+                gfx_add_point(im, X0 + boxH, Y0 - boxV);
+                gfx_close_path(im);
+                cairo_save(im->cr);
+                cairo_new_path(im->cr);
+                cairo_set_line_width(im->cr, 1.0);
+                X1 = X0 + boxH;
+                Y1 = Y0 - boxV;
+                gfx_line_fit(im, &X0, &Y0);
+                gfx_line_fit(im, &X1, &Y1);
+                cairo_move_to(im->cr, X0, Y0);
+                cairo_line_to(im->cr, X1, Y0);
+                cairo_line_to(im->cr, X1, Y1);
+                cairo_line_to(im->cr, X0, Y1);
+                cairo_close_path(im->cr);
+                cairo_set_source_rgba(im->cr,
+                                      im->
+                                      graph_col
+                                      [GRC_FRAME].
+                                      red,
+                                      im->
+                                      graph_col
+                                      [GRC_FRAME].
+                                      green,
+                                      im->
+                                      graph_col
+                                      [GRC_FRAME].
+                                      blue, im->graph_col[GRC_FRAME].alpha);
+                if (im->gdes[i].dash) {
+                    /* make box borders in legend dashed if the graph is dashed */
+                    double    dashes[] = {
+                        3.0
+                    };
+                    cairo_set_dash(im->cr, dashes, 1, 0.0);
+                }
+                cairo_stroke(im->cr);
+                cairo_restore(im->cr);
             }
+        }
     }
 }
 
@@ -2293,675 +2673,778 @@ grid_paint(image_desc_t   *im)
  * lazy check make sure we rely need to create this graph
  *****************************************************/
 
-int lazy_check(image_desc_t *im){
-    FILE *fd = NULL;
-        int size = 1;
-    struct stat  imgstat;
-    
-    if (im->lazy == 0) return 0; /* no lazy option */
-    if (stat(im->graphfile,&imgstat) != 0) 
-      return 0; /* can't stat */
+int lazy_check(
+    image_desc_t *im)
+{
+    FILE     *fd = NULL;
+    int       size = 1;
+    struct stat imgstat;
+
+    if (im->lazy == 0)
+        return 0;       /* no lazy option */
+    if (strlen(im->graphfile) == 0)
+        return 0;       /* inmemory option */
+    if (stat(im->graphfile, &imgstat) != 0)
+        return 0;       /* can't stat */
     /* one pixel in the existing graph is more then what we would
        change here ... */
-    if (time(NULL) - imgstat.st_mtime > 
-        (im->end - im->start) / im->xsize) 
-      return 0;
-    if ((fd = fopen(im->graphfile,"rb")) == NULL) 
-      return 0; /* the file does not exist */
-    switch (im->canvas->imgformat) {
+    if (time(NULL) - imgstat.st_mtime > (im->end - im->start) / im->xsize)
+        return 0;
+    if ((fd = fopen(im->graphfile, "rb")) == NULL)
+        return 0;       /* the file does not exist */
+    switch (im->imgformat) {
     case IF_PNG:
-           size = PngSize(fd,&(im->ximg),&(im->yimg));
-           break;
+        size = PngSize(fd, &(im->ximg), &(im->yimg));
+        break;
     default:
-           size = 1;
+        size = 1;
     }
     fclose(fd);
     return size;
 }
 
-#ifdef WITH_PIECHART
-void
-pie_part(image_desc_t *im, gfx_color_t color,
-            double PieCenterX, double PieCenterY, double Radius,
-            double startangle, double endangle)
-{
-    gfx_node_t *node;
-    double angle;
-    double step=M_PI/50; /* Number of iterations for the circle;
-                         ** 10 is definitely too low, more than
-                         ** 50 seems to be overkill
-                         */
-
-    /* Strange but true: we have to work clockwise or else
-    ** anti aliasing nor transparency don't work.
-    **
-    ** This test is here to make sure we do it right, also
-    ** this makes the for...next loop more easy to implement.
-    ** The return will occur if the user enters a negative number
-    ** (which shouldn't be done according to the specs) or if the
-    ** programmers do something wrong (which, as we all know, never
-    ** happens anyway :)
-    */
-    if (endangle<startangle) return;
-
-    /* Hidden feature: Radius decreases each full circle */
-    angle=startangle;
-    while (angle>=2*M_PI) {
-        angle  -= 2*M_PI;
-        Radius *= 0.8;
-    }
-
-    node=gfx_new_area(im->canvas,
-                PieCenterX+sin(startangle)*Radius,
-                PieCenterY-cos(startangle)*Radius,
-                PieCenterX,
-                PieCenterY,
-                PieCenterX+sin(endangle)*Radius,
-                PieCenterY-cos(endangle)*Radius,
-                color);
-    for (angle=endangle;angle-startangle>=step;angle-=step) {
-        gfx_add_point(node,
-                PieCenterX+sin(angle)*Radius,
-                PieCenterY-cos(angle)*Radius );
-    }
-}
-
-#endif
-
-int
-graph_size_location(image_desc_t *im, int elements
-
-#ifdef WITH_PIECHART
-, int piechart
-#endif
 
- )
+int graph_size_location(
+    image_desc_t
+    *im,
+    int elements)
 {
     /* The actual size of the image to draw is determined from
-    ** several sources.  The size given on the command line is
-    ** the graph area but we need more as we have to draw labels
-    ** and other things outside the graph area
-    */
-
-    /* +-+-------------------------------------------+
-    ** |l|.................title.....................|
-    ** |e+--+-------------------------------+--------+
-    ** |b| b|                               |        |
-    ** |a| a|                               |  pie   |
-    ** |l| l|          main graph area      | chart  |
-    ** |.| .|                               |  area  |
-    ** |t| y|                               |        |
-    ** |r+--+-------------------------------+--------+
-    ** |e|  | x-axis labels                 |        |
-    ** |v+--+-------------------------------+--------+
-    ** | |..............legends......................|
-    ** +-+-------------------------------------------+
-    ** |                 watermark                   |
-    ** +---------------------------------------------+
-    */
-    int Xvertical=0,        
-                        Ytitle   =0,
-        Xylabel  =0,        
-        Xmain    =0,        Ymain    =0,
-#ifdef WITH_PIECHART
-        Xpie     =0,        Ypie     =0,
-#endif
-                        Yxlabel  =0,
-#if 0
-        Xlegend  =0,        Ylegend  =0,
-#endif
-        Xspacing =15,  Yspacing =15,
-       
-                      Ywatermark =4;
+     ** several sources.  The size given on the command line is
+     ** the graph area but we need more as we have to draw labels
+     ** and other things outside the graph area
+     */
+
+    int       Xvertical = 0, Ytitle =
+        0, Xylabel = 0, Xmain = 0, Ymain =
+        0, Yxlabel = 0, Xspacing = 15, Yspacing = 15, Ywatermark = 4;
 
     if (im->extra_flags & ONLY_GRAPH) {
-        im->xorigin =0;
+        im->xorigin = 0;
         im->ximg = im->xsize;
         im->yimg = im->ysize;
         im->yorigin = im->ysize;
-        ytr(im,DNAN); 
+        ytr(im, DNAN);
         return 0;
     }
 
-    if (im->ylegend[0] != '\0' ) {
-           Xvertical = im->text_prop[TEXT_PROP_UNIT].size *2;
-    }
+    /** +---+--------------------------------------------+
+     ** | y |...............graph title..................|
+     ** |   +---+-------------------------------+--------+
+     ** | a | y |                               |        |
+     ** | x |   |                               |        |
+     ** | i | a |                               |  pie   |
+     ** | s | x |       main graph area         | chart  |
+     ** |   | i |                               |  area  |
+     ** | t | s |                               |        |
+     ** | i |   |                               |        |
+     ** | t | l |                               |        |
+     ** | l | b +-------------------------------+--------+
+     ** | e | l |       x axis labels           |        |
+     ** +---+---+-------------------------------+--------+
+     ** |....................legends.....................|
+     ** +------------------------------------------------+
+     ** |                   watermark                    |
+     ** +------------------------------------------------+
+     */
 
+    if (im->ylegend[0] != '\0') {
+        Xvertical = im->text_prop[TEXT_PROP_UNIT].size * 2;
+    }
 
     if (im->title[0] != '\0') {
         /* The title is placed "inbetween" two text lines so it
-        ** automatically has some vertical spacing.  The horizontal
-        ** spacing is added here, on each side.
-        */
-        /* don't care for the with of the title
-                Xtitle = gfx_get_text_width(im->canvas, 0,
-                im->text_prop[TEXT_PROP_TITLE].font,
-                im->text_prop[TEXT_PROP_TITLE].size,
-                im->tabwidth,
-                im->title, 0) + 2*Xspacing; */
-        Ytitle = im->text_prop[TEXT_PROP_TITLE].size*2.6+10;
+         ** automatically has some vertical spacing.  The horizontal
+         ** spacing is added here, on each side.
+         */
+        /* if necessary, reduce the font size of the title until it fits the image width */
+        Ytitle = im->text_prop[TEXT_PROP_TITLE].size * 2.6 + 10;
     }
 
     if (elements) {
-        Xmain=im->xsize;
-        Ymain=im->ysize;
         if (im->draw_x_grid) {
-            Yxlabel=im->text_prop[TEXT_PROP_AXIS].size *2.5;
+            Yxlabel = im->text_prop[TEXT_PROP_AXIS].size * 2.5;
         }
-        if (im->draw_y_grid || im->forceleftspace ) {
-            Xylabel=gfx_get_text_width(im->canvas, 0,
-                        im->text_prop[TEXT_PROP_AXIS].font,
-                        im->text_prop[TEXT_PROP_AXIS].size,
-                        im->tabwidth,
-                        "0", 0) * im->unitslength;
+        if (im->draw_y_grid || im->forceleftspace) {
+            Xylabel =
+                gfx_get_text_width(im, 0,
+                                   im->
+                                   text_prop
+                                   [TEXT_PROP_AXIS].
+                                   font,
+                                   im->
+                                   text_prop
+                                   [TEXT_PROP_AXIS].
+                                   size, im->tabwidth, "0") * im->unitslength;
         }
     }
 
-#ifdef WITH_PIECHART
-    if (piechart) {
-        im->piesize=im->xsize<im->ysize?im->xsize:im->ysize;
-        Xpie=im->piesize;
-        Ypie=im->piesize;
-    }
-#endif
-
-    /* Now calculate the total size.  Insert some spacing where
-       desired.  im->xorigin and im->yorigin need to correspond
-       with the lower left corner of the main graph area or, if
-       this one is not set, the imaginary box surrounding the
-       pie chart area. */
-
-    /* The legend width cannot yet be determined, as a result we
-    ** have problems adjusting the image to it.  For now, we just
-    ** forget about it at all; the legend will have to fit in the
-    ** size already allocated.
-    */
-    im->ximg = Xylabel + Xmain + 2 * Xspacing;
-
-#ifdef WITH_PIECHART
-    im->ximg  += Xpie;
-#endif
-
-    if (Xmain) im->ximg += Xspacing;
-#ifdef WITH_PIECHART
-    if (Xpie) im->ximg += Xspacing;
-#endif
-
-    im->xorigin = Xspacing + Xylabel;
+    if (im->extra_flags & FULL_SIZE_MODE) {
+        /* The actual size of the image to draw has been determined by the user.
+         ** The graph area is the space remaining after accounting for the legend,
+         ** the watermark, the pie chart, the axis labels, and the title.
+         */
+        im->xorigin = 0;
+        im->ximg = im->xsize;
+        im->yimg = im->ysize;
+        im->yorigin = im->ysize;
+        Xmain = im->ximg;
+        Ymain = im->yimg;
+        im->yorigin += Ytitle;
+        /* Now calculate the total size.  Insert some spacing where
+           desired.  im->xorigin and im->yorigin need to correspond
+           with the lower left corner of the main graph area or, if
+           this one is not set, the imaginary box surrounding the
+           pie chart area. */
+        /* Initial size calculation for the main graph area */
+        Xmain = im->ximg - (Xylabel + 2 * Xspacing);
+        if (Xmain)
+            Xmain -= Xspacing;  /* put space between main graph area and right edge */
+        im->xorigin = Xspacing + Xylabel;
+        /* the length of the title should not influence with width of the graph
+           if (Xtitle > im->ximg) im->ximg = Xtitle; */
+        if (Xvertical) {    /* unit description */
+            Xmain -= Xvertical;
+            im->xorigin += Xvertical;
+        }
+        im->xsize = Xmain;
+        xtr(im, 0);
+        /* The vertical size of the image is known in advance.  The main graph area
+         ** (Ymain) and im->yorigin must be set according to the space requirements
+         ** of the legend and the axis labels.
+         */
+        if (im->extra_flags & NOLEGEND) {
+            /* set dimensions correctly if using full size mode with no legend */
+            im->yorigin =
+                im->yimg -
+                im->text_prop[TEXT_PROP_AXIS].size * 2.5 - Yspacing;
+            Ymain = im->yorigin;
+        } else {
+            /* Determine where to place the legends onto the image.
+             ** Set Ymain and adjust im->yorigin to match the space requirements.
+             */
+            if (leg_place(im, &Ymain) == -1)
+                return -1;
+        }
 
-    /* the length of the title should not influence with width of the graph
-       if (Xtitle > im->ximg) im->ximg = Xtitle; */
 
-    if (Xvertical) { /* unit description */
-        im->ximg += Xvertical;
-        im->xorigin += Xvertical;
-    }
-    xtr(im,0);
+        /* remove title space *or* some padding above the graph from the main graph area */
+        if (Ytitle) {
+            Ymain -= Ytitle;
+        } else {
+            Ymain -= 1.5 * Yspacing;
+        }
 
-    /* The vertical size is interesting... we need to compare
-    ** the sum of {Ytitle, Ymain, Yxlabel, Ylegend, Ywatermark} with 
-    ** Yvertical however we need to know {Ytitle+Ymain+Yxlabel}
-    ** in order to start even thinking about Ylegend or Ywatermark.
-    **
-    ** Do it in three portions: First calculate the inner part,
-    ** then do the legend, then adjust the total height of the img,
-    ** adding space for a watermark if one exists;
-    */
+        /* watermark doesn't seem to effect the vertical size of the main graph area, oh well! */
+        if (im->watermark[0] != '\0') {
+            Ymain -= Ywatermark;
+        }
 
-    /* reserve space for main and/or pie */
+        im->ysize = Ymain;
+    } else {            /* dimension options -width and -height refer to the dimensions of the main graph area */
 
-    im->yimg = Ymain + Yxlabel;
-    
-#ifdef WITH_PIECHART
-    if (im->yimg < Ypie) im->yimg = Ypie;
-#endif
+        /* The actual size of the image to draw is determined from
+         ** several sources.  The size given on the command line is
+         ** the graph area but we need more as we have to draw labels
+         ** and other things outside the graph area.
+         */
 
-    im->yorigin = im->yimg - Yxlabel;
+        if (im->ylegend[0] != '\0') {
+            Xvertical = im->text_prop[TEXT_PROP_UNIT].size * 2;
+        }
 
-    /* reserve space for the title *or* some padding above the graph */
-    if (Ytitle) {
-        im->yimg += Ytitle;
-        im->yorigin += Ytitle;
-    } else {
-        im->yimg += 1.5*Yspacing;
-        im->yorigin += 1.5*Yspacing;
-    }
-    /* reserve space for padding below the graph */
-    im->yimg += Yspacing;
-     
-    /* Determine where to place the legends onto the image.
-    ** Adjust im->yimg to match the space requirements.
-    */
-    if(leg_place(im)==-1)
-        return -1;
-        
-    if (im->watermark[0] != '\0') {
-        im->yimg += Ywatermark;
-    }
 
-#if 0
-    if (Xlegend > im->ximg) {
-        im->ximg = Xlegend;
-        /* reposition Pie */
-    }
-#endif
+        if (im->title[0] != '\0') {
+            /* The title is placed "inbetween" two text lines so it
+             ** automatically has some vertical spacing.  The horizontal
+             ** spacing is added here, on each side.
+             */
+            /* don't care for the with of the title
+               Xtitle = gfx_get_text_width(im->canvas, 0,
+               im->text_prop[TEXT_PROP_TITLE].font,
+               im->text_prop[TEXT_PROP_TITLE].size,
+               im->tabwidth,
+               im->title, 0) + 2*Xspacing; */
+            Ytitle = im->text_prop[TEXT_PROP_TITLE].size * 2.6 + 10;
+        }
 
-#ifdef WITH_PIECHART
-    /* The pie is placed in the upper right hand corner,
-    ** just below the title (if any) and with sufficient
-    ** padding.
-    */
-    if (elements) {
-        im->pie_x = im->ximg - Xspacing - Xpie/2;
-        im->pie_y = im->yorigin-Ymain+Ypie/2;
-    } else {
-        im->pie_x = im->ximg/2;
-        im->pie_y = im->yorigin-Ypie/2;
+        if (elements) {
+            Xmain = im->xsize;
+            Ymain = im->ysize;
+        }
+        /* Now calculate the total size.  Insert some spacing where
+           desired.  im->xorigin and im->yorigin need to correspond
+           with the lower left corner of the main graph area or, if
+           this one is not set, the imaginary box surrounding the
+           pie chart area. */
+
+        /* The legend width cannot yet be determined, as a result we
+         ** have problems adjusting the image to it.  For now, we just
+         ** forget about it at all; the legend will have to fit in the
+         ** size already allocated.
+         */
+        im->ximg = Xylabel + Xmain + 2 * Xspacing;
+        if (Xmain)
+            im->ximg += Xspacing;
+        im->xorigin = Xspacing + Xylabel;
+        /* the length of the title should not influence with width of the graph
+           if (Xtitle > im->ximg) im->ximg = Xtitle; */
+        if (Xvertical) {    /* unit description */
+            im->ximg += Xvertical;
+            im->xorigin += Xvertical;
+        }
+        xtr(im, 0);
+        /* The vertical size is interesting... we need to compare
+         ** the sum of {Ytitle, Ymain, Yxlabel, Ylegend, Ywatermark} with 
+         ** Yvertical however we need to know {Ytitle+Ymain+Yxlabel}
+         ** in order to start even thinking about Ylegend or Ywatermark.
+         **
+         ** Do it in three portions: First calculate the inner part,
+         ** then do the legend, then adjust the total height of the img,
+         ** adding space for a watermark if one exists;
+         */
+        /* reserve space for main and/or pie */
+        im->yimg = Ymain + Yxlabel;
+        im->yorigin = im->yimg - Yxlabel;
+        /* reserve space for the title *or* some padding above the graph */
+        if (Ytitle) {
+            im->yimg += Ytitle;
+            im->yorigin += Ytitle;
+        } else {
+            im->yimg += 1.5 * Yspacing;
+            im->yorigin += 1.5 * Yspacing;
+        }
+        /* reserve space for padding below the graph */
+        im->yimg += Yspacing;
+        /* Determine where to place the legends onto the image.
+         ** Adjust im->yimg to match the space requirements.
+         */
+        if (leg_place(im, 0) == -1)
+            return -1;
+        if (im->watermark[0] != '\0') {
+            im->yimg += Ywatermark;
+        }
     }
-#endif
 
-    ytr(im,DNAN);
+    ytr(im, DNAN);
     return 0;
 }
 
-/* from http://www.cygnus-software.com/papers/comparingfloats/comparingfloats.htm */
-/* yes we are loosing precision by doing tos with floats instead of doubles
-   but it seems more stable this way. */
-   
+static cairo_status_t cairo_output(
+    void *closure,
+    const unsigned char
+    *data,
+    unsigned int length)
+{
+    image_desc_t *im = closure;
+
+    im->rendered_image =
+        realloc(im->rendered_image, im->rendered_image_size + length);
+    if (im->rendered_image == NULL)
+        return CAIRO_STATUS_WRITE_ERROR;
+    memcpy(im->rendered_image + im->rendered_image_size, data, length);
+    im->rendered_image_size += length;
+    return CAIRO_STATUS_SUCCESS;
+}
 
 /* draw that picture thing ... */
-int
-graph_paint(image_desc_t *im, char ***calcpr)
+int graph_paint(
+    image_desc_t *im)
 {
-  int i,ii;
-  int lazy =     lazy_check(im);
-#ifdef WITH_PIECHART
-  int piechart = 0;
-  double PieStart=0.0;
-#endif
-  FILE  *fo;
-  gfx_node_t *node;
-  
-  double areazero = 0.0;
-  graph_desc_t *lastgdes = NULL;    
-
-  /* if we are lazy and there is nothing to PRINT ... quit now */
-  if (lazy && im->prt_c==0) return 0;
-
-  /* pull the data from the rrd files ... */
-  
-  if(data_fetch(im)==-1)
-    return -1;
-
-  /* evaluate VDEF and CDEF operations ... */
-  if(data_calc(im)==-1)
-    return -1;
+    int       i, ii;
+    int       lazy = lazy_check(im);
+    double    areazero = 0.0;
+    graph_desc_t *lastgdes = NULL;
+    infoval   info;
+    PangoFontMap *font_map = pango_cairo_font_map_get_default();
+
+    /* if we are lazy and there is nothing to PRINT ... quit now */
+    if (lazy && im->prt_c == 0)
+        return 0;
+    /* pull the data from the rrd files ... */
+    if (data_fetch(im) == -1)
+        return -1;
+    /* evaluate VDEF and CDEF operations ... */
+    if (data_calc(im) == -1)
+        return -1;
+    /* calculate and PRINT and GPRINT definitions. We have to do it at
+     * this point because it will affect the length of the legends
+     * if there are no graph elements we stop here ... 
+     * if we are lazy, try to quit ... 
+     */
+    i = print_calc(im);
+    if (i < 0)
+        return -1;
+    if ((i == 0) || lazy)
+        return 0;
+/**************************************************************
+ *** Calculating sizes and locations became a bit confusing ***
+ *** so I moved this into a separate function.              ***
+ **************************************************************/
+    if (graph_size_location(im, i) == -1)
+        return -1;
 
-#ifdef WITH_PIECHART  
-  /* check if we need to draw a piechart */
-  for(i=0;i<im->gdes_c;i++){
-    if (im->gdes[i].gf == GF_PART) {
-      piechart=1;
-      break;
+    info.u_cnt = im->xorigin;
+    grinfo_push(im, sprintf_alloc("graph_left"), RD_I_CNT, info);
+    info.u_cnt = im->yorigin - im->ysize;
+    grinfo_push(im, sprintf_alloc("graph_top"), RD_I_CNT, info);
+    info.u_cnt = im->xsize;
+    grinfo_push(im, sprintf_alloc("graph_width"), RD_I_CNT, info);
+    info.u_cnt = im->ysize;
+    grinfo_push(im, sprintf_alloc("graph_height"), RD_I_CNT, info);
+    info.u_cnt = im->ximg;
+    grinfo_push(im, sprintf_alloc("image_width"), RD_I_CNT, info);
+    info.u_cnt = im->yimg;
+    grinfo_push(im, sprintf_alloc("image_height"), RD_I_CNT, info);
+
+    /* get actual drawing data and find min and max values */
+    if (data_proc(im) == -1)
+        return -1;
+    if (!im->logarithmic) {
+        si_unit(im);
     }
-  }
-#endif
 
-  /* calculate and PRINT and GPRINT definitions. We have to do it at
-   * this point because it will affect the length of the legends
-   * if there are no graph elements we stop here ... 
-   * if we are lazy, try to quit ... 
-   */
-  i=print_calc(im,calcpr);
-  if(i<0) return -1;
-  if(((i==0)
-#ifdef WITH_PIECHART
-&&(piechart==0)
-#endif
-) || lazy) return 0;
+    /* identify si magnitude Kilo, Mega Giga ? */
+    if (!im->rigid && !im->logarithmic)
+        expand_range(im);   /* make sure the upper and lower limit are
+                               sensible values */
 
-#ifdef WITH_PIECHART
-  /* If there's only the pie chart to draw, signal this */
-  if (i==0) piechart=2;
-#endif
-  
-  /* get actual drawing data and find min and max values*/
-  if(data_proc(im)==-1)
-    return -1;
-  
-  if(!im->logarithmic){si_unit(im);}        /* identify si magnitude Kilo, Mega Giga ? */
-  
-  if(!im->rigid && ! im->logarithmic)
-    expand_range(im);   /* make sure the upper and lower limit are
-                           sensible values */
-
-  if (!calc_horizontal_grid(im))
-    return -1;
+    info.u_val = im->minval;
+    grinfo_push(im, sprintf_alloc("value_min"), RD_I_VAL, info);
+    info.u_val = im->maxval;
+    grinfo_push(im, sprintf_alloc("value_max"), RD_I_VAL, info);
 
-  if (im->gridfit)
-    apply_gridfit(im);
+    if (!calc_horizontal_grid(im))
+        return -1;
+    /* reset precalc */
+    ytr(im, DNAN);
+/*   if (im->gridfit)
+     apply_gridfit(im); */
+    /* the actual graph is created by going through the individual
+       graph elements and then drawing them */
+    cairo_surface_destroy(im->surface);
+    switch (im->imgformat) {
+    case IF_PNG:
+        im->surface =
+            cairo_image_surface_create(CAIRO_FORMAT_ARGB32,
+                                       im->ximg * im->zoom,
+                                       im->yimg * im->zoom);
+        break;
+    case IF_PDF:
+        im->gridfit = 0;
+        im->surface = strlen(im->graphfile)
+            ?
+            cairo_pdf_surface_create_for_stream
+            (&cairo_output, im, im->ximg * im->zoom, im->yimg * im->zoom)
+            : cairo_pdf_surface_create(im->graphfile, im->ximg * im->zoom,
+                                       im->yimg * im->zoom);
+        break;
+    case IF_EPS:
+        im->gridfit = 0;
+        im->surface = strlen(im->graphfile)
+            ?
+            cairo_ps_surface_create_for_stream
+            (&cairo_output, im, im->ximg * im->zoom, im->yimg * im->zoom)
+            : cairo_ps_surface_create(im->graphfile, im->ximg * im->zoom,
+                                      im->yimg * im->zoom);
+        break;
+    case IF_SVG:
+        im->gridfit = 0;
+        im->surface = strlen(im->graphfile)
+            ?
+            cairo_svg_surface_create_for_stream
+            (&cairo_output, im, im->ximg * im->zoom, im->yimg * im->zoom)
+            : cairo_svg_surface_create(im->
+                                       graphfile,
+                                       im->
+                                       ximg * im->zoom, im->yimg * im->zoom);
+        cairo_svg_surface_restrict_to_version
+            (im->surface, CAIRO_SVG_VERSION_1_1);
+        break;
+    };
+    im->cr = cairo_create(im->surface);
+    cairo_set_antialias(im->cr, im->graph_antialias);
+    cairo_scale(im->cr, im->zoom, im->zoom);
+    pango_cairo_font_map_set_resolution(PANGO_CAIRO_FONT_MAP(font_map), 100);
+    gfx_new_area(im, 0, 0, 0, im->yimg,
+                 im->ximg, im->yimg, im->graph_col[GRC_BACK]);
+    gfx_add_point(im, im->ximg, 0);
+    gfx_close_path(im);
+    gfx_new_area(im, im->xorigin,
+                 im->yorigin,
+                 im->xorigin +
+                 im->xsize, im->yorigin,
+                 im->xorigin +
+                 im->xsize,
+                 im->yorigin - im->ysize, im->graph_col[GRC_CANVAS]);
+    gfx_add_point(im, im->xorigin, im->yorigin - im->ysize);
+    gfx_close_path(im);
+    if (im->minval > 0.0)
+        areazero = im->minval;
+    if (im->maxval < 0.0)
+        areazero = im->maxval;
+    for (i = 0; i < im->gdes_c; i++) {
+        switch (im->gdes[i].gf) {
+        case GF_CDEF:
+        case GF_VDEF:
+        case GF_DEF:
+        case GF_PRINT:
+        case GF_GPRINT:
+        case GF_COMMENT:
+        case GF_TEXTALIGN:
+        case GF_HRULE:
+        case GF_VRULE:
+        case GF_XPORT:
+        case GF_SHIFT:
+            break;
+        case GF_TICK:
+            for (ii = 0; ii < im->xsize; ii++) {
+                if (!isnan(im->gdes[i].p_data[ii])
+                    && im->gdes[i].p_data[ii] != 0.0) {
+                    if (im->gdes[i].yrule > 0) {
+                        gfx_line(im,
+                                 im->xorigin + ii,
+                                 im->yorigin,
+                                 im->xorigin + ii,
+                                 im->yorigin -
+                                 im->gdes[i].yrule *
+                                 im->ysize, 1.0, im->gdes[i].col);
+                    } else if (im->gdes[i].yrule < 0) {
+                        gfx_line(im,
+                                 im->xorigin + ii,
+                                 im->yorigin - im->ysize,
+                                 im->xorigin + ii,
+                                 im->yorigin - (1 -
+                                                im->gdes[i].
+                                                yrule) *
+                                 im->ysize, 1.0, im->gdes[i].col);
+                    }
+                }
+            }
+            break;
+        case GF_LINE:
+        case GF_AREA:
+            /* fix data points at oo and -oo */
+            for (ii = 0; ii < im->xsize; ii++) {
+                if (isinf(im->gdes[i].p_data[ii])) {
+                    if (im->gdes[i].p_data[ii] > 0) {
+                        im->gdes[i].p_data[ii] = im->maxval;
+                    } else {
+                        im->gdes[i].p_data[ii] = im->minval;
+                    }
 
+                }
+            }           /* for */
+
+            /* *******************************************************
+               a           ___. (a,t) 
+               |   |    ___
+               ____|   |   |   |
+               |       |___|
+               -------|--t-1--t--------------------------------      
+
+               if we know the value at time t was a then 
+               we draw a square from t-1 to t with the value a.
+
+               ********************************************************* */
+            if (im->gdes[i].col.alpha != 0.0) {
+                /* GF_LINE and friend */
+                if (im->gdes[i].gf == GF_LINE) {
+                    double    last_y = 0.0;
+                    int       draw_on = 0;
+
+                    cairo_save(im->cr);
+                    cairo_new_path(im->cr);
+                    cairo_set_line_width(im->cr, im->gdes[i].linewidth);
+                    if (im->gdes[i].dash) {
+                        cairo_set_dash(im->cr,
+                                       im->gdes[i].p_dashes,
+                                       im->gdes[i].ndash, im->gdes[i].offset);
+                    }
 
-/**************************************************************
- *** Calculating sizes and locations became a bit confusing ***
- *** so I moved this into a separate function.              ***
- **************************************************************/
-  if(graph_size_location(im,i
-#ifdef WITH_PIECHART
-,piechart
-#endif
-)==-1)
-    return -1;
+                    for (ii = 1; ii < im->xsize; ii++) {
+                        if (isnan(im->gdes[i].p_data[ii])
+                            || (im->slopemode == 1
+                                && isnan(im->gdes[i].p_data[ii - 1]))) {
+                            draw_on = 0;
+                            continue;
+                        }
+                        if (draw_on == 0) {
+                            last_y = ytr(im, im->gdes[i].p_data[ii]);
+                            if (im->slopemode == 0) {
+                                double    x = ii - 1 + im->xorigin;
+                                double    y = last_y;
+
+                                gfx_line_fit(im, &x, &y);
+                                cairo_move_to(im->cr, x, y);
+                                x = ii + im->xorigin;
+                                y = last_y;
+                                gfx_line_fit(im, &x, &y);
+                                cairo_line_to(im->cr, x, y);
+                            } else {
+                                double    x = ii - 1 + im->xorigin;
+                                double    y =
+                                    ytr(im, im->gdes[i].p_data[ii - 1]);
+                                gfx_line_fit(im, &x, &y);
+                                cairo_move_to(im->cr, x, y);
+                                x = ii + im->xorigin;
+                                y = last_y;
+                                gfx_line_fit(im, &x, &y);
+                                cairo_line_to(im->cr, x, y);
+                            }
+                            draw_on = 1;
+                        } else {
+                            double    x1 = ii + im->xorigin;
+                            double    y1 = ytr(im, im->gdes[i].p_data[ii]);
 
-  /* the actual graph is created by going through the individual
-     graph elements and then drawing them */
-  
-  node=gfx_new_area ( im->canvas,
-                      0, 0,
-                      0, im->yimg,
-                      im->ximg, im->yimg,                      
-                      im->graph_col[GRC_BACK]);
+                            if (im->slopemode == 0
+                                && !AlmostEqual2sComplement(y1, last_y, 4)) {
+                                double    x = ii - 1 + im->xorigin;
+                                double    y = y1;
 
-  gfx_add_point(node,im->ximg, 0);
+                                gfx_line_fit(im, &x, &y);
+                                cairo_line_to(im->cr, x, y);
+                            };
+                            last_y = y1;
+                            gfx_line_fit(im, &x1, &y1);
+                            cairo_line_to(im->cr, x1, y1);
+                        };
+                    }
+                    cairo_set_source_rgba(im->cr,
+                                          im->gdes[i].
+                                          col.red,
+                                          im->gdes[i].
+                                          col.green,
+                                          im->gdes[i].
+                                          col.blue, im->gdes[i].col.alpha);
+                    cairo_set_line_cap(im->cr, CAIRO_LINE_CAP_ROUND);
+                    cairo_set_line_join(im->cr, CAIRO_LINE_JOIN_ROUND);
+                    cairo_stroke(im->cr);
+                    cairo_restore(im->cr);
+                } else {
+                    int       idxI = -1;
+                    double   *foreY =
+                        (double *) malloc(sizeof(double) * im->xsize * 2);
+                    double   *foreX =
+                        (double *) malloc(sizeof(double) * im->xsize * 2);
+                    double   *backY =
+                        (double *) malloc(sizeof(double) * im->xsize * 2);
+                    double   *backX =
+                        (double *) malloc(sizeof(double) * im->xsize * 2);
+                    int       drawem = 0;
+
+                    for (ii = 0; ii <= im->xsize; ii++) {
+                        double    ybase, ytop;
+
+                        if (idxI > 0 && (drawem != 0 || ii == im->xsize)) {
+                            int       cntI = 1;
+                            int       lastI = 0;
+
+                            while (cntI < idxI
+                                   &&
+                                   AlmostEqual2sComplement(foreY
+                                                           [lastI],
+                                                           foreY[cntI], 4)
+                                   &&
+                                   AlmostEqual2sComplement(foreY
+                                                           [lastI],
+                                                           foreY
+                                                           [cntI + 1], 4)) {
+                                cntI++;
+                            }
+                            gfx_new_area(im,
+                                         backX[0], backY[0],
+                                         foreX[0], foreY[0],
+                                         foreX[cntI],
+                                         foreY[cntI], im->gdes[i].col);
+                            while (cntI < idxI) {
+                                lastI = cntI;
+                                cntI++;
+                                while (cntI < idxI
+                                       &&
+                                       AlmostEqual2sComplement(foreY
+                                                               [lastI],
+                                                               foreY[cntI], 4)
+                                       &&
+                                       AlmostEqual2sComplement(foreY
+                                                               [lastI],
+                                                               foreY
+                                                               [cntI
+                                                                + 1], 4)) {
+                                    cntI++;
+                                }
+                                gfx_add_point(im, foreX[cntI], foreY[cntI]);
+                            }
+                            gfx_add_point(im, backX[idxI], backY[idxI]);
+                            while (idxI > 1) {
+                                lastI = idxI;
+                                idxI--;
+                                while (idxI > 1
+                                       &&
+                                       AlmostEqual2sComplement(backY
+                                                               [lastI],
+                                                               backY[idxI], 4)
+                                       &&
+                                       AlmostEqual2sComplement(backY
+                                                               [lastI],
+                                                               backY
+                                                               [idxI
+                                                                - 1], 4)) {
+                                    idxI--;
+                                }
+                                gfx_add_point(im, backX[idxI], backY[idxI]);
+                            }
+                            idxI = -1;
+                            drawem = 0;
+                            gfx_close_path(im);
+                        }
+                        if (drawem != 0) {
+                            drawem = 0;
+                            idxI = -1;
+                        }
+                        if (ii == im->xsize)
+                            break;
+                        if (im->slopemode == 0 && ii == 0) {
+                            continue;
+                        }
+                        if (isnan(im->gdes[i].p_data[ii])) {
+                            drawem = 1;
+                            continue;
+                        }
+                        ytop = ytr(im, im->gdes[i].p_data[ii]);
+                        if (lastgdes && im->gdes[i].stack) {
+                            ybase = ytr(im, lastgdes->p_data[ii]);
+                        } else {
+                            ybase = ytr(im, areazero);
+                        }
+                        if (ybase == ytop) {
+                            drawem = 1;
+                            continue;
+                        }
 
-#ifdef WITH_PIECHART
-  if (piechart != 2) {
-#endif
-    node=gfx_new_area ( im->canvas,
-                      im->xorigin,             im->yorigin, 
-                      im->xorigin + im->xsize, im->yorigin,
-                      im->xorigin + im->xsize, im->yorigin-im->ysize,
-                      im->graph_col[GRC_CANVAS]);
-  
-    gfx_add_point(node,im->xorigin, im->yorigin - im->ysize);
+                        if (ybase > ytop) {
+                            double    extra = ytop;
 
-    if (im->minval > 0.0)
-      areazero = im->minval;
-    if (im->maxval < 0.0)
-      areazero = im->maxval;
-#ifdef WITH_PIECHART
-   }
-#endif
+                            ytop = ybase;
+                            ybase = extra;
+                        }
+                        if (im->slopemode == 0) {
+                            backY[++idxI] = ybase - 0.2;
+                            backX[idxI] = ii + im->xorigin - 1;
+                            foreY[idxI] = ytop + 0.2;
+                            foreX[idxI] = ii + im->xorigin - 1;
+                        }
+                        backY[++idxI] = ybase - 0.2;
+                        backX[idxI] = ii + im->xorigin;
+                        foreY[idxI] = ytop + 0.2;
+                        foreX[idxI] = ii + im->xorigin;
+                    }
+                    /* close up any remaining area */
+                    free(foreY);
+                    free(foreX);
+                    free(backY);
+                    free(backX);
+                }       /* else GF_LINE */
+            }
+            /* if color != 0x0 */
+            /* make sure we do not run into trouble when stacking on NaN */
+            for (ii = 0; ii < im->xsize; ii++) {
+                if (isnan(im->gdes[i].p_data[ii])) {
+                    if (lastgdes && (im->gdes[i].stack)) {
+                        im->gdes[i].p_data[ii] = lastgdes->p_data[ii];
+                    } else {
+                        im->gdes[i].p_data[ii] = areazero;
+                    }
+                }
+            }
+            lastgdes = &(im->gdes[i]);
+            break;
+        case GF_STACK:
+            rrd_set_error
+                ("STACK should already be turned into LINE or AREA here");
+            return -1;
+            break;
+        }               /* switch */
+    }
 
-#ifdef WITH_PIECHART
-  if (piechart) {
-    pie_part(im,im->graph_col[GRC_CANVAS],im->pie_x,im->pie_y,im->piesize*0.5,0,2*M_PI);
-  }
-#endif
+    /* grid_paint also does the text */
+    if (!(im->extra_flags & ONLY_GRAPH))
+        grid_paint(im);
+    if (!(im->extra_flags & ONLY_GRAPH))
+        axis_paint(im);
+    /* the RULES are the last thing to paint ... */
+    for (i = 0; i < im->gdes_c; i++) {
 
-  for(i=0;i<im->gdes_c;i++){
-    switch(im->gdes[i].gf){
-    case GF_CDEF:
-    case GF_VDEF:
-    case GF_DEF:
-    case GF_PRINT:
-    case GF_GPRINT:
-    case GF_COMMENT:
-    case GF_HRULE:
-    case GF_VRULE:
-    case GF_XPORT:
-    case GF_SHIFT:
-      break;
-    case GF_TICK:
-      for (ii = 0; ii < im->xsize; ii++)
-        {
-          if (!isnan(im->gdes[i].p_data[ii]) && 
-              im->gdes[i].p_data[ii] != 0.0)
-           { 
-              if (im -> gdes[i].yrule > 0 ) {
-                      gfx_new_line(im->canvas,
-                                   im -> xorigin + ii, im->yorigin,
-                                   im -> xorigin + ii, im->yorigin - im -> gdes[i].yrule * im -> ysize,
-                                   1.0,
-                                   im -> gdes[i].col );
-              } else if ( im -> gdes[i].yrule < 0 ) {
-                      gfx_new_line(im->canvas,
-                                   im -> xorigin + ii, im->yorigin - im -> ysize,
-                                   im -> xorigin + ii, im->yorigin - ( 1 - im -> gdes[i].yrule ) * im -> ysize,
-                                   1.0,
-                                   im -> gdes[i].col );
-              
-              }
-           }
-        }
-      break;
-    case GF_LINE:
-    case GF_AREA:
-      /* fix data points at oo and -oo */
-      for(ii=0;ii<im->xsize;ii++){
-        if (isinf(im->gdes[i].p_data[ii])){
-          if (im->gdes[i].p_data[ii] > 0) {
-            im->gdes[i].p_data[ii] = im->maxval ;
-          } else {
-            im->gdes[i].p_data[ii] = im->minval ;
-          }                 
-          
-        }
-      } /* for */
-
-      /* *******************************************************
-       a           ___. (a,t) 
-                    |   |    ___
-              ____|   |   |   |
-              |       |___|
-       -------|--t-1--t--------------------------------      
-                      
-      if we know the value at time t was a then 
-      we draw a square from t-1 to t with the value a.
-
-      ********************************************************* */
-      if (im->gdes[i].col != 0x0){   
-        /* GF_LINE and friend */
-        if(im->gdes[i].gf == GF_LINE ){
-          double last_y=0.0;
-          node = NULL;
-          for(ii=1;ii<im->xsize;ii++){
-            if (isnan(im->gdes[i].p_data[ii]) || (im->slopemode==1 && isnan(im->gdes[i].p_data[ii-1]))){
-                node = NULL;
-                continue;
-            }
-            if ( node == NULL ) {
-                     last_y = ytr(im,im->gdes[i].p_data[ii]);
-                if ( im->slopemode == 0 ){
-                  node = gfx_new_line(im->canvas,
-                                    ii-1+im->xorigin,last_y,
-                                    ii+im->xorigin,last_y,
-                                    im->gdes[i].linewidth,
-                                    im->gdes[i].col);
-                } else {
-                  node = gfx_new_line(im->canvas,
-                                    ii-1+im->xorigin,ytr(im,im->gdes[i].p_data[ii-1]),
-                                    ii+im->xorigin,last_y,
-                                    im->gdes[i].linewidth,
-                                    im->gdes[i].col);
+        switch (im->gdes[i].gf) {
+        case GF_HRULE:
+            if (im->gdes[i].yrule >= im->minval
+                && im->gdes[i].yrule <= im->maxval) {
+                cairo_save(im->cr);
+                if (im->gdes[i].dash) {
+                    cairo_set_dash(im->cr,
+                                   im->gdes[i].p_dashes,
+                                   im->gdes[i].ndash, im->gdes[i].offset);
                 }
-             } else {
-               double new_y = ytr(im,im->gdes[i].p_data[ii]);
-               if ( im->slopemode==0 && ! AlmostEqual2sComplement(new_y,last_y,4)){
-                   gfx_add_point(node,ii-1+im->xorigin,new_y);
-               };
-               last_y = new_y;
-               gfx_add_point(node,ii+im->xorigin,new_y);
-             };
-
-          }
-        } else {
-          int idxI=-1;
-          double *foreY=malloc(sizeof(double)*im->xsize*2);
-          double *foreX=malloc(sizeof(double)*im->xsize*2);
-          double *backY=malloc(sizeof(double)*im->xsize*2);
-          double *backX=malloc(sizeof(double)*im->xsize*2);
-          int drawem = 0;
-          for(ii=0;ii<=im->xsize;ii++){
-            double ybase,ytop;
-            if ( idxI > 0 && ( drawem != 0 || ii==im->xsize)){
-               int cntI=1;
-               int lastI=0;
-               while (cntI < idxI && AlmostEqual2sComplement(foreY[lastI],foreY[cntI],4) && AlmostEqual2sComplement(foreY[lastI],foreY[cntI+1],4)){cntI++;}
-               node = gfx_new_area(im->canvas,
-                                backX[0],backY[0],
-                                foreX[0],foreY[0],
-                                foreX[cntI],foreY[cntI], im->gdes[i].col);
-               while (cntI < idxI) {
-                 lastI = cntI;
-                 cntI++;
-                 while ( cntI < idxI && AlmostEqual2sComplement(foreY[lastI],foreY[cntI],4) && AlmostEqual2sComplement(foreY[lastI],foreY[cntI+1],4)){cntI++;} 
-                 gfx_add_point(node,foreX[cntI],foreY[cntI]);
-               }
-               gfx_add_point(node,backX[idxI],backY[idxI]);
-               while (idxI > 1){
-                 lastI = idxI;
-                 idxI--;
-                 while ( idxI > 1 && AlmostEqual2sComplement(backY[lastI], backY[idxI],4) && AlmostEqual2sComplement(backY[lastI],backY[idxI-1],4)){idxI--;} 
-                 gfx_add_point(node,backX[idxI],backY[idxI]);
-               }
-               idxI=-1;
-               drawem = 0;
-            }
-            if (drawem != 0){
-              drawem = 0;
-              idxI=-1;
-            }
-            if (ii == im->xsize) break;
-            
-            /* keep things simple for now, just draw these bars
-               do not try to build a big and complex area */
-
-                                                               
-            if ( im->slopemode == 0 && ii==0){
-                continue;
+                gfx_line(im, im->xorigin,
+                         ytr(im, im->gdes[i].yrule),
+                         im->xorigin + im->xsize,
+                         ytr(im, im->gdes[i].yrule), 1.0, im->gdes[i].col);
+                cairo_stroke(im->cr);
+                cairo_restore(im->cr);
             }
-            if ( isnan(im->gdes[i].p_data[ii]) ) {
-                drawem = 1;
-                continue;
+            break;
+        case GF_VRULE:
+            if (im->gdes[i].xrule >= im->start
+                && im->gdes[i].xrule <= im->end) {
+                cairo_save(im->cr);
+                if (im->gdes[i].dash) {
+                    cairo_set_dash(im->cr,
+                                   im->gdes[i].p_dashes,
+                                   im->gdes[i].ndash, im->gdes[i].offset);
+                }
+                gfx_line(im,
+                         xtr(im, im->gdes[i].xrule),
+                         im->yorigin, xtr(im,
+                                          im->
+                                          gdes[i].
+                                          xrule),
+                         im->yorigin - im->ysize, 1.0, im->gdes[i].col);
+                cairo_stroke(im->cr);
+                cairo_restore(im->cr);
             }
-            ytop = ytr(im,im->gdes[i].p_data[ii]);
-             if ( lastgdes && im->gdes[i].stack ) {
-                  ybase = ytr(im,lastgdes->p_data[ii]);
-            } else {
-                  ybase = ytr(im,areazero);
-            }
-            if ( ybase == ytop ){
-                drawem = 1;
-                continue;        
-            }
-            /* every area has to be wound clock-wise,
-               so we have to make sur base remains base  */                
-            if (ybase > ytop){
-                double extra = ytop;
-                ytop = ybase;
-                ybase = extra;
-            }
-            if ( im->slopemode == 0 ){
-                    backY[++idxI] = ybase-0.2;
-                    backX[idxI] = ii+im->xorigin-1;
-                    foreY[idxI] = ytop+0.2;
-                    foreX[idxI] = ii+im->xorigin-1;
-            }
-            backY[++idxI] = ybase-0.2;
-            backX[idxI] = ii+im->xorigin;
-            foreY[idxI] = ytop+0.2;
-            foreX[idxI] = ii+im->xorigin;
-          }
-          /* close up any remaining area */             
-          free(foreY);
-          free(foreX);
-          free(backY);
-          free(backX);
-        } /* else GF_LINE */
-      } /* if color != 0x0 */
-      /* make sure we do not run into trouble when stacking on NaN */
-      for(ii=0;ii<im->xsize;ii++){
-        if (isnan(im->gdes[i].p_data[ii])) {
-          if (lastgdes && (im->gdes[i].stack)) {
-            im->gdes[i].p_data[ii] = lastgdes->p_data[ii];
-          } else {
-            im->gdes[i].p_data[ii] = areazero;
-          }
-        }
-      } 
-      lastgdes = &(im->gdes[i]);                         
-      break;
-#ifdef WITH_PIECHART
-    case GF_PART:
-      if(isnan(im->gdes[i].yrule)) /* fetch variable */
-        im->gdes[i].yrule = im->gdes[im->gdes[i].vidx].vf.val;
-     
-      if (finite(im->gdes[i].yrule)) {        /* even the fetched var can be NaN */
-        pie_part(im,im->gdes[i].col,
-                im->pie_x,im->pie_y,im->piesize*0.4,
-                M_PI*2.0*PieStart/100.0,
-                M_PI*2.0*(PieStart+im->gdes[i].yrule)/100.0);
-        PieStart += im->gdes[i].yrule;
-      }
-      break;
-#endif
-    case GF_STACK:
-      rrd_set_error("STACK should already be turned into LINE or AREA here");
-      return -1;
-      break;
-        
-    } /* switch */
-  }
-#ifdef WITH_PIECHART
-  if (piechart==2) {
-    im->draw_x_grid=0;
-    im->draw_y_grid=0;
-  }
-#endif
+            break;
+        default:
+            break;
+        }
+    }
 
 
-  /* grid_paint also does the text */
-  if( !(im->extra_flags & ONLY_GRAPH) )  
-    grid_paint(im);
-
-  
-  if( !(im->extra_flags & ONLY_GRAPH) )  
-      axis_paint(im);
-  
-  /* the RULES are the last thing to paint ... */
-  for(i=0;i<im->gdes_c;i++){    
-    
-    switch(im->gdes[i].gf){
-    case GF_HRULE:
-      if(im->gdes[i].yrule >= im->minval
-         && im->gdes[i].yrule <= im->maxval)
-        gfx_new_line(im->canvas,
-                     im->xorigin,ytr(im,im->gdes[i].yrule),
-                     im->xorigin+im->xsize,ytr(im,im->gdes[i].yrule),
-                     1.0,im->gdes[i].col); 
-      break;
-    case GF_VRULE:
-      if(im->gdes[i].xrule >= im->start
-         && im->gdes[i].xrule <= im->end)
-        gfx_new_line(im->canvas,
-                     xtr(im,im->gdes[i].xrule),im->yorigin,
-                     xtr(im,im->gdes[i].xrule),im->yorigin-im->ysize,
-                     1.0,im->gdes[i].col); 
-      break;
+    switch (im->imgformat) {
+    case IF_PNG:
+    {
+        cairo_status_t status;
+
+        status = strlen(im->graphfile) ?
+            cairo_surface_write_to_png(im->surface, im->graphfile)
+            : cairo_surface_write_to_png_stream(im->surface, &cairo_output,
+                                                im);
+
+        if (status != CAIRO_STATUS_SUCCESS) {
+            rrd_set_error("Could not save png to '%s'", im->graphfile);
+            return 1;
+        }
+    }
+        break;
     default:
-      break;
+        if (strlen(im->graphfile)) {
+            cairo_show_page(im->cr);
+        } else {
+            cairo_surface_finish(im->surface);
+        }
+        break;
     }
-  }
 
-  
-  if (strcmp(im->graphfile,"-")==0) {
-    fo = im->graphhandle ? im->graphhandle : stdout;
-#if defined(_WIN32) && !defined(__CYGWIN__) && !defined(__CYGWIN32__)
-    /* Change translation mode for stdout to BINARY */
-    _setmode( _fileno( fo ), O_BINARY );
-#endif
-  } else {
-    if ((fo = fopen(im->graphfile,"wb")) == NULL) {
-      rrd_set_error("Opening '%s' for write: %s",im->graphfile,
-                    rrd_strerror(errno));
-      return (-1);
-    }
-  }
-  gfx_render (im->canvas,im->ximg,im->yimg,0x00000000,fo);
-  if (strcmp(im->graphfile,"-") != 0)
-    fclose(fo);
-  return 0;
+    return 0;
 }
 
 
@@ -2969,148 +3452,240 @@ graph_paint(image_desc_t *im, char ***calcpr)
  * graph stuff 
  *****************************************************/
 
-int
-gdes_alloc(image_desc_t *im){
+int gdes_alloc(
+    image_desc_t *im)
+{
 
     im->gdes_c++;
-    if ((im->gdes = (graph_desc_t *) rrd_realloc(im->gdes, (im->gdes_c)
-                                           * sizeof(graph_desc_t)))==NULL){
+    if ((im->gdes = (graph_desc_t *)
+         rrd_realloc(im->gdes, (im->gdes_c)
+                     * sizeof(graph_desc_t))) == NULL) {
         rrd_set_error("realloc graph_descs");
         return -1;
     }
 
 
-    im->gdes[im->gdes_c-1].step=im->step;
-    im->gdes[im->gdes_c-1].step_orig=im->step;
-    im->gdes[im->gdes_c-1].stack=0;
-    im->gdes[im->gdes_c-1].linewidth=0;
-    im->gdes[im->gdes_c-1].debug=0;
-    im->gdes[im->gdes_c-1].start=im->start; 
-    im->gdes[im->gdes_c-1].start_orig=im->start; 
-    im->gdes[im->gdes_c-1].end=im->end; 
-    im->gdes[im->gdes_c-1].end_orig=im->end; 
-    im->gdes[im->gdes_c-1].vname[0]='\0'; 
-    im->gdes[im->gdes_c-1].data=NULL;
-    im->gdes[im->gdes_c-1].ds_namv=NULL;
-    im->gdes[im->gdes_c-1].data_first=0;
-    im->gdes[im->gdes_c-1].p_data=NULL;
-    im->gdes[im->gdes_c-1].rpnp=NULL;
-    im->gdes[im->gdes_c-1].shift=0;
-    im->gdes[im->gdes_c-1].col = 0x0;
-    im->gdes[im->gdes_c-1].legend[0]='\0';
-    im->gdes[im->gdes_c-1].format[0]='\0';
-    im->gdes[im->gdes_c-1].strftm=0;   
-    im->gdes[im->gdes_c-1].rrd[0]='\0';
-    im->gdes[im->gdes_c-1].ds=-1;    
-    im->gdes[im->gdes_c-1].cf_reduce=CF_AVERAGE;    
-    im->gdes[im->gdes_c-1].cf=CF_AVERAGE;    
-    im->gdes[im->gdes_c-1].p_data=NULL;    
-    im->gdes[im->gdes_c-1].yrule=DNAN;
-    im->gdes[im->gdes_c-1].xrule=0;
+    im->gdes[im->gdes_c - 1].step = im->step;
+    im->gdes[im->gdes_c - 1].step_orig = im->step;
+    im->gdes[im->gdes_c - 1].stack = 0;
+    im->gdes[im->gdes_c - 1].linewidth = 0;
+    im->gdes[im->gdes_c - 1].debug = 0;
+    im->gdes[im->gdes_c - 1].start = im->start;
+    im->gdes[im->gdes_c - 1].start_orig = im->start;
+    im->gdes[im->gdes_c - 1].end = im->end;
+    im->gdes[im->gdes_c - 1].end_orig = im->end;
+    im->gdes[im->gdes_c - 1].vname[0] = '\0';
+    im->gdes[im->gdes_c - 1].data = NULL;
+    im->gdes[im->gdes_c - 1].ds_namv = NULL;
+    im->gdes[im->gdes_c - 1].data_first = 0;
+    im->gdes[im->gdes_c - 1].p_data = NULL;
+    im->gdes[im->gdes_c - 1].rpnp = NULL;
+    im->gdes[im->gdes_c - 1].p_dashes = NULL;
+    im->gdes[im->gdes_c - 1].shift = 0.0;
+    im->gdes[im->gdes_c - 1].dash = 0;
+    im->gdes[im->gdes_c - 1].ndash = 0;
+    im->gdes[im->gdes_c - 1].offset = 0;
+    im->gdes[im->gdes_c - 1].col.red = 0.0;
+    im->gdes[im->gdes_c - 1].col.green = 0.0;
+    im->gdes[im->gdes_c - 1].col.blue = 0.0;
+    im->gdes[im->gdes_c - 1].col.alpha = 0.0;
+    im->gdes[im->gdes_c - 1].legend[0] = '\0';
+    im->gdes[im->gdes_c - 1].format[0] = '\0';
+    im->gdes[im->gdes_c - 1].strftm = 0;
+    im->gdes[im->gdes_c - 1].rrd[0] = '\0';
+    im->gdes[im->gdes_c - 1].ds = -1;
+    im->gdes[im->gdes_c - 1].cf_reduce = CF_AVERAGE;
+    im->gdes[im->gdes_c - 1].cf = CF_AVERAGE;
+    im->gdes[im->gdes_c - 1].yrule = DNAN;
+    im->gdes[im->gdes_c - 1].xrule = 0;
     return 0;
 }
 
 /* copies input untill the first unescaped colon is found
    or until input ends. backslashes have to be escaped as well */
-int
-scan_for_col(const char *const input, int len, char *const output)
+int scan_for_col(
+    const char *const input,
+    int len,
+    char *const output)
 {
-    int inp,outp=0;
-    for (inp=0; 
-         inp < len &&
-           input[inp] != ':' &&
-           input[inp] != '\0';
-         inp++){
-      if (input[inp] == '\\' &&
-          input[inp+1] != '\0' && 
-          (input[inp+1] == '\\' ||
-           input[inp+1] == ':')){
-        output[outp++] = input[++inp];
-      }
-      else {
-        output[outp++] = input[inp];
-      }
+    int       inp, outp = 0;
+
+    for (inp = 0; inp < len && input[inp] != ':' && input[inp] != '\0'; inp++) {
+        if (input[inp] == '\\'
+            && input[inp + 1] != '\0'
+            && (input[inp + 1] == '\\' || input[inp + 1] == ':')) {
+            output[outp++] = input[++inp];
+        } else {
+            output[outp++] = input[inp];
+        }
     }
     output[outp] = '\0';
     return inp;
 }
+
+/* Now just a wrapper around rrd_graph_v */
+int rrd_graph(
+    int argc,
+    char **argv,
+    char ***prdata,
+    int *xsize,
+    int *ysize,
+    FILE * stream,
+    double *ymin,
+    double *ymax)
+{
+    int       prlines = 0;
+    info_t   *grinfo = NULL;
+    info_t   *walker;
+
+    grinfo = rrd_graph_v(argc, argv);
+    if (grinfo == NULL)
+        return -1;
+    walker = grinfo;
+    (*prdata) = NULL;
+    while (walker) {
+        if (strcmp(walker->key, "image_info") == 0) {
+            prlines++;
+            if (((*prdata) =
+                 rrd_realloc((*prdata),
+                             (prlines + 1) * sizeof(char *))) == NULL) {
+                rrd_set_error("realloc prdata");
+                return 0;
+            }
+            /* imginfo goes to position 0 in the prdata array */
+            (*prdata)[prlines - 1] = malloc((strlen(walker->value.u_str)
+                                             + 2) * sizeof(char));
+            strcpy((*prdata)[prlines - 1], walker->value.u_str);
+            (*prdata)[prlines] = NULL;
+        }
+        /* skip anything else */
+        walker = walker->next;
+    }
+    walker = grinfo;
+    while (walker) {
+        if (strcmp(walker->key, "image_width") == 0) {
+            *xsize = walker->value.u_int;
+        } else if (strcmp(walker->key, "image_height") == 0) {
+            *ysize = walker->value.u_int;
+        } else if (strcmp(walker->key, "value_min") == 0) {
+            *ymin = walker->value.u_val;
+        } else if (strcmp(walker->key, "value_max") == 0) {
+            *ymax = walker->value.u_val;
+        } else if (strncmp(walker->key, "print", 5) == 0) { /* keys are prdate[0..] */
+            prlines++;
+            if (((*prdata) =
+                 rrd_realloc((*prdata),
+                             (prlines + 1) * sizeof(char *))) == NULL) {
+                rrd_set_error("realloc prdata");
+                return 0;
+            }
+            (*prdata)[prlines - 1] = malloc((strlen(walker->value.u_str)
+                                             + 2) * sizeof(char));
+            (*prdata)[prlines] = NULL;
+            strcpy((*prdata)[prlines - 1], walker->value.u_str);
+        } else if (strcmp(walker->key, "image") == 0) {
+            fwrite(walker->value.u_blo.ptr, walker->value.u_blo.size, 1,
+                   (stream ? stream : stdout));
+        }
+        /* skip anything else */
+        walker = walker->next;
+    }
+    info_free(grinfo);
+    return 0;
+}
+
+
 /* Some surgery done on this function, it became ridiculously big.
 ** Things moved:
 ** - initializing     now in rrd_graph_init()
 ** - options parsing  now in rrd_graph_options()
 ** - script parsing   now in rrd_graph_script()
 */
-int 
-rrd_graph(int argc, char **argv, char ***prdata, int *xsize, int *ysize, FILE *stream, double *ymin, double *ymax)
+info_t   *rrd_graph_v(
+    int argc,
+    char **argv)
 {
-    image_desc_t   im;
+    image_desc_t im;
+    info_t   *grinfo;
+
     rrd_graph_init(&im);
-    im.graphhandle = stream;
-    
-    rrd_graph_options(argc,argv,&im);
+    /* a dummy surface so that we can measure text sizes for placements */
+    im.surface = cairo_image_surface_create(CAIRO_FORMAT_ARGB32, 10, 10);
+    im.cr = cairo_create(im.surface);
+    rrd_graph_options(argc, argv, &im);
     if (rrd_test_error()) {
+        info_free(im.grinfo);
         im_free(&im);
-        return -1;
+        return NULL;
+    }
+
+    if (optind >= argc) {
+        info_free(im.grinfo);
+        im_free(&im);
+        rrd_set_error("missing filename");
+        return NULL;
     }
-    
-    if (strlen(argv[optind])>=MAXPATH) {
+
+    if (strlen(argv[optind]) >= MAXPATH) {
         rrd_set_error("filename (including path) too long");
+        info_free(im.grinfo);
         im_free(&im);
-        return -1;
+        return NULL;
+    }
+
+    strncpy(im.graphfile, argv[optind], MAXPATH - 1);
+    im.graphfile[MAXPATH - 1] = '\0';
+
+    if (strcmp(im.graphfile, "-") == 0) {
+        im.graphfile[0] = '\0';
     }
-    strncpy(im.graphfile,argv[optind],MAXPATH-1);
-    im.graphfile[MAXPATH-1]='\0';
 
-    rrd_graph_script(argc,argv,&im,1);
+    rrd_graph_script(argc, argv, &im, 1);
     if (rrd_test_error()) {
+        info_free(im.grinfo);
         im_free(&im);
-        return -1;
+        return NULL;
     }
 
     /* Everything is now read and the actual work can start */
 
-    (*prdata)=NULL;
-    if (graph_paint(&im,prdata)==-1){
+    if (graph_paint(&im) == -1) {
+        info_free(im.grinfo);
         im_free(&im);
-        return -1;
+        return NULL;
     }
 
+
     /* The image is generated and needs to be output.
-    ** Also, if needed, print a line with information about the image.
-    */
+     ** Also, if needed, print a line with information about the image.
+     */
 
-    *xsize=im.ximg;
-    *ysize=im.yimg;
-    *ymin=im.minval;
-    *ymax=im.maxval;
     if (im.imginfo) {
-        char *filename;
-        if (!(*prdata)) {
-            /* maybe prdata is not allocated yet ... lets do it now */
-            if ((*prdata = calloc(2,sizeof(char *)))==NULL) {
-                rrd_set_error("malloc imginfo");
-                return -1; 
-            };
-        }
-        if(((*prdata)[0] = malloc((strlen(im.imginfo)+200+strlen(im.graphfile))*sizeof(char)))
-         ==NULL){
-            rrd_set_error("malloc imginfo");
-            return -1;
-        }
-        filename=im.graphfile+strlen(im.graphfile);
-        while(filename > im.graphfile) {
-            if (*(filename-1)=='/' || *(filename-1)=='\\' ) break;
-            filename--;
-        }
+        infoval   info;
+
+        info.u_str =
+            sprintf_alloc(im.imginfo,
+                          im.graphfile,
+                          (long) (im.zoom *
+                                  im.ximg), (long) (im.zoom * im.yimg));
+        grinfo_push(&im, sprintf_alloc("image_info"), RD_I_STR, info);
+        free(info.u_str);
+    }
+    if (im.rendered_image) {
+        infoval   img;
 
-        sprintf((*prdata)[0],im.imginfo,filename,(long)(im.canvas->zoom*im.ximg),(long)(im.canvas->zoom*im.yimg));
+        img.u_blo.size = im.rendered_image_size;
+        img.u_blo.ptr = im.rendered_image;
+        grinfo_push(&im, sprintf_alloc("image"), RD_I_BLO, img);
     }
+    grinfo = im.grinfo;
     im_free(&im);
-    return 0;
+    return grinfo;
 }
 
-void
-rrd_graph_init(image_desc_t *im)
+void rrd_graph_init(
+    image_desc_t
+    *im)
 {
     unsigned int i;
 
@@ -3118,160 +3693,252 @@ rrd_graph_init(image_desc_t *im)
     tzset();
 #endif
 #ifdef HAVE_SETLOCALE
-    setlocale(LC_TIME,"");
+    setlocale(LC_TIME, "");
 #ifdef HAVE_MBSTOWCS
-    setlocale(LC_CTYPE,"");
+    setlocale(LC_CTYPE, "");
 #endif
 #endif
-    im->yorigin=0;
-    im->xorigin=0;
-    im->minval=0;
-    im->xlab_user.minsec = -1;
-    im->ximg=0;
-    im->yimg=0;
-    im->xsize = 400;
-    im->ysize = 100;
-    im->step = 0;
-    im->ylegend[0] = '\0';
-    im->title[0] = '\0';
-    im->watermark[0] = '\0';
-    im->minval = DNAN;
-    im->maxval = DNAN;    
-    im->unitsexponent= 9999;
-    im->unitslength= 6; 
+    im->base = 1000;
+    im->cr = NULL;
+    im->draw_x_grid = 1;
+    im->draw_y_grid = 1;
+    im->extra_flags = 0;
+    im->font_options = cairo_font_options_create();
     im->forceleftspace = 0;
-    im->symbol = ' ';
-    im->viewfactor = 1.0;
-    im->extra_flags= 0;
-    im->rigid = 0;
+    im->gdes_c = 0;
+    im->gdes = NULL;
+    im->graph_antialias = CAIRO_ANTIALIAS_GRAY;
+    im->grid_dash_off = 1;
+    im->grid_dash_on = 1;
     im->gridfit = 1;
+    im->grinfo = (info_t *) NULL;
+    im->grinfo_current = (info_t *) NULL;
+    im->imgformat = IF_PNG;
     im->imginfo = NULL;
     im->lazy = 0;
-    im->slopemode = 0;
     im->logarithmic = 0;
-    im->ygridstep = DNAN;
-    im->draw_x_grid = 1;
-    im->draw_y_grid = 1;
-    im->base = 1000;
+    im->maxval = DNAN;
+    im->minval = 0;
+    im->minval = DNAN;
     im->prt_c = 0;
-    im->gdes_c = 0;
-    im->gdes = NULL;
-    im->canvas = gfx_new_canvas();
-    im->grid_dash_on = 1;
-    im->grid_dash_off = 1;
+    im->rigid = 0;
+    im->rendered_image_size = 0;
+    im->rendered_image = NULL;
+    im->slopemode = 0;
+    im->step = 0;
+    im->surface = NULL;
+    im->symbol = ' ';
     im->tabwidth = 40.0;
-    
-    for(i=0;i<DIM(graph_col);i++)
-        im->graph_col[i]=graph_col[i];
-
+    im->title[0] = '\0';
+    im->unitsexponent = 9999;
+    im->unitslength = 6;
+    im->viewfactor = 1.0;
+    im->watermark[0] = '\0';
+    im->ximg = 0;
+    im->xlab_user.minsec = -1;
+    im->xorigin = 0;
+    im->xsize = 400;
+    im->ygridstep = DNAN;
+    im->yimg = 0;
+    im->ylegend[0] = '\0';
+    im->yorigin = 0;
+    im->ysize = 100;
+    im->zoom = 1;
+    cairo_font_options_set_hint_style
+        (im->font_options, CAIRO_HINT_STYLE_FULL);
+    cairo_font_options_set_hint_metrics
+        (im->font_options, CAIRO_HINT_METRICS_ON);
+    cairo_font_options_set_antialias(im->font_options, CAIRO_ANTIALIAS_GRAY);
+    for (i = 0; i < DIM(graph_col); i++)
+        im->graph_col[i] = graph_col[i];
 #if defined(_WIN32) && !defined(__CYGWIN__) && !defined(__CYGWIN32__)
     {
-            char *windir; 
-            char rrd_win_default_font[1000];
-            windir = getenv("windir");
-            /* %windir% is something like D:\windows or C:\winnt */
-            if (windir != NULL) {
-                    strncpy(rrd_win_default_font,windir,500);
-                    rrd_win_default_font[500] = '\0';
-                    strcat(rrd_win_default_font,"\\fonts\\");
-                    strcat(rrd_win_default_font,RRD_DEFAULT_FONT);         
-                    for(i=0;i<DIM(text_prop);i++){
-                            strncpy(text_prop[i].font,rrd_win_default_font,sizeof(text_prop[i].font)-1);
-                            text_prop[i].font[sizeof(text_prop[i].font)-1] = '\0';
-                     }
-             }
+        char     *windir;
+        char      rrd_win_default_font[1000];
+
+        windir = getenv("windir");
+        /* %windir% is something like D:\windows or C:\winnt */
+        if (windir != NULL) {
+            strncpy(rrd_win_default_font, windir, 500);
+            rrd_win_default_font[500] = '\0';
+            strcat(rrd_win_default_font, "\\fonts\\");
+            strcat(rrd_win_default_font, RRD_DEFAULT_FONT);
+            for (i = 0; i < DIM(text_prop); i++) {
+                strncpy(text_prop[i].font,
+                        rrd_win_default_font, sizeof(text_prop[i].font) - 1);
+                text_prop[i].font[sizeof(text_prop[i].font) - 1] = '\0';
+            }
+        }
     }
 #endif
     {
-            char *deffont; 
-            deffont = getenv("RRD_DEFAULT_FONT");
-            if (deffont != NULL) {
-                 for(i=0;i<DIM(text_prop);i++){
-                        strncpy(text_prop[i].font,deffont,sizeof(text_prop[i].font)-1);
-                        text_prop[i].font[sizeof(text_prop[i].font)-1] = '\0';
-                 }
+        char     *deffont;
+
+        deffont = getenv("RRD_DEFAULT_FONT");
+        if (deffont != NULL) {
+            for (i = 0; i < DIM(text_prop); i++) {
+                strncpy(text_prop[i].font, deffont,
+                        sizeof(text_prop[i].font) - 1);
+                text_prop[i].font[sizeof(text_prop[i].font) - 1] = '\0';
             }
+        }
     }
-    for(i=0;i<DIM(text_prop);i++){        
-      im->text_prop[i].size = text_prop[i].size;
-      strcpy(im->text_prop[i].font,text_prop[i].font);
+    for (i = 0; i < DIM(text_prop); i++) {
+        im->text_prop[i].size = text_prop[i].size;
+        strcpy(im->text_prop[i].font, text_prop[i].font);
     }
 }
 
-void
-rrd_graph_options(int argc, char *argv[],image_desc_t *im)
+void rrd_graph_options(
+    int argc,
+    char *argv[],
+    image_desc_t
+    *im)
 {
-    int                        stroff;    
-    char                *parsetime_error = NULL;
-    char                scan_gtm[12],scan_mtm[12],scan_ltm[12],col_nam[12];
-    time_t                start_tmp=0,end_tmp=0;
-    long                long_tmp;
-    struct rrd_time_value        start_tv, end_tv;
-    gfx_color_t         color;
-    optind = 0; opterr = 0;  /* initialize getopt */
-
-    parsetime("end-24h", &start_tv);
-    parsetime("now", &end_tv);
+    int       stroff;
+    char     *parsetime_error = NULL;
+    char      scan_gtm[12], scan_mtm[12], scan_ltm[12], col_nam[12];
+    time_t    start_tmp = 0, end_tmp = 0;
+    long      long_tmp;
+    struct rrd_time_value start_tv, end_tv;
+    long unsigned int color;
+    char     *old_locale = "";
 
     /* defines for long options without a short equivalent. should be bytes,
        and may not collide with (the ASCII value of) short options */
-    #define LONGOPT_UNITS_SI 255
-
-    while (1){
-        static struct option long_options[] =
+#define LONGOPT_UNITS_SI 255
+    struct option long_options[] = {
         {
-            {"start",      required_argument, 0,  's'},
-            {"end",        required_argument, 0,  'e'},
-            {"x-grid",     required_argument, 0,  'x'},
-            {"y-grid",     required_argument, 0,  'y'},
-            {"vertical-label",required_argument,0,'v'},
-            {"width",      required_argument, 0,  'w'},
-            {"height",     required_argument, 0,  'h'},
-            {"interlaced", no_argument,       0,  'i'},
-            {"upper-limit",required_argument, 0,  'u'},
-            {"lower-limit",required_argument, 0,  'l'},
-            {"rigid",      no_argument,       0,  'r'},
-            {"base",       required_argument, 0,  'b'},
-            {"logarithmic",no_argument,       0,  'o'},
-            {"color",      required_argument, 0,  'c'},
-            {"font",       required_argument, 0,  'n'},
-            {"title",      required_argument, 0,  't'},
-            {"imginfo",    required_argument, 0,  'f'},
-            {"imgformat",  required_argument, 0,  'a'},
-            {"lazy",       no_argument,       0,  'z'},
-            {"zoom",       required_argument, 0,  'm'},
-            {"no-legend",  no_argument,       0,  'g'},
-            {"force-rules-legend",no_argument,0,  'F'},
-            {"only-graph", no_argument,       0,  'j'},
-            {"alt-y-grid", no_argument,       0,  'Y'},
-            {"no-minor",   no_argument,       0,  'I'},
-            {"slope-mode", no_argument,              0,  'E'},
-            {"alt-autoscale", no_argument,    0,  'A'},
-           {"alt-autoscale-min", no_argument, 0, 'J'},
-            {"alt-autoscale-max", no_argument, 0, 'M'},
-            {"no-gridfit", no_argument,       0,   'N'},
-            {"units-exponent",required_argument, 0, 'X'},
-            {"units-length",required_argument, 0, 'L'},
-            {"units",      required_argument, 0,  LONGOPT_UNITS_SI },
-            {"step",       required_argument, 0,    'S'},
-            {"tabwidth",   required_argument, 0,    'T'},            
-            {"font-render-mode", required_argument, 0, 'R'},
-            {"font-smoothing-threshold", required_argument, 0, 'B'},
-            {"watermark",  required_argument, 0,  'W'},
-            {"alt-y-mrtg", no_argument,       0,  1000}, /* this has no effect it is just here to save old apps from crashing when they use it */
-            {0,0,0,0}};
-        int option_index = 0;
-        int opt;
-        int col_start,col_end;
-
-        opt = getopt_long(argc, argv, 
-                         "s:e:x:y:v:w:h:iu:l:rb:oc:n:m:t:f:a:I:zgjFYAMEX:L:S:T:NR:B:W:",
-                          long_options, &option_index);
+         "start", required_argument, 0, 's'}, {
+                                               "end", required_argument, 0,
+                                               'e'}, {
+                                                      "x-grid",
+                                                      required_argument, 0,
+                                                      'x'}, {
+                                                             "y-grid",
+                                                             required_argument,
+                                                             0, 'y'}, {
+                                                                       "vertical-label",
+                                                                       required_argument,
+                                                                       0,
+                                                                       'v'}, {
+                                                                              "width",
+                                                                              required_argument,
+                                                                              0,
+                                                                              'w'},
+        {
+         "height", required_argument, 0, 'h'}, {
+                                                "full-size-mode", no_argument,
+                                                0, 'D'}, {
+                                                          "interlaced",
+                                                          no_argument, 0,
+                                                          'i'}, {
+                                                                 "upper-limit",
+                                                                 required_argument,
+                                                                 0,
+                                                                 'u'}, {
+                                                                        "lower-limit",
+                                                                        required_argument,
+                                                                        0,
+                                                                        'l'}, {
+                                                                               "rigid",
+                                                                               no_argument,
+                                                                               0,
+                                                                               'r'},
+        {
+         "base", required_argument, 0, 'b'}, {
+                                              "logarithmic", no_argument, 0,
+                                              'o'}, {
+                                                     "color",
+                                                     required_argument, 0,
+                                                     'c'}, {
+                                                            "font",
+                                                            required_argument,
+                                                            0, 'n'}, {
+                                                                      "title",
+                                                                      required_argument,
+                                                                      0, 't'},
+        {
+         "imginfo", required_argument, 0, 'f'}, {
+                                                 "imgformat",
+                                                 required_argument, 0, 'a'}, {
+                                                                              "lazy",
+                                                                              no_argument,
+                                                                              0,
+                                                                              'z'},
+        {
+         "zoom", required_argument, 0, 'm'}, {
+                                              "no-legend", no_argument, 0,
+                                              'g'}, {
+                                                     "force-rules-legend",
+                                                     no_argument,
+                                                     0, 'F'}, {
+                                                               "only-graph",
+                                                               no_argument, 0,
+                                                               'j'}, {
+                                                                      "alt-y-grid",
+                                                                      no_argument,
+                                                                      0, 'Y'},
+        {
+         "no-minor", no_argument, 0, 'I'}, {
+                                            "slope-mode", no_argument, 0,
+                                            'E'}, {
+                                                   "alt-autoscale",
+                                                   no_argument, 0, 'A'}, {
+                                                                          "alt-autoscale-min",
+                                                                          no_argument,
+                                                                          0,
+                                                                          'J'}, {
+                                                                                 "alt-autoscale-max",
+                                                                                 no_argument,
+                                                                                 0,
+                                                                                 'M'}, {
+                                                                                        "no-gridfit",
+                                                                                        no_argument,
+                                                                                        0,
+                                                                                        'N'},
+        {
+         "units-exponent", required_argument,
+         0, 'X'}, {
+                   "units-length", required_argument,
+                   0, 'L'}, {
+                             "units", required_argument, 0,
+                             LONGOPT_UNITS_SI}, {
+                                                 "step", required_argument, 0,
+                                                 'S'}, {
+                                                        "tabwidth",
+                                                        required_argument, 0,
+                                                        'T'}, {
+                                                               "font-render-mode",
+                                                               required_argument,
+                                                               0, 'R'}, {
+                                                                         "graph-render-mode",
+                                                                         required_argument,
+                                                                         0,
+                                                                         'G'},
+        {
+         "font-smoothing-threshold",
+         required_argument, 0, 'B'}, {
+                                      "watermark", required_argument, 0, 'W'}, {
+                                                                                "alt-y-mrtg", no_argument, 0, 1000},    /* this has no effect it is just here to save old apps from crashing when they use it */
+        {
+         0, 0, 0, 0}
+    };
+    optind = 0;
+    opterr = 0;         /* initialize getopt */
+    parsetime("end-24h", &start_tv);
+    parsetime("now", &end_tv);
+    while (1) {
+        int       option_index = 0;
+        int       opt;
+        int       col_start, col_end;
 
+        opt = getopt_long(argc, argv,
+                          "s:e:x:y:v:w:h:D:iu:l:rb:oc:n:m:t:f:a:I:zgjFYAMEX:L:S:T:NR:B:W:k",
+                          long_options, &option_index);
         if (opt == EOF)
             break;
-        
-        switch(opt) {
+        switch (opt) {
         case 'I':
             im->extra_flags |= NOMINOR;
             break;
@@ -3280,16 +3947,16 @@ rrd_graph_options(int argc, char *argv[],image_desc_t *im)
             break;
         case 'A':
             im->extra_flags |= ALTAUTOSCALE;
-           break;
-       case 'J':
-           im->extra_flags |= ALTAUTOSCALE_MIN;
+            break;
+        case 'J':
+            im->extra_flags |= ALTAUTOSCALE_MIN;
             break;
         case 'M':
             im->extra_flags |= ALTAUTOSCALE_MAX;
             break;
         case 'j':
-           im->extra_flags |= ONLY_GRAPH;
-           break;
+            im->extra_flags |= ONLY_GRAPH;
+            break;
         case 'g':
             im->extra_flags |= NOLEGEND;
             break;
@@ -3297,14 +3964,15 @@ rrd_graph_options(int argc, char *argv[],image_desc_t *im)
             im->extra_flags |= FORCE_RULES_LEGEND;
             break;
         case LONGOPT_UNITS_SI:
-            if(im->extra_flags & FORCE_UNITS) {
+            if (im->extra_flags & FORCE_UNITS) {
                 rrd_set_error("--units can only be used once!");
+                setlocale(LC_NUMERIC, old_locale);
                 return;
             }
-            if(strcmp(optarg,"si")==0)
+            if (strcmp(optarg, "si") == 0)
                 im->extra_flags |= FORCE_UNITS_SI;
             else {
-                rrd_set_error("invalid argument for --units: %s", optarg );
+                rrd_set_error("invalid argument for --units: %s", optarg);
                 return;
             }
             break;
@@ -3316,54 +3984,61 @@ rrd_graph_options(int argc, char *argv[],image_desc_t *im)
             im->forceleftspace = 1;
             break;
         case 'T':
+            old_locale = setlocale(LC_NUMERIC, "C");
             im->tabwidth = atof(optarg);
+            setlocale(LC_NUMERIC, old_locale);
             break;
         case 'S':
-            im->step =  atoi(optarg);
+            old_locale = setlocale(LC_NUMERIC, "C");
+            im->step = atoi(optarg);
+            setlocale(LC_NUMERIC, old_locale);
             break;
         case 'N':
             im->gridfit = 0;
             break;
         case 's':
             if ((parsetime_error = parsetime(optarg, &start_tv))) {
-                rrd_set_error( "start time: %s", parsetime_error );
+                rrd_set_error("start time: %s", parsetime_error);
                 return;
             }
             break;
         case 'e':
             if ((parsetime_error = parsetime(optarg, &end_tv))) {
-                rrd_set_error( "end time: %s", parsetime_error );
+                rrd_set_error("end time: %s", parsetime_error);
                 return;
             }
             break;
         case 'x':
-            if(strcmp(optarg,"none") == 0){
-              im->draw_x_grid=0;
-              break;
+            if (strcmp(optarg, "none") == 0) {
+                im->draw_x_grid = 0;
+                break;
             };
-                
-            if(sscanf(optarg,
-                      "%10[A-Z]:%ld:%10[A-Z]:%ld:%10[A-Z]:%ld:%ld:%n",
-                      scan_gtm,
-                      &im->xlab_user.gridst,
-                      scan_mtm,
-                      &im->xlab_user.mgridst,
-                      scan_ltm,
-                      &im->xlab_user.labst,
-                      &im->xlab_user.precis,
-                      &stroff) == 7 && stroff != 0){
-                strncpy(im->xlab_form, optarg+stroff, sizeof(im->xlab_form) - 1);
-                im->xlab_form[sizeof(im->xlab_form)-1] = '\0'; 
-                if((int)(im->xlab_user.gridtm = tmt_conv(scan_gtm)) == -1){
-                    rrd_set_error("unknown keyword %s",scan_gtm);
+            if (sscanf(optarg,
+                       "%10[A-Z]:%ld:%10[A-Z]:%ld:%10[A-Z]:%ld:%ld:%n",
+                       scan_gtm,
+                       &im->xlab_user.gridst,
+                       scan_mtm,
+                       &im->xlab_user.mgridst,
+                       scan_ltm,
+                       &im->xlab_user.labst,
+                       &im->xlab_user.precis, &stroff) == 7 && stroff != 0) {
+                strncpy(im->xlab_form, optarg + stroff,
+                        sizeof(im->xlab_form) - 1);
+                im->xlab_form[sizeof(im->xlab_form) - 1] = '\0';
+                if ((int)
+                    (im->xlab_user.gridtm = tmt_conv(scan_gtm)) == -1) {
+                    rrd_set_error("unknown keyword %s", scan_gtm);
                     return;
-                } else if ((int)(im->xlab_user.mgridtm = tmt_conv(scan_mtm)) == -1){
-                    rrd_set_error("unknown keyword %s",scan_mtm);
+                } else if ((int)
+                           (im->xlab_user.mgridtm = tmt_conv(scan_mtm))
+                           == -1) {
+                    rrd_set_error("unknown keyword %s", scan_mtm);
                     return;
-                } else if ((int)(im->xlab_user.labtm = tmt_conv(scan_ltm)) == -1){
-                    rrd_set_error("unknown keyword %s",scan_ltm);
+                } else if ((int)
+                           (im->xlab_user.labtm = tmt_conv(scan_ltm)) == -1) {
+                    rrd_set_error("unknown keyword %s", scan_ltm);
                     return;
-                } 
+                }
                 im->xlab_user.minsec = 1;
                 im->xlab_user.stst = im->xlab_form;
             } else {
@@ -3373,41 +4048,45 @@ rrd_graph_options(int argc, char *argv[],image_desc_t *im)
             break;
         case 'y':
 
-            if(strcmp(optarg,"none") == 0){
-              im->draw_y_grid=0;
-              break;
+            if (strcmp(optarg, "none") == 0) {
+                im->draw_y_grid = 0;
+                break;
             };
-
-            if(sscanf(optarg,
-                      "%lf:%d",
-                      &im->ygridstep,
-                      &im->ylabfact) == 2) {
-                if(im->ygridstep<=0){
+            old_locale = setlocale(LC_NUMERIC, "C");
+            if (sscanf(optarg, "%lf:%d", &im->ygridstep, &im->ylabfact) == 2) {
+                setlocale(LC_NUMERIC, old_locale);
+                if (im->ygridstep <= 0) {
                     rrd_set_error("grid step must be > 0");
                     return;
-                } else if (im->ylabfact < 1){
+                } else if (im->ylabfact < 1) {
                     rrd_set_error("label factor must be > 0");
                     return;
-                } 
+                }
             } else {
+                setlocale(LC_NUMERIC, old_locale);
                 rrd_set_error("invalid y-grid format");
                 return;
             }
             break;
         case 'v':
-            strncpy(im->ylegend,optarg,150);
-            im->ylegend[150]='\0';
+            strncpy(im->ylegend, optarg, 150);
+            im->ylegend[150] = '\0';
             break;
         case 'u':
+            old_locale = setlocale(LC_NUMERIC, "C");
             im->maxval = atof(optarg);
+            setlocale(LC_NUMERIC, old_locale);
             break;
         case 'l':
+            old_locale = setlocale(LC_NUMERIC, "C");
             im->minval = atof(optarg);
+            setlocale(LC_NUMERIC, old_locale);
             break;
         case 'b':
             im->base = atol(optarg);
-            if(im->base != 1024 && im->base != 1000 ){
-                rrd_set_error("the only sensible value for base apart from 1000 is 1024");
+            if (im->base != 1024 && im->base != 1000) {
+                rrd_set_error
+                    ("the only sensible value for base apart from 1000 is 1024");
                 return;
             }
             break;
@@ -3427,8 +4106,11 @@ rrd_graph_options(int argc, char *argv[],image_desc_t *im)
             }
             im->ysize = long_tmp;
             break;
+        case 'D':
+            im->extra_flags |= FULL_SIZE_MODE;
+            break;
         case 'i':
-            im->canvas->interlaced = 1;
+            /* interlaced png not supported at the moment */
             break;
         case 'r':
             im->rigid = 1;
@@ -3436,9 +4118,10 @@ rrd_graph_options(int argc, char *argv[],image_desc_t *im)
         case 'f':
             im->imginfo = optarg;
             break;
-            case 'a':
-            if((int)(im->canvas->imgformat = if_conv(optarg)) == -1) {
-                rrd_set_error("unsupported graphics format '%s'",optarg);
+        case 'a':
+            if ((int)
+                (im->imgformat = if_conv(optarg)) == -1) {
+                rrd_set_error("unsupported graphics format '%s'", optarg);
                 return;
             }
             break;
@@ -3448,546 +4131,628 @@ rrd_graph_options(int argc, char *argv[],image_desc_t *im)
         case 'E':
             im->slopemode = 1;
             break;
-
         case 'o':
             im->logarithmic = 1;
             break;
         case 'c':
-            if(sscanf(optarg,
-                      "%10[A-Z]#%n%8lx%n",
-                      col_nam,&col_start,&color,&col_end) == 2){
-                int ci;
-                int col_len = col_end - col_start;
-                switch (col_len){
-                        case 3:
-                                color = (
-                                        ((color & 0xF00) * 0x110000) |
-                                        ((color & 0x0F0) * 0x011000) |
-                                        ((color & 0x00F) * 0x001100) |
-                                        0x000000FF
-                                        );
-                                break;
-                        case 4:
-                                color = (
-                                        ((color & 0xF000) * 0x11000) |
-                                        ((color & 0x0F00) * 0x01100) |
-                                        ((color & 0x00F0) * 0x00110) |
-                                        ((color & 0x000F) * 0x00011)
-                                        );
-                                break;
-                        case 6:
-                                color = (color << 8) + 0xff /* shift left by 8 */;
-                                break;
-                        case 8:
-                                break;
-                        default:
-                                rrd_set_error("the color format is #RRGGBB[AA]");
-                                return;
+            if (sscanf(optarg,
+                       "%10[A-Z]#%n%8lx%n",
+                       col_nam, &col_start, &color, &col_end) == 2) {
+                int       ci;
+                int       col_len = col_end - col_start;
+
+                switch (col_len) {
+                case 3:
+                    color =
+                        (((color & 0xF00) * 0x110000) | ((color & 0x0F0) *
+                                                         0x011000) |
+                         ((color & 0x00F)
+                          * 0x001100)
+                         | 0x000000FF);
+                    break;
+                case 4:
+                    color =
+                        (((color & 0xF000) *
+                          0x11000) | ((color & 0x0F00) *
+                                      0x01100) | ((color &
+                                                   0x00F0) *
+                                                  0x00110) |
+                         ((color & 0x000F) * 0x00011)
+                        );
+                    break;
+                case 6:
+                    color = (color << 8) + 0xff /* shift left by 8 */ ;
+                    break;
+                case 8:
+                    break;
+                default:
+                    rrd_set_error("the color format is #RRGGBB[AA]");
+                    return;
                 }
-                if((ci=grc_conv(col_nam)) != -1){
-                    im->graph_col[ci]=color;
-                }  else {
-                  rrd_set_error("invalid color name '%s'",col_nam);
-                  return;
+                if ((ci = grc_conv(col_nam)) != -1) {
+                    im->graph_col[ci] = gfx_hex_to_col(color);
+                } else {
+                    rrd_set_error("invalid color name '%s'", col_nam);
+                    return;
                 }
             } else {
                 rrd_set_error("invalid color def format");
                 return;
             }
-            break;        
+            break;
         case 'n':{
-            char prop[15];
-            double size = 1;
-            int end;
-            if(sscanf(optarg,
-                                "%10[A-Z]:%lf%n",
-                                prop,&size,&end) >= 2){                                
-                int sindex,propidx;
-                if((sindex=text_prop_conv(prop)) != -1){
-                  for (propidx=sindex;propidx<TEXT_PROP_LAST;propidx++){                        
-                        if (size > 0){
-                              im->text_prop[propidx].size=size;              
-                      }        
-                       if (strlen(prop) > end){
-                          if (prop[end] == ':'){
-                             strncpy(im->text_prop[propidx].font,prop+end+1,255);
-                             im->text_prop[propidx].font[255] = '\0';
-                          } else {
-                             rrd_set_error("expected after font size in '%s'",prop);
-                            return;
-                          }
-                      }
-                      if (propidx==sindex && sindex != 0) break;
-                  }
+            char      prop[15];
+            double    size = 1;
+            int       end;
+
+            old_locale = setlocale(LC_NUMERIC, "C");
+            if (sscanf(optarg, "%10[A-Z]:%lf%n", prop, &size, &end) >= 2) {
+                int       sindex, propidx;
+
+                setlocale(LC_NUMERIC, old_locale);
+                if ((sindex = text_prop_conv(prop)) != -1) {
+                    for (propidx = sindex;
+                         propidx < TEXT_PROP_LAST; propidx++) {
+                        if (size > 0) {
+                            im->text_prop[propidx].size = size;
+                        }
+                        if ((int) strlen(prop) > end) {
+                            if (prop[end] == ':') {
+                                strncpy(im->text_prop[propidx].font,
+                                        prop + end + 1, 255);
+                                im->text_prop[propidx].font[255] = '\0';
+                            } else {
+                                rrd_set_error
+                                    ("expected after font size in '%s'",
+                                     prop);
+                                return;
+                            }
+                        }
+                        if (propidx == sindex && sindex != 0)
+                            break;
+                    }
                 } else {
-                    rrd_set_error("invalid fonttag '%s'",prop);
+                    rrd_set_error("invalid fonttag '%s'", prop);
                     return;
                 }
             } else {
+                setlocale(LC_NUMERIC, old_locale);
                 rrd_set_error("invalid text property format");
                 return;
             }
-            break;          
+            break;
         }
         case 'm':
-            im->canvas->zoom = atof(optarg);
-            if (im->canvas->zoom <= 0.0) {
+            old_locale = setlocale(LC_NUMERIC, "C");
+            im->zoom = atof(optarg);
+            setlocale(LC_NUMERIC, old_locale);
+            if (im->zoom <= 0.0) {
                 rrd_set_error("zoom factor must be > 0");
                 return;
             }
-          break;
+            break;
         case 't':
-            strncpy(im->title,optarg,150);
-            im->title[150]='\0';
+            strncpy(im->title, optarg, 150);
+            im->title[150] = '\0';
             break;
-
         case 'R':
-                if ( strcmp( optarg, "normal" ) == 0 )
-                        im->canvas->aa_type = AA_NORMAL;
-                else if ( strcmp( optarg, "light" ) == 0 )
-                        im->canvas->aa_type = AA_LIGHT;
-                else if ( strcmp( optarg, "mono" ) == 0 )
-                        im->canvas->aa_type = AA_NONE;
-                else
-                {
-                        rrd_set_error("unknown font-render-mode '%s'", optarg );
-                        return;
-                }
-                break;
-
+            if (strcmp(optarg, "normal") == 0) {
+                cairo_font_options_set_antialias
+                    (im->font_options, CAIRO_ANTIALIAS_GRAY);
+                cairo_font_options_set_hint_style
+                    (im->font_options, CAIRO_HINT_STYLE_FULL);
+            } else if (strcmp(optarg, "light") == 0) {
+                cairo_font_options_set_antialias
+                    (im->font_options, CAIRO_ANTIALIAS_GRAY);
+                cairo_font_options_set_hint_style
+                    (im->font_options, CAIRO_HINT_STYLE_SLIGHT);
+            } else if (strcmp(optarg, "mono") == 0) {
+                cairo_font_options_set_antialias
+                    (im->font_options, CAIRO_ANTIALIAS_NONE);
+                cairo_font_options_set_hint_style
+                    (im->font_options, CAIRO_HINT_STYLE_FULL);
+            } else {
+                rrd_set_error("unknown font-render-mode '%s'", optarg);
+                return;
+            }
+            break;
+        case 'G':
+            if (strcmp(optarg, "normal") == 0)
+                im->graph_antialias = CAIRO_ANTIALIAS_GRAY;
+            else if (strcmp(optarg, "mono") == 0)
+                im->graph_antialias = CAIRO_ANTIALIAS_NONE;
+            else {
+                rrd_set_error("unknown graph-render-mode '%s'", optarg);
+                return;
+            }
+            break;
         case 'B':
-            im->canvas->font_aa_threshold = atof(optarg);
-                break;
-
+            /* not supported curently */
+            break;
         case 'W':
-            strncpy(im->watermark,optarg,100);
-            im->watermark[99]='\0';
+            strncpy(im->watermark, optarg, 100);
+            im->watermark[99] = '\0';
             break;
-
         case '?':
             if (optopt != 0)
                 rrd_set_error("unknown option '%c'", optopt);
             else
-                rrd_set_error("unknown option '%s'",argv[optind-1]);
+                rrd_set_error("unknown option '%s'", argv[optind - 1]);
             return;
         }
     }
-    
-    if (optind >= argc) {
-       rrd_set_error("missing filename");
-       return;
-    }
 
-    if (im->logarithmic == 1 && im->minval <= 0){
-        rrd_set_error("for a logarithmic yaxis you must specify a lower-limit > 0");        
+    if (im->logarithmic && im->minval <= 0) {
+        rrd_set_error
+            ("for a logarithmic yaxis you must specify a lower-limit > 0");
         return;
     }
 
-    if (proc_start_end(&start_tv,&end_tv,&start_tmp,&end_tmp) == -1){
+    if (proc_start_end(&start_tv, &end_tv, &start_tmp, &end_tmp) == -1) {
         /* error string is set in parsetime.c */
         return;
-    }  
-    
-    if (start_tmp < 3600*24*365*10){
-        rrd_set_error("the first entry to fetch should be after 1980 (%ld)",start_tmp);
+    }
+
+    if (start_tmp < 3600 * 24 * 365 * 10) {
+        rrd_set_error
+            ("the first entry to fetch should be after 1980 (%ld)",
+             start_tmp);
         return;
     }
-    
+
     if (end_tmp < start_tmp) {
-        rrd_set_error("start (%ld) should be less than end (%ld)", 
-               start_tmp, end_tmp);
+        rrd_set_error
+            ("start (%ld) should be less than end (%ld)", start_tmp, end_tmp);
         return;
     }
-    
+
     im->start = start_tmp;
     im->end = end_tmp;
-    im->step = max((long)im->step, (im->end-im->start)/im->xsize);
+    im->step = max((long) im->step, (im->end - im->start) / im->xsize);
 }
 
-int
-rrd_graph_color(image_desc_t *im, char *var, char *err, int optional)
+int rrd_graph_color(
+    image_desc_t
+    *im,
+    char *var,
+    char *err,
+    int optional)
 {
-    char *color;
-    graph_desc_t *gdp=&im->gdes[im->gdes_c-1];
+    char     *color;
+    graph_desc_t *gdp = &im->gdes[im->gdes_c - 1];
 
-    color=strstr(var,"#");
-    if (color==NULL) {
-        if (optional==0) {
-            rrd_set_error("Found no color in %s",err);
+    color = strstr(var, "#");
+    if (color == NULL) {
+        if (optional == 0) {
+            rrd_set_error("Found no color in %s", err);
             return 0;
         }
         return 0;
     } else {
-        int n=0;
-        char *rest;
-        gfx_color_t    col;
+        int       n = 0;
+        char     *rest;
+        long unsigned int col;
 
-        rest=strstr(color,":");
-        if (rest!=NULL)
-            n=rest-color;
+        rest = strstr(color, ":");
+        if (rest != NULL)
+            n = rest - color;
         else
-            n=strlen(color);
-
+            n = strlen(color);
         switch (n) {
-            case 7:
-                sscanf(color,"#%6lx%n",&col,&n);
-                col = (col << 8) + 0xff /* shift left by 8 */;
-                if (n!=7) rrd_set_error("Color problem in %s",err);
+        case 7:
+            sscanf(color, "#%6lx%n", &col, &n);
+            col = (col << 8) + 0xff /* shift left by 8 */ ;
+            if (n != 7)
+                rrd_set_error("Color problem in %s", err);
+            break;
+        case 9:
+            sscanf(color, "#%8lx%n", &col, &n);
+            if (n == 9)
                 break;
-            case 9:
-                sscanf(color,"#%8lx%n",&col,&n);
-                if (n==9) break;
-            default:
-                rrd_set_error("Color problem in %s",err);
+        default:
+            rrd_set_error("Color problem in %s", err);
         }
-        if (rrd_test_error()) return 0;
-        gdp->col = col;
+        if (rrd_test_error())
+            return 0;
+        gdp->col = gfx_hex_to_col(col);
         return n;
     }
 }
 
 
-int bad_format(char *fmt) {
-    char *ptr;
-    int n=0;
+int bad_format(
+    char *fmt)
+{
+    char     *ptr;
+    int       n = 0;
+
     ptr = fmt;
     while (*ptr != '\0')
         if (*ptr++ == '%') {
-             /* line cannot end with percent char */
-             if (*ptr == '\0') return 1;
-             /* '%s', '%S' and '%%' are allowed */
-             if (*ptr == 's' || *ptr == 'S' || *ptr == '%') ptr++;
-
-             /* %c is allowed (but use only with vdef!) */
-             else if (*ptr == 'c') {
+
+            /* line cannot end with percent char */
+            if (*ptr == '\0')
+                return 1;
+            /* '%s', '%S' and '%%' are allowed */
+            if (*ptr == 's' || *ptr == 'S' || *ptr == '%')
+                ptr++;
+            /* %c is allowed (but use only with vdef!) */
+            else if (*ptr == 'c') {
                 ptr++;
-                n=1;
-             }
-
-             /* or else '% 6.2lf' and such are allowed */
-             else {
-                 /* optional padding character */
-                 if (*ptr == ' ' || *ptr == '+' || *ptr == '-') ptr++;
-
-                 /* This should take care of 'm.n' with all three optional */
-                 while (*ptr >= '0' && *ptr <= '9') ptr++;
-                 if (*ptr == '.') ptr++;
-                 while (*ptr >= '0' && *ptr <= '9') ptr++;
-  
-                 /* Either 'le', 'lf' or 'lg' must follow here */
-                 if (*ptr++ != 'l') return 1;
-                 if (*ptr == 'e' || *ptr == 'f' || *ptr == 'g') ptr++;
-                 else return 1;
-                 n++;
-            }
-         }
-      
-      return (n!=1); 
+                n = 1;
+            }
+
+            /* or else '% 6.2lf' and such are allowed */
+            else {
+                /* optional padding character */
+                if (*ptr == ' ' || *ptr == '+' || *ptr == '-')
+                    ptr++;
+                /* This should take care of 'm.n' with all three optional */
+                while (*ptr >= '0' && *ptr <= '9')
+                    ptr++;
+                if (*ptr == '.')
+                    ptr++;
+                while (*ptr >= '0' && *ptr <= '9')
+                    ptr++;
+                /* Either 'le', 'lf' or 'lg' must follow here */
+                if (*ptr++ != 'l')
+                    return 1;
+                if (*ptr == 'e' || *ptr == 'f' || *ptr == 'g')
+                    ptr++;
+                else
+                    return 1;
+                n++;
+            }
+        }
+
+    return (n != 1);
 }
 
 
-int
-vdef_parse(gdes,str)
-struct graph_desc_t *gdes;
-const char *const str;
+int vdef_parse(
+    struct graph_desc_t
+    *gdes,
+    const char *const str)
 {
     /* A VDEF currently is either "func" or "param,func"
      * so the parsing is rather simple.  Change if needed.
      */
-    double        param;
-    char        func[30];
-    int                n;
-    
-    n=0;
-    sscanf(str,"%le,%29[A-Z]%n",&param,func,&n);
-    if (n== (int)strlen(str)) { /* matched */
+    double    param;
+    char      func[30];
+    int       n;
+    char     *old_locale;
+
+    n = 0;
+    old_locale = setlocale(LC_NUMERIC, "C");
+    sscanf(str, "%le,%29[A-Z]%n", &param, func, &n);
+    setlocale(LC_NUMERIC, old_locale);
+    if (n == (int) strlen(str)) {   /* matched */
         ;
     } else {
-        n=0;
-        sscanf(str,"%29[A-Z]%n",func,&n);
-        if (n== (int)strlen(str)) { /* matched */
-            param=DNAN;
+        n = 0;
+        sscanf(str, "%29[A-Z]%n", func, &n);
+        if (n == (int) strlen(str)) {   /* matched */
+            param = DNAN;
         } else {
-            rrd_set_error("Unknown function string '%s' in VDEF '%s'"
-                ,str
-                ,gdes->vname
-                );
+            rrd_set_error
+                ("Unknown function string '%s' in VDEF '%s'",
+                 str, gdes->vname);
             return -1;
         }
     }
-    if                (!strcmp("PERCENT",func)) gdes->vf.op = VDEF_PERCENT;
-    else if        (!strcmp("MAXIMUM",func)) gdes->vf.op = VDEF_MAXIMUM;
-    else if        (!strcmp("AVERAGE",func)) gdes->vf.op = VDEF_AVERAGE;
-    else if        (!strcmp("MINIMUM",func)) gdes->vf.op = VDEF_MINIMUM;
-    else if        (!strcmp("TOTAL",  func)) gdes->vf.op = VDEF_TOTAL;
-    else if        (!strcmp("FIRST",  func)) gdes->vf.op = VDEF_FIRST;
-    else if        (!strcmp("LAST",   func)) gdes->vf.op = VDEF_LAST;
-    else if     (!strcmp("LSLSLOPE", func)) gdes->vf.op = VDEF_LSLSLOPE;
-    else if     (!strcmp("LSLINT",   func)) gdes->vf.op = VDEF_LSLINT;
-    else if     (!strcmp("LSLCORREL",func)) gdes->vf.op = VDEF_LSLCORREL;
+    if (!strcmp("PERCENT", func))
+        gdes->vf.op = VDEF_PERCENT;
+    else if (!strcmp("MAXIMUM", func))
+        gdes->vf.op = VDEF_MAXIMUM;
+    else if (!strcmp("AVERAGE", func))
+        gdes->vf.op = VDEF_AVERAGE;
+    else if (!strcmp("STDEV", func))
+        gdes->vf.op = VDEF_STDEV;
+    else if (!strcmp("MINIMUM", func))
+        gdes->vf.op = VDEF_MINIMUM;
+    else if (!strcmp("TOTAL", func))
+        gdes->vf.op = VDEF_TOTAL;
+    else if (!strcmp("FIRST", func))
+        gdes->vf.op = VDEF_FIRST;
+    else if (!strcmp("LAST", func))
+        gdes->vf.op = VDEF_LAST;
+    else if (!strcmp("LSLSLOPE", func))
+        gdes->vf.op = VDEF_LSLSLOPE;
+    else if (!strcmp("LSLINT", func))
+        gdes->vf.op = VDEF_LSLINT;
+    else if (!strcmp("LSLCORREL", func))
+        gdes->vf.op = VDEF_LSLCORREL;
     else {
-        rrd_set_error("Unknown function '%s' in VDEF '%s'\n"
-            ,func
-            ,gdes->vname
-            );
+        rrd_set_error
+            ("Unknown function '%s' in VDEF '%s'\n", func, gdes->vname);
         return -1;
     };
-
     switch (gdes->vf.op) {
-        case VDEF_PERCENT:
-            if (isnan(param)) { /* no parameter given */
-                rrd_set_error("Function '%s' needs parameter in VDEF '%s'\n"
-                    ,func
-                    ,gdes->vname
-                    );
-                return -1;
-            };
-            if (param>=0.0 && param<=100.0) {
-                gdes->vf.param = param;
-                gdes->vf.val   = DNAN;        /* undefined */
-                gdes->vf.when  = 0;        /* undefined */
-            } else {
-                rrd_set_error("Parameter '%f' out of range in VDEF '%s'\n"
-                    ,param
-                    ,gdes->vname
-                    );
-                return -1;
-            };
-            break;
-        case VDEF_MAXIMUM:
-        case VDEF_AVERAGE:
-        case VDEF_MINIMUM:
-        case VDEF_TOTAL:
-        case VDEF_FIRST:
-        case VDEF_LAST:
-        case VDEF_LSLSLOPE:
-        case VDEF_LSLINT:
-        case VDEF_LSLCORREL:
-            if (isnan(param)) {
-                gdes->vf.param = DNAN;
-                gdes->vf.val   = DNAN;
-                gdes->vf.when  = 0;
-            } else {
-                rrd_set_error("Function '%s' needs no parameter in VDEF '%s'\n"
-                    ,func
-                    ,gdes->vname
-                    );
-                return -1;
-            };
-            break;
+    case VDEF_PERCENT:
+        if (isnan(param)) { /* no parameter given */
+            rrd_set_error
+                ("Function '%s' needs parameter in VDEF '%s'\n",
+                 func, gdes->vname);
+            return -1;
+        };
+        if (param >= 0.0 && param <= 100.0) {
+            gdes->vf.param = param;
+            gdes->vf.val = DNAN;    /* undefined */
+            gdes->vf.when = 0;  /* undefined */
+        } else {
+            rrd_set_error
+                ("Parameter '%f' out of range in VDEF '%s'\n",
+                 param, gdes->vname);
+            return -1;
+        };
+        break;
+    case VDEF_MAXIMUM:
+    case VDEF_AVERAGE:
+    case VDEF_STDEV:
+    case VDEF_MINIMUM:
+    case VDEF_TOTAL:
+    case VDEF_FIRST:
+    case VDEF_LAST:
+    case VDEF_LSLSLOPE:
+    case VDEF_LSLINT:
+    case VDEF_LSLCORREL:
+        if (isnan(param)) {
+            gdes->vf.param = DNAN;
+            gdes->vf.val = DNAN;
+            gdes->vf.when = 0;
+        } else {
+            rrd_set_error
+                ("Function '%s' needs no parameter in VDEF '%s'\n",
+                 func, gdes->vname);
+            return -1;
+        };
+        break;
     };
     return 0;
 }
 
 
-int
-vdef_calc(im,gdi)
-image_desc_t *im;
-int gdi;
+int vdef_calc(
+    image_desc_t *im,
+    int gdi)
 {
-    graph_desc_t        *src,*dst;
-    rrd_value_t                *data;
-    long                step,steps;
+    graph_desc_t *src, *dst;
+    rrd_value_t *data;
+    long      step, steps;
 
     dst = &im->gdes[gdi];
     src = &im->gdes[dst->vidx];
     data = src->data + src->ds;
     steps = (src->end - src->start) / src->step;
-
 #if 0
-printf("DEBUG: start == %lu, end == %lu, %lu steps\n"
-    ,src->start
-    ,src->end
-    ,steps
-    );
+    printf
+        ("DEBUG: start == %lu, end == %lu, %lu steps\n",
+         src->start, src->end, steps);
 #endif
-
     switch (dst->vf.op) {
-        case VDEF_PERCENT: {
-                rrd_value_t *        array;
-                int                field;
-
-
-                if ((array = malloc(steps*sizeof(double)))==NULL) {
-                    rrd_set_error("malloc VDEV_PERCENT");
-                    return -1;
-                }
-                for (step=0;step < steps; step++) {
-                    array[step]=data[step*src->ds_cnt];
-                }
-                qsort(array,step,sizeof(double),vdef_percent_compar);
-
-                field = (steps-1)*dst->vf.param/100;
-                dst->vf.val  = array[field];
-                dst->vf.when = 0;        /* no time component */
-                free(array);
+    case VDEF_PERCENT:{
+        rrd_value_t *array;
+        int       field;
+        if ((array = malloc(steps * sizeof(double))) == NULL) {
+            rrd_set_error("malloc VDEV_PERCENT");
+            return -1;
+        }
+        for (step = 0; step < steps; step++) {
+            array[step] = data[step * src->ds_cnt];
+        }
+        qsort(array, step, sizeof(double), vdef_percent_compar);
+        field = (steps - 1) * dst->vf.param / 100;
+        dst->vf.val = array[field];
+        dst->vf.when = 0;   /* no time component */
+        free(array);
 #if 0
-for(step=0;step<steps;step++)
-printf("DEBUG: %3li:%10.2f %c\n",step,array[step],step==field?'*':' ');
+        for (step = 0; step < steps; step++)
+            printf("DEBUG: %3li:%10.2f %c\n",
+                   step, array[step], step == field ? '*' : ' ');
 #endif
-            }
-            break;
-        case VDEF_MAXIMUM:
-            step=0;
-            while (step != steps && isnan(data[step*src->ds_cnt])) step++;
-            if (step == steps) {
-                dst->vf.val  = DNAN;
-                dst->vf.when = 0;
-            } else {
-                dst->vf.val  = data[step*src->ds_cnt];
-                dst->vf.when = src->start + (step+1)*src->step;
-            }
-            while (step != steps) {
-                if (finite(data[step*src->ds_cnt])) {
-                    if (data[step*src->ds_cnt] > dst->vf.val) {
-                        dst->vf.val  = data[step*src->ds_cnt];
-                        dst->vf.when = src->start + (step+1)*src->step;
-                    }
+    }
+        break;
+    case VDEF_MAXIMUM:
+        step = 0;
+        while (step != steps && isnan(data[step * src->ds_cnt]))
+            step++;
+        if (step == steps) {
+            dst->vf.val = DNAN;
+            dst->vf.when = 0;
+        } else {
+            dst->vf.val = data[step * src->ds_cnt];
+            dst->vf.when = src->start + (step + 1) * src->step;
+        }
+        while (step != steps) {
+            if (finite(data[step * src->ds_cnt])) {
+                if (data[step * src->ds_cnt] > dst->vf.val) {
+                    dst->vf.val = data[step * src->ds_cnt];
+                    dst->vf.when = src->start + (step + 1) * src->step;
                 }
-                step++;
-            }
-            break;
-        case VDEF_TOTAL:
-        case VDEF_AVERAGE: {
-            int cnt=0;
-            double sum=0.0;
-            for (step=0;step<steps;step++) {
-                if (finite(data[step*src->ds_cnt])) {
-                    sum += data[step*src->ds_cnt];
-                    cnt ++;
-                };
-            }
-            if (cnt) {
-                if (dst->vf.op == VDEF_TOTAL) {
-                    dst->vf.val  = sum*src->step;
-                    dst->vf.when = 0;        /* no time component */
-                } else {
-                    dst->vf.val = sum/cnt;
-                    dst->vf.when = 0;        /* no time component */
-                };
-            } else {
-                dst->vf.val  = DNAN;
-                dst->vf.when = 0;
-            }
             }
-            break;
-        case VDEF_MINIMUM:
-            step=0;
-            while (step != steps && isnan(data[step*src->ds_cnt])) step++;
-            if (step == steps) {
-                dst->vf.val  = DNAN;
-                dst->vf.when = 0;
+            step++;
+        }
+        break;
+    case VDEF_TOTAL:
+    case VDEF_STDEV:
+    case VDEF_AVERAGE:{
+        int       cnt = 0;
+        double    sum = 0.0;
+        double    average = 0.0;
+
+        for (step = 0; step < steps; step++) {
+            if (finite(data[step * src->ds_cnt])) {
+                sum += data[step * src->ds_cnt];
+                cnt++;
+            };
+        }
+        if (cnt) {
+            if (dst->vf.op == VDEF_TOTAL) {
+                dst->vf.val = sum * src->step;
+                dst->vf.when = 0;   /* no time component */
+            } else if (dst->vf.op == VDEF_AVERAGE) {
+                dst->vf.val = sum / cnt;
+                dst->vf.when = 0;   /* no time component */
             } else {
-                dst->vf.val  = data[step*src->ds_cnt];
-                dst->vf.when = src->start + (step+1)*src->step;
-            }
-            while (step != steps) {
-                if (finite(data[step*src->ds_cnt])) {
-                    if (data[step*src->ds_cnt] < dst->vf.val) {
-                        dst->vf.val  = data[step*src->ds_cnt];
-                        dst->vf.when = src->start + (step+1)*src->step;
-                    }
+                average = sum / cnt;
+                sum = 0.0;
+                for (step = 0; step < steps; step++) {
+                    if (finite(data[step * src->ds_cnt])) {
+                        sum += pow((data[step * src->ds_cnt] - average), 2.0);
+                    };
+                }
+                dst->vf.val = pow(sum / cnt, 0.5);
+                dst->vf.when = 0;   /* no time component */
+            };
+        } else {
+            dst->vf.val = DNAN;
+            dst->vf.when = 0;
+        }
+    }
+        break;
+    case VDEF_MINIMUM:
+        step = 0;
+        while (step != steps && isnan(data[step * src->ds_cnt]))
+            step++;
+        if (step == steps) {
+            dst->vf.val = DNAN;
+            dst->vf.when = 0;
+        } else {
+            dst->vf.val = data[step * src->ds_cnt];
+            dst->vf.when = src->start + (step + 1) * src->step;
+        }
+        while (step != steps) {
+            if (finite(data[step * src->ds_cnt])) {
+                if (data[step * src->ds_cnt] < dst->vf.val) {
+                    dst->vf.val = data[step * src->ds_cnt];
+                    dst->vf.when = src->start + (step + 1) * src->step;
                 }
-                step++;
             }
-            break;
-        case VDEF_FIRST:
-            /* The time value returned here is one step before the
-             * actual time value.  This is the start of the first
-             * non-NaN interval.
-             */
-            step=0;
-            while (step != steps && isnan(data[step*src->ds_cnt])) step++;
-            if (step == steps) { /* all entries were NaN */
-                dst->vf.val  = DNAN;
+            step++;
+        }
+        break;
+    case VDEF_FIRST:
+        /* The time value returned here is one step before the
+         * actual time value.  This is the start of the first
+         * non-NaN interval.
+         */
+        step = 0;
+        while (step != steps && isnan(data[step * src->ds_cnt]))
+            step++;
+        if (step == steps) {    /* all entries were NaN */
+            dst->vf.val = DNAN;
+            dst->vf.when = 0;
+        } else {
+            dst->vf.val = data[step * src->ds_cnt];
+            dst->vf.when = src->start + step * src->step;
+        }
+        break;
+    case VDEF_LAST:
+        /* The time value returned here is the
+         * actual time value.  This is the end of the last
+         * non-NaN interval.
+         */
+        step = steps - 1;
+        while (step >= 0 && isnan(data[step * src->ds_cnt]))
+            step--;
+        if (step < 0) { /* all entries were NaN */
+            dst->vf.val = DNAN;
+            dst->vf.when = 0;
+        } else {
+            dst->vf.val = data[step * src->ds_cnt];
+            dst->vf.when = src->start + (step + 1) * src->step;
+        }
+        break;
+    case VDEF_LSLSLOPE:
+    case VDEF_LSLINT:
+    case VDEF_LSLCORREL:{
+        /* Bestfit line by linear least squares method */
+
+        int       cnt = 0;
+        double    SUMx, SUMy, SUMxy, SUMxx, SUMyy, slope, y_intercept, correl;
+
+        SUMx = 0;
+        SUMy = 0;
+        SUMxy = 0;
+        SUMxx = 0;
+        SUMyy = 0;
+        for (step = 0; step < steps; step++) {
+            if (finite(data[step * src->ds_cnt])) {
+                cnt++;
+                SUMx += step;
+                SUMxx += step * step;
+                SUMxy += step * data[step * src->ds_cnt];
+                SUMy += data[step * src->ds_cnt];
+                SUMyy += data[step * src->ds_cnt] * data[step * src->ds_cnt];
+            };
+        }
+
+        slope = (SUMx * SUMy - cnt * SUMxy) / (SUMx * SUMx - cnt * SUMxx);
+        y_intercept = (SUMy - slope * SUMx) / cnt;
+        correl =
+            (SUMxy -
+             (SUMx * SUMy) / cnt) /
+            sqrt((SUMxx -
+                  (SUMx * SUMx) / cnt) * (SUMyy - (SUMy * SUMy) / cnt));
+        if (cnt) {
+            if (dst->vf.op == VDEF_LSLSLOPE) {
+                dst->vf.val = slope;
                 dst->vf.when = 0;
-            } else {
-                dst->vf.val  = data[step*src->ds_cnt];
-                dst->vf.when = src->start + step*src->step;
-            }
-            break;
-        case VDEF_LAST:
-            /* The time value returned here is the
-             * actual time value.  This is the end of the last
-             * non-NaN interval.
-             */
-            step=steps-1;
-            while (step >= 0 && isnan(data[step*src->ds_cnt])) step--;
-            if (step < 0) { /* all entries were NaN */
-                dst->vf.val  = DNAN;
+            } else if (dst->vf.op == VDEF_LSLINT) {
+                dst->vf.val = y_intercept;
                 dst->vf.when = 0;
-            } else {
-                dst->vf.val  = data[step*src->ds_cnt];
-                dst->vf.when = src->start + (step+1)*src->step;
-            }
-            break;
-        case VDEF_LSLSLOPE:
-        case VDEF_LSLINT:
-        case VDEF_LSLCORREL:{
-            /* Bestfit line by linear least squares method */ 
-
-            int cnt=0;
-            double SUMx, SUMy, SUMxy, SUMxx, SUMyy, slope, y_intercept, correl ;
-            SUMx = 0; SUMy = 0; SUMxy = 0; SUMxx = 0; SUMyy = 0;
-
-            for (step=0;step<steps;step++) {
-                if (finite(data[step*src->ds_cnt])) {
-                    cnt++;
-                    SUMx  += step;
-                    SUMxx += step * step;
-                    SUMxy += step * data[step*src->ds_cnt];
-                    SUMy  += data[step*src->ds_cnt];
-                    SUMyy  += data[step*src->ds_cnt]*data[step*src->ds_cnt];
-                };
-            }
-
-            slope = ( SUMx*SUMy - cnt*SUMxy ) / ( SUMx*SUMx - cnt*SUMxx );
-            y_intercept = ( SUMy - slope*SUMx ) / cnt;
-            correl = (SUMxy - (SUMx*SUMy)/cnt) / sqrt((SUMxx - (SUMx*SUMx)/cnt)*(SUMyy - (SUMy*SUMy)/cnt));
-
-            if (cnt) {
-                    if (dst->vf.op == VDEF_LSLSLOPE) {
-                        dst->vf.val  = slope;
-                        dst->vf.when = 0;
-                    } else if (dst->vf.op == VDEF_LSLINT)  {
-                        dst->vf.val = y_intercept;
-                        dst->vf.when = 0;
-                    } else if (dst->vf.op == VDEF_LSLCORREL)  {
-                        dst->vf.val = correl;
-                        dst->vf.when = 0;
-                    };
-                
-            } else {
-                dst->vf.val  = DNAN;
+            } else if (dst->vf.op == VDEF_LSLCORREL) {
+                dst->vf.val = correl;
                 dst->vf.when = 0;
-            }
+            };
+        } else {
+            dst->vf.val = DNAN;
+            dst->vf.when = 0;
         }
+    }
         break;
     }
     return 0;
 }
 
 /* NaN < -INF < finite_values < INF */
-int
-vdef_percent_compar(a,b)
-const void *a,*b;
+int vdef_percent_compar(
+    const void
+    *a,
+    const void
+    *b)
 {
     /* Equality is not returned; this doesn't hurt except
      * (maybe) for a little performance.
      */
 
     /* First catch NaN values. They are smallest */
-    if (isnan( *(double *)a )) return -1;
-    if (isnan( *(double *)b )) return  1;
-
+    if (isnan(*(double *) a))
+        return -1;
+    if (isnan(*(double *) b))
+        return 1;
     /* NaN doesn't reach this part so INF and -INF are extremes.
      * The sign from isinf() is compatible with the sign we return
      */
-    if (isinf( *(double *)a )) return isinf( *(double *)a );
-    if (isinf( *(double *)b )) return isinf( *(double *)b );
-
+    if (isinf(*(double *) a))
+        return isinf(*(double *) a);
+    if (isinf(*(double *) b))
+        return isinf(*(double *) b);
     /* If we reach this, both values must be finite */
-    if ( *(double *)a < *(double *)b ) return -1; else return 1;
+    if (*(double *) a < *(double *) b)
+        return -1;
+    else
+        return 1;
+}
+
+void grinfo_push(
+    image_desc_t *im,
+    char *key,
+    enum info_type type,
+    infoval value)
+{
+    im->grinfo_current = info_push(im->grinfo_current, key, type, value);
+    if (im->grinfo == NULL) {
+        im->grinfo = im->grinfo_current;
+    }
 }
index e83b442aab6e0d6bb71ac1574ec858f5bd10359b..7e85cd635935d990b17fa3aeb52ab7b0e7832af8 100644 (file)
 #ifndef _RRD_GRAPH_H
 #define _RRD_GRAPH_H
 
+#define y0 cairo_y0
+#define y1 cairo_y1
+#define index cairo_index
+
+#include <cairo.h>
+#include <cairo-pdf.h>
+#include <cairo-svg.h>
+#include <cairo-ps.h>
+#include <pango/pangocairo.h>
+
 #include "rrd_tool.h"
 #include "rrd_rpncalc.h"
-#include "rrd_gfx.h"
 
-#define MAX_VNAME_LEN 255
-#define DEF_NAM_FMT "%255[-_A-Za-z0-9]"
 
-#define ALTYGRID        0x01   /* use alternative y grid algorithm */
-#define ALTAUTOSCALE    0x02   /* use alternative algorithm to find lower and upper bounds */
-#define ALTAUTOSCALE_MIN 0x04  /* use alternative algorithm to find lower bounds */
-#define ALTAUTOSCALE_MAX 0x08  /* use alternative algorithm to find upper bounds */
-#define NOLEGEND        0x10   /* use no legend */
-#define NOMINOR          0x20    /* Turn off minor gridlines */
+#define ALTYGRID        0x01   /* use alternative y grid algorithm */
+#define ALTAUTOSCALE    0x02   /* use alternative algorithm to find lower and upper bounds */
+#define ALTAUTOSCALE_MIN 0x04   /* use alternative algorithm to find lower bounds */
+#define ALTAUTOSCALE_MAX 0x08   /* use alternative algorithm to find upper bounds */
+#define NOLEGEND        0x10   /* use no legend */
+#define NOMINOR          0x20   /* Turn off minor gridlines */
 #define ONLY_GRAPH       0x40   /* use only graph */
-#define FORCE_RULES_LEGEND 0x80        /* force printing of HRULE and VRULE legend */
+#define FORCE_RULES_LEGEND 0x80 /* force printing of HRULE and VRULE legend */
+
+#define FORCE_UNITS 0x100   /* mask for all FORCE_UNITS_* flags */
+#define FORCE_UNITS_SI 0x100    /* force use of SI units in Y axis (no effect in linear graph, SI instead of E in log graph) */
 
-#define FORCE_UNITS 0x100        /* mask for all FORCE_UNITS_* flags */
-#define FORCE_UNITS_SI 0x100     /* force use of SI units in Y axis (no effect in linear graph, SI instead of E in log graph) */
+#define FULL_SIZE_MODE     0x200    /* -width and -height indicate the total size of the image */
 
-enum tmt_en {TMT_SECOND=0,TMT_MINUTE,TMT_HOUR,TMT_DAY,
-            TMT_WEEK,TMT_MONTH,TMT_YEAR};
+enum tmt_en { TMT_SECOND = 0, TMT_MINUTE, TMT_HOUR, TMT_DAY,
+    TMT_WEEK, TMT_MONTH, TMT_YEAR
+};
 
-enum grc_en {GRC_CANVAS=0,GRC_BACK,GRC_SHADEA,GRC_SHADEB,
-            GRC_GRID,GRC_MGRID,GRC_FONT,GRC_ARROW,GRC_AXIS,GRC_FRAME,__GRC_END__};
+enum grc_en { GRC_CANVAS = 0, GRC_BACK, GRC_SHADEA, GRC_SHADEB,
+    GRC_GRID, GRC_MGRID, GRC_FONT, GRC_ARROW, GRC_AXIS, GRC_FRAME, __GRC_END__
+};
 
 #define MGRIDWIDTH 0.6
 #define GRIDWIDTH  0.4
 
-enum gf_en {GF_PRINT=0,GF_GPRINT,GF_COMMENT,GF_HRULE,GF_VRULE,GF_LINE,
-           GF_AREA,GF_STACK,GF_TICK,
-           GF_DEF, GF_CDEF, GF_VDEF, GF_SHIFT,
-#ifdef WITH_PIECHART
-           GF_PART,
-#endif
-            GF_XPORT};
+enum gf_en { GF_PRINT = 0, GF_GPRINT, GF_COMMENT, GF_HRULE, GF_VRULE, GF_LINE,
+    GF_AREA, GF_STACK, GF_TICK, GF_TEXTALIGN,
+    GF_DEF, GF_CDEF, GF_VDEF, GF_SHIFT,
+    GF_XPORT
+};
+
+enum txa_en { TXA_LEFT = 0, TXA_RIGHT, TXA_CENTER, TXA_JUSTIFIED };
 
 enum vdef_op_en {
-                VDEF_MAXIMUM=0 /* like the MAX in (G)PRINT */
-               ,VDEF_MINIMUM   /* like the MIN in (G)PRINT */
-               ,VDEF_AVERAGE   /* like the AVERAGE in (G)PRINT */
-               ,VDEF_PERCENT   /* Nth percentile */
-               ,VDEF_TOTAL     /* average multiplied by time */
-               ,VDEF_FIRST     /* first non-unknown value and time */
-               ,VDEF_LAST      /* last  non-unknown value and time */
-               ,VDEF_LSLSLOPE  /* least squares line slope */
-               ,VDEF_LSLINT    /* least squares line y_intercept */
-               ,VDEF_LSLCORREL /* least squares line correlation coefficient */
-               };
-enum text_prop_en { TEXT_PROP_DEFAULT=0,   /* default settings */
-                   TEXT_PROP_TITLE,       /* properties for the title */
-                   TEXT_PROP_AXIS,        /* for the numbers next to the axis */
-                   TEXT_PROP_UNIT,        /* for the vertical unit description */
-                   TEXT_PROP_LEGEND,      /* fot the legend below the graph */
-                   TEXT_PROP_LAST };
+    VDEF_MAXIMUM = 0    /* like the MAX in (G)PRINT */
+        , VDEF_MINIMUM  /* like the MIN in (G)PRINT */
+        , VDEF_AVERAGE  /* like the AVERAGE in (G)PRINT */
+        , VDEF_STDEV    /* the standard deviation */
+        , VDEF_PERCENT  /* Nth percentile */
+        , VDEF_TOTAL    /* average multiplied by time */
+        , VDEF_FIRST    /* first non-unknown value and time */
+        , VDEF_LAST     /* last  non-unknown value and time */
+        , VDEF_LSLSLOPE /* least squares line slope */
+        , VDEF_LSLINT   /* least squares line y_intercept */
+        , VDEF_LSLCORREL    /* least squares line correlation coefficient */
+};
+enum text_prop_en { TEXT_PROP_DEFAULT = 0,  /* default settings */
+    TEXT_PROP_TITLE,    /* properties for the title */
+    TEXT_PROP_AXIS,     /* for the numbers next to the axis */
+    TEXT_PROP_UNIT,     /* for the vertical unit description */
+    TEXT_PROP_LEGEND,   /* fot the legend below the graph */
+    TEXT_PROP_LAST
+};
+
+
+enum gfx_if_en { IF_PNG = 0, IF_SVG, IF_EPS, IF_PDF };
+enum gfx_en { GFX_LINE = 0, GFX_AREA, GFX_TEXT };
+enum gfx_h_align_en { GFX_H_NULL = 0, GFX_H_LEFT, GFX_H_RIGHT, GFX_H_CENTER };
+enum gfx_v_align_en { GFX_V_NULL = 0, GFX_V_TOP, GFX_V_BOTTOM, GFX_V_CENTER };
+
+/* cairo color components */
+typedef struct gfx_color_t {
+    double    red;
+    double    green;
+    double    blue;
+    double    alpha;
+} gfx_color_t;
+
 
 typedef struct text_prop_t {
-  double       size;
-  char         font[1024];
+    double    size;
+    char      font[1024];
 } text_prop_t;
 
 
 typedef struct vdef_t {
-    enum vdef_op_en    op;
-    double             param;  /* parameter for function, if applicable */
-    double             val;    /* resulting value */
-    time_t             when;   /* timestamp, if applicable */
+    enum vdef_op_en op;
+    double    param;    /* parameter for function, if applicable */
+    double    val;      /* resulting value */
+    time_t    when;     /* timestamp, if applicable */
 } vdef_t;
 
 typedef struct xlab_t {
-    long         minsec;       /* minimum sec per pix */
-    long         length;       /* number of secs on the image */
-    enum tmt_en  gridtm;       /* grid interval in what ?*/
-    long         gridst;       /* how many whats per grid*/
-    enum tmt_en  mgridtm;      /* label interval in what ?*/
-    long         mgridst;      /* how many whats per label*/
-    enum tmt_en  labtm;        /* label interval in what ?*/
-    long         labst;        /* how many whats per label*/
-    long         precis;       /* label precision -> label placement*/
-    char         *stst;        /* strftime string*/
+    long      minsec;   /* minimum sec per pix */
+    long      length;   /* number of secs on the image */
+    enum tmt_en gridtm; /* grid interval in what ? */
+    long      gridst;   /* how many whats per grid */
+    enum tmt_en mgridtm;    /* label interval in what ? */
+    long      mgridst;  /* how many whats per label */
+    enum tmt_en labtm;  /* label interval in what ? */
+    long      labst;    /* how many whats per label */
+    long      precis;   /* label precision -> label placement */
+    char     *stst;     /* strftime string */
 } xlab_t;
 
 typedef struct ygrid_scale_t {  /* y axis grid scaling info */
-    double       gridstep;
-    int          labfact;
-    char         labfmt[64];
+    double    gridstep;
+    int       labfact;
+    char      labfmt[64];
 } ygrid_scale_t;
 
 /* sensible y label intervals ...*/
 
 typedef struct ylab_t {
-    double   grid;    /* grid spacing */
-    int      lfac[4]; /* associated label spacing*/
+    double    grid;     /* grid spacing */
+    int       lfac[4];  /* associated label spacing */
 } ylab_t;
 
-
 /* this structure describes the elements which can make up a graph.
    because they are quite diverse, not all elements will use all the
    possible parts of the structure. */
@@ -105,159 +132,327 @@ typedef struct ylab_t {
 #define FMT_LEG_LEN 2000
 #endif
 
-typedef  struct graph_desc_t {
-    enum gf_en     gf;         /* graphing function */
-    int            stack;      /* boolean */
-    int            debug;      /* boolean */
-    char           vname[MAX_VNAME_LEN+1];  /* name of the variable */
-    long           vidx;       /* gdes reference */
-    char           rrd[1024];   /* name of the rrd_file containing data */
-    char           ds_nam[DS_NAM_SIZE]; /* data source name */
-    long           ds;         /* data source number */
-    enum cf_en     cf;         /* consolidation function */
-    enum cf_en     cf_reduce;  /* consolidation function for reduce_data() */
-    gfx_color_t    col;        /* graph color */
-    char  format[FMT_LEG_LEN+5]; /* format for PRINT AND GPRINT */
-    char  legend[FMT_LEG_LEN+5]; /* legend*/
-    int            strftm;     /* should the VDEF legend be formated with strftime */
-    double         leg_x,leg_y;  /* location of legend */   
-    double         yrule;      /* value for y rule line and for VDEF */
-    time_t         xrule;      /* time for x rule line and for VDEF */
-    vdef_t         vf;         /* instruction for VDEF function */
-    rpnp_t         *rpnp;     /* instructions for CDEF function */
+typedef struct graph_desc_t {
+    enum gf_en gf;      /* graphing function */
+    int       stack;    /* boolean */
+    int       debug;    /* boolean */
+    char      vname[MAX_VNAME_LEN + 1]; /* name of the variable */
+    long      vidx;     /* gdes reference */
+    char      rrd[1024];    /* name of the rrd_file containing data */
+    char      ds_nam[DS_NAM_SIZE];  /* data source name */
+    long      ds;       /* data source number */
+    enum cf_en cf;      /* consolidation function */
+    enum cf_en cf_reduce;   /* consolidation function for reduce_data() */
+    struct gfx_color_t col; /* graph color */
+    char      format[FMT_LEG_LEN + 5];  /* format for PRINT AND GPRINT */
+    char      legend[FMT_LEG_LEN + 5];  /* legend */
+    int       strftm;   /* should the VDEF legend be formated with strftime */
+    double    leg_x, leg_y; /* location of legend */
+    double    yrule;    /* value for y rule line and for VDEF */
+    time_t    xrule;    /* time for x rule line and for VDEF */
+    vdef_t    vf;       /* instruction for VDEF function */
+    rpnp_t   *rpnp;     /* instructions for CDEF function */
 
     /* SHIFT implementation */
-    int            shidx; /* gdes reference for offset (-1 --> constant) */
-    time_t         shval; /* offset if shidx is -1 */
-    time_t         shift; /* current shift applied */
+    int       shidx;    /* gdes reference for offset (-1 --> constant) */
+    time_t    shval;    /* offset if shidx is -1 */
+    time_t    shift;    /* current shift applied */
 
     /* description of data fetched for the graph element */
-    time_t         start,end; /* timestaps for first and last data element */
-    time_t         start_orig,end_orig; /* timestaps for first and last data element */
-    unsigned long  step;      /* time between samples */
-    unsigned long  step_orig;      /* time between samples */
-    unsigned long  ds_cnt; /* how many data sources are there in the fetch */
-    long           data_first; /* first pointer to this data */
-    char           **ds_namv; /* name of datasources  in the fetch. */
-    rrd_value_t    *data; /* the raw data drawn from the rrd */
-    rrd_value_t    *p_data; /* processed data, xsize elments */
-    double         linewidth;  /* linewideth */
+    time_t    start, end;   /* timestaps for first and last data element */
+    time_t    start_orig, end_orig; /* timestaps for first and last data element */
+    unsigned long step; /* time between samples */
+    unsigned long step_orig;    /* time between samples */
+    unsigned long ds_cnt;   /* how many data sources are there in the fetch */
+    long      data_first;   /* first pointer to this data */
+    char    **ds_namv;  /* name of datasources  in the fetch. */
+    rrd_value_t *data;  /* the raw data drawn from the rrd */
+    rrd_value_t *p_data;    /* processed data, xsize elments */
+    double    linewidth;    /* linewideth */
+
+    /* dashed line stuff */
+    int       dash;     /* boolean, draw dashed line? */
+    double   *p_dashes; /* pointer do dash array which keeps the lengths of dashes */
+    int       ndash;    /* number of dash segments */
+    double    offset;   /* dash offset along the line */
+
+    enum txa_en txtalign;   /* change default alignment strategy for text */
 } graph_desc_t;
 
 typedef struct image_desc_t {
 
     /* configuration of graph */
 
-    char           graphfile[MAXPATH]; /* filename for graphic */
-    FILE         *graphhandle;        /* FILE to use if filename is "-" */
-    long           xsize,ysize;        /* graph area size in pixels */
-#ifdef WITH_PIECHART
-    long          piesize;            /* size of the piechart */
-#endif
-    gfx_color_t    graph_col[__GRC_END__]; /* real colors for the graph */   
-    text_prop_t    text_prop[TEXT_PROP_LAST]; /* text properties */
-    char           ylegend[210];   /* legend along the yaxis */
-    char           title[210];     /* title for graph */
-    char           watermark[110];   /* watermark for graph */
-    int            draw_x_grid;      /* no x-grid at all */
-    int            draw_y_grid;      /* no x-grid at all */
-    double         grid_dash_on, grid_dash_off;
-    xlab_t         xlab_user;      /* user defined labeling for xaxis */
-    char           xlab_form[210]; /* format for the label on the xaxis */
-
-    double         ygridstep;      /* user defined step for y grid */
-    int            ylabfact;       /* every how many y grid shall a label be written ? */
-    double         tabwidth;       /* tabwdith */
-    time_t         start,end;      /* what time does the graph cover */
-    unsigned long  step;           /* any preference for the default step ? */
-    rrd_value_t    minval,maxval;  /* extreme values in the data */
-    int            rigid;          /* do not expand range even with 
-                                     values outside */
-    ygrid_scale_t  ygrid_scale;    /* calculated y axis grid info */
-    int            gridfit;        /* adjust y-axis range etc so all
-                                     grindlines falls in integer pixel values */
-    char*          imginfo;        /* construct an <IMG ... tag and return 
-                                     as first retval */
-    int            lazy;           /* only update the image if there is
-                                     reasonable probablility that the
-                                     existing one is out of date */
-    int                   slopemode;      /* connect the dots of the curve directly, not using a stair */
-    int            logarithmic;    /* scale the yaxis logarithmic */
-    
+    char      graphfile[MAXPATH];   /* filename for graphic */
+    long      xsize, ysize; /* graph area size in pixels */
+    struct gfx_color_t graph_col[__GRC_END__];  /* real colors for the graph */
+    text_prop_t text_prop[TEXT_PROP_LAST];  /* text properties */
+    char      ylegend[210]; /* legend along the yaxis */
+    char      title[210];   /* title for graph */
+    char      watermark[110];   /* watermark for graph */
+    int       draw_x_grid;  /* no x-grid at all */
+    int       draw_y_grid;  /* no x-grid at all */
+    double    grid_dash_on, grid_dash_off;
+    xlab_t    xlab_user;    /* user defined labeling for xaxis */
+    char      xlab_form[210];   /* format for the label on the xaxis */
+
+    double    ygridstep;    /* user defined step for y grid */
+    int       ylabfact; /* every how many y grid shall a label be written ? */
+    double    tabwidth; /* tabwdith */
+    time_t    start, end;   /* what time does the graph cover */
+    unsigned long step; /* any preference for the default step ? */
+    rrd_value_t minval, maxval; /* extreme values in the data */
+    int       rigid;    /* do not expand range even with 
+                           values outside */
+    ygrid_scale_t ygrid_scale;  /* calculated y axis grid info */
+    int       gridfit;  /* adjust y-axis range etc so all
+                           grindlines falls in integer pixel values */
+    char     *imginfo;  /* construct an <IMG ... tag and return 
+                           as first retval */
+    enum gfx_if_en imgformat;   /* image format */
+    int       lazy;     /* only update the image if there is
+                           reasonable probablility that the
+                           existing one is out of date */
+    int       slopemode;    /* connect the dots of the curve directly, not using a stair */
+    int       logarithmic;  /* scale the yaxis logarithmic */
+    double    force_scale_min;  /* Force a scale--min */
+    double    force_scale_max;  /* Force a scale--max */
+
     /* status information */
-           
-    long           xorigin,yorigin;/* where is (0,0) of the graph */
-#ifdef WITH_PIECHART
-    long           pie_x,pie_y;    /* where is the centerpoint */
-#endif
-    long           ximg,yimg;      /* total size of the image */
-    double         magfact;        /* numerical magnitude*/
-    long         base;             /* 1000 or 1024 depending on what we graph */
-    char           symbol;         /* magnitude symbol for y-axis */
-    float          viewfactor;     /* how should the numbers on the y-axis be scaled for viewing ? */
-    int            unitsexponent;  /* 10*exponent for units on y-asis */
-    int            unitslength;    /* width of the yaxis labels */
-    int            forceleftspace; /* do not kill the space to the left of the y-axis if there is no grid */
-
-    int            extra_flags;    /* flags for boolean options */
+
+    long      xorigin, yorigin; /* where is (0,0) of the graph */
+    long      ximg, yimg;   /* total size of the image */
+    size_t    rendered_image_size;
+    double    zoom;
+    double    magfact;  /* numerical magnitude */
+    long      base;     /* 1000 or 1024 depending on what we graph */
+    char      symbol;   /* magnitude symbol for y-axis */
+    float     viewfactor;   /* how should the numbers on the y-axis be scaled for viewing ? */
+    int       unitsexponent;    /* 10*exponent for units on y-asis */
+    int       unitslength;  /* width of the yaxis labels */
+    int       forceleftspace;   /* do not kill the space to the left of the y-axis if there is no grid */
+
+    int       extra_flags;  /* flags for boolean options */
     /* data elements */
 
-    long  prt_c;                  /* number of print elements */
-    long  gdes_c;                  /* number of graphics elements */
-    graph_desc_t   *gdes;          /* points to an array of graph elements */
-    gfx_canvas_t   *canvas;        /* graphics library */
+    unsigned char *rendered_image;
+    long      prt_c;    /* number of print elements */
+    long      gdes_c;   /* number of graphics elements */
+    graph_desc_t *gdes; /* points to an array of graph elements */
+    cairo_surface_t *surface;   /* graphics library */
+    cairo_t  *cr;       /* drawin context */
+    cairo_font_options_t *font_options; /* cairo font options */
+    cairo_antialias_t graph_antialias;  /* antialiasing for the graph */
+
+    info_t   *grinfo;   /* root pointer to extra graph info */
+    info_t   *grinfo_current;   /* pointing to current entry */
 } image_desc_t;
 
 /* Prototypes */
-int xtr(image_desc_t *,time_t);
-double ytr(image_desc_t *, double);
-enum gf_en gf_conv(char *);
-enum gfx_if_en if_conv(char *);
-enum tmt_en tmt_conv(char *);
-enum grc_en grc_conv(char *);
-enum text_prop_en text_prop_conv(char *);
-int im_free(image_desc_t *);
-void auto_scale( image_desc_t *,  double *, char **, double *);
-void si_unit( image_desc_t *);
-void expand_range(image_desc_t *);
-void apply_gridfit(image_desc_t *);
-void reduce_data( enum cf_en,  unsigned long,  time_t *, time_t *,  unsigned long *,  unsigned long *,  rrd_value_t **);
-int data_fetch( image_desc_t *);
-long find_var(image_desc_t *, char *);
-long find_var_wrapper(void *arg1, char *key);
-long lcd(long *);
-int data_calc( image_desc_t *);
-int data_proc( image_desc_t *);
-time_t find_first_time( time_t,  enum tmt_en,  long);
-time_t find_next_time( time_t,  enum tmt_en,  long);
-int print_calc(image_desc_t *, char ***);
-int leg_place(image_desc_t *);
-int calc_horizontal_grid(image_desc_t *);
-int draw_horizontal_grid(image_desc_t *);
-int horizontal_log_grid(image_desc_t *);
-void vertical_grid(image_desc_t *);
-void axis_paint(image_desc_t *);
-void grid_paint(image_desc_t *);
-int lazy_check(image_desc_t *);
-int graph_paint(image_desc_t *, char ***);
-#ifdef WITH_PIECHART
-void pie_part(image_desc_t *, gfx_color_t, double, double, double, double, double);
-#endif
-int gdes_alloc(image_desc_t *);
-int scan_for_col(const char *const , int, char *const);
-int rrd_graph(int, char **, char ***, int *, int *, FILE *, double *, double *);
-void rrd_graph_init(image_desc_t *);
-void rrd_graph_options(int, char **, image_desc_t *);
-void rrd_graph_script(int, char **, image_desc_t *, int);
-int rrd_graph_color(image_desc_t *, char *, char *, int);
-int bad_format(char *);
-int vdef_parse(struct graph_desc_t *,const char *const);
-int vdef_calc(image_desc_t *, int);
-int vdef_percent_compar(const void *,const void *);
-int graph_size_location(image_desc_t *, int
-#ifdef WITH_PIECHART
- ,int
-#endif
-);
+int       xtr(
+    image_desc_t *,
+    time_t);
+double    ytr(
+    image_desc_t *,
+    double);
+enum gf_en gf_conv(
+    char *);
+enum gfx_if_en if_conv(
+    char *);
+enum tmt_en tmt_conv(
+    char *);
+enum grc_en grc_conv(
+    char *);
+enum text_prop_en text_prop_conv(
+    char *);
+int       im_free(
+    image_desc_t *);
+void      auto_scale(
+    image_desc_t *,
+    double *,
+    char **,
+    double *);
+void      si_unit(
+    image_desc_t *);
+void      expand_range(
+    image_desc_t *);
+void      apply_gridfit(
+    image_desc_t *);
+void      reduce_data(
+    enum cf_en,
+    unsigned long,
+    time_t *,
+    time_t *,
+    unsigned long *,
+    unsigned long *,
+    rrd_value_t **);
+int       data_fetch(
+    image_desc_t *);
+long      find_var(
+    image_desc_t *,
+    char *);
+long      find_var_wrapper(
+    void *arg1,
+    char *key);
+long      lcd(
+    long *);
+int       data_calc(
+    image_desc_t *);
+int       data_proc(
+    image_desc_t *);
+time_t    find_first_time(
+    time_t,
+    enum tmt_en,
+    long);
+time_t    find_next_time(
+    time_t,
+    enum tmt_en,
+    long);
+int       print_calc(
+    image_desc_t *);
+int       leg_place(
+    image_desc_t *,
+    int *);
+int       calc_horizontal_grid(
+    image_desc_t *);
+int       draw_horizontal_grid(
+    image_desc_t *);
+int       horizontal_log_grid(
+    image_desc_t *);
+void      vertical_grid(
+    image_desc_t *);
+void      axis_paint(
+    image_desc_t *);
+void      grid_paint(
+    image_desc_t *);
+int       lazy_check(
+    image_desc_t *);
+int       graph_paint(
+    image_desc_t *);
+
+int       gdes_alloc(
+    image_desc_t *);
+int       scan_for_col(
+    const char *const,
+    int,
+    char *const);
+void      rrd_graph_init(
+    image_desc_t *);
+void      rrd_graph_options(
+    int,
+    char **,
+    image_desc_t *);
+void      rrd_graph_script(
+    int,
+    char **,
+    image_desc_t *,
+    int);
+int       rrd_graph_color(
+    image_desc_t *,
+    char *,
+    char *,
+    int);
+int       bad_format(
+    char *);
+int       vdef_parse(
+    struct graph_desc_t *,
+    const char *const);
+int       vdef_calc(
+    image_desc_t *,
+    int);
+int       vdef_percent_compar(
+    const void *,
+    const void *);
+int       graph_size_location(
+    image_desc_t *,
+    int);
+
+
+/* create a new line */
+void      gfx_line(
+    image_desc_t *im,
+    double X0,
+    double Y0,
+    double X1,
+    double Y1,
+    double width,
+    gfx_color_t color);
+
+void      gfx_dashed_line(
+    image_desc_t *im,
+    double X0,
+    double Y0,
+    double X1,
+    double Y1,
+    double width,
+    gfx_color_t color,
+    double dash_on,
+    double dash_off);
+
+/* create a new area */
+void      gfx_new_area(
+    image_desc_t *im,
+    double X0,
+    double Y0,
+    double X1,
+    double Y1,
+    double X2,
+    double Y2,
+    gfx_color_t color);
+
+/* add a point to a line or to an area */
+void      gfx_add_point(
+    image_desc_t *im,
+    double x,
+    double y);
+
+/* close current path so it ends at the same point as it started */
+void      gfx_close_path(
+    image_desc_t *im);
+
+
+/* create a text node */
+void      gfx_text(
+    image_desc_t *im,
+    double x,
+    double y,
+    gfx_color_t color,
+    char *font,
+    double size,
+    double tabwidth,
+    double angle,
+    enum gfx_h_align_en h_align,
+    enum gfx_v_align_en v_align,
+    const char *text);
+
+/* measure width of a text string */
+double    gfx_get_text_width(
+    image_desc_t *im,
+    double start,
+    char *font,
+    double size,
+    double tabwidth,
+    char *text);
+
+
+/* convert color */
+gfx_color_t gfx_hex_to_col(
+    long unsigned int);
+
+void      gfx_line_fit(
+    image_desc_t *im,
+    double *x,
+    double *y);
+
+void      gfx_area_fit(
+    image_desc_t *im,
+    double *x,
+    double *y);
 
 #endif
+
+void      grinfo_push(
+    image_desc_t *im,
+    char *key,
+    enum info_type type,
+    infoval value);
index 86a2467aeeaa038583c9dbaebb42a404af12f1bf..f9c01871b514afa665da4baa8ba81a6cf5b6a76e 100644 (file)
@@ -1,5 +1,5 @@
 /****************************************************************************
- * RRDtool 1.2.27  Copyright by Tobi Oetiker, 1997-2008
+ * RRDtool 1.3rc4  Copyright by Tobi Oetiker, 1997-2008
  ****************************************************************************
  * rrd_graph_helper.c  commandline parser functions 
  *                     this code initially written by Alex van den Bogaerdt
    image_desc_t *const im    - a fixed pointer to a changing image description
 */
 
-int rrd_parse_find_gf (const char * const, unsigned int *const, graph_desc_t *const);
-int rrd_parse_legend  (const char * const, unsigned int *const, graph_desc_t *const);
-int rrd_parse_color   (const char * const, graph_desc_t *const);
-int rrd_parse_CF      (const char * const, unsigned int *const, graph_desc_t *const, enum cf_en *const);
-int rrd_parse_print   (const char * const, unsigned int *const, graph_desc_t *const, image_desc_t *const);
-int rrd_parse_shift   (const char * const, unsigned int *const, graph_desc_t *const, image_desc_t *const);
-int rrd_parse_xport   (const char * const, unsigned int *const, graph_desc_t *const, image_desc_t *const);
-int rrd_parse_PVHLAST (const char * const, unsigned int *const, graph_desc_t *const, image_desc_t *const);
-int rrd_parse_make_vname   (const char * const, unsigned int *const, graph_desc_t *const, image_desc_t *const);
-int rrd_parse_find_vname   (const char * const, unsigned int *const, graph_desc_t *const, image_desc_t *const);
-int rrd_parse_def     (const char * const, unsigned int *const, graph_desc_t *const, image_desc_t *const);
-int rrd_parse_vdef    (const char * const, unsigned int *const, graph_desc_t *const, image_desc_t *const);
-int rrd_parse_cdef    (const char * const, unsigned int *const, graph_desc_t *const, image_desc_t *const);
-
-
-
-int
-rrd_parse_find_gf(const char *const line, unsigned int *const eaten, graph_desc_t *const gdp) {
-    char funcname[11],c1=0;
-    int i=0;
+int       rrd_parse_find_gf(
+    const char *const,
+    unsigned int *const,
+    graph_desc_t *const);
+
+int       rrd_parse_legend(
+    const char *const,
+    unsigned int *const,
+    graph_desc_t *const);
+
+int       rrd_parse_color(
+    const char *const,
+    graph_desc_t *const);
+
+int       rrd_parse_textalign(
+    const char *const,
+    unsigned int *const,
+    graph_desc_t *const);
+
+
+int       rrd_parse_CF(
+    const char *const,
+    unsigned int *const,
+    graph_desc_t *const,
+    enum cf_en *const);
+
+int       rrd_parse_print(
+    const char *const,
+    unsigned int *const,
+    graph_desc_t *const,
+    image_desc_t *const);
+
+int       rrd_parse_shift(
+    const char *const,
+    unsigned int *const,
+    graph_desc_t *const,
+    image_desc_t *const);
+
+int       rrd_parse_xport(
+    const char *const,
+    unsigned int *const,
+    graph_desc_t *const,
+    image_desc_t *const);
+
+int       rrd_parse_PVHLAST(
+    const char *const,
+    unsigned int *const,
+    graph_desc_t *const,
+    image_desc_t *const);
+
+int       rrd_parse_make_vname(
+    const char *const,
+    unsigned int *const,
+    graph_desc_t *const,
+    image_desc_t *const);
+
+int       rrd_parse_find_vname(
+    const char *const,
+    unsigned int *const,
+    graph_desc_t *const,
+    image_desc_t *const);
+
+int       rrd_parse_def(
+    const char *const,
+    unsigned int *const,
+    graph_desc_t *const,
+    image_desc_t *const);
+
+int       rrd_parse_vdef(
+    const char *const,
+    unsigned int *const,
+    graph_desc_t *const,
+    image_desc_t *const);
+
+int       rrd_parse_cdef(
+    const char *const,
+    unsigned int *const,
+    graph_desc_t *const,
+    image_desc_t *const);
+
+int rrd_parse_find_gf(
+    const char *const line,
+    unsigned int *const eaten,
+    graph_desc_t *const gdp)
+{
+    char      funcname[11], c1 = 0;
+    int       i = 0;
 
     /* start an argument with DEBUG to be able to see how it is parsed */
     sscanf(&line[*eaten], "DEBUG%n", &i);
     if (i) {
-       gdp->debug=1;
-       (*eaten)+=i;
-       i=0;
-       dprintf("Scanning line '%s'\n",&line[*eaten]);
+        gdp->debug = 1;
+        (*eaten) += i;
+        i = 0;
+        dprintf("Scanning line '%s'\n", &line[*eaten]);
     }
-    i=0;c1='\0';
+    i = 0;
+    c1 = '\0';
     sscanf(&line[*eaten], "%10[A-Z]%n%c", funcname, &i, &c1);
     if (!i) {
-       rrd_set_error("Could not make sense out of '%s'",line);
-       return 1;
+        rrd_set_error("Could not make sense out of '%s'", line);
+        return 1;
     }
-    (*eaten)+=i;
-    if ((int)(gdp->gf=gf_conv(funcname)) == -1) {
-       rrd_set_error("'%s' is not a valid function name", funcname);
-       return 1;
+    (*eaten) += i;
+    if ((int) (gdp->gf = gf_conv(funcname)) == -1) {
+        rrd_set_error("'%s' is not a valid function name", funcname);
+        return 1;
     } else {
-       dprintf("- found function name '%s'\n",funcname);
+        dprintf("- found function name '%s'\n", funcname);
     }
 
     if (c1 == '\0') {
-       rrd_set_error("Function %s needs parameters.  Line: %s\n",funcname,line);
-       return 1;
+        rrd_set_error("Function %s needs parameters.  Line: %s\n", funcname,
+                      line);
+        return 1;
     }
-    if (c1 == ':') (*eaten)++;
+    if (c1 == ':')
+        (*eaten)++;
 
     /* Some commands have a parameter before the colon
      * (currently only LINE)
      */
     switch (gdp->gf) {
-       case GF_LINE:
-           if (c1 == ':') {
-               gdp->linewidth=1;
-               dprintf("- - using default width of 1\n");
-           } else {
-               i=0;sscanf(&line[*eaten],"%lf:%n",&gdp->linewidth,&i);
-               if (!i) {
-                   rrd_set_error("Cannot parse line width '%s' in line '%s'\n",&line[*eaten],line);
-                   return 1;
-               } else {
-                   dprintf("- - scanned width %f\n",gdp->linewidth);
-                   if (isnan(gdp->linewidth)) {
-                       rrd_set_error("LINE width '%s' is not a number in line '%s'\n",&line[*eaten],line);
-                       return 1;
-                   }
-                   if (isinf(gdp->linewidth)) {
-                       rrd_set_error("LINE width '%s' is out of range in line '%s'\n",&line[*eaten],line);
-                       return 1;
-                   }
-                   if (gdp->linewidth<0) {
-                       rrd_set_error("LINE width '%s' is less than 0 in line '%s'\n",&line[*eaten],line);
-                       return 1;
-                   }
-               }
-               (*eaten)+=i;
-           }
-           break;
-       default:
-           if (c1 == ':') break;
-           rrd_set_error("Malformed '%s' command in line '%s'\n",&line[*eaten],line);
-           return 1;
+    case GF_LINE:
+        if (c1 == ':') {
+            gdp->linewidth = 1;
+            dprintf("- using default width of 1\n");
+        } else {
+            i = 0;
+            sscanf(&line[*eaten], "%lf:%n", &gdp->linewidth, &i);
+            if (!i) {
+                rrd_set_error("Cannot parse line width '%s' in line '%s'\n",
+                              &line[*eaten], line);
+                return 1;
+            } else {
+                dprintf("- scanned width %f\n", gdp->linewidth);
+                if (isnan(gdp->linewidth)) {
+                    rrd_set_error
+                        ("LINE width '%s' is not a number in line '%s'\n",
+                         &line[*eaten], line);
+                    return 1;
+                }
+                if (isinf(gdp->linewidth)) {
+                    rrd_set_error
+                        ("LINE width '%s' is out of range in line '%s'\n",
+                         &line[*eaten], line);
+                    return 1;
+                }
+                if (gdp->linewidth < 0) {
+                    rrd_set_error
+                        ("LINE width '%s' is less than 0 in line '%s'\n",
+                         &line[*eaten], line);
+                    return 1;
+                }
+            }
+            (*eaten) += i;
+        }
+        break;
+    default:
+        if (c1 == ':')
+            break;
+        rrd_set_error("Malformed '%s' command in line '%s'\n", &line[*eaten],
+                      line);
+        return 1;
     }
     if (line[*eaten] == '\0') {
-       rrd_set_error("Expected some arguments after '%s'\n",line);
-       return 1;
+        rrd_set_error("Expected some arguments after '%s'\n", line);
+        return 1;
     }
     return 0;
 }
 
-int
-rrd_parse_legend(const char *const line, unsigned int *const eaten, graph_desc_t *const gdp) {
-    int i;
+int rrd_parse_legend(
+    const char *const line,
+    unsigned int *const eaten,
+    graph_desc_t *const gdp)
+{
+    int       i;
 
-    if (line[*eaten]=='\0' || line[*eaten]==':') {
-       dprintf("- no (or: empty) legend found\n");
-       return 0;
+    if (line[*eaten] == '\0' || line[*eaten] == ':') {
+        dprintf("- no (or: empty) legend found\n");
+        return 0;
     }
 
-    i=scan_for_col(&line[*eaten],FMT_LEG_LEN,gdp->legend);
+    i = scan_for_col(&line[*eaten], FMT_LEG_LEN, gdp->legend);
 
-    (*eaten)+=i;
+    (*eaten) += i;
 
-    if (line[*eaten]!='\0' && line[*eaten]!=':') {
-       rrd_set_error("Legend too long");
-       return 1;
+    if (line[*eaten] != '\0' && line[*eaten] != ':') {
+        rrd_set_error("Legend too long");
+        return 1;
     } else {
-       return 0;
+        return 0;
     }
 }
 
-int
-rrd_parse_color(const char *const string, graph_desc_t *const gdp) {
-    unsigned int r=0,g=0,b=0,a=0,i;
+int rrd_parse_color(
+    const char *const string,
+    graph_desc_t *const gdp)
+{
+    unsigned int r = 0, g = 0, b = 0, a = 0, i;
 
     /* matches the following formats:
-    ** RGB
-    ** RGBA
-    ** RRGGBB
-    ** RRGGBBAA
-    */
-
-    i=0;
-    while (string[i] && isxdigit((unsigned int)string[i])) i++;
-    if (string[i] != '\0') return 1; /* garbage follows hexdigits */
+     ** RGB
+     ** RGBA
+     ** RRGGBB
+     ** RRGGBBAA
+     */
+
+    i = 0;
+    while (string[i] && isxdigit((unsigned int) string[i]))
+        i++;
+    if (string[i] != '\0')
+        return 1;       /* garbage follows hexdigits */
     switch (i) {
-       case 3:
-       case 4:
-           sscanf(string, "%1x%1x%1x%1x",&r,&g,&b,&a);
-           r *= 0x11;
-           g *= 0x11;
-           b *= 0x11;
-           a *= 0x11;
-           if (i==3) a=0xFF;
-           break;
-       case 6:
-       case 8:
-           sscanf(string, "%02x%02x%02x%02x",&r,&g,&b,&a);
-           if (i==6) a=0xFF;
-           break;
-       default:
-           return 1;   /* wrong number of digits */
-    }
-    gdp->col = r<<24|g<<16|b<<8|a;
+    case 3:
+    case 4:
+        sscanf(string, "%1x%1x%1x%1x", &r, &g, &b, &a);
+        r *= 0x11;
+        g *= 0x11;
+        b *= 0x11;
+        a *= 0x11;
+        if (i == 3)
+            a = 0xFF;
+        break;
+    case 6:
+    case 8:
+        sscanf(string, "%02x%02x%02x%02x", &r, &g, &b, &a);
+        if (i == 6)
+            a = 0xFF;
+        break;
+    default:
+        return 1;       /* wrong number of digits */
+    }
+    gdp->col = gfx_hex_to_col(r << 24 | g << 16 | b << 8 | a);
     return 0;
 }
 
-int
-rrd_parse_CF(const char *const line, unsigned int *const eaten, graph_desc_t *const gdp, enum cf_en *cf) {
-    char               symname[CF_NAM_SIZE];
-    int                        i=0;
-
-    sscanf(&line[*eaten], CF_NAM_FMT "%n", symname,&i);
-    if ((!i)||((line[(*eaten)+i]!='\0')&&(line[(*eaten)+i]!=':'))) {
-       rrd_set_error("Cannot parse CF in '%s'",line);
-       return 1;
+int rrd_parse_CF(
+    const char *const line,
+    unsigned int *const eaten,
+    graph_desc_t *const gdp,
+    enum cf_en *cf)
+{
+    char      symname[CF_NAM_SIZE];
+    int       i = 0;
+
+    sscanf(&line[*eaten], CF_NAM_FMT "%n", symname, &i);
+    if ((!i) || ((line[(*eaten) + i] != '\0') && (line[(*eaten) + i] != ':'))) {
+        rrd_set_error("Cannot parse CF in '%s'", line);
+        return 1;
     }
-    (*eaten)+=i;
-    dprintf("- using CF '%s'\n",symname);
+    (*eaten) += i;
+    dprintf("- using CF '%s'\n", symname);
 
-    if ((int)(*cf = cf_conv(symname))==-1) {
-       rrd_set_error("Unknown CF '%s' in '%s'",symname,line);
-       return 1;
+    if ((int) (*cf = cf_conv(symname)) == -1) {
+        rrd_set_error("Unknown CF '%s' in '%s'", symname, line);
+        return 1;
     }
 
-    if (line[*eaten]!='\0') (*eaten)++;
+    if (line[*eaten] != '\0')
+        (*eaten)++;
     return 0;
 }
 
@@ -227,142 +321,201 @@ rrd_parse_CF(const char *const line, unsigned int *const eaten, graph_desc_t *co
  *
  * *eaten is incremented only when a vname is found.
  */
-int
-rrd_parse_find_vname(const char *const line, unsigned int *const eaten, graph_desc_t *const gdp, image_desc_t *const im) {
-    char tmpstr[MAX_VNAME_LEN+1];
-    int i;
-    long vidx;
-
-    i=0;sscanf(&line[*eaten], DEF_NAM_FMT "%n", tmpstr,&i);
+int rrd_parse_find_vname(
+    const char *const line,
+    unsigned int *const eaten,
+    graph_desc_t *const gdp,
+    image_desc_t *const im)
+{
+    char      tmpstr[MAX_VNAME_LEN + 1];
+    int       i;
+    long      vidx;
+
+    i = 0;
+    sscanf(&line[*eaten], DEF_NAM_FMT "%n", tmpstr, &i);
     if (!i) {
-       rrd_set_error("Could not parse line '%s'",line);
-       return -1;
+        rrd_set_error("Could not parse line '%s'", line);
+        return -1;
     }
-    if (line[*eaten+i]!=':' && line[*eaten+i]!='\0') {
-       rrd_set_error("Could not parse line '%s'",line);
-       return -1;
+    if (line[*eaten + i] != ':' && line[*eaten + i] != '\0') {
+        rrd_set_error("Could not parse line '%s'", line);
+        return -1;
     }
-    dprintf("- Considering '%s'\n",tmpstr);
+    dprintf("- Considering '%s'\n", tmpstr);
 
-    if ((vidx=find_var(im,tmpstr))<0) {
-       dprintf("- Not a vname\n");
-       rrd_set_error("Not a valid vname: %s in line %s",tmpstr,line);
-       return -1;
+    if ((vidx = find_var(im, tmpstr)) < 0) {
+        dprintf("- Not a vname\n");
+        rrd_set_error("Not a valid vname: %s in line %s", tmpstr, line);
+        return -1;
     }
-    dprintf("- Found vname '%s' vidx '%li'\n",tmpstr,gdp->vidx);
-    if (line[*eaten+i]==':') i++;
-    (*eaten)+=i;
+    dprintf("- Found vname '%s' vidx '%li'\n", tmpstr, gdp->vidx);
+    if (line[*eaten + i] == ':')
+        i++;
+    (*eaten) += i;
     return vidx;
 }
 
 /* Parsing old-style xPRINT and new-style xPRINT */
-int
-rrd_parse_print(const char *const line, unsigned int *const eaten, graph_desc_t *const gdp, image_desc_t *const im) {
+int rrd_parse_print(
+    const char *const line,
+    unsigned int *const eaten,
+    graph_desc_t *const gdp,
+    image_desc_t *const im)
+{
     /* vname:CF:format in case of DEF-based vname
-    ** vname:CF:format in case of CDEF-based vname
-    ** vname:format[:strftime] in case of VDEF-based vname
-    */
-    if ((gdp->vidx=rrd_parse_find_vname(line,eaten,gdp,im))<0) return 1;
+     ** vname:CF:format in case of CDEF-based vname
+     ** vname:format[:strftime] in case of VDEF-based vname
+     */
+    if ((gdp->vidx = rrd_parse_find_vname(line, eaten, gdp, im)) < 0)
+        return 1;
+
     switch (im->gdes[gdp->vidx].gf) {
-       case GF_DEF:
-       case GF_CDEF:
-           dprintf("- vname is of type DEF or CDEF, looking for CF\n");
-           if (rrd_parse_CF(line,eaten,gdp,&gdp->cf)) return 1;
-           break;
-       case GF_VDEF:
-           dprintf("- vname is of type VDEF\n");
-           break;
-       default:
-           rrd_set_error("Encountered unknown type variable '%s'",im->gdes[gdp->vidx].vname);
-           return 1;
-    }
-
-    if (rrd_parse_legend(line,eaten,gdp)) return 1;
+    case GF_DEF:
+    case GF_CDEF:
+        dprintf("- vname is of type DEF or CDEF, looking for CF\n");
+        if (rrd_parse_CF(line, eaten, gdp, &gdp->cf))
+            return 1;
+        break;
+    case GF_VDEF:
+        dprintf("- vname is of type VDEF\n");
+        break;
+    default:
+        rrd_set_error("Encountered unknown type variable '%s'",
+                      im->gdes[gdp->vidx].vname);
+        return 1;
+    }
+
+    if (rrd_parse_legend(line, eaten, gdp))
+        return 1;
     /* for *PRINT the legend itself gets rendered later. We only
        get the format at this juncture */
-    strcpy(gdp->format,gdp->legend);
-    gdp->legend[0]='\0';       
+    strcpy(gdp->format, gdp->legend);
+    gdp->legend[0] = '\0';
     /* this is a very crud test, parsing :style flags should be in a function */
-    if (im->gdes[gdp->vidx].gf == GF_VDEF && strcmp(line+(*eaten),":strftime")==0){
-       gdp->strftm = 1;
-        (*eaten)+=strlen(":strftime");
+    if (im->gdes[gdp->vidx].gf == GF_VDEF
+        && strcmp(line + (*eaten), ":strftime") == 0) {
+        gdp->strftm = 1;
+        (*eaten) += strlen(":strftime");
     }
     return 0;
 }
 
 /* SHIFT:_def_or_cdef:_vdef_or_number_
  */
-int
-rrd_parse_shift(const char *const line, unsigned int *const eaten, graph_desc_t *const gdp, image_desc_t *const im) {
-    int i;
-    long time_tmp = 0;
-    if ((gdp->vidx=rrd_parse_find_vname(line,eaten,gdp,im))<0) return 1;
+int rrd_parse_shift(
+    const char *const line,
+    unsigned int *const eaten,
+    graph_desc_t *const gdp,
+    image_desc_t *const im)
+{
+    int       i;
+
+    if ((gdp->vidx = rrd_parse_find_vname(line, eaten, gdp, im)) < 0)
+        return 1;
 
     switch (im->gdes[gdp->vidx].gf) {
-       case GF_DEF:
-       case GF_CDEF:
-           dprintf("- vname is of type DEF or CDEF, OK\n");
-           break;
-       case GF_VDEF:
-           rrd_set_error("Cannot shift a VDEF: '%s' in line '%s'\n",im->gdes[gdp->vidx].vname,line);
-           return 1;
-       default:
-           rrd_set_error("Encountered unknown type variable '%s' in line '%s'",im->gdes[gdp->vidx].vname,line);
-           return 1;
-    }
-
-    if ((gdp->shidx=rrd_parse_find_vname(line,eaten,gdp,im))>=0) {
-       switch (im->gdes[gdp->shidx].gf) {
-           case GF_DEF:
-           case GF_CDEF:
-               rrd_set_error("Offset cannot be a (C)DEF: '%s' in line '%s'\n",im->gdes[gdp->shidx].vname,line);
-               return 1;
-           case GF_VDEF:
-               dprintf("- vname is of type VDEF, OK\n");
-               break;
-           default:
-               rrd_set_error("Encountered unknown type variable '%s' in line '%s'",im->gdes[gdp->vidx].vname,line);
-               return 1;
-       }
+    case GF_DEF:
+    case GF_CDEF:
+        dprintf("- vname is of type DEF or CDEF, OK\n");
+        break;
+    case GF_VDEF:
+        rrd_set_error("Cannot shift a VDEF: '%s' in line '%s'\n",
+                      im->gdes[gdp->vidx].vname, line);
+        return 1;
+    default:
+        rrd_set_error("Encountered unknown type variable '%s' in line '%s'",
+                      im->gdes[gdp->vidx].vname, line);
+        return 1;
+    }
+
+    if ((gdp->shidx = rrd_parse_find_vname(line, eaten, gdp, im)) >= 0) {
+        switch (im->gdes[gdp->shidx].gf) {
+        case GF_DEF:
+        case GF_CDEF:
+            rrd_set_error("Offset cannot be a (C)DEF: '%s' in line '%s'\n",
+                          im->gdes[gdp->shidx].vname, line);
+            return 1;
+        case GF_VDEF:
+            dprintf("- vname is of type VDEF, OK\n");
+            break;
+        default:
+            rrd_set_error
+                ("Encountered unknown type variable '%s' in line '%s'",
+                 im->gdes[gdp->vidx].vname, line);
+            return 1;
+        }
     } else {
-       rrd_clear_error();
-       i=0; sscanf(&line[*eaten],"%li%n",&time_tmp,&i);
-    gdp->shval = time_tmp;
-       if (i!=(int)strlen(&line[*eaten])) {
-           rrd_set_error("Not a valid offset: %s in line %s",&line[*eaten],line);
-           return 1;
-       }
-       (*eaten)+=i;
-       dprintf("- offset is number %li\n",gdp->shval);
-       gdp->shidx = -1;
+        long      time_tmp = 0;
+
+        rrd_clear_error();
+        i = 0;
+        sscanf(&line[*eaten], "%li%n", &time_tmp, &i);
+        gdp->shval = time_tmp;
+        if (i != (int) strlen(&line[*eaten])) {
+            rrd_set_error("Not a valid offset: %s in line %s", &line[*eaten],
+                          line);
+            return 1;
+        }
+        (*eaten) += i;
+        dprintf("- offset is number %li\n", gdp->shval);
+        gdp->shidx = -1;
     }
     return 0;
 }
 
 /* XPORT:_def_or_cdef[:legend]
  */
-int
-rrd_parse_xport(const char *const line, unsigned int *const eaten, graph_desc_t *const gdp, image_desc_t *const im) {
-    if ((gdp->vidx=rrd_parse_find_vname(line,eaten,gdp,im))<0) return 1;
+int rrd_parse_xport(
+    const char *const line,
+    unsigned int *const eaten,
+    graph_desc_t *const gdp,
+    image_desc_t *const im)
+{
+    if ((gdp->vidx = rrd_parse_find_vname(line, eaten, gdp, im)) < 0)
+        return 1;
 
     switch (im->gdes[gdp->vidx].gf) {
-       case GF_DEF:
-       case GF_CDEF:
-           dprintf("- vname is of type DEF or CDEF, OK\n");
-           break;
-       case GF_VDEF:
-           rrd_set_error("Cannot xport a VDEF: '%s' in line '%s'\n",im->gdes[gdp->vidx].vname,line);
-           return 1;
-       default:
-           rrd_set_error("Encountered unknown type variable '%s' in line '%s'",im->gdes[gdp->vidx].vname,line);
-           return 1;
-    }
-    dprintf("- looking for legend in '%s'\n",&line[*eaten]);
-    if (rrd_parse_legend(line,eaten,gdp)) return 1;
+    case GF_DEF:
+    case GF_CDEF:
+        dprintf("- vname is of type DEF or CDEF, OK\n");
+        break;
+    case GF_VDEF:
+        rrd_set_error("Cannot xport a VDEF: '%s' in line '%s'\n",
+                      im->gdes[gdp->vidx].vname, line);
+        return 1;
+    default:
+        rrd_set_error("Encountered unknown type variable '%s' in line '%s'",
+                      im->gdes[gdp->vidx].vname, line);
+        return 1;
+    }
+    dprintf("- looking for legend in '%s'\n", &line[*eaten]);
+    if (rrd_parse_legend(line, eaten, gdp))
+        return 1;
+    return 0;
+}
+
+int rrd_parse_textalign(
+    const char *const line,
+    unsigned int *const eaten,
+    graph_desc_t *const gdp)
+{
+    if (strcmp(&line[*eaten], "left") == 0) {
+        gdp->txtalign = TXA_LEFT;
+    } else if (strcmp(&line[*eaten], "right") == 0) {
+        gdp->txtalign = TXA_RIGHT;
+    } else if (strcmp(&line[*eaten], "justified") == 0) {
+        gdp->txtalign = TXA_JUSTIFIED;
+    } else if (strcmp(&line[*eaten], "center") == 0) {
+        gdp->txtalign = TXA_CENTER;
+    } else {
+        rrd_set_error("Unknown alignement type '%s'", &line[*eaten]);
+        return 1;
+    }
+    *eaten += strlen(&line[*eaten]);
     return 0;
 }
 
+
 /* Parsing of PART, VRULE, HRULE, LINE, AREA, STACK and TICK
 ** is done in one function.
 **
@@ -373,45 +526,60 @@ rrd_parse_xport(const char *const line, unsigned int *const eaten, graph_desc_t
 ** While this is arguable, so is entering fixed numbers
 ** with more than MAX_VNAME_LEN significant digits.
 */
-int
-rrd_parse_PVHLAST(const char *const line, unsigned int *const eaten, graph_desc_t *const gdp, image_desc_t *const im) {
-    int i,j,k;
-    int colorfound=0;
-    char tmpstr[MAX_VNAME_LEN + 10];   /* vname#RRGGBBAA\0 */
-    long time_tmp = 0;
+int rrd_parse_PVHLAST(
+    const char *const line,
+    unsigned int *const eaten,
+    graph_desc_t *const gdp,
+    image_desc_t *const im)
+{
+    int       i, j, k;
+    int       colorfound = 0;
+    char      tmpstr[MAX_VNAME_LEN + 10];   /* vname#RRGGBBAA\0 */
     static int spacecnt = 0;
 
-    if (spacecnt == 0) {        
-       float one_space = gfx_get_text_width(im->canvas, 0,
-                               im->text_prop[TEXT_PROP_LEGEND].font,
-                               im->text_prop[TEXT_PROP_LEGEND].size,
-                               im->tabwidth,"    ", 0) / 4.0;
-       float target_space = gfx_get_text_width(im->canvas, 0,
-                               im->text_prop[TEXT_PROP_LEGEND].font,
-                               im->text_prop[TEXT_PROP_LEGEND].size,
-                               im->tabwidth,"oo", 0);
-       spacecnt =  target_space / one_space;   
-        dprintf("- spacecnt: %i onespace: %f targspace: %f\n",spacecnt,one_space,target_space);
+    if (spacecnt == 0) {
+        float     one_space = gfx_get_text_width(im, 0,
+                                                 im->
+                                                 text_prop[TEXT_PROP_LEGEND].
+                                                 font,
+                                                 im->
+                                                 text_prop[TEXT_PROP_LEGEND].
+                                                 size,
+                                                 im->tabwidth, "    ") / 4.0;
+        float     target_space = gfx_get_text_width(im, 0,
+                                                    im->
+                                                    text_prop
+                                                    [TEXT_PROP_LEGEND].font,
+                                                    im->
+                                                    text_prop
+                                                    [TEXT_PROP_LEGEND].size,
+                                                    im->tabwidth, "oo");
+
+        spacecnt = target_space / one_space;
+        dprintf("- spacecnt: %i onespace: %f targspace: %f\n", spacecnt,
+                one_space, target_space);
     }
 
 
-    dprintf("- parsing '%s'\n",&line[*eaten]);
+    dprintf("- parsing '%s'\n", &line[*eaten]);
 
     /* have simpler code in the drawing section */
-    if ( gdp->gf == GF_STACK ){
-           gdp->stack=1;
+    if (gdp->gf == GF_STACK) {
+        gdp->stack = 1;
     }
 
-    i=scan_for_col(&line[*eaten],MAX_VNAME_LEN+9,tmpstr);
-    if (line[*eaten+i]!='\0' && line[*eaten+i]!=':') {
-       rrd_set_error("Cannot parse line '%s'",line);
-       return 1;
+    i = scan_for_col(&line[*eaten], MAX_VNAME_LEN + 9, tmpstr);
+    if (line[*eaten + i] != '\0' && line[*eaten + i] != ':') {
+        rrd_set_error("Cannot parse line '%s'", line);
+        return 1;
     }
 
-    j=i; while (j>0 && tmpstr[j]!='#') j--;
+    j = i;
+    while (j > 0 && tmpstr[j] != '#')
+        j--;
 
     if (j) {
-       tmpstr[j]='\0';
+        tmpstr[j] = '\0';
     }
     /* We now have:
      * tmpstr[0]    containing vname
@@ -425,302 +593,405 @@ rrd_parse_PVHLAST(const char *const line, unsigned int *const eaten, graph_desc_
      * valid type (need time for VRULE, not a float)
      * Else see if it parses as a number.
      */
-    dprintf("- examining string '%s'\n",tmpstr);
-    if ((gdp->vidx=find_var(im,tmpstr))>=0) {
-       dprintf("- found vname: '%s' vidx %li\n",tmpstr,gdp->vidx);
-       switch (gdp->gf) {
-#ifdef WITH_PIECHART
-           case GF_PART:
-#endif
-           case GF_VRULE:
-           case GF_HRULE:
-               if (im->gdes[gdp->vidx].gf != GF_VDEF) {
-                   rrd_set_error("Using vname %s of wrong type in line %s\n",im->gdes[gdp->gf].vname,line);
-                   return 1;
-               }
-               break;
-           default:;
-       }
+    dprintf("- examining string '%s'\n", tmpstr);
+    if ((gdp->vidx = find_var(im, tmpstr)) >= 0) {
+        dprintf("- found vname: '%s' vidx %li\n", tmpstr, gdp->vidx);
+        switch (gdp->gf) {
+        case GF_VRULE:
+        case GF_HRULE:
+            if (im->gdes[gdp->vidx].gf != GF_VDEF) {
+                rrd_set_error("Using vname %s of wrong type in line %s\n",
+                              im->gdes[gdp->gf].vname, line);
+                return 1;
+            }
+            break;
+        default:;
+        }
     } else {
-       dprintf("- it is not an existing vname\n");
-       switch (gdp->gf) {
-           case GF_VRULE:
-               k=0;sscanf(tmpstr,"%li%n",&time_tmp,&k);
-        gdp->xrule = time_tmp;
-               if (((j!=0)&&(k==j))||((j==0)&&(k==i))) {
-                   dprintf("- found time: %li\n",gdp->xrule);
-               } else {
-                   dprintf("- is is not a valid number: %li\n",gdp->xrule);
-                   rrd_set_error("parameter '%s' does not represent time in line %s\n",tmpstr,line);
-                   return 1;
-               }
-           default:
-               k=0;sscanf(tmpstr,"%lf%n",&gdp->yrule,&k);
-               if (((j!=0)&&(k==j))||((j==0)&&(k==i))) {
-                   dprintf("- found number: %lf\n",gdp->yrule);
-               } else {
-                   dprintf("- is is not a valid number: %lf\n",gdp->yrule);
-                   rrd_set_error("parameter '%s' does not represent a number in line %s\n",tmpstr,line);
-                   return 1;
-               }
-       }
+        long      time_tmp = 0;
+
+        dprintf("- it is not an existing vname\n");
+        switch (gdp->gf) {
+        case GF_VRULE:
+            k = 0;
+            sscanf(tmpstr, "%li%n", &time_tmp, &k);
+            gdp->xrule = time_tmp;
+            if (((j != 0) && (k == j)) || ((j == 0) && (k == i))) {
+                dprintf("- found time: %li\n", gdp->xrule);
+            } else {
+                dprintf("- is is not a valid number: %li\n", gdp->xrule);
+                rrd_set_error
+                    ("parameter '%s' does not represent time in line %s\n",
+                     tmpstr, line);
+                return 1;
+            }
+        default:
+            k = 0;
+            sscanf(tmpstr, "%lf%n", &gdp->yrule, &k);
+            if (((j != 0) && (k == j)) || ((j == 0) && (k == i))) {
+                dprintf("- found number: %lf\n", gdp->yrule);
+            } else {
+                dprintf("- is is not a valid number: %lf\n", gdp->yrule);
+                rrd_set_error
+                    ("parameter '%s' does not represent a number in line %s\n",
+                     tmpstr, line);
+                return 1;
+            }
+        }
     }
 
     if (j) {
-       j++;
-       dprintf("- examining color '%s'\n",&tmpstr[j]);
-       if (rrd_parse_color(&tmpstr[j],gdp)) {
-           rrd_set_error("Could not parse color in '%s'",&tmpstr[j]);
-           return 1;
-       }
-       dprintf("- parsed color 0x%08x\n",(unsigned int)gdp->col);
-       colorfound=1;
+        j++;
+        dprintf("- examining color '%s'\n", &tmpstr[j]);
+        if (rrd_parse_color(&tmpstr[j], gdp)) {
+            rrd_set_error("Could not parse color in '%s'", &tmpstr[j]);
+            return 1;
+        }
+        dprintf("- parsed color %0.0f,%0.0f,%0.0f,%0.0f\n", gdp->col.red,
+                gdp->col.green, gdp->col.blue, gdp->col.alpha);
+        colorfound = 1;
     } else {
-       dprintf("- no color present in '%s'\n",tmpstr);
+        dprintf("- no color present in '%s'\n", tmpstr);
     }
 
-    (*eaten) += i; /* after vname#color */
-    if (line[*eaten]!='\0') {
-       (*eaten)++;     /* after colon */
+    (*eaten) += i;      /* after vname#color */
+    if (line[*eaten] != '\0') {
+        (*eaten)++;     /* after colon */
     }
 
     if (gdp->gf == GF_TICK) {
-       dprintf("- parsing '%s'\n",&line[*eaten]);
-       dprintf("- looking for optional TICK number\n");
-       j=0;
-       sscanf(&line[*eaten],"%lf%n",&gdp->yrule,&j);
-       if (j) {
-           if (line[*eaten+j]!='\0' && line[*eaten+j]!=':') {
-               rrd_set_error("Cannot parse TICK fraction '%s'",line);
-               return 1;
-           }
-           dprintf("- found number %f\n",gdp->yrule);
-           if (gdp->yrule > 1.0 || gdp->yrule < -1.0) {
-               rrd_set_error("Tick factor should be <= 1.0");
-               return 1;
-           }
-           (*eaten)+=j;
-       } else {
+        dprintf("- parsing '%s'\n", &line[*eaten]);
+        dprintf("- looking for optional TICK number\n");
+        j = 0;
+        sscanf(&line[*eaten], "%lf%n", &gdp->yrule, &j);
+        if (j) {
+            if (line[*eaten + j] != '\0' && line[*eaten + j] != ':') {
+                rrd_set_error("Cannot parse TICK fraction '%s'", line);
+                return 1;
+            }
+            dprintf("- found number %f\n", gdp->yrule);
+            if (gdp->yrule > 1.0 || gdp->yrule < -1.0) {
+                rrd_set_error("Tick factor should be <= 1.0");
+                return 1;
+            }
+            (*eaten) += j;
+        } else {
             dprintf("- not found, defaulting to 0.1\n");
-            gdp->yrule=0.1;
-       }
-       if (line[*eaten] == '\0') {
-           dprintf("- done parsing line\n");
-           return 0;
-       } else { if (line[*eaten] == ':') {
-                   (*eaten)++;    
-                } else {
-                    rrd_set_error("Can't make sense of that TICK line");
-                  return 1;
-                 }
+            gdp->yrule = 0.1;
+        }
+        if (line[*eaten] == '\0') {
+            dprintf("- done parsing line\n");
+            return 0;
+        } else {
+            if (line[*eaten] == ':') {
+                (*eaten)++;
+            } else {
+                rrd_set_error("Can't make sense of that TICK line");
+                return 1;
+            }
         }
     }
 
-    dprintf("- parsing '%s'\n",&line[*eaten]);
+    dprintf("- parsing '%s'\n", &line[*eaten]);
 
     /* Legend is next.  A legend without a color is an error.
-    ** Stacking an item without having a legend is OK however
-    ** then an empty legend should be specified.
-    **   LINE:val#color:STACK  means legend is string "STACK"
-    **   LINE:val#color::STACK means no legend, and do STACK
-    **   LINE:val:STACK                is an error (legend but no color)
-    **   LINE:val::STACK       means no legend, and do STACK
-    */
+     ** Stacking an item without having a legend is OK however
+     ** then an empty legend should be specified.
+     **   LINE:val#color:STACK  means legend is string "STACK"
+     **   LINE:val#color::STACK means no legend, and do STACK
+     **   LINE:val:STACK        is an error (legend but no color)
+     **   LINE:val::STACK   means no legend, and do STACK
+     */
     if (colorfound) {
-       int err=0;
-        char *linecp = strdup(line);
-       dprintf("- looking for optional legend\n");
-       
-       dprintf("- examining '%s'\n",&line[*eaten]);
-       if (linecp[*eaten] != '\0' && linecp[*eaten] != ':') {
-           int spi;            
-           /* If the legend is not empty, it has to be prefixed with spacecnt ' ' characters. This then gets
-            * replaced by the color box later on. */
-           for (spi=0;spi<spacecnt && (*eaten) > 1;spi++){
-              linecp[--(*eaten)]=' ';
-           }
-       }
-
-       if (rrd_parse_legend(linecp, eaten, gdp)) err=1;
-       free(linecp);
-       if (err) return 1;
-
-       dprintf("- found legend '%s'\n", &gdp->legend[2]);
+        int       err = 0;
+        char     *linecp = strdup(line);
+
+        dprintf("- looking for optional legend\n");
+
+        dprintf("- examining '%s'\n", &line[*eaten]);
+        if (linecp[*eaten] != '\0' && linecp[*eaten] != ':') {
+            int       spi;
+
+            /* If the legend is not empty, it has to be prefixed with spacecnt ' ' characters. This then gets
+             * replaced by the color box later on. */
+            for (spi = 0; spi < spacecnt && (*eaten) > 1; spi++) {
+                linecp[--(*eaten)] = ' ';
+            }
+        }
+
+        if (rrd_parse_legend(linecp, eaten, gdp))
+            err = 1;
+        free(linecp);
+        if (err)
+            return 1;
+
+        dprintf("- found legend '%s'\n", &gdp->legend[2]);
     } else {
-       dprintf("- skipping empty legend\n");
-       if (line[*eaten] != '\0' && line[*eaten] != ':') {
-           rrd_set_error("Legend set but no color: %s",&line[*eaten]);
-           return 1;
-       }
+        dprintf("- skipping empty legend\n");
+        if (line[*eaten] != '\0' && line[*eaten] != ':') {
+            rrd_set_error("Legend set but no color: %s", &line[*eaten]);
+            return 1;
+        }
     }
-    if (line[*eaten]=='\0') {
-       dprintf("- done parsing line\n");
-       return 0;
+    if (line[*eaten] == '\0') {
+        dprintf("- done parsing line\n");
+        return 0;
     }
-    (*eaten)++;        /* after colon */
+    (*eaten)++;         /* after colon */
 
     /* PART, HRULE, VRULE and TICK cannot be stacked. */
-    if (   (gdp->gf == GF_HRULE)
-       || (gdp->gf == GF_VRULE)
-#ifdef WITH_PIECHART
-       || (gdp->gf == GF_PART)
-#endif
-       || (gdp->gf == GF_TICK)
-       ) return 0;
-
-    dprintf("- parsing '%s'\n",&line[*eaten]);
-    if (line[*eaten]!='\0') {
-       dprintf("- still more, should be STACK\n");
-       j=scan_for_col(&line[*eaten],5,tmpstr);
-       if (line[*eaten+j]!='\0' && line[*eaten+j]!=':') {
-           /* not 5 chars */
-           rrd_set_error("Garbage found where STACK expected");
-           return 1;
-       }
-       if (!strcmp("STACK",tmpstr)) {
-           dprintf("- found STACK\n");
-           gdp->stack=1;
-           (*eaten)+=j;
-       } else {
-           rrd_set_error("Garbage found where STACK expected");
-           return 1;
-       }
-    }
-    if (line[*eaten]=='\0') {
-       dprintf("- done parsing line\n");
-       return 0;
+    if ((gdp->gf != GF_HRULE)
+        && (gdp->gf != GF_VRULE)
+        && (gdp->gf != GF_TICK)) {
+
+        dprintf("- parsing '%s', looking for STACK\n", &line[*eaten]);
+        j = scan_for_col(&line[*eaten], 5, tmpstr);
+        if (!strcmp("STACK", tmpstr)) {
+            dprintf("- found STACK\n");
+            gdp->stack = 1;
+            (*eaten) += j;
+            if (line[*eaten] == ':') {
+                (*eaten) += 1;
+            } else if (line[*eaten] == '\0') {
+                dprintf("- done parsing line\n");
+                return 0;
+            } else {
+                dprintf("- found %s instead of just STACK\n", &line[*eaten]);
+                rrd_set_error("STACK expected but %s found", &line[*eaten]);
+                return 1;
+            }
+        } else
+            dprintf("- not STACKing\n");
+    }
+
+    dprintf("- still more, should be dashes[=...]\n");
+    dprintf("- parsing '%s'\n", &line[*eaten]);
+    if (line[*eaten] != '\0') {
+        /* parse dash arguments here. Possible options:
+           - dashes
+           - dashes=n_on[,n_off[,n_on,n_off]]
+           - dashes[=n_on[,n_off[,n_on,n_off]]]:dash-offset=offset
+           allowing 64 characters for definition of dash style */
+        j = scan_for_col(&line[*eaten], 64, tmpstr);
+        /* start with dashes */
+        if (strcmp(tmpstr, "dashes") == 0) {
+            /* if line was "dashes" or "dashes:dash-offset=xdashes="
+               tmpstr will be "dashes" */
+            dprintf("- found %s\n", tmpstr);
+            /* initialise all required variables we need for dashed lines
+               using default dash length of 5 pixels */
+            gdp->dash = 1;
+            gdp->p_dashes = (double *) malloc(sizeof(double));
+            gdp->p_dashes[0] = 5;
+            gdp->ndash = 1;
+            gdp->offset = 0;
+            (*eaten) += j;
+        } else if (sscanf(tmpstr, "dashes=%s", tmpstr)) {
+            /* dashes=n_on[,n_off[,n_on,n_off]] */
+            char      csv[64];
+            char     *pch;
+            float     dsh;
+            int       count = 0;
+            char     *saveptr;
+
+            strcpy(csv, tmpstr);
+
+            pch = strtok_r(tmpstr, ",", &saveptr);
+            while (pch != NULL) {
+                pch = strtok_r(NULL, ",", &saveptr);
+                count++;
+            }
+            dprintf("- %d dash value(s) found: ", count);
+            if (count > 0) {
+                gdp->dash = 1;
+                gdp->ndash = count;
+                gdp->p_dashes = (double *) malloc(sizeof(double) * count);
+                pch = strtok_r(csv, ",", &saveptr);
+                count = 0;
+                while (pch != NULL) {
+                    if (sscanf(pch, "%f", &dsh)) {
+                        gdp->p_dashes[count] = (double) dsh;
+                        dprintf("%.1f ", gdp->p_dashes[count]);
+                        count++;
+                    }
+                    pch = strtok_r(NULL, ",", &saveptr);
+                }
+                dprintf("\n");
+            } else
+                dprintf("- syntax error. No dash lengths found!\n");
+            (*eaten) += j;
+        } else
+            dprintf("- error: expected dashes[=...], found %s\n", tmpstr);
+        if (line[*eaten] == ':') {
+            (*eaten) += 1;
+        } else if (line[*eaten] == '\0') {
+            dprintf("- done parsing line\n");
+            return 0;
+        }
+        /* dashes[=n_on[,n_off[,n_on,n_off]]]:dash-offset=offset
+           allowing 16 characters for dash-offset=....
+           => 4 characters for the offset value */
+        j = scan_for_col(&line[*eaten], 16, tmpstr);
+        if (sscanf(tmpstr, "dash-offset=%lf", &gdp->offset)) {
+            dprintf("- found dash-offset=%.1f\n", gdp->offset);
+            gdp->dash = 1;
+            (*eaten) += j;
+            if (line[*eaten] == ':')
+                (*eaten) += 1;
+        }
+        if (line[*eaten] == '\0') {
+            dprintf("- done parsing line\n");
+            return 0;
+        }
+    }
+    if (line[*eaten] == '\0') {
+        dprintf("- done parsing line\n");
+        return 0;
     }
     (*eaten)++;
-    dprintf("- parsing '%s'\n",&line[*eaten]);
+    dprintf("- parsing '%s'\n", &line[*eaten]);
 
     return 0;
 }
 
-int
-rrd_parse_make_vname(const char *const line, unsigned int *const eaten, graph_desc_t *const gdp, image_desc_t *const im) {
-    char tmpstr[MAX_VNAME_LEN + 10];
-    int i=0;
+int rrd_parse_make_vname(
+    const char *const line,
+    unsigned int *const eaten,
+    graph_desc_t *const gdp,
+    image_desc_t *const im)
+{
+    char      tmpstr[MAX_VNAME_LEN + 10];
+    int       i = 0;
 
-    sscanf(&line[*eaten], DEF_NAM_FMT "=%n", tmpstr,&i);
+    sscanf(&line[*eaten], DEF_NAM_FMT "=%n", tmpstr, &i);
     if (!i) {
-       rrd_set_error("Cannot parse vname from '%s'",line);
-       return 1;
+        rrd_set_error("Cannot parse vname from '%s'", line);
+        return 1;
     }
-    dprintf("- found candidate '%s'\n",tmpstr);
+    dprintf("- found candidate '%s'\n", tmpstr);
 
-    if ((gdp->vidx=find_var(im,tmpstr))>=0) {
-       rrd_set_error("Attempting to reuse '%s'",im->gdes[gdp->vidx].vname);
-       return 1;
+    if ((gdp->vidx = find_var(im, tmpstr)) >= 0) {
+        rrd_set_error("Attempting to reuse '%s'", im->gdes[gdp->vidx].vname);
+        return 1;
     }
-    strcpy(gdp->vname,tmpstr);
-    dprintf("- created vname '%s' vidx %lu\n", gdp->vname,im->gdes_c-1);
-    (*eaten)+=i;
+    strcpy(gdp->vname, tmpstr);
+    dprintf("- created vname '%s' vidx %lu\n", gdp->vname, im->gdes_c - 1);
+    (*eaten) += i;
     return 0;
 }
 
-int
-rrd_parse_def(const char *const line, unsigned int *const eaten, graph_desc_t *const gdp, image_desc_t *const im) {
-    int                        i=0;
-    char               command[7]; /* step, start, end, reduce */
-    char               tmpstr[256];
-    struct rrd_time_value      start_tv,end_tv;
-    time_t             start_tmp=0,end_tmp=0;
-    char               *parsetime_error=NULL;
-
-    start_tv.type   = end_tv.type=ABSOLUTE_TIME;
-    start_tv.offset = end_tv.offset=0;
+int rrd_parse_def(
+    const char *const line,
+    unsigned int *const eaten,
+    graph_desc_t *const gdp,
+    image_desc_t *const im)
+{
+    int       i = 0;
+    char      command[7];   /* step, start, end, reduce */
+    char      tmpstr[256];
+    struct rrd_time_value start_tv, end_tv;
+    time_t    start_tmp = 0, end_tmp = 0;
+    char     *parsetime_error = NULL;
+
+    start_tv.type = end_tv.type = ABSOLUTE_TIME;
+    start_tv.offset = end_tv.offset = 0;
     localtime_r(&gdp->start, &start_tv.tm);
     localtime_r(&gdp->end, &end_tv.tm);
-    
-    dprintf("- parsing '%s'\n",&line[*eaten]);
-    dprintf("- from line '%s'\n",line);
 
-    if (rrd_parse_make_vname(line,eaten,gdp,im)) return 1;
-    i=scan_for_col(&line[*eaten],sizeof(gdp->rrd)-1,gdp->rrd);
-    if (line[*eaten+i]!=':') {
-       rrd_set_error("Problems reading database name");
-       return 1;
+    dprintf("- parsing '%s'\n", &line[*eaten]);
+    dprintf("- from line '%s'\n", line);
+
+    if (rrd_parse_make_vname(line, eaten, gdp, im))
+        return 1;
+    i = scan_for_col(&line[*eaten], sizeof(gdp->rrd) - 1, gdp->rrd);
+    if (line[*eaten + i] != ':') {
+        rrd_set_error("Problems reading database name");
+        return 1;
     }
-    (*eaten)+=++i;
-    dprintf("- using file '%s'\n",gdp->rrd);
+    (*eaten) += ++i;
+    dprintf("- using file '%s'\n", gdp->rrd);
 
-    i=0;
-    sscanf(&line[*eaten], DS_NAM_FMT ":%n", gdp->ds_nam,&i);
+    i = 0;
+    sscanf(&line[*eaten], DS_NAM_FMT ":%n", gdp->ds_nam, &i);
     if (!i) {
-       rrd_set_error("Cannot parse DS in '%s'",line);
-       return 1;
+        rrd_set_error("Cannot parse DS in '%s'", line);
+        return 1;
     }
-    (*eaten)+=i;
-    dprintf("- using DS '%s'\n",gdp->ds_nam);
+    (*eaten) += i;
+    dprintf("- using DS '%s'\n", gdp->ds_nam);
 
-    if (rrd_parse_CF(line,eaten,gdp,&gdp->cf)) return 1;
+    if (rrd_parse_CF(line, eaten, gdp, &gdp->cf))
+        return 1;
     gdp->cf_reduce = gdp->cf;
-    
-    if (line[*eaten]=='\0') return 0;
+
+    if (line[*eaten] == '\0')
+        return 0;
 
     while (1) {
-       dprintf("- optional parameter follows: %s\n", &line[*eaten]);
-       i=0;
-       sscanf(&line[*eaten], "%6[a-z]=%n", command, &i);
-       if (!i) {
-           rrd_set_error("Parse error in '%s'",line);
-           return 1;
-       }
-       (*eaten)+=i;
-       dprintf("- processing '%s'\n",command);
-       if (!strcmp("reduce",command)) {
-         if (rrd_parse_CF(line,eaten,gdp,&gdp->cf_reduce)) return 1;
-         if (line[*eaten] != '\0')
-             (*eaten)--;
-       } else if (!strcmp("step",command)) {
-           i=0;
-           sscanf(&line[*eaten],"%lu%n",&gdp->step,&i);
-           gdp->step_orig = gdp->step;
-           (*eaten)+=i;
-           dprintf("- using step %lu\n",gdp->step);
-       } else if (!strcmp("start",command)) {
-           i=scan_for_col(&line[*eaten],255,tmpstr);
-           (*eaten)+=i;
-           if ((parsetime_error = parsetime(tmpstr, &start_tv))) {
-               rrd_set_error( "start time: %s", parsetime_error );
-               return 1;
-           }
-           dprintf("- done parsing:  '%s'\n",&line[*eaten]);
-       } else if (!strcmp("end",command)) {
-           i=scan_for_col(&line[*eaten],255,tmpstr);
-           (*eaten)+=i;
-           if ((parsetime_error = parsetime(tmpstr, &end_tv))) {
-               rrd_set_error( "end time: %s", parsetime_error );
-               return 1;
-           }
-           dprintf("- done parsing:  '%s'\n",&line[*eaten]);
-       } else {
-           rrd_set_error("Parse error in '%s'",line);
-           return 1;
-       }
-       if (line[*eaten]=='\0') break;
-       if (line[*eaten]!=':') {
-           dprintf("- Expected to see end of string but got '%s'\n",\
-                                                        &line[*eaten]);
-           rrd_set_error("Parse error in '%s'",line);
-           return 1;
-       }
-       (*eaten)++;
-    }
-    if (proc_start_end(&start_tv,&end_tv,&start_tmp,&end_tmp) == -1){
-       /* error string is set in parsetime.c */
-       return 1;
-    }
-    if (start_tmp < 3600*24*365*10) {
-       rrd_set_error("the first entry to fetch should be "
-                       "after 1980 (%ld)",start_tmp);
-       return 1;
+        dprintf("- optional parameter follows: %s\n", &line[*eaten]);
+        i = 0;
+        sscanf(&line[*eaten], "%6[a-z]=%n", command, &i);
+        if (!i) {
+            rrd_set_error("Parse error in '%s'", line);
+            return 1;
+        }
+        (*eaten) += i;
+        dprintf("- processing '%s'\n", command);
+        if (!strcmp("reduce", command)) {
+            if (rrd_parse_CF(line, eaten, gdp, &gdp->cf_reduce))
+                return 1;
+            if (line[*eaten] != '\0')
+                (*eaten)--;
+        } else if (!strcmp("step", command)) {
+            i = 0;
+            sscanf(&line[*eaten], "%lu%n", &gdp->step, &i);
+            gdp->step_orig = gdp->step;
+            (*eaten) += i;
+            dprintf("- using step %lu\n", gdp->step);
+        } else if (!strcmp("start", command)) {
+            i = scan_for_col(&line[*eaten], 255, tmpstr);
+            (*eaten) += i;
+            if ((parsetime_error = parsetime(tmpstr, &start_tv))) {
+                rrd_set_error("start time: %s", parsetime_error);
+                return 1;
+            }
+            dprintf("- done parsing:  '%s'\n", &line[*eaten]);
+        } else if (!strcmp("end", command)) {
+            i = scan_for_col(&line[*eaten], 255, tmpstr);
+            (*eaten) += i;
+            if ((parsetime_error = parsetime(tmpstr, &end_tv))) {
+                rrd_set_error("end time: %s", parsetime_error);
+                return 1;
+            }
+            dprintf("- done parsing:  '%s'\n", &line[*eaten]);
+        } else {
+            rrd_set_error("Parse error in '%s'", line);
+            return 1;
+        }
+        if (line[*eaten] == '\0')
+            break;
+        if (line[*eaten] != ':') {
+            dprintf("- Expected to see end of string but got '%s'\n",
+                    &line[*eaten]);
+            rrd_set_error("Parse error in '%s'", line);
+            return 1;
+        }
+        (*eaten)++;
+    }
+    if (proc_start_end(&start_tv, &end_tv, &start_tmp, &end_tmp) == -1) {
+        /* error string is set in parsetime.c */
+        return 1;
+    }
+    if (start_tmp < 3600 * 24 * 365 * 10) {
+        rrd_set_error("the first entry to fetch should be "
+                      "after 1980 (%ld)", start_tmp);
+        return 1;
     }
 
     if (end_tmp < start_tmp) {
-       rrd_set_error("start (%ld) should be less than end (%ld)",
-                       start_tmp, end_tmp);
-       return 1;
+        rrd_set_error("start (%ld) should be less than end (%ld)",
+                      start_tmp, end_tmp);
+        return 1;
     }
 
     gdp->start = start_tmp;
@@ -728,142 +999,165 @@ rrd_parse_def(const char *const line, unsigned int *const eaten, graph_desc_t *c
     gdp->start_orig = start_tmp;
     gdp->end_orig = end_tmp;
 
-    dprintf("- start time %lu\n",gdp->start);
-    dprintf("- end   time %lu\n",gdp->end);
+    dprintf("- start time %lu\n", gdp->start);
+    dprintf("- end   time %lu\n", gdp->end);
 
     return 0;
 }
 
-int
-rrd_parse_vdef(const char *const line, unsigned int *const eaten, graph_desc_t *const gdp, image_desc_t *const im) {
-    char tmpstr[MAX_VNAME_LEN+1];      /* vname\0 */
-    int i=0;
+int rrd_parse_vdef(
+    const char *const line,
+    unsigned int *const eaten,
+    graph_desc_t *const gdp,
+    image_desc_t *const im)
+{
+    char      tmpstr[MAX_VNAME_LEN + 1];    /* vname\0 */
+    int       i = 0;
 
-    dprintf("- parsing '%s'\n",&line[*eaten]);
-    if (rrd_parse_make_vname(line,eaten,gdp,im)) return 1;
+    dprintf("- parsing '%s'\n", &line[*eaten]);
+    if (rrd_parse_make_vname(line, eaten, gdp, im))
+        return 1;
 
-    sscanf(&line[*eaten], DEF_NAM_FMT ",%n", tmpstr,&i);
+    sscanf(&line[*eaten], DEF_NAM_FMT ",%n", tmpstr, &i);
     if (!i) {
-       rrd_set_error("Cannot parse line '%s'",line);
-       return 1;
+        rrd_set_error("Cannot parse line '%s'", line);
+        return 1;
     }
-    if ((gdp->vidx=find_var(im,tmpstr))<0) {
-       rrd_set_error("Not a valid vname: %s in line %s",tmpstr,line);
-       return 1;
+    if ((gdp->vidx = find_var(im, tmpstr)) < 0) {
+        rrd_set_error("Not a valid vname: %s in line %s", tmpstr, line);
+        return 1;
     }
-    if (   im->gdes[gdp->vidx].gf != GF_DEF
-       && im->gdes[gdp->vidx].gf != GF_CDEF) {
-       rrd_set_error("variable '%s' not DEF nor "
-                       "CDEF in VDEF '%s'", tmpstr,gdp->vname);
-       return 1;
+    if (im->gdes[gdp->vidx].gf != GF_DEF && im->gdes[gdp->vidx].gf != GF_CDEF) {
+        rrd_set_error("variable '%s' not DEF nor "
+                      "CDEF in VDEF '%s'", tmpstr, gdp->vname);
+        return 1;
     }
-    dprintf("- found vname: '%s' vidx %li\n",tmpstr,gdp->vidx);
-    (*eaten)+=i;
+    dprintf("- found vname: '%s' vidx %li\n", tmpstr, gdp->vidx);
+    (*eaten) += i;
 
-    dprintf("- calling vdef_parse with param '%s'\n",&line[*eaten]);
-    vdef_parse(gdp,&line[*eaten]);
-    while (line[*eaten]!='\0'&&line[*eaten]!=':')
-       (*eaten)++;
+    dprintf("- calling vdef_parse with param '%s'\n", &line[*eaten]);
+    vdef_parse(gdp, &line[*eaten]);
+    while (line[*eaten] != '\0' && line[*eaten] != ':')
+        (*eaten)++;
 
     return 0;
 }
 
-int
-rrd_parse_cdef(const char *const line, unsigned int *const eaten, graph_desc_t *const gdp, image_desc_t *const im) {
-    dprintf("- parsing '%s'\n",&line[*eaten]);
-    if (rrd_parse_make_vname(line,eaten,gdp,im)) return 1;
-    if ((gdp->rpnp = rpn_parse(
-       (void *)im,
-       &line[*eaten],
-       &find_var_wrapper)
-    )==NULL) {
-       rrd_set_error("invalid rpn expression in: %s",&line[*eaten]);
-       return 1;
+int rrd_parse_cdef(
+    const char *const line,
+    unsigned int *const eaten,
+    graph_desc_t *const gdp,
+    image_desc_t *const im)
+{
+    dprintf("- parsing '%s'\n", &line[*eaten]);
+    if (rrd_parse_make_vname(line, eaten, gdp, im))
+        return 1;
+    if ((gdp->rpnp = rpn_parse((void *) im, &line[*eaten], &find_var_wrapper)
+        ) == NULL) {
+        rrd_set_error("invalid rpn expression in: %s", &line[*eaten]);
+        return 1;
     };
-    while (line[*eaten]!='\0'&&line[*eaten]!=':')
-       (*eaten)++;
+    while (line[*eaten] != '\0' && line[*eaten] != ':')
+        (*eaten)++;
     return 0;
 }
 
-void
-rrd_graph_script(int argc, char *argv[], image_desc_t *const im, int optno) {
-    int i;
+void rrd_graph_script(
+    int argc,
+    char *argv[],
+    image_desc_t *const im,
+    int optno)
+{
+    int       i;
+
     /* save state for STACK backward compat function */
-    enum gf_en     last_gf=GF_PRINT;
-    float          last_linewidth=0.0;
+    enum gf_en last_gf = GF_PRINT;
+    float     last_linewidth = 0.0;
 
-    for (i=optind+optno;i<argc;i++) {
-       graph_desc_t *gdp;
-       unsigned int eaten=0;
+    for (i = optind + optno; i < argc; i++) {
+        graph_desc_t *gdp;
+        unsigned int eaten = 0;
 
-       if (gdes_alloc(im)) return; /* the error string is already set */
-       gdp = &im->gdes[im->gdes_c-1];
+        if (gdes_alloc(im))
+            return;     /* the error string is already set */
+        gdp = &im->gdes[im->gdes_c - 1];
 #ifdef DEBUG
-       gdp->debug = 1;
+        gdp->debug = 1;
 #endif
 
-       if (rrd_parse_find_gf(argv[i],&eaten,gdp)) return;
-        
-       switch (gdp->gf) {
-           case GF_SHIFT:      /* vname:value */
-               if (rrd_parse_shift(argv[i],&eaten,gdp,im)) return;
-               break;
-           case GF_XPORT:
-               if (rrd_parse_xport(argv[i],&eaten,gdp,im)) return;
-               break;
-           case GF_PRINT:      /* vname:CF:format -or- vname:format */
-               im->prt_c++;            
-           case GF_GPRINT:     /* vname:CF:format -or- vname:format */
-               if (rrd_parse_print(argv[i],&eaten,gdp,im)) return;
-               break;
-            case GF_COMMENT:   /* text */
-               if (rrd_parse_legend(argv[i],&eaten,gdp)) return;
-               break;
-#ifdef WITH_PIECHART
-           case GF_PART:       /* value[#color[:legend]] */
-#endif
-           case GF_VRULE:      /* value#color[:legend] */
-           case GF_HRULE:      /* value#color[:legend] */
-           case GF_LINE:       /* vname-or-value[#color[:legend]][:STACK] */
-           case GF_AREA:       /* vname-or-value[#color[:legend]][:STACK] */
-           case GF_TICK:       /* vname#color[:num[:legend]] */
-               if (rrd_parse_PVHLAST(argv[i],&eaten,gdp,im))return;
-                last_gf = gdp->gf;
-                last_linewidth = gdp->linewidth;
-               break;
-           case GF_STACK:      /* vname-or-value[#color[:legend]] */           
-               if (rrd_parse_PVHLAST(argv[i],&eaten,gdp,im))return;
-                if (last_gf == GF_LINE || last_gf == GF_AREA){
-                   gdp->gf = last_gf;
-                   gdp->linewidth = last_linewidth;
-                } else {
-                   rrd_set_error("STACK must follow LINE or AREA! command:\n%s",
-                        &argv[i][eaten],argv[i]);
-                   return;
-                }
-               break;
-       /* data acquisition */
-           case GF_DEF:        /* vname=x:DS:CF:[:step=#][:start=#][:end=#] */
-               if (rrd_parse_def(argv[i],&eaten,gdp,im)) return;
-               break;
-           case GF_CDEF:       /* vname=rpn-expression */
-               if (rrd_parse_cdef(argv[i],&eaten,gdp,im)) return;
-               break;
-           case GF_VDEF:       /* vname=rpn-expression */
-               if (rrd_parse_vdef(argv[i],&eaten,gdp,im)) return;
-               break;
-       }
-       if (gdp->debug) {
-           dprintf("used %i out of %i chars\n",eaten,strlen(argv[i]));
-           dprintf("parsed line: '%s'\n",argv[i]);
-           dprintf("remaining: '%s'\n",&argv[i][eaten]);
-           if (eaten >= strlen(argv[i]))
-               dprintf("Command finished successfully\n");
-       }
-       if (eaten < strlen(argv[i])) {
-           rrd_set_error("Garbage '%s' after command:\n%s",
-                       &argv[i][eaten],argv[i]);
-           return;
-       }
+        if (rrd_parse_find_gf(argv[i], &eaten, gdp))
+            return;
+
+        switch (gdp->gf) {
+        case GF_SHIFT: /* vname:value */
+            if (rrd_parse_shift(argv[i], &eaten, gdp, im))
+                return;
+            break;
+        case GF_TEXTALIGN: /* left|right|center|justified */
+            if (rrd_parse_textalign(argv[i], &eaten, gdp))
+                return;
+            break;
+        case GF_XPORT:
+            if (rrd_parse_xport(argv[i], &eaten, gdp, im))
+                return;
+            break;
+        case GF_PRINT: /* vname:CF:format -or- vname:format */
+            im->prt_c++;
+        case GF_GPRINT:    /* vname:CF:format -or- vname:format */
+            if (rrd_parse_print(argv[i], &eaten, gdp, im))
+                return;
+            break;
+        case GF_COMMENT:   /* text */
+            if (rrd_parse_legend(argv[i], &eaten, gdp))
+                return;
+            break;
+        case GF_VRULE: /* value#color[:legend] */
+        case GF_HRULE: /* value#color[:legend] */
+        case GF_LINE:  /* vname-or-value[#color[:legend]][:STACK] */
+        case GF_AREA:  /* vname-or-value[#color[:legend]][:STACK] */
+        case GF_TICK:  /* vname#color[:num[:legend]] */
+            if (rrd_parse_PVHLAST(argv[i], &eaten, gdp, im))
+                return;
+            last_gf = gdp->gf;
+            last_linewidth = gdp->linewidth;
+            break;
+        case GF_STACK: /* vname-or-value[#color[:legend]] */
+            if (rrd_parse_PVHLAST(argv[i], &eaten, gdp, im))
+                return;
+            if (last_gf == GF_LINE || last_gf == GF_AREA) {
+                gdp->gf = last_gf;
+                gdp->linewidth = last_linewidth;
+            } else {
+                rrd_set_error("STACK must follow LINE or AREA! command:\n%s",
+                              &argv[i][eaten], argv[i]);
+                return;
+            }
+            break;
+            /* data acquisition */
+        case GF_DEF:   /* vname=x:DS:CF:[:step=#][:start=#][:end=#] */
+            if (rrd_parse_def(argv[i], &eaten, gdp, im))
+                return;
+            break;
+        case GF_CDEF:  /* vname=rpn-expression */
+            if (rrd_parse_cdef(argv[i], &eaten, gdp, im))
+                return;
+            break;
+        case GF_VDEF:  /* vname=rpn-expression */
+            if (rrd_parse_vdef(argv[i], &eaten, gdp, im))
+                return;
+            break;
+        }
+        if (gdp->debug) {
+            dprintf("used %i out of %zi chars\n", eaten, strlen(argv[i]));
+            dprintf("parsed line: '%s'\n", argv[i]);
+            dprintf("remaining: '%s'\n", &argv[i][eaten]);
+            if (eaten >= strlen(argv[i]))
+                dprintf("Command finished successfully\n");
+        }
+        if (eaten < strlen(argv[i])) {
+            rrd_set_error("I don't understand '%s' in command: '%s'.",
+                          &argv[i][eaten], argv[i]);
+            return;
+        }
     }
 }
index 43158fde321b54e8501bdcadc105cdc9172ea33d..6522949d10d6f970ddd7afb7d5d388d7acf011a3 100644 (file)
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * RRDtool 1.2.27  Copyright by Tobi Oetiker, 1997-2008
+ * RRDtool 1.3rc4  Copyright by Tobi Oetiker, 1997-2008
  *****************************************************************************
  * rrd_hw.c : Support for Holt-Winters Smoothing/ Aberrant Behavior Detection
  *****************************************************************************
 
 #include "rrd_tool.h"
 #include "rrd_hw.h"
+#include "rrd_hw_math.h"
+#include "rrd_hw_update.h"
+
+#define hw_dep_idx(rrd, rra_idx) rrd->rra_def[rra_idx].par[RRA_dependent_rra_idx].u_cnt
 
 /* #define DEBUG */
 
 /* private functions */
-unsigned long MyMod(signed long val, unsigned long mod);
-int update_hwpredict(rrd_t *rrd, unsigned long cdp_idx, unsigned long rra_idx, 
-                 unsigned long ds_idx, unsigned short CDP_scratch_idx);
-int update_seasonal(rrd_t *rrd, unsigned long cdp_idx, unsigned long rra_idx, 
-                                unsigned long ds_idx, unsigned short CDP_scratch_idx, 
-                                rrd_value_t *seasonal_coef);
-int update_devpredict(rrd_t *rrd, unsigned long cdp_idx, 
-                                 unsigned long rra_idx, unsigned long ds_idx, unsigned short CDP_scratch_idx);
-int update_devseasonal(rrd_t *rrd, unsigned long cdp_idx, unsigned long rra_idx, 
-                      unsigned long ds_idx, unsigned short CDP_scratch_idx, 
-                                  rrd_value_t *seasonal_dev);
-int update_failures(rrd_t *rrd, unsigned long cdp_idx, unsigned long rra_idx, 
-                               unsigned long ds_idx, unsigned short CDP_scratch_idx);
-
-int
-update_hwpredict(rrd_t *rrd, unsigned long cdp_idx, unsigned long rra_idx, 
-                 unsigned long ds_idx, unsigned short CDP_scratch_idx)
-{
-   rrd_value_t prediction, seasonal_coef;
-   unsigned long dependent_rra_idx, seasonal_cdp_idx;
-   unival *coefs = rrd -> cdp_prep[cdp_idx].scratch;
-   rra_def_t *current_rra = &(rrd -> rra_def[rra_idx]);
-
-   /* save coefficients from current prediction */
-   coefs[CDP_hw_last_intercept].u_val = coefs[CDP_hw_intercept].u_val;
-   coefs[CDP_hw_last_slope].u_val = coefs[CDP_hw_slope].u_val;
-   coefs[CDP_last_null_count].u_cnt = coefs[CDP_null_count].u_cnt;
-
-   /* retrieve the current seasonal coef */
-   dependent_rra_idx = current_rra -> par[RRA_dependent_rra_idx].u_cnt;
-   seasonal_cdp_idx = dependent_rra_idx*(rrd -> stat_head -> ds_cnt) + ds_idx;
-   if (dependent_rra_idx < rra_idx)
-         seasonal_coef = rrd -> cdp_prep[seasonal_cdp_idx].scratch[CDP_hw_last_seasonal].u_val;
-   else
-         seasonal_coef = rrd -> cdp_prep[seasonal_cdp_idx].scratch[CDP_hw_seasonal].u_val;
-   
-   /* compute the prediction */
-   if (isnan(coefs[CDP_hw_intercept].u_val) || isnan(coefs[CDP_hw_slope].u_val)
-      || isnan(seasonal_coef))
-   {
-     prediction = DNAN;
-      
-     /* bootstrap initialization of slope and intercept */
-     if (isnan(coefs[CDP_hw_intercept].u_val) &&
-        !isnan(coefs[CDP_scratch_idx].u_val)) 
-     {
-#ifdef DEBUG
-       fprintf(stderr,"Initialization of slope/intercept\n");
-#endif
-       coefs[CDP_hw_intercept].u_val = coefs[CDP_scratch_idx].u_val;
-       coefs[CDP_hw_last_intercept].u_val = coefs[CDP_scratch_idx].u_val;
-       /* initialize the slope to 0 */
-       coefs[CDP_hw_slope].u_val = 0.0;
-       coefs[CDP_hw_last_slope].u_val = 0.0;
-       /* initialize null count to 1 */
-       coefs[CDP_null_count].u_cnt = 1;
-       coefs[CDP_last_null_count].u_cnt = 1;
-     }
-     /* if seasonal coefficient is NA, then don't update intercept, slope */
-   } else {
-     prediction = coefs[CDP_hw_intercept].u_val + 
-       (coefs[CDP_hw_slope].u_val)*(coefs[CDP_null_count].u_cnt)
-       + seasonal_coef;
-#ifdef DEBUG
-     fprintf(stderr,"computed prediction: %f\n",prediction);
-#endif
-     if (isnan(coefs[CDP_scratch_idx].u_val))
-     {
-       /* NA value, no updates of intercept, slope;
-           * increment the null count */
-       (coefs[CDP_null_count].u_cnt)++;
-     } else {
-#ifdef DEBUG
-       fprintf(stderr,"Updating intercept, slope\n");
-#endif
-       /* update the intercept */
-       coefs[CDP_hw_intercept].u_val = (current_rra -> par[RRA_hw_alpha].u_val)*
-               (coefs[CDP_scratch_idx].u_val - seasonal_coef) +
-               (1 - current_rra -> par[RRA_hw_alpha].u_val)*(coefs[CDP_hw_intercept].u_val
-               + (coefs[CDP_hw_slope].u_val)*(coefs[CDP_null_count].u_cnt));
-       /* update the slope */
-       coefs[CDP_hw_slope].u_val = (current_rra -> par[RRA_hw_beta].u_val)*
-               (coefs[CDP_hw_intercept].u_val - coefs[CDP_hw_last_intercept].u_val) +
-               (1 - current_rra -> par[RRA_hw_beta].u_val)*(coefs[CDP_hw_slope].u_val);
-       /* reset the null count */
-       coefs[CDP_null_count].u_cnt = 1;
-     }
-   }
-
-   /* store the prediction for writing */
-   coefs[CDP_scratch_idx].u_val = prediction;
-   return 0;
-}
-
-int
-lookup_seasonal(rrd_t *rrd, unsigned long rra_idx, unsigned long rra_start,
-                               FILE *rrd_file, unsigned long offset, rrd_value_t **seasonal_coef)
-{
-   unsigned long pos_tmp;
-   /* rra_ptr[].cur_row points to the rra row to be written; this function
-       * reads cur_row + offset */
-   unsigned long row_idx = rrd -> rra_ptr[rra_idx].cur_row + offset;
-   /* handle wrap around */
-   if (row_idx >= rrd -> rra_def[rra_idx].row_cnt)
-     row_idx = row_idx % (rrd -> rra_def[rra_idx].row_cnt);
-
-   /* rra_start points to the appropriate rra block in the file */
-   /* compute the pointer to the appropriate location in the file */
-   pos_tmp = rra_start + (row_idx)*(rrd -> stat_head -> ds_cnt)*sizeof(rrd_value_t);
-
-   /* allocate memory if need be */
-   if (*seasonal_coef == NULL)
-         *seasonal_coef = 
-            (rrd_value_t *) malloc((rrd -> stat_head -> ds_cnt)*sizeof(rrd_value_t));
-   if (*seasonal_coef == NULL) {
-         rrd_set_error("memory allocation failure: seasonal coef");
-         return -1;
-   }
-
-   if (!fseek(rrd_file,pos_tmp,SEEK_SET))
-   {
-      if (fread(*seasonal_coef,sizeof(rrd_value_t),rrd->stat_head->ds_cnt,rrd_file)
-                 == rrd -> stat_head -> ds_cnt)
-         {
-                /* success! */
-         /* we can safely ignore the rule requiring a seek operation between read
-          * and write, because this read moves the file pointer to somewhere
-          * in the file other than the next write location.
-          * */
-                return 0;
-         } else {
-            rrd_set_error("read operation failed in lookup_seasonal(): %lu\n",pos_tmp);
-         }
-   } else {
-         rrd_set_error("seek operation failed in lookup_seasonal(): %lu\n",pos_tmp);
-   }
-   
-   return -1;
-}
-
-int
-update_seasonal(rrd_t *rrd, unsigned long cdp_idx, unsigned long rra_idx, 
-                                unsigned long ds_idx, unsigned short CDP_scratch_idx, rrd_value_t *seasonal_coef)
-{
-/* TODO: extract common if subblocks in the wake of I/O optimization */
-   rrd_value_t intercept, seasonal;
-   rra_def_t *current_rra = &(rrd -> rra_def[rra_idx]);
-   rra_def_t *hw_rra = &(rrd -> rra_def[current_rra -> par[RRA_dependent_rra_idx].u_cnt]);
-   /* obtain cdp_prep index for HWPREDICT */
-   unsigned long hw_cdp_idx = (current_rra -> par[RRA_dependent_rra_idx].u_cnt)
-      * (rrd -> stat_head -> ds_cnt) + ds_idx;
-   unival *coefs = rrd -> cdp_prep[hw_cdp_idx].scratch;
-
-   /* update seasonal coefficient in cdp prep areas */
-   seasonal = rrd -> cdp_prep[cdp_idx].scratch[CDP_hw_seasonal].u_val;
-   rrd -> cdp_prep[cdp_idx].scratch[CDP_hw_last_seasonal].u_val = seasonal;
-   rrd -> cdp_prep[cdp_idx].scratch[CDP_hw_seasonal].u_val =
-         seasonal_coef[ds_idx];
-
-   /* update seasonal value for disk */
-   if (current_rra -> par[RRA_dependent_rra_idx].u_cnt < rra_idx)
-         /* associated HWPREDICT has already been updated */
-         /* check for possible NA values */
-      if (isnan(rrd -> cdp_prep[cdp_idx].scratch[CDP_scratch_idx].u_val))
-         {
-                /* no update, store the old value unchanged,
-                 * doesn't matter if it is NA */
-            rrd -> cdp_prep[cdp_idx].scratch[CDP_scratch_idx].u_val = seasonal;
-         } else if (isnan(coefs[CDP_hw_last_intercept].u_val) 
-                    || isnan(coefs[CDP_hw_last_slope].u_val))
-         {
-                /* this should never happen, as HWPREDICT was already updated */
-                rrd -> cdp_prep[cdp_idx].scratch[CDP_scratch_idx].u_val= DNAN;
-         } else if (isnan(seasonal))
-         {
-                /* initialization: intercept is not currently being updated */
-#ifdef DEBUG
-                fprintf(stderr,"Initialization of seasonal coef %lu\n",
-                       rrd -> rra_ptr[rra_idx].cur_row);
-#endif
-                rrd -> cdp_prep[cdp_idx].scratch[CDP_scratch_idx].u_val 
-                       -= coefs[CDP_hw_last_intercept].u_val; 
-         } else {
-                intercept = coefs[CDP_hw_intercept].u_val;
-#ifdef DEBUG
-                fprintf(stderr,
-                       "Updating seasonal, params: gamma %f, new intercept %f, old seasonal %f\n",
-                       current_rra -> par[RRA_seasonal_gamma].u_val,
-                       intercept, seasonal);
-#endif
-                rrd -> cdp_prep[cdp_idx].scratch[CDP_scratch_idx].u_val =
-                       (current_rra -> par[RRA_seasonal_gamma].u_val)*
-                       (rrd -> cdp_prep[cdp_idx].scratch[CDP_scratch_idx].u_val - intercept) +
-                       (1 - current_rra -> par[RRA_seasonal_gamma].u_val)*seasonal;
-         }
-   else {
-         /* SEASONAL array is updated first, which means the new intercept
-          * hasn't be computed; so we compute it here. */
-
-         /* check for possible NA values */
-      if (isnan(rrd -> cdp_prep[cdp_idx].scratch[CDP_scratch_idx].u_val))
-         {
-                /* no update, simple store the old value unchanged,
-                 * doesn't matter if it is NA */
-                rrd -> cdp_prep[cdp_idx].scratch[CDP_scratch_idx].u_val =  seasonal;
-         } else if (isnan(coefs[CDP_hw_intercept].u_val) 
-                    || isnan(coefs[CDP_hw_slope].u_val))
-         {
-                /* Initialization of slope and intercept will occur.
-                 * force seasonal coefficient to 0. */
-                rrd -> cdp_prep[cdp_idx].scratch[CDP_scratch_idx].u_val= 0.0;
-         } else if (isnan(seasonal))
-         {
-                /* initialization: intercept will not be updated
-                 * CDP_hw_intercept = CDP_hw_last_intercept; just need to 
-                 * subtract this baseline value. */
-#ifdef DEBUG
-                fprintf(stderr,"Initialization of seasonal coef %lu\n",
-                       rrd -> rra_ptr[rra_idx].cur_row);
-#endif
-                rrd -> cdp_prep[cdp_idx].scratch[CDP_scratch_idx].u_val -= coefs[CDP_hw_intercept].u_val; 
-         } else {
-                /* Note that we must get CDP_scratch_idx from SEASONAL array, as CDP_scratch_idx
-                 * for HWPREDICT array will be DNAN. */
-            intercept = (hw_rra -> par[RRA_hw_alpha].u_val)*
-                   (rrd -> cdp_prep[cdp_idx].scratch[CDP_scratch_idx].u_val - seasonal)
-                   + (1 - hw_rra -> par[RRA_hw_alpha].u_val)*(coefs[CDP_hw_intercept].u_val
-                   + (coefs[CDP_hw_slope].u_val)*(coefs[CDP_null_count].u_cnt));
-                rrd -> cdp_prep[cdp_idx].scratch[CDP_scratch_idx].u_val =
-                  (current_rra -> par[RRA_seasonal_gamma].u_val)*
-                  (rrd -> cdp_prep[cdp_idx].scratch[CDP_scratch_idx].u_val - intercept) +
-                  (1 - current_rra -> par[RRA_seasonal_gamma].u_val)*seasonal;
-         }
-   }
-#ifdef DEBUG
-   fprintf(stderr,"seasonal coefficient set= %f\n",
-         rrd -> cdp_prep[cdp_idx].scratch[CDP_scratch_idx].u_val);
-#endif
-   return 0;
-}
-
-int
-update_devpredict(rrd_t *rrd, unsigned long cdp_idx, 
-                                 unsigned long rra_idx, unsigned long ds_idx, unsigned short CDP_scratch_idx)
-{
-   /* there really isn't any "update" here; the only reason this information
-    * is stored separately from DEVSEASONAL is to preserve deviation predictions
-    * for a longer duration than one seasonal cycle. */
-   unsigned long seasonal_cdp_idx = (rrd -> rra_def[rra_idx].par[RRA_dependent_rra_idx].u_cnt)
-      * (rrd -> stat_head -> ds_cnt) + ds_idx;
-
-   if (rrd -> rra_def[rra_idx].par[RRA_dependent_rra_idx].u_cnt < rra_idx)
-   {
-         /* associated DEVSEASONAL array already updated */
-         rrd -> cdp_prep[cdp_idx].scratch[CDP_scratch_idx].u_val
-                = rrd -> cdp_prep[seasonal_cdp_idx].scratch[CDP_last_seasonal_deviation].u_val;
-   } else {
-         /* associated DEVSEASONAL not yet updated */
-         rrd -> cdp_prep[cdp_idx].scratch[CDP_scratch_idx].u_val
-                = rrd -> cdp_prep[seasonal_cdp_idx].scratch[CDP_seasonal_deviation].u_val;
-   }
-   return 0;
-}
-
-int
-update_devseasonal(rrd_t *rrd, unsigned long cdp_idx, unsigned long rra_idx, 
-                      unsigned long ds_idx, unsigned short CDP_scratch_idx, 
-                                  rrd_value_t *seasonal_dev)
+static unsigned long MyMod(
+    signed long val,
+    unsigned long mod);
+
+int lookup_seasonal(
+    rrd_t *rrd,
+    unsigned long rra_idx,
+    unsigned long rra_start,
+    rrd_file_t *rrd_file,
+    unsigned long offset,
+    rrd_value_t **seasonal_coef)
 {
-   rrd_value_t prediction = 0, seasonal_coef = DNAN;
-   rra_def_t *current_rra = &(rrd -> rra_def[rra_idx]);
-   /* obtain cdp_prep index for HWPREDICT */
-   unsigned long hw_rra_idx = current_rra -> par[RRA_dependent_rra_idx].u_cnt;
-   unsigned long hw_cdp_idx = hw_rra_idx * (rrd -> stat_head -> ds_cnt) + ds_idx;
-   unsigned long seasonal_cdp_idx;
-   unival *coefs = rrd -> cdp_prep[hw_cdp_idx].scratch;
-   rrd -> cdp_prep[cdp_idx].scratch[CDP_last_seasonal_deviation].u_val =
-         rrd -> cdp_prep[cdp_idx].scratch[CDP_seasonal_deviation].u_val;
-   /* retrieve the next seasonal deviation value, could be NA */
-   rrd -> cdp_prep[cdp_idx].scratch[CDP_seasonal_deviation].u_val =
-         seasonal_dev[ds_idx];
-
-   /* retrieve the current seasonal_coef (not to be confused with the
-       * current seasonal deviation). Could make this more readable by introducing
-       * some wrapper functions. */
-   seasonal_cdp_idx = (rrd -> rra_def[hw_rra_idx].par[RRA_dependent_rra_idx].u_cnt)
-         *(rrd -> stat_head -> ds_cnt) + ds_idx;
-   if (rrd -> rra_def[hw_rra_idx].par[RRA_dependent_rra_idx].u_cnt < rra_idx)
-         /* SEASONAL array already updated */
-         seasonal_coef = rrd -> cdp_prep[seasonal_cdp_idx].scratch[CDP_hw_last_seasonal].u_val;
-   else
-         /* SEASONAL array not yet updated */
-         seasonal_coef = rrd -> cdp_prep[seasonal_cdp_idx].scratch[CDP_hw_seasonal].u_val;
-   
-   /* compute the abs value of the difference between the prediction and
-       * observed value */
-   if (hw_rra_idx < rra_idx)
-   {
-         /* associated HWPREDICT has already been updated */
-         if (isnan(coefs[CDP_hw_last_intercept].u_val) ||
-             isnan(coefs[CDP_hw_last_slope].u_val) ||
-             isnan(seasonal_coef))
-         {
-                /* one of the prediction values is uinitialized */
-                rrd -> cdp_prep[cdp_idx].scratch[CDP_scratch_idx].u_val = DNAN;
-                return 0;
-         } else {
-            prediction = coefs[CDP_hw_last_intercept].u_val + 
-                  (coefs[CDP_hw_last_slope].u_val)*(coefs[CDP_last_null_count].u_cnt)
-                  + seasonal_coef;
-         }
-   } else {
-         /* associated HWPREDICT has NOT been updated */
-         if (isnan(coefs[CDP_hw_intercept].u_val) ||
-             isnan(coefs[CDP_hw_slope].u_val) ||
-             isnan(seasonal_coef))
-         {
-                /* one of the prediction values is uinitialized */
-                rrd -> cdp_prep[cdp_idx].scratch[CDP_scratch_idx].u_val = DNAN;
-                return 0;
-         } else {
-            prediction = coefs[CDP_hw_intercept].u_val + 
-                  (coefs[CDP_hw_slope].u_val)*(coefs[CDP_null_count].u_cnt) 
-                  + seasonal_coef;
-         }
-   }
-
-   if (isnan(rrd -> cdp_prep[cdp_idx].scratch[CDP_scratch_idx].u_val))
-   {
-      /* no update, store existing value unchanged, doesn't
-          * matter if it is NA */
-         rrd -> cdp_prep[cdp_idx].scratch[CDP_scratch_idx].u_val =
-                rrd -> cdp_prep[cdp_idx].scratch[CDP_last_seasonal_deviation].u_val;
-   } else if (isnan(rrd -> cdp_prep[cdp_idx].scratch[CDP_last_seasonal_deviation].u_val))
-   {
-         /* initialization */
-#ifdef DEBUG
-         fprintf(stderr,"Initialization of seasonal deviation\n");
-#endif
-         rrd -> cdp_prep[cdp_idx].scratch[CDP_scratch_idx].u_val =
-            fabs(prediction - rrd -> cdp_prep[cdp_idx].scratch[CDP_scratch_idx].u_val);
-   } else {
-         /* exponential smoothing update */
-         rrd -> cdp_prep[cdp_idx].scratch[CDP_scratch_idx].u_val =
-           (rrd -> rra_def[rra_idx].par[RRA_seasonal_gamma].u_val)*
-           fabs(prediction - rrd -> cdp_prep[cdp_idx].scratch[CDP_scratch_idx].u_val)
-           + (1 -  rrd -> rra_def[rra_idx].par[RRA_seasonal_gamma].u_val)*
-           (rrd -> cdp_prep[cdp_idx].scratch[CDP_last_seasonal_deviation].u_val);
-   }
-   return 0;
-}
-
-/* Check for a failure based on a threshold # of violations within the specified
- * window. */
-int 
-update_failures(rrd_t *rrd, unsigned long cdp_idx, unsigned long rra_idx, 
-                               unsigned long ds_idx, unsigned short CDP_scratch_idx)
-{
-   /* detection of a violation depends on 3 RRAs:
-       * HWPREDICT, SEASONAL, and DEVSEASONAL */
-   rra_def_t *current_rra = &(rrd -> rra_def[rra_idx]);
-   unsigned long dev_rra_idx = current_rra -> par[RRA_dependent_rra_idx].u_cnt;
-   rra_def_t *dev_rra = &(rrd -> rra_def[dev_rra_idx]);
-   unsigned long hw_rra_idx = dev_rra -> par[RRA_dependent_rra_idx].u_cnt;
-   rra_def_t *hw_rra =  &(rrd -> rra_def[hw_rra_idx]);
-   unsigned long seasonal_rra_idx = hw_rra -> par[RRA_dependent_rra_idx].u_cnt;
-   unsigned long temp_cdp_idx;
-   rrd_value_t deviation = DNAN;
-   rrd_value_t seasonal_coef = DNAN;
-   rrd_value_t prediction = DNAN;
-   char violation = 0; 
-   unsigned short violation_cnt = 0, i;
-   char *violations_array;
-
-   /* usual checks to determine the order of the RRAs */
-   temp_cdp_idx = dev_rra_idx * (rrd -> stat_head -> ds_cnt) + ds_idx;
-   if (rra_idx < seasonal_rra_idx)
-   {
-         /* DEVSEASONAL not yet updated */
-         deviation = rrd -> cdp_prep[temp_cdp_idx].scratch[CDP_seasonal_deviation].u_val;
-   } else {
-         /* DEVSEASONAL already updated */
-         deviation = rrd -> cdp_prep[temp_cdp_idx].scratch[CDP_last_seasonal_deviation].u_val;
-   }
-   if (!isnan(deviation)) {
-
-   temp_cdp_idx = seasonal_rra_idx * (rrd -> stat_head -> ds_cnt) + ds_idx;
-   if (rra_idx < seasonal_rra_idx)
-   {
-         /* SEASONAL not yet updated */
-         seasonal_coef = rrd -> cdp_prep[temp_cdp_idx].scratch[CDP_hw_seasonal].u_val;
-   } else {
-         /* SEASONAL already updated */
-         seasonal_coef = rrd -> cdp_prep[temp_cdp_idx].scratch[CDP_hw_last_seasonal].u_val;
-   }
-   /* in this code block, we know seasonal coef is not DNAN, because deviation is not
-       * null */
-
-   temp_cdp_idx = hw_rra_idx * (rrd -> stat_head -> ds_cnt) + ds_idx;
-   if (rra_idx < hw_rra_idx)
-   {
-         /* HWPREDICT not yet updated */
-         prediction = rrd -> cdp_prep[temp_cdp_idx].scratch[CDP_hw_intercept].u_val + 
-            (rrd -> cdp_prep[temp_cdp_idx].scratch[CDP_hw_slope].u_val)
-                *(rrd -> cdp_prep[temp_cdp_idx].scratch[CDP_null_count].u_cnt)
-                + seasonal_coef;
-   } else {
-         /* HWPREDICT already updated */
-         prediction = rrd -> cdp_prep[temp_cdp_idx].scratch[CDP_hw_last_intercept].u_val + 
-            (rrd -> cdp_prep[temp_cdp_idx].scratch[CDP_hw_last_slope].u_val)
-                *(rrd -> cdp_prep[temp_cdp_idx].scratch[CDP_last_null_count].u_cnt)
-                + seasonal_coef;
-   }
-
-   /* determine if the observed value is a violation */
-   if (!isnan(rrd -> cdp_prep[cdp_idx].scratch[CDP_scratch_idx].u_val))
-   {
-         if (rrd -> cdp_prep[cdp_idx].scratch[CDP_scratch_idx].u_val > prediction + 
-                (current_rra -> par[RRA_delta_pos].u_val)*deviation
-            || rrd -> cdp_prep[cdp_idx].scratch[CDP_scratch_idx].u_val < prediction - 
-                (current_rra -> par[RRA_delta_neg].u_val)*deviation)
-                violation = 1;
-   } else {
-         violation = 1; /* count DNAN values as violations */
-   }
-
-   }
-
-   /* determine if a failure has occurred and update the failure array */
-   violation_cnt = violation;
-   violations_array = (char *) ((void *) rrd -> cdp_prep[cdp_idx].scratch);
-   for (i = current_rra -> par[RRA_window_len].u_cnt; i > 1; i--)
-   {
-         /* shift */
-         violations_array[i-1] = violations_array[i-2]; 
-         violation_cnt += violations_array[i-1];
-   }
-   violations_array[0] = violation;
-
-   if (violation_cnt < current_rra -> par[RRA_failure_threshold].u_cnt)
-         /* not a failure */
-         rrd -> cdp_prep[cdp_idx].scratch[CDP_scratch_idx].u_val = 0.0;
-   else
-         rrd -> cdp_prep[cdp_idx].scratch[CDP_scratch_idx].u_val = 1.0;
-
-   return (rrd-> cdp_prep[cdp_idx].scratch[CDP_scratch_idx].u_val);
+    unsigned long pos_tmp;
+
+    /* rra_ptr[].cur_row points to the rra row to be written; this function
+     * reads cur_row + offset */
+    unsigned long row_idx = rrd->rra_ptr[rra_idx].cur_row + offset;
+
+    /* handle wrap around */
+    if (row_idx >= rrd->rra_def[rra_idx].row_cnt)
+        row_idx = row_idx % (rrd->rra_def[rra_idx].row_cnt);
+
+    /* rra_start points to the appropriate rra block in the file */
+    /* compute the pointer to the appropriate location in the file */
+    pos_tmp =
+        rra_start +
+        (row_idx) * (rrd->stat_head->ds_cnt) * sizeof(rrd_value_t);
+
+    /* allocate memory if need be */
+    if (*seasonal_coef == NULL)
+        *seasonal_coef =
+            (rrd_value_t *) malloc((rrd->stat_head->ds_cnt) *
+                                   sizeof(rrd_value_t));
+    if (*seasonal_coef == NULL) {
+        rrd_set_error("memory allocation failure: seasonal coef");
+        return -1;
+    }
+
+    if (!rrd_seek(rrd_file, pos_tmp, SEEK_SET)) {
+        if (rrd_read
+            (rrd_file, *seasonal_coef,
+             sizeof(rrd_value_t) * rrd->stat_head->ds_cnt)
+            == (ssize_t) (sizeof(rrd_value_t) * rrd->stat_head->ds_cnt)) {
+            /* success! */
+            /* we can safely ignore the rule requiring a seek operation between read
+             * and write, because this read moves the file pointer to somewhere
+             * in the file other than the next write location.
+             * */
+            return 0;
+        } else {
+            rrd_set_error("read operation failed in lookup_seasonal(): %lu\n",
+                          pos_tmp);
+        }
+    } else {
+        rrd_set_error("seek operation failed in lookup_seasonal(): %lu\n",
+                      pos_tmp);
+    }
+
+    return -1;
 }
 
 /* For the specified CDP prep area and the FAILURES RRA,
  * erase all history of past violations.
  */
-void
-erase_violations(rrd_t *rrd, unsigned long cdp_idx, unsigned long rra_idx)
+void erase_violations(
+    rrd_t *rrd,
+    unsigned long cdp_idx,
+    unsigned long rra_idx)
 {
-   unsigned short i;
-   char *violations_array;
-   /* check that rra_idx is a CF_FAILURES array */
-   if (cf_conv(rrd -> rra_def[rra_idx].cf_nam) != CF_FAILURES)
-   {
+    unsigned short i;
+    char     *violations_array;
+
+    /* check that rra_idx is a CF_FAILURES array */
+    if (cf_conv(rrd->rra_def[rra_idx].cf_nam) != CF_FAILURES) {
 #ifdef DEBUG
-         fprintf(stderr,"erase_violations called for non-FAILURES RRA: %s\n",
-            rrd -> rra_def[rra_idx].cf_nam);
+        fprintf(stderr, "erase_violations called for non-FAILURES RRA: %s\n",
+                rrd->rra_def[rra_idx].cf_nam);
 #endif
-         return;
-   }
-
+        return;
+    }
 #ifdef DEBUG
-   fprintf(stderr,"scratch buffer before erase:\n");
-   for (i = 0; i < MAX_CDP_PAR_EN; i++)
-   {
-         fprintf(stderr,"%lu ", rrd -> cdp_prep[cdp_idx].scratch[i].u_cnt);
-   }
-   fprintf(stderr,"\n");
+    fprintf(stderr, "scratch buffer before erase:\n");
+    for (i = 0; i < MAX_CDP_PAR_EN; i++) {
+        fprintf(stderr, "%lu ", rrd->cdp_prep[cdp_idx].scratch[i].u_cnt);
+    }
+    fprintf(stderr, "\n");
 #endif
 
-   /* WARNING: an array of longs on disk is treated as an array of chars
-    * in memory. */
-   violations_array = (char *) ((void *) rrd -> cdp_prep[cdp_idx].scratch);
-   /* erase everything in the part of the CDP scratch array that will be
-    * used to store violations for the current window */
-   for (i = rrd -> rra_def[rra_idx].par[RRA_window_len].u_cnt; i > 0; i--)
-   {
-         violations_array[i-1] = 0;
-   }
+    /* WARNING: an array of longs on disk is treated as an array of chars
+     * in memory. */
+    violations_array = (char *) ((void *) rrd->cdp_prep[cdp_idx].scratch);
+    /* erase everything in the part of the CDP scratch array that will be
+     * used to store violations for the current window */
+    for (i = rrd->rra_def[rra_idx].par[RRA_window_len].u_cnt; i > 0; i--) {
+        violations_array[i - 1] = 0;
+    }
 #ifdef DEBUG
-   fprintf(stderr,"scratch buffer after erase:\n");
-   for (i = 0; i < MAX_CDP_PAR_EN; i++)
-   {
-         fprintf(stderr,"%lu ", rrd -> cdp_prep[cdp_idx].scratch[i].u_cnt);
-   }
-   fprintf(stderr,"\n");
+    fprintf(stderr, "scratch buffer after erase:\n");
+    for (i = 0; i < MAX_CDP_PAR_EN; i++) {
+        fprintf(stderr, "%lu ", rrd->cdp_prep[cdp_idx].scratch[i].u_cnt);
+    }
+    fprintf(stderr, "\n");
 #endif
 }
 
 /* Smooth a periodic array with a moving average: equal weights and
  * length = 5% of the period. */
-int
-apply_smoother(rrd_t *rrd, unsigned long rra_idx, unsigned long rra_start,
-               FILE *rrd_file)
+int apply_smoother(
+    rrd_t *rrd,
+    unsigned long rra_idx,
+    unsigned long rra_start,
+    rrd_file_t *rrd_file)
 {
-   unsigned long i, j, k;
-   unsigned long totalbytes;
-   rrd_value_t *rrd_values;
-   unsigned long row_length = rrd -> stat_head -> ds_cnt;
-   unsigned long row_count = rrd -> rra_def[rra_idx].row_cnt;
-   unsigned long offset;
-   FIFOqueue **buffers;
-   rrd_value_t *working_average;
-   rrd_value_t *baseline;
-
-   offset = floor(0.025*row_count);
-   if (offset == 0) return 0; /* no smoothing */
-
-   /* allocate memory */
-   totalbytes = sizeof(rrd_value_t)*row_length*row_count;
-   rrd_values = (rrd_value_t *) malloc(totalbytes);
-   if (rrd_values == NULL)
-   {
-         rrd_set_error("apply smoother: memory allocation failure");
-         return -1;
-   }
-
-   /* rra_start is at the beginning of this rra */
-   if (fseek(rrd_file,rra_start,SEEK_SET))
-   {
-         rrd_set_error("seek to rra %d failed", rra_start);
-         free(rrd_values);
-         return -1;
-   }
-   fflush(rrd_file);
-   /* could read all data in a single block, but we need to
-    * check for NA values */
-   for (i = 0; i < row_count; ++i)
-   {
-         for (j = 0; j < row_length; ++j)
-         {
-                fread(&(rrd_values[i*row_length + j]),sizeof(rrd_value_t),1,rrd_file);
-                /* should check fread for errors... */
-                if (isnan(rrd_values[i*row_length + j])) {
-                       /* can't apply smoothing, still uninitialized values */
+    unsigned long i, j, k;
+    unsigned long totalbytes;
+    rrd_value_t *rrd_values;
+    unsigned long row_length = rrd->stat_head->ds_cnt;
+    unsigned long row_count = rrd->rra_def[rra_idx].row_cnt;
+    unsigned long offset;
+    FIFOqueue **buffers;
+    rrd_value_t *working_average;
+    rrd_value_t *baseline;
+
+    if (atoi(rrd->stat_head->version) >= 4) {
+        offset = floor(rrd->rra_def[rra_idx].
+                       par[RRA_seasonal_smoothing_window].
+                       u_val / 2 * row_count);
+    } else {
+        offset = floor(0.05 / 2 * row_count);
+    }
+
+    if (offset == 0)
+        return 0;       /* no smoothing */
+
+    /* allocate memory */
+    totalbytes = sizeof(rrd_value_t) * row_length * row_count;
+    rrd_values = (rrd_value_t *) malloc(totalbytes);
+    if (rrd_values == NULL) {
+        rrd_set_error("apply smoother: memory allocation failure");
+        return -1;
+    }
+
+    /* rra_start is at the beginning of this rra */
+    if (rrd_seek(rrd_file, rra_start, SEEK_SET)) {
+        rrd_set_error("seek to rra %d failed", rra_start);
+        free(rrd_values);
+        return -1;
+    }
+    rrd_flush(rrd_file);
+    /* could read all data in a single block, but we need to
+     * check for NA values */
+    for (i = 0; i < row_count; ++i) {
+        for (j = 0; j < row_length; ++j) {
+            if (rrd_read
+                (rrd_file, &(rrd_values[i * row_length + j]),
+                 sizeof(rrd_value_t) * 1)
+                != (ssize_t) (sizeof(rrd_value_t) * 1)) {
+                rrd_set_error("reading value failed: %s",
+                              rrd_strerror(errno));
+            }
+            if (isnan(rrd_values[i * row_length + j])) {
+                /* can't apply smoothing, still uninitialized values */
 #ifdef DEBUG
-                       fprintf(stderr,"apply_smoother: NA detected in seasonal array: %ld %ld\n",i,j);
+                fprintf(stderr,
+                        "apply_smoother: NA detected in seasonal array: %ld %ld\n",
+                        i, j);
 #endif
-                       free(rrd_values);
-                       return 0;
-                }
-         }
-   }
-
-   /* allocate queues, one for each data source */
-   buffers = (FIFOqueue **) malloc(sizeof(FIFOqueue *)*row_length);
-   for (i = 0; i < row_length; ++i)
-   {
-      queue_alloc(&(buffers[i]),2*offset + 1);
-   }
-   /* need working average initialized to 0 */
-   working_average = (rrd_value_t *) calloc(row_length,sizeof(rrd_value_t));
-   baseline = (rrd_value_t *) calloc(row_length,sizeof(rrd_value_t));
-
-   /* compute sums of the first 2*offset terms */ 
-   for (i = 0; i < 2*offset; ++i)
-   {
-         k = MyMod(i - offset,row_count);
-         for (j = 0; j < row_length; ++j)
-         {
-                queue_push(buffers[j],rrd_values[k*row_length + j]);
-                working_average[j] += rrd_values[k*row_length + j];
-         }
-   }
-
-   /* compute moving averages */
-   for (i = offset; i < row_count + offset; ++i)
-   {
-         for (j = 0; j < row_length; ++j)
-         {
-            k = MyMod(i,row_count);
-            /* add a term to the sum */
-            working_average[j] += rrd_values[k*row_length + j];
-            queue_push(buffers[j],rrd_values[k*row_length + j]);
-
-            /* reset k to be the center of the window */
-            k = MyMod(i - offset,row_count);
-            /* overwrite rdd_values entry, the old value is already
-             * saved in buffers */
-            rrd_values[k*row_length + j] = working_average[j]/(2*offset + 1);
-            baseline[j] += rrd_values[k*row_length + j];
-
-            /* remove a term from the sum */
-            working_average[j] -= queue_pop(buffers[j]);
-         }     
-   } 
-   for (i = 0; i < row_length; ++i)
-   {
-         queue_dealloc(buffers[i]);
-         baseline[i] /= row_count; 
-   }
-   free(buffers);
-   free(working_average);
-
-   if (cf_conv(rrd->rra_def[rra_idx].cf_nam) == CF_SEASONAL) {
-   for (j = 0; j < row_length; ++j)
-   {
-   for (i = 0; i < row_count; ++i)
-   {
-        rrd_values[i*row_length + j] -= baseline[j];
-   }
-        /* update the baseline coefficient,
-         * first, compute the cdp_index. */
-        offset = (rrd->rra_def[rra_idx].par[RRA_dependent_rra_idx].u_cnt)
-         * row_length + j;
-        (rrd->cdp_prep[offset]).scratch[CDP_hw_intercept].u_val += baseline[j];
-   }
-   /* flush cdp to disk */
-   fflush(rrd_file);
-   if (fseek(rrd_file,sizeof(stat_head_t) + 
-         rrd->stat_head->ds_cnt * sizeof(ds_def_t) +
-         rrd->stat_head->rra_cnt * sizeof(rra_def_t) + 
-         sizeof(live_head_t) +
-         rrd->stat_head->ds_cnt * sizeof(pdp_prep_t),SEEK_SET))
-   {
-         rrd_set_error("apply_smoother: seek to cdp_prep failed");
-         free(rrd_values);
-         return -1;
-   }
-   if (fwrite( rrd -> cdp_prep,
-         sizeof(cdp_prep_t),
-         (rrd->stat_head->rra_cnt) * rrd->stat_head->ds_cnt, rrd_file) 
-         != (rrd->stat_head->rra_cnt) * (rrd->stat_head->ds_cnt) )
-   { 
-         rrd_set_error("apply_smoother: cdp_prep write failed");
-         free(rrd_values);
-         return -1;
-   }
-   } /* endif CF_SEASONAL */ 
-
-   /* flush updated values to disk */
-   fflush(rrd_file);
-   if (fseek(rrd_file,rra_start,SEEK_SET))
-   {
-         rrd_set_error("apply_smoother: seek to pos %d failed", rra_start);
-         free(rrd_values);
-         return -1;
-   }
-   /* write as a single block */
-   if (fwrite(rrd_values,sizeof(rrd_value_t),row_length*row_count,rrd_file)
-         != row_length*row_count)
-   {
-         rrd_set_error("apply_smoother: write failed to %lu",rra_start);
-         free(rrd_values);
-         return -1;
-   }
-
-   fflush(rrd_file);
-   free(rrd_values);
-   free(baseline);
-   return 0;
+                free(rrd_values);
+                return 0;
+            }
+        }
+    }
+
+    /* allocate queues, one for each data source */
+    buffers = (FIFOqueue **) malloc(sizeof(FIFOqueue *) * row_length);
+    for (i = 0; i < row_length; ++i) {
+        queue_alloc(&(buffers[i]), 2 * offset + 1);
+    }
+    /* need working average initialized to 0 */
+    working_average = (rrd_value_t *) calloc(row_length, sizeof(rrd_value_t));
+    baseline = (rrd_value_t *) calloc(row_length, sizeof(rrd_value_t));
+
+    /* compute sums of the first 2*offset terms */
+    for (i = 0; i < 2 * offset; ++i) {
+        k = MyMod(i - offset, row_count);
+        for (j = 0; j < row_length; ++j) {
+            queue_push(buffers[j], rrd_values[k * row_length + j]);
+            working_average[j] += rrd_values[k * row_length + j];
+        }
+    }
+
+    /* compute moving averages */
+    for (i = offset; i < row_count + offset; ++i) {
+        for (j = 0; j < row_length; ++j) {
+            k = MyMod(i, row_count);
+            /* add a term to the sum */
+            working_average[j] += rrd_values[k * row_length + j];
+            queue_push(buffers[j], rrd_values[k * row_length + j]);
+
+            /* reset k to be the center of the window */
+            k = MyMod(i - offset, row_count);
+            /* overwrite rdd_values entry, the old value is already
+             * saved in buffers */
+            rrd_values[k * row_length + j] =
+                working_average[j] / (2 * offset + 1);
+            baseline[j] += rrd_values[k * row_length + j];
+
+            /* remove a term from the sum */
+            working_average[j] -= queue_pop(buffers[j]);
+        }
+    }
+
+    for (i = 0; i < row_length; ++i) {
+        queue_dealloc(buffers[i]);
+        baseline[i] /= row_count;
+    }
+    free(buffers);
+    free(working_average);
+
+    if (cf_conv(rrd->rra_def[rra_idx].cf_nam) == CF_SEASONAL) {
+        rrd_value_t (
+    *init_seasonality) (
+    rrd_value_t seasonal_coef,
+    rrd_value_t intercept);
+
+        switch (cf_conv(rrd->rra_def[hw_dep_idx(rrd, rra_idx)].cf_nam)) {
+        case CF_HWPREDICT:
+            init_seasonality = hw_additive_init_seasonality;
+            break;
+        case CF_MHWPREDICT:
+            init_seasonality = hw_multiplicative_init_seasonality;
+            break;
+        default:
+            rrd_set_error("apply smoother: SEASONAL rra doesn't have "
+                          "valid dependency: %s",
+                          rrd->rra_def[hw_dep_idx(rrd, rra_idx)].cf_nam);
+            return -1;
+        }
+
+        for (j = 0; j < row_length; ++j) {
+            for (i = 0; i < row_count; ++i) {
+                rrd_values[i * row_length + j] =
+                    init_seasonality(rrd_values[i * row_length + j],
+                                     baseline[j]);
+            }
+            /* update the baseline coefficient,
+             * first, compute the cdp_index. */
+            offset = hw_dep_idx(rrd, rra_idx) * row_length + j;
+            (rrd->cdp_prep[offset]).scratch[CDP_hw_intercept].u_val +=
+                baseline[j];
+        }
+        /* flush cdp to disk */
+        rrd_flush(rrd_file);
+        if (rrd_seek(rrd_file, sizeof(stat_head_t) +
+                     rrd->stat_head->ds_cnt * sizeof(ds_def_t) +
+                     rrd->stat_head->rra_cnt * sizeof(rra_def_t) +
+                     sizeof(live_head_t) +
+                     rrd->stat_head->ds_cnt * sizeof(pdp_prep_t), SEEK_SET)) {
+            rrd_set_error("apply_smoother: seek to cdp_prep failed");
+            free(rrd_values);
+            return -1;
+        }
+        if (rrd_write(rrd_file, rrd->cdp_prep,
+                      sizeof(cdp_prep_t) *
+                      (rrd->stat_head->rra_cnt) * rrd->stat_head->ds_cnt)
+            != (ssize_t) (sizeof(cdp_prep_t) * (rrd->stat_head->rra_cnt) *
+                          (rrd->stat_head->ds_cnt))) {
+            rrd_set_error("apply_smoother: cdp_prep write failed");
+            free(rrd_values);
+            return -1;
+        }
+    }
+
+    /* endif CF_SEASONAL */
+    /* flush updated values to disk */
+    rrd_flush(rrd_file);
+    if (rrd_seek(rrd_file, rra_start, SEEK_SET)) {
+        rrd_set_error("apply_smoother: seek to pos %d failed", rra_start);
+        free(rrd_values);
+        return -1;
+    }
+    /* write as a single block */
+    if (rrd_write
+        (rrd_file, rrd_values, sizeof(rrd_value_t) * row_length * row_count)
+        != (ssize_t) (sizeof(rrd_value_t) * row_length * row_count)) {
+        rrd_set_error("apply_smoother: write failed to %lu", rra_start);
+        free(rrd_values);
+        return -1;
+    }
+
+    rrd_flush(rrd_file);
+    free(rrd_values);
+    free(baseline);
+    return 0;
 }
 
 /* Reset aberrant behavior model coefficients, including intercept, slope,
  * seasonal, and seasonal deviation for the specified data source. */
-void
-reset_aberrant_coefficients(rrd_t *rrd, FILE *rrd_file, unsigned long ds_idx)
+void reset_aberrant_coefficients(
+    rrd_t *rrd,
+    rrd_file_t *rrd_file,
+    unsigned long ds_idx)
 {
-   unsigned long cdp_idx, rra_idx, i;
-   unsigned long cdp_start, rra_start;
-   rrd_value_t nan_buffer = DNAN;
-
-   /* compute the offset for the cdp area */
-   cdp_start = sizeof(stat_head_t) + 
-         rrd->stat_head->ds_cnt * sizeof(ds_def_t) +
-         rrd->stat_head->rra_cnt * sizeof(rra_def_t) + 
-         sizeof(live_head_t) +
-         rrd->stat_head->ds_cnt * sizeof(pdp_prep_t);
-   /* compute the offset for the first rra */
-   rra_start = cdp_start + 
-         (rrd->stat_head->ds_cnt) * (rrd->stat_head->rra_cnt) * sizeof(cdp_prep_t) +
-         rrd->stat_head->rra_cnt * sizeof(rra_ptr_t);
-
-   /* loop over the RRAs */
-   for (rra_idx = 0; rra_idx < rrd -> stat_head -> rra_cnt; rra_idx++)
-   {
-         cdp_idx = rra_idx * (rrd-> stat_head-> ds_cnt) + ds_idx;
-         switch (cf_conv(rrd -> rra_def[rra_idx].cf_nam))
-         {
-                case CF_HWPREDICT:
-               init_hwpredict_cdp(&(rrd -> cdp_prep[cdp_idx]));
-                       break;
-                case CF_SEASONAL:
-                case CF_DEVSEASONAL:
-                       /* don't use init_seasonal because it will reset burn-in, which
-                        * means different data sources will be calling for the smoother
-                        * at different times. */
-               rrd->cdp_prep[cdp_idx].scratch[CDP_hw_seasonal].u_val = DNAN;
-               rrd->cdp_prep[cdp_idx].scratch[CDP_hw_last_seasonal].u_val = DNAN;
-                       /* move to first entry of data source for this rra */
-                       fseek(rrd_file,rra_start + ds_idx * sizeof(rrd_value_t),SEEK_SET);
-                       /* entries for the same data source are not contiguous, 
-                        * temporal entries are contiguous */
-               for (i = 0; i < rrd->rra_def[rra_idx].row_cnt; ++i)
-                       {
-                          if (fwrite(&nan_buffer,sizeof(rrd_value_t),1,rrd_file) != 1)
-                          {
-                  rrd_set_error(
-                                 "reset_aberrant_coefficients: write failed data source %lu rra %s",
-                                 ds_idx,rrd->rra_def[rra_idx].cf_nam);
-                                 return;
-                          } 
-                          fseek(rrd_file,(rrd->stat_head->ds_cnt - 1) * 
-                                 sizeof(rrd_value_t),SEEK_CUR);
-                       }
-                       break;
-                case CF_FAILURES:
-                       erase_violations(rrd,cdp_idx,rra_idx);
-                       break;
-                default:
-                       break;
-         }
-         /* move offset to the next rra */
-         rra_start += rrd->rra_def[rra_idx].row_cnt * rrd->stat_head->ds_cnt * 
-                sizeof(rrd_value_t);
-   }
-   fseek(rrd_file,cdp_start,SEEK_SET);
-   if (fwrite( rrd -> cdp_prep,
-         sizeof(cdp_prep_t),
-         (rrd->stat_head->rra_cnt) * rrd->stat_head->ds_cnt, rrd_file) 
-         != (rrd->stat_head->rra_cnt) * (rrd->stat_head->ds_cnt) )
-   {
-         rrd_set_error("reset_aberrant_coefficients: cdp_prep write failed");
-         return;
-   }
+    unsigned long cdp_idx, rra_idx, i;
+    unsigned long cdp_start, rra_start;
+    rrd_value_t nan_buffer = DNAN;
+
+    /* compute the offset for the cdp area */
+    cdp_start = sizeof(stat_head_t) +
+        rrd->stat_head->ds_cnt * sizeof(ds_def_t) +
+        rrd->stat_head->rra_cnt * sizeof(rra_def_t) +
+        sizeof(live_head_t) + rrd->stat_head->ds_cnt * sizeof(pdp_prep_t);
+    /* compute the offset for the first rra */
+    rra_start = cdp_start +
+        (rrd->stat_head->ds_cnt) * (rrd->stat_head->rra_cnt) *
+        sizeof(cdp_prep_t) + rrd->stat_head->rra_cnt * sizeof(rra_ptr_t);
+
+    /* loop over the RRAs */
+    for (rra_idx = 0; rra_idx < rrd->stat_head->rra_cnt; rra_idx++) {
+        cdp_idx = rra_idx * (rrd->stat_head->ds_cnt) + ds_idx;
+        switch (cf_conv(rrd->rra_def[rra_idx].cf_nam)) {
+        case CF_HWPREDICT:
+        case CF_MHWPREDICT:
+            init_hwpredict_cdp(&(rrd->cdp_prep[cdp_idx]));
+            break;
+        case CF_SEASONAL:
+        case CF_DEVSEASONAL:
+            /* don't use init_seasonal because it will reset burn-in, which
+             * means different data sources will be calling for the smoother
+             * at different times. */
+            rrd->cdp_prep[cdp_idx].scratch[CDP_hw_seasonal].u_val = DNAN;
+            rrd->cdp_prep[cdp_idx].scratch[CDP_hw_last_seasonal].u_val = DNAN;
+            /* move to first entry of data source for this rra */
+            rrd_seek(rrd_file, rra_start + ds_idx * sizeof(rrd_value_t),
+                     SEEK_SET);
+            /* entries for the same data source are not contiguous, 
+             * temporal entries are contiguous */
+            for (i = 0; i < rrd->rra_def[rra_idx].row_cnt; ++i) {
+                if (rrd_write(rrd_file, &nan_buffer, sizeof(rrd_value_t) * 1)
+                    != sizeof(rrd_value_t) * 1) {
+                    rrd_set_error
+                        ("reset_aberrant_coefficients: write failed data source %lu rra %s",
+                         ds_idx, rrd->rra_def[rra_idx].cf_nam);
+                    return;
+                }
+                rrd_seek(rrd_file, (rrd->stat_head->ds_cnt - 1) *
+                         sizeof(rrd_value_t), SEEK_CUR);
+            }
+            break;
+        case CF_FAILURES:
+            erase_violations(rrd, cdp_idx, rra_idx);
+            break;
+        default:
+            break;
+        }
+        /* move offset to the next rra */
+        rra_start += rrd->rra_def[rra_idx].row_cnt * rrd->stat_head->ds_cnt *
+            sizeof(rrd_value_t);
+    }
+    rrd_seek(rrd_file, cdp_start, SEEK_SET);
+    if (rrd_write(rrd_file, rrd->cdp_prep,
+                  sizeof(cdp_prep_t) *
+                  (rrd->stat_head->rra_cnt) * rrd->stat_head->ds_cnt)
+        != (ssize_t) (sizeof(cdp_prep_t) * (rrd->stat_head->rra_cnt) *
+                      (rrd->stat_head->ds_cnt))) {
+        rrd_set_error("reset_aberrant_coefficients: cdp_prep write failed");
+    }
 }
 
-void init_hwpredict_cdp(cdp_prep_t *cdp)
+void init_hwpredict_cdp(
+    cdp_prep_t *cdp)
 {
-   cdp->scratch[CDP_hw_intercept].u_val = DNAN;
-   cdp->scratch[CDP_hw_last_intercept].u_val = DNAN;
-   cdp->scratch[CDP_hw_slope].u_val = DNAN;
-   cdp->scratch[CDP_hw_last_slope].u_val = DNAN;
-   cdp->scratch[CDP_null_count].u_cnt = 1;
-   cdp->scratch[CDP_last_null_count].u_cnt = 1;
+    cdp->scratch[CDP_hw_intercept].u_val = DNAN;
+    cdp->scratch[CDP_hw_last_intercept].u_val = DNAN;
+    cdp->scratch[CDP_hw_slope].u_val = DNAN;
+    cdp->scratch[CDP_hw_last_slope].u_val = DNAN;
+    cdp->scratch[CDP_null_count].u_cnt = 1;
+    cdp->scratch[CDP_last_null_count].u_cnt = 1;
 }
 
-void init_seasonal_cdp(cdp_prep_t *cdp)
+void init_seasonal_cdp(
+    cdp_prep_t *cdp)
 {
-   cdp->scratch[CDP_hw_seasonal].u_val = DNAN;
-   cdp->scratch[CDP_hw_last_seasonal].u_val = DNAN;
-   cdp->scratch[CDP_init_seasonal].u_cnt = 1;
+    cdp->scratch[CDP_hw_seasonal].u_val = DNAN;
+    cdp->scratch[CDP_hw_last_seasonal].u_val = DNAN;
+    cdp->scratch[CDP_init_seasonal].u_cnt = 1;
 }
 
-int
-update_aberrant_CF(rrd_t *rrd, rrd_value_t pdp_val, enum cf_en current_cf, 
-                 unsigned long cdp_idx, unsigned long rra_idx, unsigned long ds_idx, 
-                 unsigned short CDP_scratch_idx, rrd_value_t *seasonal_coef)
+int update_aberrant_CF(
+    rrd_t *rrd,
+    rrd_value_t pdp_val,
+    enum cf_en current_cf,
+    unsigned long cdp_idx,
+    unsigned long rra_idx,
+    unsigned long ds_idx,
+    unsigned short CDP_scratch_idx,
+    rrd_value_t *seasonal_coef)
 {
-   rrd -> cdp_prep[cdp_idx].scratch[CDP_scratch_idx].u_val = pdp_val;
-   switch (current_cf) {
-   case CF_AVERAGE:
-   default:
-        return 0;
-   case CF_HWPREDICT:
-     return update_hwpredict(rrd,cdp_idx,rra_idx,ds_idx,CDP_scratch_idx);
-   case CF_DEVPREDICT:
-        return update_devpredict(rrd,cdp_idx,rra_idx,ds_idx,CDP_scratch_idx);
-   case CF_SEASONAL:
-     return update_seasonal(rrd,cdp_idx,rra_idx,ds_idx,CDP_scratch_idx,seasonal_coef);
-   case CF_DEVSEASONAL:
-     return update_devseasonal(rrd,cdp_idx,rra_idx,ds_idx,CDP_scratch_idx,seasonal_coef);
-   case CF_FAILURES:
-     return update_failures(rrd,cdp_idx,rra_idx,ds_idx,CDP_scratch_idx);
-   }
-   return -1;
+    static hw_functions_t hw_multiplicative_functions = {
+        hw_multiplicative_calculate_prediction,
+        hw_multiplicative_calculate_intercept,
+        hw_calculate_slope,
+        hw_multiplicative_calculate_seasonality,
+        hw_multiplicative_init_seasonality,
+        hw_calculate_seasonal_deviation,
+        hw_init_seasonal_deviation,
+        1.0             /* identity value */
+    };
+
+    static hw_functions_t hw_additive_functions = {
+        hw_additive_calculate_prediction,
+        hw_additive_calculate_intercept,
+        hw_calculate_slope,
+        hw_additive_calculate_seasonality,
+        hw_additive_init_seasonality,
+        hw_calculate_seasonal_deviation,
+        hw_init_seasonal_deviation,
+        0.0             /* identity value  */
+    };
+
+    rrd->cdp_prep[cdp_idx].scratch[CDP_scratch_idx].u_val = pdp_val;
+    switch (current_cf) {
+    case CF_HWPREDICT:
+        return update_hwpredict(rrd, cdp_idx, rra_idx, ds_idx,
+                                CDP_scratch_idx, &hw_additive_functions);
+    case CF_MHWPREDICT:
+        return update_hwpredict(rrd, cdp_idx, rra_idx, ds_idx,
+                                CDP_scratch_idx,
+                                &hw_multiplicative_functions);
+    case CF_DEVPREDICT:
+        return update_devpredict(rrd, cdp_idx, rra_idx, ds_idx,
+                                 CDP_scratch_idx);
+    case CF_SEASONAL:
+        switch (cf_conv(rrd->rra_def[hw_dep_idx(rrd, rra_idx)].cf_nam)) {
+        case CF_HWPREDICT:
+            return update_seasonal(rrd, cdp_idx, rra_idx, ds_idx,
+                                   CDP_scratch_idx, seasonal_coef,
+                                   &hw_additive_functions);
+        case CF_MHWPREDICT:
+            return update_seasonal(rrd, cdp_idx, rra_idx, ds_idx,
+                                   CDP_scratch_idx, seasonal_coef,
+                                   &hw_multiplicative_functions);
+        default:
+            return -1;
+        }
+    case CF_DEVSEASONAL:
+        switch (cf_conv(rrd->rra_def[hw_dep_idx(rrd, rra_idx)].cf_nam)) {
+        case CF_HWPREDICT:
+            return update_devseasonal(rrd, cdp_idx, rra_idx, ds_idx,
+                                      CDP_scratch_idx, seasonal_coef,
+                                      &hw_additive_functions);
+        case CF_MHWPREDICT:
+            return update_devseasonal(rrd, cdp_idx, rra_idx, ds_idx,
+                                      CDP_scratch_idx, seasonal_coef,
+                                      &hw_multiplicative_functions);
+        default:
+            return -1;
+        }
+    case CF_FAILURES:
+        switch (cf_conv
+                (rrd->rra_def[hw_dep_idx(rrd, hw_dep_idx(rrd, rra_idx))].
+                 cf_nam)) {
+        case CF_HWPREDICT:
+            return update_failures(rrd, cdp_idx, rra_idx, ds_idx,
+                                   CDP_scratch_idx, &hw_additive_functions);
+        case CF_MHWPREDICT:
+            return update_failures(rrd, cdp_idx, rra_idx, ds_idx,
+                                   CDP_scratch_idx,
+                                   &hw_multiplicative_functions);
+        default:
+            return -1;
+        }
+    case CF_AVERAGE:
+    default:
+        return 0;
+    }
+    return -1;
 }
 
-unsigned long MyMod(signed long val, unsigned long mod)
+static unsigned long MyMod(
+    signed long val,
+    unsigned long mod)
 {
-   unsigned long new_val;
-   if (val < 0)
-     new_val = ((unsigned long) abs(val)) % mod;
-   else
-     new_val = (val % mod);
-   
-   if (val < 0) 
-     return (mod - new_val);
-   else
-     return (new_val);
+    unsigned long new_val;
+
+    if (val < 0)
+        new_val = ((unsigned long) abs(val)) % mod;
+    else
+        new_val = (val % mod);
+
+    if (val < 0)
+        return (mod - new_val);
+    else
+        return (new_val);
 }
 
 /* a standard fixed-capacity FIF0 queue implementation
  * No overflow checking is performed. */
-int queue_alloc(FIFOqueue **q,int capacity)
+int queue_alloc(
+    FIFOqueue **q,
+    int capacity)
 {
-   *q = (FIFOqueue *) malloc(sizeof(FIFOqueue));
-   if (*q == NULL) return -1;
-   (*q) -> queue = (rrd_value_t *) malloc(sizeof(rrd_value_t)*capacity);
-   if ((*q) -> queue == NULL)
-   {
-         free(*q);
-         return -1;
-   }
-   (*q) -> capacity = capacity;
-   (*q) -> head = capacity;
-   (*q) -> tail = 0;
-   return 0;
+    *q = (FIFOqueue *) malloc(sizeof(FIFOqueue));
+    if (*q == NULL)
+        return -1;
+    (*q)->queue = (rrd_value_t *) malloc(sizeof(rrd_value_t) * capacity);
+    if ((*q)->queue == NULL) {
+        free(*q);
+        return -1;
+    }
+    (*q)->capacity = capacity;
+    (*q)->head = capacity;
+    (*q)->tail = 0;
+    return 0;
 }
 
-int queue_isempty(FIFOqueue *q)
+int queue_isempty(
+    FIFOqueue *q)
 {
-   return (q -> head % q -> capacity == q -> tail);
+    return (q->head % q->capacity == q->tail);
 }
 
-void queue_push(FIFOqueue *q, rrd_value_t value)
+void queue_push(
+    FIFOqueue *q,
+    rrd_value_t value)
 {
-   q -> queue[(q -> tail)++] = value;
-   q -> tail = q -> tail % q -> capacity;
+    q->queue[(q->tail)++] = value;
+    q->tail = q->tail % q->capacity;
 }
 
-rrd_value_t queue_pop(FIFOqueue *q)
+rrd_value_t queue_pop(
+    FIFOqueue *q)
 {
-   q -> head = q -> head % q -> capacity;
-   return q -> queue[(q -> head)++];
+    q->head = q->head % q->capacity;
+    return q->queue[(q->head)++];
 }
 
-void queue_dealloc(FIFOqueue *q)
+void queue_dealloc(
+    FIFOqueue *q)
 {
-   free(q -> queue);
-   free(q);
+    free(q->queue);
+    free(q);
 }
index 54f150f97eeeebdd94ccbf17f71039a8d1052441..1ac24b74bdbdd12e2edfb3b8f0956befd51b2a1e 100644 (file)
@@ -1,33 +1,65 @@
 /*****************************************************************************
- * RRDtool 1.2.27  Copyright by Tobi Oetiker, 1997-2008
+ * RRDtool 1.3rc4  Copyright by Tobi Oetiker, 1997-2008
  *****************************************************************************
  * rrd_hw.h : Support for Holt-Winters Smoothing/ Aberrant Behavior Detection
  *****************************************************************************/
 
 /* functions implemented in rrd_hw.c */
-int update_aberrant_CF(rrd_t *rrd, rrd_value_t pdp_val, enum cf_en current_cf,
-   unsigned long cdp_idx, unsigned long rra_idx, unsigned long ds_idx,
-   unsigned short CDP_scratch_idx, rrd_value_t *seasonal_coef);
-int create_hw_contingent_rras(rrd_t *rrd, unsigned short period, 
-   unsigned long hashed_name);
-int lookup_seasonal(rrd_t *rrd, unsigned long rra_idx, unsigned long rra_start,
-   FILE *rrd_file, unsigned long offset, rrd_value_t **seasonal_coef);
-void erase_violations(rrd_t *rrd, unsigned long cdp_idx, unsigned long rra_idx);
-int apply_smoother(rrd_t *rrd, unsigned long rra_idx, unsigned long rra_start,
-   FILE *rrd_file);
-void reset_aberrant_coefficients(rrd_t *rrd, FILE *rrd_file, unsigned long ds_idx);
-void init_hwpredict_cdp(cdp_prep_t *);
-void init_seasonal_cdp(cdp_prep_t *);
+int       update_aberrant_CF(
+    rrd_t *rrd,
+    rrd_value_t pdp_val,
+    enum cf_en current_cf,
+    unsigned long cdp_idx,
+    unsigned long rra_idx,
+    unsigned long ds_idx,
+    unsigned short CDP_scratch_idx,
+    rrd_value_t *seasonal_coef);
+int       create_hw_contingent_rras(
+    rrd_t *rrd,
+    unsigned short period,
+    unsigned long hashed_name);
+int       lookup_seasonal(
+    rrd_t *rrd,
+    unsigned long rra_idx,
+    unsigned long rra_start,
+    rrd_file_t *rrd_file,
+    unsigned long offset,
+    rrd_value_t **seasonal_coef);
+void      erase_violations(
+    rrd_t *rrd,
+    unsigned long cdp_idx,
+    unsigned long rra_idx);
+int       apply_smoother(
+    rrd_t *rrd,
+    unsigned long rra_idx,
+    unsigned long rra_start,
+    rrd_file_t *rrd_file);
+void      reset_aberrant_coefficients(
+    rrd_t *rrd,
+    rrd_file_t *rrd_file,
+    unsigned long ds_idx);
+void      init_hwpredict_cdp(
+    cdp_prep_t *);
+void      init_seasonal_cdp(
+    cdp_prep_t *);
+
 #define BURNIN_CYCLES 3
 
 /* a standard fixed-capacity FIFO queue implementation */
 typedef struct FIFOqueue {
-   rrd_value_t *queue;
-   int capacity, head, tail;
+    rrd_value_t *queue;
+    int       capacity, head, tail;
 } FIFOqueue;
 
-int queue_alloc(FIFOqueue **q,int capacity);
-void queue_dealloc(FIFOqueue *q);
-void queue_push(FIFOqueue *q, rrd_value_t value);
-int queue_isempty(FIFOqueue *q);
-rrd_value_t queue_pop(FIFOqueue *q);
+int       queue_alloc(
+    FIFOqueue **q,
+    int capacity);
+void      queue_dealloc(
+    FIFOqueue *q);
+void      queue_push(
+    FIFOqueue *q,
+    rrd_value_t value);
+int       queue_isempty(
+    FIFOqueue *q);
+rrd_value_t queue_pop(
+    FIFOqueue *q);
diff --git a/src/rrd_hw_math.c b/src/rrd_hw_math.c
new file mode 100644 (file)
index 0000000..2b2c00f
--- /dev/null
@@ -0,0 +1,143 @@
+/*****************************************************************************
+ * rrd_hw_math.c  Math functions for Holt-Winters computations
+ *****************************************************************************/
+
+#include "rrd_hw_math.h"
+#include "rrd_config.h"
+
+/*****************************************************************************
+ * RRDtool supports both the additive and multiplicative Holt-Winters methods. 
+ * The additive method makes predictions by adding seasonality to the baseline, 
+ * whereas the multiplicative method multiplies the seasonality coefficient by 
+ * the baseline to make a prediction. This file contains all the differences
+ * between the additive and multiplicative methods, as well as a few math 
+ * functions common to them both.
+ ****************************************************************************/
+
+/*****************************************************************************
+ * Functions for additive Holt-Winters
+ *****************************************************************************/
+
+rrd_value_t hw_additive_calculate_prediction(
+    rrd_value_t intercept,
+    rrd_value_t slope,
+    int null_count,
+    rrd_value_t seasonal_coef)
+{
+    return intercept + slope * null_count + seasonal_coef;
+}
+
+rrd_value_t hw_additive_calculate_intercept(
+    rrd_value_t hw_alpha,
+    rrd_value_t observed,
+    rrd_value_t seasonal_coef,
+    unival *coefs)
+{
+    return hw_alpha * (observed - seasonal_coef)
+        + (1 - hw_alpha) * (coefs[CDP_hw_intercept].u_val
+                            +
+                            (coefs[CDP_hw_slope].u_val) *
+                            (coefs[CDP_null_count].u_cnt));
+}
+
+rrd_value_t hw_additive_calculate_seasonality(
+    rrd_value_t hw_gamma,
+    rrd_value_t observed,
+    rrd_value_t intercept,
+    rrd_value_t seasonal_coef)
+{
+    return hw_gamma * (observed - intercept)
+        + (1 - hw_gamma) * seasonal_coef;
+}
+
+rrd_value_t hw_additive_init_seasonality(
+    rrd_value_t seasonal_coef,
+    rrd_value_t intercept)
+{
+    return seasonal_coef - intercept;
+}
+
+/*****************************************************************************
+ * Functions for multiplicative Holt-Winters
+ *****************************************************************************/
+
+rrd_value_t hw_multiplicative_calculate_prediction(
+    rrd_value_t intercept,
+    rrd_value_t slope,
+    int null_count,
+    rrd_value_t seasonal_coef)
+{
+    return (intercept + slope * null_count) * seasonal_coef;
+}
+
+rrd_value_t hw_multiplicative_calculate_intercept(
+    rrd_value_t hw_alpha,
+    rrd_value_t observed,
+    rrd_value_t seasonal_coef,
+    unival *coefs)
+{
+    if (seasonal_coef <= 0) {
+        return DNAN;
+    }
+
+    return hw_alpha * (observed / seasonal_coef)
+        + (1 - hw_alpha) * (coefs[CDP_hw_intercept].u_val
+                            +
+                            (coefs[CDP_hw_slope].u_val) *
+                            (coefs[CDP_null_count].u_cnt));
+}
+
+rrd_value_t hw_multiplicative_calculate_seasonality(
+    rrd_value_t hw_gamma,
+    rrd_value_t observed,
+    rrd_value_t intercept,
+    rrd_value_t seasonal_coef)
+{
+    if (intercept <= 0) {
+        return DNAN;
+    }
+
+    return hw_gamma * (observed / intercept)
+        + (1 - hw_gamma) * seasonal_coef;
+}
+
+rrd_value_t hw_multiplicative_init_seasonality(
+    rrd_value_t seasonal_coef,
+    rrd_value_t intercept)
+{
+    if (intercept <= 0) {
+        return DNAN;
+    }
+
+    return seasonal_coef / intercept;
+}
+
+/*****************************************************************************
+ * Math functions common to additive and multiplicative Holt-Winters
+ *****************************************************************************/
+
+rrd_value_t hw_calculate_slope(
+    rrd_value_t hw_beta,
+    unival *coefs)
+{
+    return hw_beta * (coefs[CDP_hw_intercept].u_val -
+                      coefs[CDP_hw_last_intercept].u_val)
+        + (1 - hw_beta) * coefs[CDP_hw_slope].u_val;
+}
+
+rrd_value_t hw_calculate_seasonal_deviation(
+    rrd_value_t hw_gamma,
+    rrd_value_t prediction,
+    rrd_value_t observed,
+    rrd_value_t last)
+{
+    return hw_gamma * fabs(prediction - observed)
+        + (1 - hw_gamma) * last;
+}
+
+rrd_value_t hw_init_seasonal_deviation(
+    rrd_value_t prediction,
+    rrd_value_t observed)
+{
+    return fabs(prediction - observed);
+}
diff --git a/src/rrd_hw_math.h b/src/rrd_hw_math.h
new file mode 100644 (file)
index 0000000..3677b31
--- /dev/null
@@ -0,0 +1,132 @@
+/*****************************************************************************
+ * rrd_hw_math.h  Math functions for Holt-Winters computations
+ *****************************************************************************/
+
+#include "rrd.h"
+#include "rrd_format.h"
+
+/* since /usr/include/bits/mathcalls.h:265 defines gamma already */
+#define gamma hw_gamma
+
+/*****************************************************************************
+ * Functions for additive Holt-Winters
+ *****************************************************************************/
+
+rrd_value_t hw_additive_calculate_prediction(
+    rrd_value_t intercept,
+    rrd_value_t slope,
+    int null_count,
+    rrd_value_t seasonal_coef);
+
+rrd_value_t hw_additive_calculate_intercept(
+    rrd_value_t alpha,
+    rrd_value_t scratch,
+    rrd_value_t seasonal_coef,
+    unival *coefs);
+
+rrd_value_t hw_additive_calculate_seasonality(
+    rrd_value_t gamma,
+    rrd_value_t scratch,
+    rrd_value_t intercept,
+    rrd_value_t seasonal_coef);
+
+rrd_value_t hw_additive_init_seasonality(
+    rrd_value_t seasonal_coef,
+    rrd_value_t intercept);
+
+/*****************************************************************************
+ * Functions for multiplicative Holt-Winters
+ *****************************************************************************/
+
+rrd_value_t hw_multiplicative_calculate_prediction(
+    rrd_value_t intercept,
+    rrd_value_t slope,
+    int null_count,
+    rrd_value_t seasonal_coef);
+
+rrd_value_t hw_multiplicative_calculate_intercept(
+    rrd_value_t alpha,
+    rrd_value_t scratch,
+    rrd_value_t seasonal_coef,
+    unival *coefs);
+
+rrd_value_t hw_multiplicative_calculate_seasonality(
+    rrd_value_t gamma,
+    rrd_value_t scratch,
+    rrd_value_t intercept,
+    rrd_value_t seasonal_coef);
+
+rrd_value_t hw_multiplicative_init_seasonality(
+    rrd_value_t seasonal_coef,
+    rrd_value_t intercept);
+
+/*****************************************************************************
+ * Math functions common to additive and multiplicative Holt-Winters
+ *****************************************************************************/
+
+rrd_value_t hw_calculate_slope(
+    rrd_value_t beta,
+    unival *coefs);
+
+rrd_value_t hw_calculate_seasonal_deviation(
+    rrd_value_t gamma,
+    rrd_value_t prediction,
+    rrd_value_t observed,
+    rrd_value_t last);
+
+rrd_value_t hw_init_seasonal_deviation(
+    rrd_value_t prediction,
+    rrd_value_t observed);
+
+
+/* Function container */
+
+typedef struct hw_functions_t {
+    rrd_value_t (
+    *predict) (
+    rrd_value_t intercept,
+    rrd_value_t slope,
+    int null_count,
+    rrd_value_t seasonal_coef);
+
+    rrd_value_t (
+    *intercept) (
+    rrd_value_t alpha,
+    rrd_value_t observed,
+    rrd_value_t seasonal_coef,
+    unival *coefs);
+
+    rrd_value_t (
+    *slope)   (
+    rrd_value_t beta,
+    unival *coefs);
+
+    rrd_value_t (
+    *seasonality) (
+    rrd_value_t gamma,
+    rrd_value_t observed,
+    rrd_value_t intercept,
+    rrd_value_t seasonal_coef);
+
+    rrd_value_t (
+    *init_seasonality) (
+    rrd_value_t seasonal_coef,
+    rrd_value_t intercept);
+
+    rrd_value_t (
+    *seasonal_deviation) (
+    rrd_value_t gamma,
+    rrd_value_t prediction,
+    rrd_value_t observed,
+    rrd_value_t last);
+
+    rrd_value_t (
+    *init_seasonal_deviation) (
+    rrd_value_t prediction,
+    rrd_value_t observed);
+
+    rrd_value_t identity;
+} hw_functions_t;
+
+
+#undef gamma
diff --git a/src/rrd_hw_update.c b/src/rrd_hw_update.c
new file mode 100644 (file)
index 0000000..89d0c8e
--- /dev/null
@@ -0,0 +1,474 @@
+/*****************************************************************************
+ * rrd_hw_update.c  Functions for updating a Holt-Winters RRA
+ ****************************************************************************/
+
+#include "rrd_format.h"
+#include "rrd_config.h"
+#include "rrd_hw_math.h"
+#include "rrd_hw_update.h"
+
+static void init_slope_intercept(
+    unival *coefs,
+    unsigned short CDP_scratch_idx)
+{
+#ifdef DEBUG
+    fprintf(stderr, "Initialization of slope/intercept\n");
+#endif
+    coefs[CDP_hw_intercept].u_val = coefs[CDP_scratch_idx].u_val;
+    coefs[CDP_hw_last_intercept].u_val = coefs[CDP_scratch_idx].u_val;
+    /* initialize the slope to 0 */
+    coefs[CDP_hw_slope].u_val = 0.0;
+    coefs[CDP_hw_last_slope].u_val = 0.0;
+    /* initialize null count to 1 */
+    coefs[CDP_null_count].u_cnt = 1;
+    coefs[CDP_last_null_count].u_cnt = 1;
+}
+
+static int hw_is_violation(
+    rrd_value_t observed,
+    rrd_value_t prediction,
+    rrd_value_t deviation,
+    rrd_value_t delta_pos,
+    rrd_value_t delta_neg)
+{
+    return (observed > prediction + delta_pos * deviation
+            || observed < prediction - delta_neg * deviation);
+}
+
+int update_hwpredict(
+    rrd_t *rrd,
+    unsigned long cdp_idx,
+    unsigned long rra_idx,
+    unsigned long ds_idx,
+    unsigned short CDP_scratch_idx,
+    hw_functions_t * functions)
+{
+    rrd_value_t prediction;
+    unsigned long dependent_rra_idx, seasonal_cdp_idx;
+    unival   *coefs = rrd->cdp_prep[cdp_idx].scratch;
+    rra_def_t *current_rra = &(rrd->rra_def[rra_idx]);
+
+    /* save coefficients from current prediction */
+    coefs[CDP_hw_last_intercept].u_val = coefs[CDP_hw_intercept].u_val;
+    coefs[CDP_hw_last_slope].u_val = coefs[CDP_hw_slope].u_val;
+    coefs[CDP_last_null_count].u_cnt = coefs[CDP_null_count].u_cnt;
+
+    /* retrieve the current seasonal coef */
+    dependent_rra_idx = current_rra->par[RRA_dependent_rra_idx].u_cnt;
+    seasonal_cdp_idx = dependent_rra_idx * (rrd->stat_head->ds_cnt) + ds_idx;
+
+    rrd_value_t seasonal_coef = (dependent_rra_idx < rra_idx)
+        ? rrd->cdp_prep[seasonal_cdp_idx].scratch[CDP_hw_last_seasonal].u_val
+        : rrd->cdp_prep[seasonal_cdp_idx].scratch[CDP_hw_seasonal].u_val;
+
+    /* compute the prediction */
+    if (isnan(coefs[CDP_hw_intercept].u_val)
+        || isnan(coefs[CDP_hw_slope].u_val)
+        || isnan(seasonal_coef)) {
+        prediction = DNAN;
+
+        /* bootstrap initialization of slope and intercept */
+        if (isnan(coefs[CDP_hw_intercept].u_val) &&
+            !isnan(coefs[CDP_scratch_idx].u_val)) {
+            init_slope_intercept(coefs, CDP_scratch_idx);
+        }
+        /* if seasonal coefficient is NA, then don't update intercept, slope */
+    } else {
+        prediction = functions->predict(coefs[CDP_hw_intercept].u_val,
+                                        coefs[CDP_hw_slope].u_val,
+                                        coefs[CDP_null_count].u_cnt,
+                                        seasonal_coef);
+#ifdef DEBUG
+        fprintf(stderr,
+                "computed prediction: %f (intercept %f, slope %f, season %f)\n",
+                prediction, coefs[CDP_hw_intercept].u_val,
+                coefs[CDP_hw_slope].u_val, seasonal_coef);
+#endif
+        if (isnan(coefs[CDP_scratch_idx].u_val)) {
+            /* NA value, no updates of intercept, slope;
+             * increment the null count */
+            (coefs[CDP_null_count].u_cnt)++;
+        } else {
+            /* update the intercept */
+            coefs[CDP_hw_intercept].u_val =
+                functions->intercept(current_rra->par[RRA_hw_alpha].u_val,
+                                     coefs[CDP_scratch_idx].u_val,
+                                     seasonal_coef, coefs);
+
+            /* update the slope */
+            coefs[CDP_hw_slope].u_val =
+                functions->slope(current_rra->par[RRA_hw_beta].u_val, coefs);
+
+            /* reset the null count */
+            coefs[CDP_null_count].u_cnt = 1;
+#ifdef DEBUG
+            fprintf(stderr, "Updating intercept = %f, slope = %f\n",
+                    coefs[CDP_hw_intercept].u_val, coefs[CDP_hw_slope].u_val);
+#endif
+        }
+    }
+
+    /* store the prediction for writing */
+    coefs[CDP_scratch_idx].u_val = prediction;
+    return 0;
+}
+
+int update_seasonal(
+    rrd_t *rrd,
+    unsigned long cdp_idx,
+    unsigned long rra_idx,
+    unsigned long ds_idx,
+    unsigned short CDP_scratch_idx,
+    rrd_value_t *seasonal_coef,
+    hw_functions_t * functions)
+{
+/* TODO: extract common if subblocks in the wake of I/O optimization */
+    rrd_value_t intercept, seasonal;
+    rra_def_t *current_rra = &(rrd->rra_def[rra_idx]);
+    rra_def_t *hw_rra =
+        &(rrd->rra_def[current_rra->par[RRA_dependent_rra_idx].u_cnt]);
+
+    /* obtain cdp_prep index for HWPREDICT */
+    unsigned long hw_cdp_idx = (current_rra->par[RRA_dependent_rra_idx].u_cnt)
+        * (rrd->stat_head->ds_cnt) + ds_idx;
+    unival   *coefs = rrd->cdp_prep[hw_cdp_idx].scratch;
+
+    /* update seasonal coefficient in cdp prep areas */
+    seasonal = rrd->cdp_prep[cdp_idx].scratch[CDP_hw_seasonal].u_val;
+    rrd->cdp_prep[cdp_idx].scratch[CDP_hw_last_seasonal].u_val = seasonal;
+    rrd->cdp_prep[cdp_idx].scratch[CDP_hw_seasonal].u_val =
+        seasonal_coef[ds_idx];
+
+    if (isnan(rrd->cdp_prep[cdp_idx].scratch[CDP_scratch_idx].u_val)) {
+        /* no update, store the old value unchanged,
+         * doesn't matter if it is NA */
+        rrd->cdp_prep[cdp_idx].scratch[CDP_scratch_idx].u_val = seasonal;
+        return 0;
+    }
+
+    /* update seasonal value for disk */
+    if (current_rra->par[RRA_dependent_rra_idx].u_cnt < rra_idx) {
+        /* associated HWPREDICT has already been updated */
+        /* check for possible NA values */
+        if (isnan(coefs[CDP_hw_last_intercept].u_val)
+            || isnan(coefs[CDP_hw_last_slope].u_val)) {
+            /* this should never happen, as HWPREDICT was already updated */
+            rrd->cdp_prep[cdp_idx].scratch[CDP_scratch_idx].u_val = DNAN;
+        } else if (isnan(seasonal)) {
+            /* initialization: intercept is not currently being updated */
+#ifdef DEBUG
+            fprintf(stderr, "Initialization of seasonal coef %lu\n",
+                    rrd->rra_ptr[rra_idx].cur_row);
+#endif
+            rrd->cdp_prep[cdp_idx].scratch[CDP_scratch_idx].u_val =
+                functions->init_seasonality(rrd->cdp_prep[cdp_idx].
+                                            scratch[CDP_scratch_idx].u_val,
+                                            coefs[CDP_hw_last_intercept].
+                                            u_val);
+        } else {
+            intercept = coefs[CDP_hw_intercept].u_val;
+
+            rrd->cdp_prep[cdp_idx].scratch[CDP_scratch_idx].u_val =
+                functions->seasonality(current_rra->par[RRA_seasonal_gamma].
+                                       u_val,
+                                       rrd->cdp_prep[cdp_idx].
+                                       scratch[CDP_scratch_idx].u_val,
+                                       intercept, seasonal);
+#ifdef DEBUG
+            fprintf(stderr,
+                    "Updating seasonal = %f (params: gamma %f, new intercept %f, old seasonal %f)\n",
+                    rrd->cdp_prep[cdp_idx].scratch[CDP_scratch_idx].u_val,
+                    current_rra->par[RRA_seasonal_gamma].u_val,
+                    intercept, seasonal);
+#endif
+        }
+    } else {
+        /* SEASONAL array is updated first, which means the new intercept
+         * hasn't be computed; so we compute it here. */
+
+        /* check for possible NA values */
+        if (isnan(coefs[CDP_hw_intercept].u_val)
+            || isnan(coefs[CDP_hw_slope].u_val)) {
+            /* Initialization of slope and intercept will occur.
+             * force seasonal coefficient to 0 or 1. */
+            rrd->cdp_prep[cdp_idx].scratch[CDP_scratch_idx].u_val =
+                functions->identity;
+        } else if (isnan(seasonal)) {
+            /* initialization: intercept will not be updated
+             * CDP_hw_intercept = CDP_hw_last_intercept; just need to 
+             * subtract/divide by this baseline value. */
+#ifdef DEBUG
+            fprintf(stderr, "Initialization of seasonal coef %lu\n",
+                    rrd->rra_ptr[rra_idx].cur_row);
+#endif
+            rrd->cdp_prep[cdp_idx].scratch[CDP_scratch_idx].u_val =
+                functions->init_seasonality(rrd->cdp_prep[cdp_idx].
+                                            scratch[CDP_scratch_idx].u_val,
+                                            coefs[CDP_hw_intercept].u_val);
+        } else {
+            /* Note that we must get CDP_scratch_idx from SEASONAL array, as CDP_scratch_idx
+             * for HWPREDICT array will be DNAN. */
+            intercept = functions->intercept(hw_rra->par[RRA_hw_alpha].u_val,
+                                             rrd->cdp_prep[cdp_idx].
+                                             scratch[CDP_scratch_idx].u_val,
+                                             seasonal, coefs);
+
+            rrd->cdp_prep[cdp_idx].scratch[CDP_scratch_idx].u_val =
+                functions->seasonality(current_rra->par[RRA_seasonal_gamma].
+                                       u_val,
+                                       rrd->cdp_prep[cdp_idx].
+                                       scratch[CDP_scratch_idx].u_val,
+                                       intercept, seasonal);
+        }
+    }
+#ifdef DEBUG
+    fprintf(stderr, "seasonal coefficient set= %f\n",
+            rrd->cdp_prep[cdp_idx].scratch[CDP_scratch_idx].u_val);
+#endif
+    return 0;
+}
+
+int update_devpredict(
+    rrd_t *rrd,
+    unsigned long cdp_idx,
+    unsigned long rra_idx,
+    unsigned long ds_idx,
+    unsigned short CDP_scratch_idx)
+{
+    /* there really isn't any "update" here; the only reason this information
+     * is stored separately from DEVSEASONAL is to preserve deviation predictions
+     * for a longer duration than one seasonal cycle. */
+    unsigned long seasonal_cdp_idx =
+        (rrd->rra_def[rra_idx].par[RRA_dependent_rra_idx].u_cnt)
+        * (rrd->stat_head->ds_cnt) + ds_idx;
+
+    if (rrd->rra_def[rra_idx].par[RRA_dependent_rra_idx].u_cnt < rra_idx) {
+        /* associated DEVSEASONAL array already updated */
+        rrd->cdp_prep[cdp_idx].scratch[CDP_scratch_idx].u_val
+            =
+            rrd->cdp_prep[seasonal_cdp_idx].
+            scratch[CDP_last_seasonal_deviation].u_val;
+    } else {
+        /* associated DEVSEASONAL not yet updated */
+        rrd->cdp_prep[cdp_idx].scratch[CDP_scratch_idx].u_val
+            =
+            rrd->cdp_prep[seasonal_cdp_idx].scratch[CDP_seasonal_deviation].
+            u_val;
+    }
+    return 0;
+}
+
+int update_devseasonal(
+    rrd_t *rrd,
+    unsigned long cdp_idx,
+    unsigned long rra_idx,
+    unsigned long ds_idx,
+    unsigned short CDP_scratch_idx,
+    rrd_value_t *seasonal_dev,
+    hw_functions_t * functions)
+{
+    rrd_value_t prediction = 0, seasonal_coef = DNAN;
+    rra_def_t *current_rra = &(rrd->rra_def[rra_idx]);
+
+    /* obtain cdp_prep index for HWPREDICT */
+    unsigned long hw_rra_idx = current_rra->par[RRA_dependent_rra_idx].u_cnt;
+    unsigned long hw_cdp_idx = hw_rra_idx * (rrd->stat_head->ds_cnt) + ds_idx;
+    unsigned long seasonal_cdp_idx;
+    unival   *coefs = rrd->cdp_prep[hw_cdp_idx].scratch;
+
+    rrd->cdp_prep[cdp_idx].scratch[CDP_last_seasonal_deviation].u_val =
+        rrd->cdp_prep[cdp_idx].scratch[CDP_seasonal_deviation].u_val;
+    /* retrieve the next seasonal deviation value, could be NA */
+    rrd->cdp_prep[cdp_idx].scratch[CDP_seasonal_deviation].u_val =
+        seasonal_dev[ds_idx];
+
+    /* retrieve the current seasonal_coef (not to be confused with the
+     * current seasonal deviation). Could make this more readable by introducing
+     * some wrapper functions. */
+    seasonal_cdp_idx =
+        (rrd->rra_def[hw_rra_idx].par[RRA_dependent_rra_idx].u_cnt)
+        * (rrd->stat_head->ds_cnt) + ds_idx;
+    if (rrd->rra_def[hw_rra_idx].par[RRA_dependent_rra_idx].u_cnt < rra_idx)
+        /* SEASONAL array already updated */
+        seasonal_coef =
+            rrd->cdp_prep[seasonal_cdp_idx].scratch[CDP_hw_last_seasonal].
+            u_val;
+    else
+        /* SEASONAL array not yet updated */
+        seasonal_coef =
+            rrd->cdp_prep[seasonal_cdp_idx].scratch[CDP_hw_seasonal].u_val;
+
+    /* compute the abs value of the difference between the prediction and
+     * observed value */
+    if (hw_rra_idx < rra_idx) {
+        /* associated HWPREDICT has already been updated */
+        if (isnan(coefs[CDP_hw_last_intercept].u_val) ||
+            isnan(coefs[CDP_hw_last_slope].u_val) || isnan(seasonal_coef)) {
+            /* one of the prediction values is uinitialized */
+            rrd->cdp_prep[cdp_idx].scratch[CDP_scratch_idx].u_val = DNAN;
+            return 0;
+        } else {
+            prediction =
+                functions->predict(coefs[CDP_hw_last_intercept].u_val,
+                                   coefs[CDP_hw_last_slope].u_val,
+                                   coefs[CDP_last_null_count].u_cnt,
+                                   seasonal_coef);
+        }
+    } else {
+        /* associated HWPREDICT has NOT been updated */
+        if (isnan(coefs[CDP_hw_intercept].u_val) ||
+            isnan(coefs[CDP_hw_slope].u_val) || isnan(seasonal_coef)) {
+            /* one of the prediction values is uinitialized */
+            rrd->cdp_prep[cdp_idx].scratch[CDP_scratch_idx].u_val = DNAN;
+            return 0;
+        } else {
+            prediction = functions->predict(coefs[CDP_hw_intercept].u_val,
+                                            coefs[CDP_hw_slope].u_val,
+                                            coefs[CDP_null_count].u_cnt,
+                                            seasonal_coef);
+        }
+    }
+
+    if (isnan(rrd->cdp_prep[cdp_idx].scratch[CDP_scratch_idx].u_val)) {
+        /* no update, store existing value unchanged, doesn't
+         * matter if it is NA */
+        rrd->cdp_prep[cdp_idx].scratch[CDP_scratch_idx].u_val =
+            rrd->cdp_prep[cdp_idx].scratch[CDP_last_seasonal_deviation].u_val;
+    } else
+        if (isnan
+            (rrd->cdp_prep[cdp_idx].scratch[CDP_last_seasonal_deviation].
+             u_val)) {
+        /* initialization */
+#ifdef DEBUG
+        fprintf(stderr, "Initialization of seasonal deviation\n");
+#endif
+        rrd->cdp_prep[cdp_idx].scratch[CDP_scratch_idx].u_val =
+            functions->init_seasonal_deviation(prediction,
+                                               rrd->cdp_prep[cdp_idx].
+                                               scratch[CDP_scratch_idx].
+                                               u_val);
+    } else {
+        /* exponential smoothing update */
+        rrd->cdp_prep[cdp_idx].scratch[CDP_scratch_idx].u_val =
+            functions->seasonal_deviation(rrd->rra_def[rra_idx].
+                                          par[RRA_seasonal_gamma].u_val,
+                                          prediction,
+                                          rrd->cdp_prep[cdp_idx].
+                                          scratch[CDP_scratch_idx].u_val,
+                                          rrd->cdp_prep[cdp_idx].
+                                          scratch
+                                          [CDP_last_seasonal_deviation].
+                                          u_val);
+    }
+    return 0;
+}
+
+/* Check for a failure based on a threshold # of violations within the specified
+ * window. */
+int update_failures(
+    rrd_t *rrd,
+    unsigned long cdp_idx,
+    unsigned long rra_idx,
+    unsigned long ds_idx,
+    unsigned short CDP_scratch_idx,
+    hw_functions_t * functions)
+{
+    /* detection of a violation depends on 3 RRAs:
+     * HWPREDICT, SEASONAL, and DEVSEASONAL */
+    rra_def_t *current_rra = &(rrd->rra_def[rra_idx]);
+    unsigned long dev_rra_idx = current_rra->par[RRA_dependent_rra_idx].u_cnt;
+    rra_def_t *dev_rra = &(rrd->rra_def[dev_rra_idx]);
+    unsigned long hw_rra_idx = dev_rra->par[RRA_dependent_rra_idx].u_cnt;
+    rra_def_t *hw_rra = &(rrd->rra_def[hw_rra_idx]);
+    unsigned long seasonal_rra_idx = hw_rra->par[RRA_dependent_rra_idx].u_cnt;
+    unsigned long temp_cdp_idx;
+    rrd_value_t deviation = DNAN;
+    rrd_value_t seasonal_coef = DNAN;
+    rrd_value_t prediction = DNAN;
+    char      violation = 0;
+    unsigned short violation_cnt = 0, i;
+    char     *violations_array;
+
+    /* usual checks to determine the order of the RRAs */
+    temp_cdp_idx = dev_rra_idx * (rrd->stat_head->ds_cnt) + ds_idx;
+    if (rra_idx < seasonal_rra_idx) {
+        /* DEVSEASONAL not yet updated */
+        deviation =
+            rrd->cdp_prep[temp_cdp_idx].scratch[CDP_seasonal_deviation].u_val;
+    } else {
+        /* DEVSEASONAL already updated */
+        deviation =
+            rrd->cdp_prep[temp_cdp_idx].scratch[CDP_last_seasonal_deviation].
+            u_val;
+    }
+    if (!isnan(deviation)) {
+
+        temp_cdp_idx = seasonal_rra_idx * (rrd->stat_head->ds_cnt) + ds_idx;
+        if (rra_idx < seasonal_rra_idx) {
+            /* SEASONAL not yet updated */
+            seasonal_coef =
+                rrd->cdp_prep[temp_cdp_idx].scratch[CDP_hw_seasonal].u_val;
+        } else {
+            /* SEASONAL already updated */
+            seasonal_coef =
+                rrd->cdp_prep[temp_cdp_idx].scratch[CDP_hw_last_seasonal].
+                u_val;
+        }
+        /* in this code block, we know seasonal coef is not DNAN, because deviation is not
+         * null */
+
+        temp_cdp_idx = hw_rra_idx * (rrd->stat_head->ds_cnt) + ds_idx;
+        if (rra_idx < hw_rra_idx) {
+            /* HWPREDICT not yet updated */
+            prediction =
+                functions->predict(rrd->cdp_prep[temp_cdp_idx].
+                                   scratch[CDP_hw_intercept].u_val,
+                                   rrd->cdp_prep[temp_cdp_idx].
+                                   scratch[CDP_hw_slope].u_val,
+                                   rrd->cdp_prep[temp_cdp_idx].
+                                   scratch[CDP_null_count].u_cnt,
+                                   seasonal_coef);
+        } else {
+            /* HWPREDICT already updated */
+            prediction =
+                functions->predict(rrd->cdp_prep[temp_cdp_idx].
+                                   scratch[CDP_hw_last_intercept].u_val,
+                                   rrd->cdp_prep[temp_cdp_idx].
+                                   scratch[CDP_hw_last_slope].u_val,
+                                   rrd->cdp_prep[temp_cdp_idx].
+                                   scratch[CDP_last_null_count].u_cnt,
+                                   seasonal_coef);
+        }
+
+        /* determine if the observed value is a violation */
+        if (!isnan(rrd->cdp_prep[cdp_idx].scratch[CDP_scratch_idx].u_val)) {
+            if (hw_is_violation
+                (rrd->cdp_prep[cdp_idx].scratch[CDP_scratch_idx].u_val,
+                 prediction, deviation, current_rra->par[RRA_delta_pos].u_val,
+                 current_rra->par[RRA_delta_neg].u_val)) {
+                violation = 1;
+            }
+        } else {
+            violation = 1;  /* count DNAN values as violations */
+        }
+
+    }
+
+    /* determine if a failure has occurred and update the failure array */
+    violation_cnt = violation;
+    violations_array = (char *) ((void *) rrd->cdp_prep[cdp_idx].scratch);
+    for (i = current_rra->par[RRA_window_len].u_cnt; i > 1; i--) {
+        /* shift */
+        violations_array[i - 1] = violations_array[i - 2];
+        violation_cnt += violations_array[i - 1];
+    }
+    violations_array[0] = violation;
+
+    if (violation_cnt < current_rra->par[RRA_failure_threshold].u_cnt)
+        /* not a failure */
+        rrd->cdp_prep[cdp_idx].scratch[CDP_scratch_idx].u_val = 0.0;
+    else
+        rrd->cdp_prep[cdp_idx].scratch[CDP_scratch_idx].u_val = 1.0;
+
+    return (rrd->cdp_prep[cdp_idx].scratch[CDP_scratch_idx].u_val);
+}
diff --git a/src/rrd_hw_update.h b/src/rrd_hw_update.h
new file mode 100644 (file)
index 0000000..e59e2db
--- /dev/null
@@ -0,0 +1,44 @@
+/*****************************************************************************
+ * rrd_hw_update.h  Functions for updating a Holt-Winters RRA
+ ****************************************************************************/
+
+int       update_hwpredict(
+    rrd_t *rrd,
+    unsigned long cdp_idx,
+    unsigned long rra_idx,
+    unsigned long ds_idx,
+    unsigned short CDP_scratch_idx,
+    hw_functions_t * functions);
+
+int       update_seasonal(
+    rrd_t *rrd,
+    unsigned long cdp_idx,
+    unsigned long rra_idx,
+    unsigned long ds_idx,
+    unsigned short CDP_scratch_idx,
+    rrd_value_t *seasonal_coef,
+    hw_functions_t * functions);
+
+int       update_devpredict(
+    rrd_t *rrd,
+    unsigned long cdp_idx,
+    unsigned long rra_idx,
+    unsigned long ds_idx,
+    unsigned short CDP_scratch_idx);
+
+int       update_devseasonal(
+    rrd_t *rrd,
+    unsigned long cdp_idx,
+    unsigned long rra_idx,
+    unsigned long ds_idx,
+    unsigned short CDP_scratch_idx,
+    rrd_value_t *seasonal_dev,
+    hw_functions_t * functions);
+
+int       update_failures(
+    rrd_t *rrd,
+    unsigned long cdp_idx,
+    unsigned long rra_idx,
+    unsigned long ds_idx,
+    unsigned short CDP_scratch_idx,
+    hw_functions_t * functions);
diff --git a/src/rrd_i18n.h b/src/rrd_i18n.h
new file mode 100644 (file)
index 0000000..a75a836
--- /dev/null
@@ -0,0 +1,31 @@
+/*****************************************************************************
+ * RRDtool 1.3rc4  Copyright by Takao Fujiwara, 2008
+ *****************************************************************************
+ * rrd_i18n.h   Common Header File
+ *****************************************************************************/
+#ifdef  __cplusplus
+extern    "C" {
+#endif
+
+
+#ifndef _RRD_I18N_H
+#define _RRD_I18N_H
+
+#ifndef _
+/* This is for other GNU distributions with internationalized messages.
+   When compiling libc, the _ macro is predefined.  */
+#if defined(HAVE_LIBINTL_H) && defined(BUILD_LIBINTL)
+#  include <libintl.h>
+#define _(String) gettext (String)
+#else
+#define _(String) (String)
+#endif
+#define N_(String) (String)
+#endif
+
+
+#endif
+
+#ifdef  __cplusplus
+}
+#endif
index b2a55d959c923e8697600c913d965b195074ad13..389607d2c091edcb1604b2c964f14f1beee7a71c 100644 (file)
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * RRDtool 1.2.27  Copyright by Tobi Oetiker, 1997-2008
+ * RRDtool 1.3rc4  Copyright by Tobi Oetiker, 1997-2008
  *****************************************************************************
  * rrd_info  Get Information about the configuration of an RRD
  *****************************************************************************/
 #include <stdarg.h>
 
 /* proto */
-info_t *rrd_info(int, char **);
-info_t *rrd_info_r(char *filename);
+info_t   *rrd_info(
+    int,
+    char **);
+info_t   *rrd_info_r(
+    char *filename);
 
 /* allocate memory for string */
-char *
-sprintf_alloc(char *fmt, ...) {
-#ifdef HAVE_VSNPRINTF    
-    int maxlen = 50;
+char     *sprintf_alloc(
+    char *fmt,
+    ...)
+{
+#ifdef HAVE_VSNPRINTF
+    int       maxlen = 50;
 #else
-    int maxlen = 1000;
+    int       maxlen = 1000;
 #endif
-    char *str = NULL;
-    va_list argp;
-    str = malloc(sizeof(char)*(strlen(fmt)+maxlen));
+    char     *str = NULL;
+    va_list   argp;
+    str = malloc(sizeof(char) * (strlen(fmt) + maxlen));
     if (str != NULL) {
-       va_start(argp, fmt);
+        va_start(argp, fmt);
 #ifdef HAVE_VSNPRINTF
-       vsnprintf(str, maxlen-1, fmt, argp);
+        vsnprintf(str, maxlen - 1, fmt, argp);
 #else
-       vsprintf(str, fmt, argp);
+        vsprintf(str, fmt, argp);
 #endif
     }
     va_end(argp);
     return str;
 }
+
 /* the function formerly known as push was renamed info_push because
  * it is now used outside the scope of this file */
-info_t 
-*info_push(info_t *info, char *key, enum info_type type, infoval value){
-    info_t *next;
+info_t
+         *info_push(
+    info_t *info,
+    char *key,
+    enum info_type type,
+    infoval value)
+{
+    info_t   *next;
+
     next = malloc(sizeof(*next));
     next->next = (info_t *) 0;
-    if( info )
-       info->next = next;
+    if (info)
+        info->next = next;
     next->type = type;
-    next->key  = key;
+    next->key = key;
     switch (type) {
     case RD_I_VAL:
-       next->value.u_val = value.u_val;
-       break;
+        next->value.u_val = value.u_val;
+        break;
     case RD_I_CNT:
-       next->value.u_cnt = value.u_cnt;
-       break;
+        next->value.u_cnt = value.u_cnt;
+        break;
     case RD_I_INT:
-       next->value.u_int = value.u_int;
-       break;
+        next->value.u_int = value.u_int;
+        break;
     case RD_I_STR:
-       next->value.u_str = malloc(sizeof(char)*(strlen(value.u_str)+1));
-       strcpy(next->value.u_str,value.u_str);
-       break;
+        next->value.u_str = malloc(sizeof(char) * (strlen(value.u_str) + 1));
+        strcpy(next->value.u_str, value.u_str);
+        break;
+    case RD_I_BLO:
+        next->value.u_blo.size = value.u_blo.size;
+        next->value.u_blo.ptr =
+            malloc(sizeof(unsigned char) * value.u_blo.size);
+        memcpy(next->value.u_blo.ptr, value.u_blo.ptr, value.u_blo.size);
+        break;
     }
-    return(next);
+    return (next);
 }
 
 
-info_t *
-rrd_info(int argc, char **argv) {   
-    info_t             *info;
+info_t   *rrd_info(
+    int argc,
+    char **argv)
+{
+    info_t   *info;
 
-    if(argc < 2){
+    if (argc < 2) {
         rrd_set_error("please specify an rrd");
         return NULL;
     }
 
     info = rrd_info_r(argv[1]);
 
-    return(info);
+    return (info);
 }
 
 
-  
-info_t *
-rrd_info_r(char *filename) {   
-    unsigned int i,ii=0;
-    FILE         *in_file;
-    rrd_t        rrd;
-    info_t       *data,*cd;
-    infoval      info;
-       enum cf_en   current_cf;
-       enum dst_en  current_ds;
 
-    if(rrd_open(filename,&in_file,&rrd, RRD_READONLY)==-1){
-       return(NULL);
+info_t   *rrd_info_r(
+    char *filename)
+{
+    unsigned int i, ii = 0;
+    rrd_t     rrd;
+    info_t   *data = NULL, *cd;
+    infoval   info;
+    rrd_file_t *rrd_file;
+    enum cf_en current_cf;
+    enum dst_en current_ds;
+
+    rrd_file = rrd_open(filename, &rrd, RRD_READONLY);
+    if (rrd_file == NULL)
+        goto err_free;
+
+    info.u_str = filename;
+    cd = info_push(NULL, sprintf_alloc("filename"), RD_I_STR, info);
+    data = cd;
+
+    info.u_str = rrd.stat_head->version;
+    cd = info_push(cd, sprintf_alloc("rrd_version"), RD_I_STR, info);
+
+    info.u_cnt = rrd.stat_head->pdp_step;
+    cd = info_push(cd, sprintf_alloc("step"), RD_I_CNT, info);
+
+    info.u_cnt = rrd.live_head->last_up;
+    cd = info_push(cd, sprintf_alloc("last_update"), RD_I_CNT, info);
+
+    for (i = 0; i < rrd.stat_head->ds_cnt; i++) {
+
+        info.u_str = rrd.ds_def[i].dst;
+        cd = info_push(cd, sprintf_alloc("ds[%s].type", rrd.ds_def[i].ds_nam),
+                       RD_I_STR, info);
+
+        current_ds = dst_conv(rrd.ds_def[i].dst);
+        switch (current_ds) {
+        case DST_CDEF:
+        {
+            char     *buffer = NULL;
+
+            rpn_compact2str((rpn_cdefds_t *) &(rrd.ds_def[i].par[DS_cdef]),
+                            rrd.ds_def, &buffer);
+            info.u_str = buffer;
+            cd = info_push(cd,
+                           sprintf_alloc("ds[%s].cdef", rrd.ds_def[i].ds_nam),
+                           RD_I_STR, info);
+            free(buffer);
+        }
+            break;
+        default:
+            info.u_cnt = rrd.ds_def[i].par[DS_mrhb_cnt].u_cnt;
+            cd = info_push(cd,
+                           sprintf_alloc("ds[%s].minimal_heartbeat",
+                                         rrd.ds_def[i].ds_nam), RD_I_CNT,
+                           info);
+
+            info.u_val = rrd.ds_def[i].par[DS_min_val].u_val;
+            cd = info_push(cd,
+                           sprintf_alloc("ds[%s].min", rrd.ds_def[i].ds_nam),
+                           RD_I_VAL, info);
+
+            info.u_val = rrd.ds_def[i].par[DS_max_val].u_val;
+            cd = info_push(cd,
+                           sprintf_alloc("ds[%s].max", rrd.ds_def[i].ds_nam),
+                           RD_I_VAL, info);
+            break;
+        }
+
+        info.u_str = rrd.pdp_prep[i].last_ds;
+        cd = info_push(cd,
+                       sprintf_alloc("ds[%s].last_ds", rrd.ds_def[i].ds_nam),
+                       RD_I_STR, info);
+
+        info.u_val = rrd.pdp_prep[i].scratch[PDP_val].u_val;
+        cd = info_push(cd,
+                       sprintf_alloc("ds[%s].value", rrd.ds_def[i].ds_nam),
+                       RD_I_VAL, info);
+
+        info.u_cnt = rrd.pdp_prep[i].scratch[PDP_unkn_sec_cnt].u_cnt;
+        cd = info_push(cd,
+                       sprintf_alloc("ds[%s].unknown_sec",
+                                     rrd.ds_def[i].ds_nam), RD_I_CNT, info);
     }
-    fclose(in_file);
-
-    info.u_str=filename;
-    cd=info_push(NULL,sprintf_alloc("filename"),    RD_I_STR, info);
-    data=cd;
-
-    info.u_str=rrd.stat_head->version;
-    cd=info_push(cd,sprintf_alloc("rrd_version"),    RD_I_STR, info);
-
-    info.u_cnt=rrd.stat_head->pdp_step;
-    cd=info_push(cd,sprintf_alloc("step"),       RD_I_CNT, info);
-
-    info.u_cnt=rrd.live_head->last_up;
-    cd=info_push(cd,sprintf_alloc("last_update"), RD_I_CNT, info);
-
-    for(i=0;i<rrd.stat_head->ds_cnt;i++){
-
-       info.u_str=rrd.ds_def[i].dst;
-       cd=info_push(cd,sprintf_alloc("ds[%s].type",             rrd.ds_def[i].ds_nam), RD_I_STR, info);
-  
-       current_ds = dst_conv(rrd.ds_def[i].dst);
-    switch (current_ds) {
-          case DST_CDEF:
-                 {
-                 char *buffer = NULL;
-                 rpn_compact2str((rpn_cdefds_t *) &(rrd.ds_def[i].par[DS_cdef]),
-                        rrd.ds_def, &buffer);
-                 info.u_str = buffer;
-                 cd=info_push(cd,sprintf_alloc("ds[%s].cdef",rrd.ds_def[i].ds_nam),RD_I_STR,info);
-                 free(buffer);
-                 }
-                 break;
-          default:
-          info.u_cnt=rrd.ds_def[i].par[DS_mrhb_cnt].u_cnt;
-          cd=info_push(cd,sprintf_alloc("ds[%s].minimal_heartbeat",rrd.ds_def[i].ds_nam), RD_I_CNT, info);
-
-          info.u_val=rrd.ds_def[i].par[DS_min_val].u_val;
-          cd=info_push(cd,sprintf_alloc("ds[%s].min",rrd.ds_def[i].ds_nam), RD_I_VAL, info);
-       
-          info.u_val=rrd.ds_def[i].par[DS_max_val].u_val;
-          cd=info_push(cd,sprintf_alloc("ds[%s].max",rrd.ds_def[i].ds_nam), RD_I_VAL, info);
-          break;
-       }
-       
-       info.u_str=rrd.pdp_prep[i].last_ds;
-       cd=info_push(cd,sprintf_alloc("ds[%s].last_ds",          rrd.ds_def[i].ds_nam), RD_I_STR, info);
-
-       info.u_val=rrd.pdp_prep[i].scratch[PDP_val].u_val;
-        cd=info_push(cd,sprintf_alloc("ds[%s].value",            rrd.ds_def[i].ds_nam), RD_I_VAL, info);
-
-       info.u_cnt=rrd.pdp_prep[i].scratch[PDP_unkn_sec_cnt].u_cnt;
-       cd=info_push(cd,sprintf_alloc("ds[%s].unknown_sec",      rrd.ds_def[i].ds_nam), RD_I_CNT, info);
+
+    for (i = 0; i < rrd.stat_head->rra_cnt; i++) {
+        info.u_str = rrd.rra_def[i].cf_nam;
+        cd = info_push(cd, sprintf_alloc("rra[%d].cf", i), RD_I_STR, info);
+        current_cf = cf_conv(rrd.rra_def[i].cf_nam);
+
+        info.u_cnt = rrd.rra_def[i].row_cnt;
+        cd = info_push(cd, sprintf_alloc("rra[%d].rows", i), RD_I_CNT, info);
+
+        info.u_cnt = rrd.rra_ptr[i].cur_row;
+        cd = info_push(cd, sprintf_alloc("rra[%d].cur_row", i), RD_I_CNT,
+                       info);
+
+        info.u_cnt = rrd.rra_def[i].pdp_cnt;
+        cd = info_push(cd, sprintf_alloc("rra[%d].pdp_per_row", i), RD_I_CNT,
+                       info);
+
+        switch (current_cf) {
+        case CF_HWPREDICT:
+        case CF_MHWPREDICT:
+            info.u_val = rrd.rra_def[i].par[RRA_hw_alpha].u_val;
+            cd = info_push(cd, sprintf_alloc("rra[%d].alpha", i), RD_I_VAL,
+                           info);
+            info.u_val = rrd.rra_def[i].par[RRA_hw_beta].u_val;
+            cd = info_push(cd, sprintf_alloc("rra[%d].beta", i), RD_I_VAL,
+                           info);
+            break;
+        case CF_SEASONAL:
+        case CF_DEVSEASONAL:
+            info.u_val = rrd.rra_def[i].par[RRA_seasonal_gamma].u_val;
+            cd = info_push(cd, sprintf_alloc("rra[%d].gamma", i), RD_I_VAL,
+                           info);
+            if (atoi(rrd.stat_head->version) >= 4) {
+                info.u_val =
+                    rrd.rra_def[i].par[RRA_seasonal_smoothing_window].u_val;
+                cd = info_push(cd,
+                               sprintf_alloc("rra[%d].smoothing_window", i),
+                               RD_I_VAL, info);
+            }
+            break;
+        case CF_FAILURES:
+            info.u_val = rrd.rra_def[i].par[RRA_delta_pos].u_val;
+            cd = info_push(cd, sprintf_alloc("rra[%d].delta_pos", i),
+                           RD_I_VAL, info);
+            info.u_val = rrd.rra_def[i].par[RRA_delta_neg].u_val;
+            cd = info_push(cd, sprintf_alloc("rra[%d].delta_neg", i),
+                           RD_I_VAL, info);
+            info.u_cnt = rrd.rra_def[i].par[RRA_failure_threshold].u_cnt;
+            cd = info_push(cd, sprintf_alloc("rra[%d].failure_threshold", i),
+                           RD_I_CNT, info);
+            info.u_cnt = rrd.rra_def[i].par[RRA_window_len].u_cnt;
+            cd = info_push(cd, sprintf_alloc("rra[%d].window_length", i),
+                           RD_I_CNT, info);
+            break;
+        case CF_DEVPREDICT:
+            break;
+        default:
+            info.u_val = rrd.rra_def[i].par[RRA_cdp_xff_val].u_val;
+            cd = info_push(cd, sprintf_alloc("rra[%d].xff", i), RD_I_VAL,
+                           info);
+            break;
+        }
+
+        for (ii = 0; ii < rrd.stat_head->ds_cnt; ii++) {
+            switch (current_cf) {
+            case CF_HWPREDICT:
+            case CF_MHWPREDICT:
+                info.u_val =
+                    rrd.cdp_prep[i * rrd.stat_head->ds_cnt +
+                                 ii].scratch[CDP_hw_intercept].u_val;
+                cd = info_push(cd,
+                               sprintf_alloc("rra[%d].cdp_prep[%d].intercept",
+                                             i, ii), RD_I_VAL, info);
+                info.u_val =
+                    rrd.cdp_prep[i * rrd.stat_head->ds_cnt +
+                                 ii].scratch[CDP_hw_slope].u_val;
+                cd = info_push(cd,
+                               sprintf_alloc("rra[%d].cdp_prep[%d].slope", i,
+                                             ii), RD_I_VAL, info);
+                info.u_cnt =
+                    rrd.cdp_prep[i * rrd.stat_head->ds_cnt +
+                                 ii].scratch[CDP_null_count].u_cnt;
+                cd = info_push(cd,
+                               sprintf_alloc("rra[%d].cdp_prep[%d].NaN_count",
+                                             i, ii), RD_I_CNT, info);
+                break;
+            case CF_SEASONAL:
+                info.u_val =
+                    rrd.cdp_prep[i * rrd.stat_head->ds_cnt +
+                                 ii].scratch[CDP_hw_seasonal].u_val;
+                cd = info_push(cd,
+                               sprintf_alloc("rra[%d].cdp_prep[%d].seasonal",
+                                             i, ii), RD_I_VAL, info);
+                break;
+            case CF_DEVSEASONAL:
+                info.u_val =
+                    rrd.cdp_prep[i * rrd.stat_head->ds_cnt +
+                                 ii].scratch[CDP_seasonal_deviation].u_val;
+                cd = info_push(cd,
+                               sprintf_alloc("rra[%d].cdp_prep[%d].deviation",
+                                             i, ii), RD_I_VAL, info);
+                break;
+            case CF_DEVPREDICT:
+                break;
+            case CF_FAILURES:
+            {
+                unsigned short j;
+                char     *violations_array;
+                char      history[MAX_FAILURES_WINDOW_LEN + 1];
+
+                violations_array =
+                    (char *) rrd.cdp_prep[i * rrd.stat_head->ds_cnt +
+                                          ii].scratch;
+                for (j = 0; j < rrd.rra_def[i].par[RRA_window_len].u_cnt; ++j)
+                    history[j] = (violations_array[j] == 1) ? '1' : '0';
+                history[j] = '\0';
+                info.u_str = history;
+                cd = info_push(cd,
+                               sprintf_alloc("rra[%d].cdp_prep[%d].history",
+                                             i, ii), RD_I_STR, info);
+            }
+                break;
+            default:
+                info.u_val =
+                    rrd.cdp_prep[i * rrd.stat_head->ds_cnt +
+                                 ii].scratch[CDP_val].u_val;
+                cd = info_push(cd,
+                               sprintf_alloc("rra[%d].cdp_prep[%d].value", i,
+                                             ii), RD_I_VAL, info);
+                info.u_cnt =
+                    rrd.cdp_prep[i * rrd.stat_head->ds_cnt +
+                                 ii].scratch[CDP_unkn_pdp_cnt].u_cnt;
+                cd = info_push(cd,
+                               sprintf_alloc
+                               ("rra[%d].cdp_prep[%d].unknown_datapoints", i,
+                                ii), RD_I_CNT, info);
+                break;
+            }
+        }
     }
 
-    for(i=0;i<rrd.stat_head->rra_cnt;i++){
-       info.u_str=rrd.rra_def[i].cf_nam;
-       cd=info_push(cd,sprintf_alloc("rra[%d].cf",         i),  RD_I_STR,   info);
-       current_cf = cf_conv(rrd.rra_def[i].cf_nam);
-
-       info.u_cnt=rrd.rra_def[i].row_cnt;
-       cd=info_push(cd,sprintf_alloc("rra[%d].rows",i),  RD_I_CNT,   info);
-
-       info.u_cnt=rrd.rra_def[i].pdp_cnt;
-       cd=info_push(cd,sprintf_alloc("rra[%d].pdp_per_row",i),  RD_I_CNT,   info);
-
-       switch(current_cf)
-       {
-          case CF_HWPREDICT:
-                 info.u_val=rrd.rra_def[i].par[RRA_hw_alpha].u_val;
-                 cd=info_push(cd,sprintf_alloc("rra[%d].alpha",i),RD_I_VAL,info);
-                 info.u_val=rrd.rra_def[i].par[RRA_hw_beta].u_val;
-                 cd=info_push(cd,sprintf_alloc("rra[%d].beta",i),RD_I_VAL,info);
-                 break;
-          case CF_SEASONAL:
-          case CF_DEVSEASONAL:
-                 info.u_val=rrd.rra_def[i].par[RRA_seasonal_gamma].u_val;
-                 cd=info_push(cd,sprintf_alloc("rra[%d].gamma",i),RD_I_VAL,info);
-                 break;
-          case CF_FAILURES:
-                 info.u_val=rrd.rra_def[i].par[RRA_delta_pos].u_val;
-                 cd=info_push(cd,sprintf_alloc("rra[%d].delta_pos",i),RD_I_VAL,info);
-                 info.u_val=rrd.rra_def[i].par[RRA_delta_neg].u_val;
-                 cd=info_push(cd,sprintf_alloc("rra[%d].delta_neg",i),RD_I_VAL,info);
-                 info.u_cnt=rrd.rra_def[i].par[RRA_failure_threshold].u_cnt;
-                 cd=info_push(cd,sprintf_alloc("rra[%d].failure_threshold",i),RD_I_CNT,info);
-                 info.u_cnt=rrd.rra_def[i].par[RRA_window_len].u_cnt;
-                 cd=info_push(cd,sprintf_alloc("rra[%d].window_length",i),RD_I_CNT,info);
-                 break;
-          case CF_DEVPREDICT:
-                 break;
-          default:
-                 info.u_val=rrd.rra_def[i].par[RRA_cdp_xff_val].u_val;
-                 cd=info_push(cd,sprintf_alloc("rra[%d].xff",i),RD_I_VAL,info);
-                 break;
-       }
-
-       for(ii=0;ii<rrd.stat_head->ds_cnt;ii++){
-        switch(current_cf)
-               {
-               case CF_HWPREDICT:
-           info.u_val=rrd.cdp_prep[i*rrd.stat_head->ds_cnt+ii].scratch[CDP_hw_intercept].u_val;
-           cd=info_push(cd,sprintf_alloc("rra[%d].cdp_prep[%d].intercept",i,ii), RD_I_VAL, info);
-           info.u_val=rrd.cdp_prep[i*rrd.stat_head->ds_cnt+ii].scratch[CDP_hw_slope].u_val;
-           cd=info_push(cd,sprintf_alloc("rra[%d].cdp_prep[%d].slope",i,ii), RD_I_VAL, info);
-           info.u_cnt=rrd.cdp_prep[i*rrd.stat_head->ds_cnt+ii].scratch[CDP_null_count].u_cnt;
-           cd=info_push(cd,sprintf_alloc("rra[%d].cdp_prep[%d].NaN_count",i,ii), RD_I_CNT, info);
-                  break;
-               case CF_SEASONAL:
-           info.u_val=rrd.cdp_prep[i*rrd.stat_head->ds_cnt+ii].scratch[CDP_hw_seasonal].u_val;
-           cd=info_push(cd,sprintf_alloc("rra[%d].cdp_prep[%d].seasonal",i,ii), RD_I_VAL, info);
-                  break;
-               case CF_DEVSEASONAL:
-           info.u_val=rrd.cdp_prep[i*rrd.stat_head->ds_cnt+ii].scratch[CDP_seasonal_deviation].u_val;
-           cd=info_push(cd,sprintf_alloc("rra[%d].cdp_prep[%d].deviation",i,ii), RD_I_VAL, info);
-                  break;
-               case CF_DEVPREDICT:
-                  break;
-               case CF_FAILURES:
-                  {
-                         unsigned short j;
-                         char *violations_array;
-                         char history[MAX_FAILURES_WINDOW_LEN+1];
-                         violations_array = (char*) rrd.cdp_prep[i*rrd.stat_head->ds_cnt +ii].scratch;
-                         for (j = 0; j < rrd.rra_def[i].par[RRA_window_len].u_cnt; ++j)
-                                history[j] = (violations_array[j] == 1) ? '1' : '0';
-                     history[j] = '\0';
-                     info.u_str = history;
-                         cd=info_push(cd,sprintf_alloc("rra[%d].cdp_prep[%d].history",i,ii), RD_I_STR, info);
-                  }
-                  break;
-               default:
-           info.u_val=rrd.cdp_prep[i*rrd.stat_head->ds_cnt+ii].scratch[CDP_val].u_val;
-           cd=info_push(cd,sprintf_alloc("rra[%d].cdp_prep[%d].value",i,ii), RD_I_VAL, info);
-           info.u_cnt=rrd.cdp_prep[i*rrd.stat_head->ds_cnt+ii].scratch[CDP_unkn_pdp_cnt].u_cnt;
-           cd=info_push(cd,sprintf_alloc("rra[%d].cdp_prep[%d].unknown_datapoints",i,ii), RD_I_CNT, info);
-                  break;
+    rrd_close(rrd_file);
+  err_free:
+    rrd_free(&rrd);
+    return (data);
+}
+
+
+void info_print(
+    info_t *data)
+{
+    while (data) {
+        printf("%s = ", data->key);
+
+        switch (data->type) {
+        case RD_I_VAL:
+            if (isnan(data->value.u_val))
+                printf("NaN\n");
+            else
+                printf("%0.10e\n", data->value.u_val);
+            break;
+        case RD_I_CNT:
+            printf("%lu\n", data->value.u_cnt);
+            break;
+        case RD_I_INT:
+            printf("%d\n", data->value.u_int);
+            break;
+        case RD_I_STR:
+            printf("\"%s\"\n", data->value.u_str);
+            break;
+        case RD_I_BLO:
+            printf("BLOB_SIZE:%lu\n", data->value.u_blo.size);
+            fwrite(data->value.u_blo.ptr, data->value.u_blo.size, 1, stdout);
+            break;
         }
+        data = data->next;
     }
-       }
-       rrd_free(&rrd);
-    return(data);
+}
+
+void info_free(
+    info_t *data)
+{
+    info_t   *save;
 
+    while (data) {
+        save = data;
+        if (data->key) {
+            if (data->type == RD_I_STR) {
+                free(data->value.u_str);
+            }
+            if (data->type == RD_I_BLO) {
+                free(data->value.u_blo.ptr);
+            }
+            free(data->key);
+        }
+        data = data->next;
+        free(save);
+    }
 }
index 15d876df93a09e28401cb21e4d1440140c6651f2..800c538a4691ceeae4aac8a594d665e694696609 100644 (file)
@@ -1,19 +1,19 @@
 /*****************************************************************************
- * RRDtool 1.2.27  Copyright by Tobi Oetiker, 1997-2008
+ * RRDtool 1.3rc4  Copyright by Tobi Oetiker, 1997-2008
  * This file:     Copyright 2003 Peter Stamfest <peter@stamfest.at> 
  *                             & Tobias Oetiker
  * Distributed under the GPL
  *****************************************************************************
  * rrd_is_thread_safe.c   Poisons some nasty function calls using GNU cpp
  *****************************************************************************
- * $Id: rrd_is_thread_safe.h 1286 2008-02-17 10:08:10Z oetiker $
+ * $Id: rrd_is_thread_safe.h 1366 2008-05-18 13:06:44Z oetiker $
  *************************************************************************** */
 
 #ifndef _RRD_IS_THREAD_SAFE_H
 #define _RRD_IS_THREAD_SAFE_H
 
 #ifdef  __cplusplus
-extern "C" {
+extern    "C" {
 #endif
 
 #undef strerror
@@ -25,5 +25,4 @@ extern "C" {
 #ifdef  __cplusplus
 }
 #endif
-
 #endif /*_RRD_IS_THREAD_SAFE_H */
index a0a7cbbf785698da361e96c326300feba7a17dd0..c38b9db8f6f075b21c18d9a5686634dc800f7da7 100644 (file)
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * RRDtool 1.2.27  Copyright by Tobi Oetiker, 1997-2008
+ * RRDtool 1.3rc4  Copyright by Tobi Oetiker, 1997-2008
  *****************************************************************************
  * rrd_last.c
  *****************************************************************************
@@ -8,33 +8,32 @@
 
 #include "rrd_tool.h"
 
-time_t
-rrd_last(int argc, char **argv)
+time_t rrd_last(
+    int argc,
+    char **argv)
 {
-    if(argc < 2){
+    if (argc < 2) {
         rrd_set_error("please specify an rrd");
-        return(-1);
+        return (-1);
     }
 
-    return( rrd_last_r(argv[1]) );
+    return (rrd_last_r(argv[1]));
 }
 
-time_t
-rrd_last_r(const char *filename)
+
+time_t rrd_last_r(
+    const char *filename)
 {
-    FILE       *in_file;
-    time_t       lastup;
+    time_t    lastup = -1;
+    rrd_file_t *rrd_file;
 
-    rrd_t       rrd;
+    rrd_t     rrd;
 
-    if(rrd_open(filename, &in_file, &rrd, RRD_READONLY)==-1){
-        return(-1);
+    rrd_file = rrd_open(filename, &rrd, RRD_READONLY);
+    if (rrd_file != NULL) {
+        lastup = rrd.live_head->last_up;
+        rrd_close(rrd_file);
     }
-    lastup = rrd.live_head->last_up;
     rrd_free(&rrd);
-    fclose(in_file);
-    return(lastup);
+    return (lastup);
 }
-
-
index 159aafaf28ef7f01e921fc01eed1c3118e186894..b42194cc1b0e60d6d9e3313733124f857b322260 100644 (file)
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * RRDtool 1.2.27  Copyright by Tobi Oetiker, 1997-2008
+ * RRDtool 1.3rc4  Copyright by Tobi Oetiker, 1997-2008
  *****************************************************************************
  * rrd_lastupdate  Get the last datum entered for each DS
  *****************************************************************************/
@@ -8,47 +8,58 @@
 #include "rrd_rpncalc.h"
 #include <stdarg.h>
 
-int
-rrd_lastupdate(int argc, char **argv, time_t *last_update,
-                 unsigned long *ds_cnt, char ***ds_namv, char ***last_ds) {
-    unsigned long i=0;
-    char        *filename;
-    FILE         *in_file;
-    rrd_t        rrd;
+int rrd_lastupdate(
+    int argc,
+    char **argv,
+    time_t *last_update,
+    unsigned long *ds_cnt,
+    char ***ds_namv,
+    char ***last_ds)
+{
+    unsigned long i = 0;
+    char     *filename;
+    rrd_t     rrd;
+    rrd_file_t *rrd_file;
 
-    if(argc < 2){
+    if (argc < 2) {
         rrd_set_error("please specify an rrd");
-        return -1;
+        goto err_out;
     }
     filename = argv[1];
 
-    if(rrd_open(filename,&in_file,&rrd, RRD_READONLY)==-1){
-       return(-1);
-    }
-    fclose(in_file);
+    rrd_file = rrd_open(filename, &rrd, RRD_READONLY);
+    if (rrd_file == NULL)
+        goto err_free;
 
-    *last_update=rrd.live_head->last_up;
+    *last_update = rrd.live_head->last_up;
     *ds_cnt = rrd.stat_head->ds_cnt;
     if (((*ds_namv) =
-               (char **) malloc(rrd.stat_head->ds_cnt * sizeof(char*)))==NULL){
+         (char **) malloc(rrd.stat_head->ds_cnt * sizeof(char *))) == NULL) {
         rrd_set_error("malloc fetch ds_namv array");
-       rrd_free(&rrd);
-       return(-1);
-    } 
+        goto err_close;
+    }
 
     if (((*last_ds) =
-               (char **) malloc(rrd.stat_head->ds_cnt * sizeof(char*)))==NULL){
+         (char **) malloc(rrd.stat_head->ds_cnt * sizeof(char *))) == NULL) {
         rrd_set_error("malloc fetch last_ds array");
-       rrd_free(&rrd);
-       free(*ds_namv);
-       return(-1);
-    } 
-
-    for(i=0;i<rrd.stat_head->ds_cnt;i++){
-       (*ds_namv)[i] = sprintf_alloc("%s", rrd.ds_def[i].ds_nam);
-       (*last_ds)[i] = sprintf_alloc("%s", rrd.pdp_prep[i].last_ds);
+        goto err_free_ds_namv;
+    }
+
+    for (i = 0; i < rrd.stat_head->ds_cnt; i++) {
+        (*ds_namv)[i] = sprintf_alloc("%s", rrd.ds_def[i].ds_nam);
+        (*last_ds)[i] = sprintf_alloc("%s", rrd.pdp_prep[i].last_ds);
     }
 
     rrd_free(&rrd);
-    return(0); 
+    rrd_close(rrd_file);
+    return (0);
+
+  err_free_ds_namv:
+    free(*ds_namv);
+  err_close:
+    rrd_close(rrd_file);
+  err_free:
+    rrd_free(&rrd);
+  err_out:
+    return (-1);
 }
index 2a5ac1455cd3c50b57fca647b5e59fcf99a477bc..1787948e409ea570af345a33a3bc757fe12ddeea 100644 (file)
@@ -1,32 +1,40 @@
-#include "rrd_nan_inf.h"
+int       done_nan = 0;
+int       done_inf = 0;
 
-int done_nan = 0;
-int done_inf = 0;
-
-double dnan;
-double dinf;
+double    dnan;
+double    dinf;
 
 #if defined(_WIN32) && !defined(__CYGWIN__) && !defined(__CYGWIN32__)
 #include <math.h>
+#include "rrd.h"
 
 #define NAN_FUNC (double)fmod(0.0,0.0)
 #define INF_FUNC (double)fabs((double)log(0.0))
 
 #else
+#include "rrd.h"
 
 #define NAN_FUNC (double)(0.0/0.0)
 #define INF_FUNC (double)(1.0/0.0)
 
 #endif
 
-double set_to_DNAN(void)
+double set_to_DNAN(
+    void)
 {
-  if ( !done_nan ) { dnan = NAN_FUNC; done_nan = 1; }
-  return dnan;
+    if (!done_nan) {
+        dnan = NAN_FUNC;
+        done_nan = 1;
+    }
+    return dnan;
 }
 
-double set_to_DINF(void)
+double set_to_DINF(
+    void)
 {
-  if ( !done_inf ) { dinf = INF_FUNC; done_inf = 1; }
-  return dinf;
+    if (!done_inf) {
+        dinf = INF_FUNC;
+        done_inf = 1;
+    }
+    return dinf;
 }
diff --git a/src/rrd_nan_inf.h b/src/rrd_nan_inf.h
deleted file mode 100644 (file)
index 7934fdb..0000000
+++ /dev/null
@@ -1,5 +0,0 @@
-#define DNAN          set_to_DNAN()
-#define DINF          set_to_DINF()
-
-double set_to_DNAN(void);
-double set_to_DINF(void);
index ccc40fff5cf4282c5059b471157345cdbeb5f32f..efbd0027b1475bfedde6fcd61f9795003c0bf3b8 100644 (file)
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * RRDtool 1.2.27  Copyright by Tobi Oetiker, 1997-2008
+ * RRDtool 1.3rc4  Copyright by Tobi Oetiker, 1997-2008
  * This file:     Copyright 2003 Peter Stamfest <peter@stamfest.at> 
  *                             & Tobias Oetiker
  * Distributed under the GPL
@@ -7,32 +7,36 @@
  * rrd_not_thread_safe.c   Contains routines used when thread safety is not
  *                         an issue
  *****************************************************************************
- * $Id: rrd_not_thread_safe.c 1286 2008-02-17 10:08:10Z oetiker $
+ * $Id: rrd_not_thread_safe.c 1366 2008-05-18 13:06:44Z oetiker $
  *************************************************************************** */
 #include "rrd.h"
 #include "rrd_tool.h"
 #define MAXLEN 4096
 #define ERRBUFLEN 256
 
-static char rrd_error[MAXLEN+10];
-static char rrd_liberror[ERRBUFLEN+10];
-static int  rrd_context_init = 0;
+static char rrd_error[MAXLEN + 10];
+static char rrd_liberror[ERRBUFLEN + 10];
+static int rrd_context_init = 0;
+
 /* The global context is very useful in the transition period to even
    more thread-safe stuff, it can be used whereever we need a context
    and do not need to worry about concurrency. */
 static struct rrd_context global_ctx = {
     MAXLEN,
     ERRBUFLEN,
-    rrd_error, 
+    rrd_error,
     rrd_liberror
 };
+
 /* #include <stdarg.h> */
 
-struct rrd_context *rrd_get_context(void) {
-    if (! rrd_context_init ){
-       rrd_context_init = 1;
-        global_ctx.rrd_error[0]='\0';
-        global_ctx.lib_errstr[0]='\0';
+struct rrd_context *rrd_get_context(
+    void)
+{
+    if (!rrd_context_init) {
+        rrd_context_init = 1;
+        global_ctx.rrd_error[0] = '\0';
+        global_ctx.lib_errstr[0] = '\0';
     }
     return &global_ctx;
 }
@@ -42,6 +46,8 @@ struct rrd_context *rrd_get_context(void) {
    silently turning misplaced strerror into rrd_strerror, but here
    this turns recursive! */
 #undef strerror
-const char *rrd_strerror(int err) {
+const char *rrd_strerror(
+    int err)
+{
     return strerror(err);
 }
index 72999eee32889691fa1cddae0fc5f168c8ce8843..1f3f4394d2e7445657d4f411256093e937231f1a 100644 (file)
 /*****************************************************************************
- * RRDtool 1.2.27  Copyright by Tobi Oetiker, 1997-2008
+ * RRDtool 1.3rc4  Copyright by Tobi Oetiker, 1997-2008
  *****************************************************************************
  * rrd_open.c  Open an RRD File
  *****************************************************************************
- * $Id: rrd_open.c 1286 2008-02-17 10:08:10Z oetiker $
- * $Log$
- * Revision 1.10  2004/05/26 22:11:12  oetiker
- * reduce compiler warnings. Many small fixes. -- Mike Slifcak <slif@bellsouth.net>
- *
- * Revision 1.9  2003/04/29 21:56:49  oetiker
- * readline in rrd_open.c reads the file in 8 KB blocks, and calls realloc for
- * each block. realloc is very slow in Mac OS X for huge blocks, e.g. when
- * restoring databases from huge xml files. This patch finds the size of the
- * file, and starts out with malloc'ing the full size.
- * -- Peter Speck <speck@ruc.dk>
- *
- * Revision 1.8  2003/04/11 19:43:44  oetiker
- * New special value COUNT which allows calculations based on the position of a
- * value within a data set. Bug fix in rrd_rpncalc.c. PREV returned erroneus
- * value for the second value. Bug fix in rrd_restore.c. Bug causing seek error
- * when accesing an RRD restored from an xml that holds an RRD version <3.
- * --  Ruben Justo <ruben@ainek.com>
- *
- * Revision 1.7  2003/03/31 21:22:12  oetiker
- * enables RRDtool updates with microsecond or in case of windows millisecond
- * precision. This is needed to reduce time measurement error when archive step
- * is small. (<30s) --  Sasha Mikheev <sasha@avalon-net.co.il>
- *
- * Revision 1.6  2003/02/13 07:05:27  oetiker
- * Find attached the patch I promised to send to you. Please note that there
- * are three new source files (src/rrd_is_thread_safe.h, src/rrd_thread_safe.c
- * and src/rrd_not_thread_safe.c) and the introduction of librrd_th. This
- * library is identical to librrd, but it contains support code for per-thread
- * global variables currently used for error information only. This is similar
- * to how errno per-thread variables are implemented.  librrd_th must be linked
- * alongside of libpthred
- *
- * There is also a new file "THREADS", holding some documentation.
- *
- * -- Peter Stamfest <peter@stamfest.at>
- *
- * Revision 1.5  2002/06/20 00:21:03  jake
- * More Win32 build changes; thanks to Kerry Calvert.
- *
- * Revision 1.4  2002/02/01 20:34:49  oetiker
- * fixed version number and date/time
- *
- * Revision 1.3  2001/03/04 13:01:55  oetiker
- * Aberrant Behavior Detection support. A brief overview added to rrdtool.pod.
- * Major updates to rrd_update.c, rrd_create.c. Minor update to other core files.
- * This is backwards compatible! But new files using the Aberrant stuff are not readable
- * by old rrdtool versions. See http://cricket.sourceforge.net/aberrant/rrd_hw.htm
- * -- Jake Brutlag <jakeb@corp.webtv.net>
- *
- * Revision 1.2  2001/03/04 10:29:20  oetiker
- * fixed filedescriptor leak
- * -- Mike Franusich <mike@franusich.com>
- *
- * Revision 1.1.1.1  2001/02/25 22:25:05  oetiker
- * checkin
- *
+ * $Id: rrd_open.c 1366 2008-05-18 13:06:44Z oetiker $
  *****************************************************************************/
 
 #include "rrd_tool.h"
+#include "unused.h"
 #define MEMBLK 8192
 
-/* open a database file, return its header and a open filehandle */
-/* positioned to the first cdp in the first rra */
+/* DEBUG 2 prints information obtained via mincore(2) */
+#define DEBUG 1
+/* do not calculate exact madvise hints but assume 1 page for headers and
+ * set DONTNEED for the rest, which is assumed to be data */
+/* Avoid calling madvise on areas that were already hinted. May be benefical if
+ * your syscalls are very slow */
 
-int
-rrd_open(const char *file_name, FILE **in_file, rrd_t *rrd, int rdwr)    
+#ifdef HAVE_MMAP
+/* the cast to void* is there to avoid this warning seen on ia64 with certain
+   versions of gcc: 'cast increases required alignment of target type'
+*/
+#define __rrd_read(dst, dst_t, cnt) \
+       (dst) = (dst_t*)(void*) (data + offset); \
+       offset += sizeof(dst_t) * (cnt)
+#else
+#define __rrd_read(dst, dst_t, cnt) \
+       if ((dst = malloc(sizeof(dst_t)*(cnt))) == NULL) { \
+               rrd_set_error(#dst " malloc"); \
+               goto out_nullify_head; \
+       } \
+       offset += read (rrd_file->fd, dst, sizeof(dst_t)*(cnt))
+#endif
+
+/* get the address of the start of this page */
+#ifndef PAGE_START
+#define PAGE_START(addr) ((addr)&(~(_page_size-1)))
+#endif
+
+
+/* Open a database file, return its header and an open filehandle,
+ * positioned to the first cdp in the first rra.
+ * In the error path of rrd_open, only rrd_free(&rrd) has to be called
+ * before returning an error. Do not call rrd_close upon failure of rrd_open.
+ */
+
+rrd_file_t *rrd_open(
+    const char *const file_name,
+    rrd_t *rrd,
+    unsigned rdwr)
 {
+    int       flags = 0;
+    mode_t    mode = S_IRUSR;
+    int       version;
+
+#ifdef HAVE_MMAP
+    ssize_t   _page_size = sysconf(_SC_PAGESIZE);
+    int       mm_prot = PROT_READ, mm_flags = 0;
+    char     *data;
+#endif
+    off_t     offset = 0;
+    struct stat statb;
+    rrd_file_t *rrd_file = NULL;
+    off_t     newfile_size = 0;
 
-    
-    char *mode = NULL;
-    int version;
-    
+    if (rdwr & RRD_CREAT) {
+        /* yes bad inline signaling alert, we are using the
+           floatcookie to pass the size in ... only used in resize */
+        newfile_size = (off_t) rrd->stat_head->float_cookie;
+        free(rrd->stat_head);
+    }
     rrd_init(rrd);
-    if (rdwr == RRD_READONLY) {
-        mode = "rb";
+    rrd_file = malloc(sizeof(rrd_file_t));
+    if (rrd_file == NULL) {
+        rrd_set_error("allocating rrd_file descriptor for '%s'", file_name);
+        return NULL;
+    }
+    memset(rrd_file, 0, sizeof(rrd_file_t));
+
+#ifdef DEBUG
+    if ((rdwr & (RRD_READONLY | RRD_READWRITE)) ==
+        (RRD_READONLY | RRD_READWRITE)) {
+        /* Both READONLY and READWRITE were given, which is invalid.  */
+        rrd_set_error("in read/write request mask");
+        exit(-1);
+    }
+#endif
+    if (rdwr & RRD_READONLY) {
+        flags |= O_RDONLY;
+#ifdef HAVE_MMAP
+        mm_flags = MAP_PRIVATE;
+# ifdef MAP_NORESERVE
+        mm_flags |= MAP_NORESERVE;  /* readonly, so no swap backing needed */
+# endif
+#endif
     } else {
-        mode = "rb+";
+        if (rdwr & RRD_READWRITE) {
+            mode |= S_IWUSR;
+            flags |= O_RDWR;
+#ifdef HAVE_MMAP
+            mm_flags = MAP_SHARED;
+            mm_prot |= PROT_WRITE;
+#endif
+        }
+        if (rdwr & RRD_CREAT) {
+            flags |= (O_CREAT | O_TRUNC);
+        }
+    }
+    if (rdwr & RRD_READAHEAD) {
+#ifdef MAP_POPULATE
+        mm_flags |= MAP_POPULATE;   /* populate ptes and data */
+#endif
+#if defined MAP_NONBLOCK
+        mm_flags |= MAP_NONBLOCK;   /* just populate ptes */
+#endif
     }
-    
-    if (((*in_file) = fopen(file_name,mode)) == NULL ){
-        rrd_set_error("opening '%s': %s",file_name, rrd_strerror(errno));
-        return (-1);
+
+    if ((rrd_file->fd = open(file_name, flags, mode)) < 0) {
+        rrd_set_error("opening '%s': %s", file_name, rrd_strerror(errno));
+        goto out_free;
     }
 
+    /* Better try to avoid seeks as much as possible. stat may be heavy but
+     * many concurrent seeks are even worse.  */
+    if (newfile_size == 0 && ((fstat(rrd_file->fd, &statb)) < 0)) {
+        rrd_set_error("fstat '%s': %s", file_name, rrd_strerror(errno));
+        goto out_close;
+    }
+    if (newfile_size == 0) {
+        rrd_file->file_len = statb.st_size;
+    } else {
+        rrd_file->file_len = newfile_size;
+        lseek(rrd_file->fd, newfile_size - 1, SEEK_SET);
+        write(rrd_file->fd, "\0", 1);   /* poke */
+        lseek(rrd_file->fd, 0, SEEK_SET);
+    }
 #ifdef HAVE_POSIX_FADVISE
     /* In general we need no read-ahead when dealing with rrd_files.
        When we stop reading, it is highly unlikely that we start up again.
        In this manner we actually save time and diskaccess (and buffer cache).
-       Thanks to Dave Plonka for the Idea of using POSIX_FADV_RANDOM here. */       
-    /* if (0 != posix_fadvise(fileno(*in_file), 0, 0, POSIX_FADV_RANDOM)) {
-        rrd_set_error("setting POSIX_FADV_RANDOM on '%s': %s",file_name, rrd_strerror(errno));
-        fclose(*in_file);
-        return(-1); */
-
-        /* if it does not work, then this is sad, but we should not quit */
-     posix_fadvise(fileno(*in_file), 0, 0, POSIX_FADV_RANDOM);
-        
-     /*     }     */
+       Thanks to Dave Plonka for the Idea of using POSIX_FADV_RANDOM here. */
+    posix_fadvise(rrd_file->fd, 0, 0, POSIX_FADV_RANDOM);
 #endif
 
 /*
-        if (rdwr == RRD_READWRITE)
+        if (rdwr & RRD_READWRITE)
         {
-           if (setvbuf((*in_file),NULL,_IONBF,2)) {
+           if (setvbuf((rrd_file->fd),NULL,_IONBF,2)) {
                   rrd_set_error("failed to disable the stream buffer\n");
                   return (-1);
            }
         }
 */
-    
-#define MYFREAD(MYVAR,MYVART,MYCNT) \
-    if ((MYVAR = malloc(sizeof(MYVART) * MYCNT)) == NULL) {\
-        rrd_set_error("" #MYVAR " malloc"); \
-        fclose(*in_file); \
-        return (-1); } \
-    fread(MYVAR,sizeof(MYVART),MYCNT, *in_file); 
+#ifdef HAVE_MMAP
+    data = mmap(0, rrd_file->file_len, mm_prot, mm_flags,
+                rrd_file->fd, offset);
 
-
-    MYFREAD(rrd->stat_head, stat_head_t,  1)
     /* lets see if the first read worked */
-    if (ferror( *in_file ) || feof(*in_file)) {
-        rrd_set_error("reading the cookie off %s faild",file_name);
-        fclose(*in_file);
-        return(-1);
-    }        
-
-        /* lets do some test if we are on track ... */
-        if (strncmp(rrd->stat_head->cookie,RRD_COOKIE,4) != 0){
-            rrd_set_error("'%s' is not an RRD file",file_name);
-            free(rrd->stat_head);
-            rrd->stat_head = NULL; 
-            fclose(*in_file);
-            return(-1);}
-
-        if (rrd->stat_head->float_cookie != FLOAT_COOKIE){
-            rrd_set_error("This RRD was created on other architecture");
-            free(rrd->stat_head);
-            rrd->stat_head = NULL; 
-            fclose(*in_file);
-            return(-1);}
+    if (data == MAP_FAILED) {
+        rrd_set_error("mmaping file '%s': %s", file_name,
+                      rrd_strerror(errno));
+        goto out_close;
+    }
+    rrd_file->file_start = data;
+    if (rdwr & RRD_CREAT) {
+        memset(data, DNAN, newfile_size - 1);
+        goto out_done;
+    }
+#endif
+    if (rdwr & RRD_CREAT)
+        goto out_done;
+#ifdef USE_MADVISE
+    if (rdwr & RRD_COPY) {
+        /* We will read everything in a moment (copying) */
+        madvise(data, rrd_file->file_len, MADV_WILLNEED | MADV_SEQUENTIAL);
+    } else {
+        /* We do not need to read anything in for the moment */
+        madvise(data, rrd_file->file_len, MADV_RANDOM);
+        /* the stat_head will be needed soonish, so hint accordingly */
+        madvise(data, sizeof(stat_head_t), MADV_WILLNEED | MADV_RANDOM);
+    }
+#endif
+
+    __rrd_read(rrd->stat_head, stat_head_t,
+               1);
+
+    /* lets do some test if we are on track ... */
+    if (memcmp(rrd->stat_head->cookie, RRD_COOKIE, sizeof(RRD_COOKIE)) != 0) {
+        rrd_set_error("'%s' is not an RRD file", file_name);
+        goto out_nullify_head;
+    }
+
+    if (rrd->stat_head->float_cookie != FLOAT_COOKIE) {
+        rrd_set_error("This RRD was created on another architecture");
+        goto out_nullify_head;
+    }
 
     version = atoi(rrd->stat_head->version);
 
-        if (version > atoi(RRD_VERSION)){
-            rrd_set_error("can't handle RRD file version %s",
-                        rrd->stat_head->version);
-            free(rrd->stat_head);
-            rrd->stat_head = NULL; 
-            fclose(*in_file);
-            return(-1);}
+    if (version > atoi(RRD_VERSION)) {
+        rrd_set_error("can't handle RRD file version %s",
+                      rrd->stat_head->version);
+        goto out_nullify_head;
+    }
+#if defined USE_MADVISE
+    /* the ds_def will be needed soonish, so hint accordingly */
+    madvise(data + PAGE_START(offset),
+            sizeof(ds_def_t) * rrd->stat_head->ds_cnt, MADV_WILLNEED);
+#endif
+    __rrd_read(rrd->ds_def, ds_def_t,
+               rrd->stat_head->ds_cnt);
 
+#if defined USE_MADVISE
+    /* the rra_def will be needed soonish, so hint accordingly */
+    madvise(data + PAGE_START(offset),
+            sizeof(rra_def_t) * rrd->stat_head->rra_cnt, MADV_WILLNEED);
+#endif
+    __rrd_read(rrd->rra_def, rra_def_t,
+               rrd->stat_head->rra_cnt);
 
-    MYFREAD(rrd->ds_def,    ds_def_t,     rrd->stat_head->ds_cnt)
-    MYFREAD(rrd->rra_def,   rra_def_t,    rrd->stat_head->rra_cnt)
     /* handle different format for the live_head */
-    if(version < 3) {
-            rrd->live_head = (live_head_t *)malloc(sizeof(live_head_t));
-            if(rrd->live_head == NULL) {
-                rrd_set_error("live_head_t malloc");
-                fclose(*in_file); 
-                return (-1);
+    if (version < 3) {
+        rrd->live_head = (live_head_t *) malloc(sizeof(live_head_t));
+        if (rrd->live_head == NULL) {
+            rrd_set_error("live_head_t malloc");
+            goto out_close;
+        }
+#ifdef HAVE_MMAP
+        memmove(&rrd->live_head->last_up, data + offset, sizeof(long));
+        offset += sizeof(long);
+#else
+        offset += read(rrd_file->fd, &rrd->live_head->last_up, sizeof(long));
+#endif
+        rrd->live_head->last_up_usec = 0;
+    } else {
+#if defined USE_MADVISE
+        /* the live_head will be needed soonish, so hint accordingly */
+        madvise(data + PAGE_START(offset),
+                sizeof(live_head_t), MADV_WILLNEED);
+#endif
+        __rrd_read(rrd->live_head, live_head_t,
+                   1);
+    }
+    __rrd_read(rrd->pdp_prep, pdp_prep_t,
+               rrd->stat_head->ds_cnt);
+    __rrd_read(rrd->cdp_prep, cdp_prep_t,
+               rrd->stat_head->rra_cnt * rrd->stat_head->ds_cnt);
+    __rrd_read(rrd->rra_ptr, rra_ptr_t,
+               rrd->stat_head->rra_cnt);
+
+    rrd_file->header_len = offset;
+    rrd_file->pos = offset;
+  out_done:
+    return (rrd_file);
+  out_nullify_head:
+    rrd->stat_head = NULL;
+  out_close:
+    close(rrd_file->fd);
+  out_free:
+    free(rrd_file);
+    return NULL;
+}
+
+
+#if defined DEBUG && DEBUG > 1
+/* Print list of in-core pages of a the current rrd_file.  */
+static
+void mincore_print(
+    rrd_file_t *rrd_file,
+    char *mark)
+{
+#ifdef HAVE_MMAP
+    /* pretty print blocks in core */
+    off_t     off;
+    unsigned char *vec;
+    ssize_t   _page_size = sysconf(_SC_PAGESIZE);
+
+    off = rrd_file->file_len +
+        ((rrd_file->file_len + _page_size - 1) / _page_size);
+    vec = malloc(off);
+    if (vec != NULL) {
+        memset(vec, 0, off);
+        if (mincore(rrd_file->file_start, rrd_file->file_len, vec) == 0) {
+            int       prev;
+            unsigned  is_in = 0, was_in = 0;
+
+            for (off = 0, prev = 0; off < rrd_file->file_len; ++off) {
+                is_in = vec[off] & 1;   /* if lsb set then is core resident */
+                if (off == 0)
+                    was_in = is_in;
+                if (was_in != is_in) {
+                    fprintf(stderr, "%s: %sin core: %p len %ld\n", mark,
+                            was_in ? "" : "not ", vec + prev, off - prev);
+                    was_in = is_in;
+                    prev = off;
+                }
             }
-                fread(&rrd->live_head->last_up, sizeof(long), 1, *in_file); 
-                rrd->live_head->last_up_usec = 0;
+            fprintf(stderr,
+                    "%s: %sin core: %p len %ld\n", mark,
+                    was_in ? "" : "not ", vec + prev, off - prev);
+        } else
+            fprintf(stderr, "mincore: %s", rrd_strerror(errno));
     }
-    else {
-            MYFREAD(rrd->live_head, live_head_t, 1)
+#else
+    fprintf(stderr, "sorry mincore only works with mmap");
+#endif
+}
+#endif                          /* defined DEBUG && DEBUG > 1 */
+
+
+/* drop cache except for the header and the active pages */
+void rrd_dontneed(
+    rrd_file_t *rrd_file,
+    rrd_t *rrd)
+{
+    unsigned long dontneed_start;
+    unsigned long rra_start;
+    unsigned long active_block;
+    unsigned long i;
+    ssize_t   _page_size = sysconf(_SC_PAGESIZE);
+
+#if defined DEBUG && DEBUG > 1
+    mincore_print(rrd_file, "before");
+#endif
+
+    /* ignoring errors from RRDs that are smaller then the file_len+rounding */
+    rra_start = rrd_file->header_len;
+    dontneed_start = PAGE_START(rra_start) + _page_size;
+    for (i = 0; i < rrd->stat_head->rra_cnt; ++i) {
+        active_block =
+            PAGE_START(rra_start
+                       + rrd->rra_ptr[i].cur_row
+                       * rrd->stat_head->ds_cnt * sizeof(rrd_value_t));
+        if (active_block > dontneed_start) {
+#ifdef USE_MADVISE
+            madvise(rrd_file->file_start + dontneed_start,
+                    active_block - dontneed_start - 1, MADV_DONTNEED);
+#endif
+/* in linux at least only fadvise DONTNEED seems to purge pages from cache */
+#ifdef HAVE_POSIX_FADVISE
+            posix_fadvise(rrd_file->fd, dontneed_start,
+                          active_block - dontneed_start - 1,
+                          POSIX_FADV_DONTNEED);
+#endif
+        }
+        dontneed_start = active_block;
+        /* do not release 'hot' block if update for this RAA will occur
+         * within 10 minutes */
+        if (rrd->stat_head->pdp_step * rrd->rra_def[i].pdp_cnt -
+            rrd->live_head->last_up % (rrd->stat_head->pdp_step *
+                                       rrd->rra_def[i].pdp_cnt) < 10 * 60) {
+            dontneed_start += _page_size;
+        }
+        rra_start +=
+            rrd->rra_def[i].row_cnt * rrd->stat_head->ds_cnt *
+            sizeof(rrd_value_t);
+    }
+#ifdef USE_MADVISE
+    madvise(rrd_file->file_start + dontneed_start,
+            rrd_file->file_len - dontneed_start, MADV_DONTNEED);
+#endif
+#ifdef HAVE_POSIX_FADVISE
+    posix_fadvise(rrd_file->fd, dontneed_start,
+                  rrd_file->file_len - dontneed_start, POSIX_FADV_DONTNEED);
+#endif
+#if defined DEBUG && DEBUG > 1
+    mincore_print(rrd_file, "after");
+#endif
+}
+
+int rrd_close(
+    rrd_file_t *rrd_file)
+{
+    int       ret;
+
+#ifdef HAVE_MMAP
+    ret = msync(rrd_file->file_start, rrd_file->file_len, MS_ASYNC);
+    if (ret != 0)
+        rrd_set_error("msync rrd_file: %s", rrd_strerror(errno));
+    ret = munmap(rrd_file->file_start, rrd_file->file_len);
+    if (ret != 0)
+        rrd_set_error("munmap rrd_file: %s", rrd_strerror(errno));
+#endif
+    ret = close(rrd_file->fd);
+    if (ret != 0)
+        rrd_set_error("closing file: %s", rrd_strerror(errno));
+    free(rrd_file);
+    rrd_file = NULL;
+    return ret;
+}
+
+
+/* Set position of rrd_file.  */
+
+off_t rrd_seek(
+    rrd_file_t *rrd_file,
+    off_t off,
+    int whence)
+{
+    off_t     ret = 0;
+
+#ifdef HAVE_MMAP
+    if (whence == SEEK_SET)
+        rrd_file->pos = off;
+    else if (whence == SEEK_CUR)
+        rrd_file->pos += off;
+    else if (whence == SEEK_END)
+        rrd_file->pos = rrd_file->file_len + off;
+#else
+    ret = lseek(rrd_file->fd, off, whence);
+    if (ret < 0)
+        rrd_set_error("lseek: %s", rrd_strerror(errno));
+    rrd_file->pos = ret;
+#endif
+    /* mimic fseek, which returns 0 upon success */
+    return ret < 0;     /*XXX: or just ret to mimic lseek */
+}
+
+
+/* Get current position in rrd_file.  */
+
+inline off_t rrd_tell(
+    rrd_file_t *rrd_file)
+{
+    return rrd_file->pos;
+}
+
+
+/* Read count bytes into buffer buf, starting at rrd_file->pos.
+ * Returns the number of bytes read or <0 on error.  */
+
+inline ssize_t rrd_read(
+    rrd_file_t *rrd_file,
+    void *buf,
+    size_t count)
+{
+#ifdef HAVE_MMAP
+    size_t    _cnt = count;
+    ssize_t   _surplus;
+
+    if (rrd_file->pos > rrd_file->file_len || _cnt == 0)    /* EOF */
+        return 0;
+    if (buf == NULL)
+        return -1;      /* EINVAL */
+    _surplus = rrd_file->pos + _cnt - rrd_file->file_len;
+    if (_surplus > 0) { /* short read */
+        _cnt -= _surplus;
     }
-    MYFREAD(rrd->pdp_prep,  pdp_prep_t,   rrd->stat_head->ds_cnt)
-    MYFREAD(rrd->cdp_prep,  cdp_prep_t,   (rrd->stat_head->rra_cnt
-                                             * rrd->stat_head->ds_cnt))
-    MYFREAD(rrd->rra_ptr,   rra_ptr_t,    rrd->stat_head->rra_cnt)
-#undef MYFREAD
+    if (_cnt == 0)
+        return 0;       /* EOF */
+    buf = memcpy(buf, rrd_file->file_start + rrd_file->pos, _cnt);
+
+    rrd_file->pos += _cnt;  /* mimmic read() semantics */
+    return _cnt;
+#else
+    ssize_t   ret;
+
+    ret = read(rrd_file->fd, buf, count);
+    if (ret > 0)
+        rrd_file->pos += ret;   /* mimmic read() semantics */
+    return ret;
+#endif
+}
+
+
+/* Write count bytes from buffer buf to the current position
+ * rrd_file->pos of rrd_file->fd.
+ * Returns the number of bytes written or <0 on error.  */
+
+inline ssize_t rrd_write(
+    rrd_file_t *rrd_file,
+    const void *buf,
+    size_t count)
+{
+#ifdef HAVE_MMAP
+    if (count == 0)
+        return 0;
+    if (buf == NULL)
+        return -1;      /* EINVAL */
+    memcpy(rrd_file->file_start + rrd_file->pos, buf, count);
+    rrd_file->pos += count;
+    return count;       /* mimmic write() semantics */
+#else
+    ssize_t   _sz = write(rrd_file->fd, buf, count);
+
+    if (_sz > 0)
+        rrd_file->pos += _sz;
+    return _sz;
+#endif
+}
 
-    return(0);
+
+/* flush all data pending to be written to FD.  */
+
+inline void rrd_flush(
+    rrd_file_t *rrd_file)
+{
+    if (fdatasync(rrd_file->fd) != 0) {
+        rrd_set_error("flushing fd %d: %s", rrd_file->fd,
+                      rrd_strerror(errno));
+    }
 }
 
-void rrd_init(rrd_t *rrd)
+
+/* Initialize RRD header.  */
+
+void rrd_init(
+    rrd_t *rrd)
 {
     rrd->stat_head = NULL;
     rrd->ds_def = NULL;
@@ -193,66 +518,96 @@ void rrd_init(rrd_t *rrd)
     rrd->rrd_value = NULL;
 }
 
-void rrd_free(rrd_t *rrd)
+
+/* free RRD header data.  */
+
+#ifdef HAVE_MMAP
+inline void rrd_free(
+    rrd_t UNUSED(*rrd))
 {
-    if (rrd->stat_head) free(rrd->stat_head);
-    if (rrd->ds_def) free(rrd->ds_def);
-    if (rrd->rra_def) free(rrd->rra_def);
-    if (rrd->live_head) free(rrd->live_head);
-    if (rrd->rra_ptr) free(rrd->rra_ptr);
-    if (rrd->pdp_prep) free(rrd->pdp_prep);
-    if (rrd->cdp_prep) free(rrd->cdp_prep);
-    if (rrd->rrd_value) free(rrd->rrd_value);
 }
+#else
+void rrd_free(
+    rrd_t *rrd)
+{
+    free(rrd->live_head);
+    free(rrd->stat_head);
+    free(rrd->ds_def);
+    free(rrd->rra_def);
+    free(rrd->rra_ptr);
+    free(rrd->pdp_prep);
+    free(rrd->cdp_prep);
+    free(rrd->rrd_value);
+}
+#endif
+
 
 /* routine used by external libraries to free memory allocated by
  * rrd library */
-void rrd_freemem(void *mem)
-{
 
-    if (mem) free(mem);
+void rrd_freemem(
+    void *mem)
+{
+    free(mem);
 }
 
-int readfile(const char *file_name, char **buffer, int skipfirst){
-    long writecnt=0,totalcnt = MEMBLK;
-     long offset = 0;
-    FILE *input=NULL;
-    char c ;
-    if ((strcmp("-",file_name) == 0)) { input = stdin; }
-    else {
-      if ((input = fopen(file_name,"rb")) == NULL ){
-        rrd_set_error("opening '%s': %s",file_name,rrd_strerror(errno));
-        return (-1);
-      }
+
+/* XXX: FIXME: missing documentation.  */
+/*XXX: FIXME should be renamed to rrd_readfile or _rrd_readfile */
+
+int /*_rrd_*/ readfile(
+    const char *file_name,
+    char **buffer,
+    int skipfirst)
+{
+    long      writecnt = 0, totalcnt = MEMBLK;
+    long      offset = 0;
+    FILE     *input = NULL;
+    char      c;
+
+    if ((strcmp("-", file_name) == 0)) {
+        input = stdin;
+    } else {
+        if ((input = fopen(file_name, "rb")) == NULL) {
+            rrd_set_error("opening '%s': %s", file_name, rrd_strerror(errno));
+            return (-1);
+        }
     }
-    if (skipfirst){
-      do { c = getc(input); offset++; } while (c != '\n' && ! feof(input));
+    if (skipfirst) {
+        do {
+            c = getc(input);
+            offset++;
+        } while (c != '\n' && !feof(input));
     }
-    if (strcmp("-",file_name)) {
-      fseek(input, 0, SEEK_END);
-      /* have extra space for detecting EOF without realloc */
-      totalcnt = (ftell(input) + 1) / sizeof(char) - offset;
-      if (totalcnt < MEMBLK)
-        totalcnt = MEMBLK; /* sanitize */
-      fseek(input, offset * sizeof(char), SEEK_SET);
+    if (strcmp("-", file_name)) {
+        fseek(input, 0, SEEK_END);
+        /* have extra space for detecting EOF without realloc */
+        totalcnt = (ftell(input) + 1) / sizeof(char) - offset;
+        if (totalcnt < MEMBLK)
+            totalcnt = MEMBLK;  /* sanitize */
+        fseek(input, offset * sizeof(char), SEEK_SET);
     }
-    if (((*buffer) = (char *) malloc((totalcnt+4) * sizeof(char))) == NULL) {
+    if (((*buffer) = (char *) malloc((totalcnt + 4) * sizeof(char))) == NULL) {
         perror("Allocate Buffer:");
         exit(1);
     };
-    do{
-      writecnt += fread((*buffer)+writecnt, 1, (totalcnt - writecnt) * sizeof(char),input);
-      if (writecnt >= totalcnt){
-        totalcnt += MEMBLK;
-        if (((*buffer)=rrd_realloc((*buffer), (totalcnt+4) * sizeof(char)))==NULL){
-            perror("Realloc Buffer:");
-            exit(1);
-        };
-      }
-    } while (! feof(input));
+    do {
+        writecnt +=
+            fread((*buffer) + writecnt, 1,
+                  (totalcnt - writecnt) * sizeof(char), input);
+        if (writecnt >= totalcnt) {
+            totalcnt += MEMBLK;
+            if (((*buffer) =
+                 rrd_realloc((*buffer),
+                             (totalcnt + 4) * sizeof(char))) == NULL) {
+                perror("Realloc Buffer:");
+                exit(1);
+            };
+        }
+    } while (!feof(input));
     (*buffer)[writecnt] = '\0';
-    if (strcmp("-",file_name) != 0) {fclose(input);};
+    if (strcmp("-", file_name) != 0) {
+        fclose(input);
+    };
     return writecnt;
 }
-
-
index 9779c9762a4da11b2f4ee3df7560dced5a5448c5..f113e69f58811732e64a8ec78312d45c33c825e6 100644 (file)
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * RRDtool 1.2.27  Copyright by Tobi Oetiker, 1997-2008
+ * RRDtool 1.3rc4  Copyright by Tobi Oetiker, 1997-2008
  *****************************************************************************
  * rrd_resize.c Alters size of an RRA
  *****************************************************************************
 
 #include "rrd_tool.h"
 
-int
-rrd_resize(int argc, char **argv)
+int rrd_resize(
+    int argc,
+    char **argv)
 {
-    char               *infilename,outfilename[11]="resize.rrd";
-    FILE               *infile,*outfile;
-    rrd_t              rrdold,rrdnew;
-    rrd_value_t                buffer;
-    int                        version;
-    unsigned long      l,rra;
-    long               modify;
-    unsigned long      target_rra;
-    int                        grow=0,shrink=0;
-    char               *endptr;
-
-    infilename=argv[1];
-    if (!strcmp(infilename,"resize.rrd")) {
+    char     *infilename, outfilename[11] = "resize.rrd";
+    rrd_t     rrdold, rrdnew;
+    rrd_value_t buffer;
+    int       version;
+    unsigned long l, rra;
+    long      modify;
+    unsigned long target_rra;
+    int       grow = 0, shrink = 0;
+    char     *endptr;
+    rrd_file_t *rrd_file, *rrd_out_file;
+
+    infilename = argv[1];
+    if (!strcmp(infilename, "resize.rrd")) {
         rrd_set_error("resize.rrd is a reserved name");
-        return(-1);
+        return (-1);
     }
-    if (argc!=5) {
+    if (argc != 5) {
         rrd_set_error("wrong number of parameters");
-        return(-1);
+        return (-1);
     }
 
-    target_rra=strtol(argv[2],&endptr,0);
+    target_rra = strtol(argv[2], &endptr, 0);
 
-    if (!strcmp(argv[3],"GROW")) grow=1;
-    else if (!strcmp(argv[3],"SHRINK")) shrink=1;
+    if (!strcmp(argv[3], "GROW"))
+        grow = 1;
+    else if (!strcmp(argv[3], "SHRINK"))
+        shrink = 1;
     else {
         rrd_set_error("I can only GROW or SHRINK");
-        return(-1);
+        return (-1);
     }
 
-    modify=strtol(argv[4],&endptr,0);
+    modify = strtol(argv[4], &endptr, 0);
 
-    if ((modify<1)) {
+    if ((modify < 1)) {
         rrd_set_error("Please grow or shrink with at least 1 row");
-        return(-1);
+        return (-1);
     }
 
-    if (shrink) modify = -modify;
+    if (shrink)
+        modify = -modify;
 
 
-    if (rrd_open(infilename, &infile, &rrdold, RRD_READWRITE)==-1) {
-        rrd_set_error("could not open RRD");
-        return(-1);
+    rrd_file = rrd_open(infilename, &rrdold, RRD_READWRITE | RRD_COPY);
+    if (rrd_file == NULL) {
+        rrd_free(&rrdold);
+        return (-1);
     }
-    if (LockRRD(infile) != 0) {
+    if (LockRRD(rrd_file->fd) != 0) {
         rrd_set_error("could not lock original RRD");
         rrd_free(&rrdold);
-        fclose(infile);
-        return(-1);
+        rrd_close(rrd_file);
+        return (-1);
     }
 
     if (target_rra >= rrdold.stat_head->rra_cnt) {
         rrd_set_error("no such RRA in this RRD");
         rrd_free(&rrdold);
-        fclose(infile);
-        return(-1);
+        rrd_close(rrd_file);
+        return (-1);
     }
 
     if (modify < 0)
-       if ((long)rrdold.rra_def[target_rra].row_cnt <= -modify) {
-           rrd_set_error("This RRA is not that big");
-           rrd_free(&rrdold);
-           fclose(infile);
-           return(-1);
-       }
-
+        if ((long) rrdold.rra_def[target_rra].row_cnt <= -modify) {
+            rrd_set_error("This RRA is not that big");
+            rrd_free(&rrdold);
+            rrd_close(rrd_file);
+            return (-1);
+        }
+    /* the size of the new file */
+    /* yes we are abusing the float cookie for this, aargh */
+    if ((rrdnew.stat_head = calloc(1, sizeof(stat_head_t))) == NULL) {
+        rrd_set_error("allocating stat_head for new RRD");
+        rrd_free(&rrdold);
+        rrd_close(rrd_file);
+        return (-1);
+    }
+    rrdnew.stat_head->float_cookie = rrd_file->file_len +
+        (rrdold.stat_head->ds_cnt * sizeof(rrd_value_t) * modify);
+    rrd_out_file = rrd_open(outfilename, &rrdnew, RRD_READWRITE | RRD_CREAT);
+    if (rrd_out_file == NULL) {
+        rrd_set_error("Can't create '%s': %s", outfilename,
+                      rrd_strerror(errno));
+        rrd_free(&rrdnew);
+        return (-1);
+    }
+    if (LockRRD(rrd_out_file->fd) != 0) {
+        rrd_set_error("could not lock new RRD");
+        rrd_free(&rrdold);
+        rrd_close(rrd_file);
+        rrd_close(rrd_out_file);
+        return (-1);
+    }
+/*XXX: do one write for those parts of header that are unchanged */
     rrdnew.stat_head = rrdold.stat_head;
-    rrdnew.ds_def    = rrdold.ds_def;
-    rrdnew.rra_def   = rrdold.rra_def;
+    rrdnew.ds_def = rrdold.ds_def;
+    rrdnew.rra_def = rrdold.rra_def;
     rrdnew.live_head = rrdold.live_head;
-    rrdnew.pdp_prep  = rrdold.pdp_prep;
-    rrdnew.cdp_prep  = rrdold.cdp_prep;
-    rrdnew.rra_ptr   = rrdold.rra_ptr;
+    rrdnew.pdp_prep = rrdold.pdp_prep;
+    rrdnew.cdp_prep = rrdold.cdp_prep;
+    rrdnew.rra_ptr = rrdold.rra_ptr;
 
     version = atoi(rrdold.stat_head->version);
     switch (version) {
-       case 3: break;
-       case 1: rrdold.stat_head->version[3]='3';
-               break;
-       default: {
-               rrd_set_error("Do not know how to handle RRD version %s",rrdold.stat_head->version);
-               rrd_free(&rrdold);      
-               fclose(infile);
-               return(-1);
-               }
-    }
-
-    if ((outfile=fopen(outfilename,"wb"))==NULL) {
-        rrd_set_error("Can't create '%s'",outfilename);
-        return(-1);
-    }
-    if (LockRRD(outfile) != 0) {
-        rrd_set_error("could not lock new RRD");
+    case 3:
+        break;
+    case 1:
+        rrdold.stat_head->version[3] = '3';
+        break;
+    default:
+        rrd_set_error("Do not know how to handle RRD version %s",
+                      rrdold.stat_head->version);
+        rrd_close(rrd_file);
         rrd_free(&rrdold);
-        fclose(infile);
-        fclose(outfile);
-        return(-1);
+        return (-1);
+        break;
     }
-    fwrite(rrdnew.stat_head, sizeof(stat_head_t),1,outfile);
-    fwrite(rrdnew.ds_def,sizeof(ds_def_t),rrdnew.stat_head->ds_cnt,outfile);
-    fwrite(rrdnew.rra_def,sizeof(rra_def_t),rrdnew.stat_head->rra_cnt,outfile);
-    fwrite(rrdnew.live_head,sizeof(live_head_t),1,outfile);
-    fwrite(rrdnew.pdp_prep,sizeof(pdp_prep_t),rrdnew.stat_head->ds_cnt,outfile);
-    fwrite(rrdnew.cdp_prep,sizeof(cdp_prep_t),rrdnew.stat_head->ds_cnt*rrdnew.stat_head->rra_cnt,outfile);
-    fwrite(rrdnew.rra_ptr,sizeof(rra_ptr_t),rrdnew.stat_head->rra_cnt,outfile);
+
+/* XXX: Error checking? */
+    rrd_write(rrd_out_file, rrdnew.stat_head, sizeof(stat_head_t) * 1);
+    rrd_write(rrd_out_file, rrdnew.ds_def,
+              sizeof(ds_def_t) * rrdnew.stat_head->ds_cnt);
+    rrd_write(rrd_out_file, rrdnew.rra_def,
+              sizeof(rra_def_t) * rrdnew.stat_head->rra_cnt);
+    rrd_write(rrd_out_file, rrdnew.live_head, sizeof(live_head_t) * 1);
+    rrd_write(rrd_out_file, rrdnew.pdp_prep,
+              sizeof(pdp_prep_t) * rrdnew.stat_head->ds_cnt);
+    rrd_write(rrd_out_file, rrdnew.cdp_prep,
+              sizeof(cdp_prep_t) * rrdnew.stat_head->ds_cnt *
+              rrdnew.stat_head->rra_cnt);
+    rrd_write(rrd_out_file, rrdnew.rra_ptr,
+              sizeof(rra_ptr_t) * rrdnew.stat_head->rra_cnt);
 
     /* Move the CDPs from the old to the new database.
-    ** This can be made (much) faster but isn't worth the effort. Clarity
-    ** is much more important.
-    */
+     ** This can be made (much) faster but isn't worth the effort. Clarity
+     ** is much more important.
+     */
 
     /* Move data in unmodified RRAs
-    */
-    l=0;
-    for (rra=0;rra<target_rra;rra++) {
-        l+=rrdnew.stat_head->ds_cnt * rrdnew.rra_def[rra].row_cnt;
+     */
+    l = 0;
+    for (rra = 0; rra < target_rra; rra++) {
+        l += rrdnew.stat_head->ds_cnt * rrdnew.rra_def[rra].row_cnt;
     }
-    while (l>0) {
-        fread(&buffer,sizeof(rrd_value_t),1,infile);
-        fwrite(&buffer,sizeof(rrd_value_t),1,outfile);
+    while (l > 0) {
+        rrd_read(rrd_file, &buffer, sizeof(rrd_value_t) * 1);
+        rrd_write(rrd_out_file, &buffer, sizeof(rrd_value_t) * 1);
         l--;
     }
     /* Move data in this RRA, either removing or adding some rows
-    */
-    if (modify>0) {
+     */
+    if (modify > 0) {
         /* Adding extra rows; insert unknown values just after the
-        ** current row number.
-        */
-        l = rrdnew.stat_head->ds_cnt * (rrdnew.rra_ptr[target_rra].cur_row+1);
-        while (l>0) {
-            fread(&buffer,sizeof(rrd_value_t),1,infile);
-            fwrite(&buffer,sizeof(rrd_value_t),1,outfile);
+         ** current row number.
+         */
+        l = rrdnew.stat_head->ds_cnt *
+            (rrdnew.rra_ptr[target_rra].cur_row + 1);
+        while (l > 0) {
+            rrd_read(rrd_file, &buffer, sizeof(rrd_value_t) * 1);
+            rrd_write(rrd_out_file, &buffer, sizeof(rrd_value_t) * 1);
             l--;
         }
-        buffer=DNAN;
-        l=rrdnew.stat_head->ds_cnt * modify;
-        while (l>0) {
-            fwrite(&buffer,sizeof(rrd_value_t),1,outfile);
+#ifndef HAVE_MMAP
+        buffer = DNAN;
+        l = rrdnew.stat_head->ds_cnt * modify;
+        while (l > 0) {
+            rrd_write(rrd_out_file, &buffer, sizeof(rrd_value_t) * 1);
             l--;
         }
+#else
+        /* for the mmap case, we did already fill the whole new file with DNAN
+         * before we copied the old values, so nothing to do here.  */
+#endif
     } else {
         /* Removing rows. Normally this would be just after the cursor
-        ** however this may also mean that we wrap to the beginning of
-        ** the array.
-        */
-        signed long int remove_end=0;
-
-        remove_end=(rrdnew.rra_ptr[target_rra].cur_row-modify)%rrdnew.rra_def[target_rra].row_cnt;
-        if (remove_end <= (signed long int)rrdnew.rra_ptr[target_rra].cur_row) {
+         ** however this may also mean that we wrap to the beginning of
+         ** the array.
+         */
+        signed long int remove_end = 0;
+
+        remove_end =
+            (rrdnew.rra_ptr[target_rra].cur_row -
+             modify) % rrdnew.rra_def[target_rra].row_cnt;
+        if (remove_end <=
+            (signed long int) rrdnew.rra_ptr[target_rra].cur_row) {
             while (remove_end >= 0) {
-                fseek(infile,sizeof(rrd_value_t)*rrdnew.stat_head->ds_cnt,SEEK_CUR);
+                rrd_seek(rrd_file,
+                         sizeof(rrd_value_t) * rrdnew.stat_head->ds_cnt,
+                         SEEK_CUR);
                 rrdnew.rra_ptr[target_rra].cur_row--;
                 rrdnew.rra_def[target_rra].row_cnt--;
                 remove_end--;
                 modify++;
             }
-            remove_end=rrdnew.rra_def[target_rra].row_cnt-1;
+            remove_end = rrdnew.rra_def[target_rra].row_cnt - 1;
         }
-        for (l=0;l<=rrdnew.rra_ptr[target_rra].cur_row;l++) {
+        for (l = 0; l <= rrdnew.rra_ptr[target_rra].cur_row; l++) {
             unsigned int tmp;
-            for (tmp=0;tmp<rrdnew.stat_head->ds_cnt;tmp++) {
-                fread(&buffer,sizeof(rrd_value_t),1,infile);
-                fwrite(&buffer,sizeof(rrd_value_t),1,outfile);
+
+            for (tmp = 0; tmp < rrdnew.stat_head->ds_cnt; tmp++) {
+                rrd_read(rrd_file, &buffer, sizeof(rrd_value_t) * 1);
+                rrd_write(rrd_out_file, &buffer, sizeof(rrd_value_t) * 1);
             }
         }
-        while (modify<0) {
-            fseek(infile,sizeof(rrd_value_t)*rrdnew.stat_head->ds_cnt,SEEK_CUR);
+        while (modify < 0) {
+            rrd_seek(rrd_file,
+                     sizeof(rrd_value_t) * rrdnew.stat_head->ds_cnt,
+                     SEEK_CUR);
             rrdnew.rra_def[target_rra].row_cnt--;
             modify++;
         }
     }
     /* Move the rest of the CDPs
-    */
+     */
     while (1) {
-       fread(&buffer,sizeof(rrd_value_t),1,infile);
-       if (feof(infile))
-           break;
-        fwrite(&buffer,sizeof(rrd_value_t),1,outfile);
+        if (rrd_read(rrd_file, &buffer, sizeof(rrd_value_t) * 1) <= 0)
+            break;
+        rrd_write(rrd_out_file, &buffer, sizeof(rrd_value_t) * 1);
     }
     rrdnew.rra_def[target_rra].row_cnt += modify;
-    fseek(outfile,sizeof(stat_head_t)+sizeof(ds_def_t)*rrdnew.stat_head->ds_cnt,SEEK_SET);
-    fwrite(rrdnew.rra_def,sizeof(rra_def_t),rrdnew.stat_head->rra_cnt, outfile);
-    fseek(outfile,sizeof(live_head_t),SEEK_CUR);
-    fseek(outfile,sizeof(pdp_prep_t)*rrdnew.stat_head->ds_cnt,SEEK_CUR);
-    fseek(outfile,sizeof(cdp_prep_t)*rrdnew.stat_head->ds_cnt*rrdnew.stat_head->rra_cnt,SEEK_CUR);
-    fwrite(rrdnew.rra_ptr,sizeof(rra_ptr_t),rrdnew.stat_head->rra_cnt, outfile);
-    
-    fclose(outfile);
+    rrd_seek(rrd_out_file,
+             sizeof(stat_head_t) +
+             sizeof(ds_def_t) * rrdnew.stat_head->ds_cnt, SEEK_SET);
+    rrd_write(rrd_out_file, rrdnew.rra_def,
+              sizeof(rra_def_t) * rrdnew.stat_head->rra_cnt);
+    rrd_seek(rrd_out_file, sizeof(live_head_t), SEEK_CUR);
+    rrd_seek(rrd_out_file, sizeof(pdp_prep_t) * rrdnew.stat_head->ds_cnt,
+             SEEK_CUR);
+    rrd_seek(rrd_out_file,
+             sizeof(cdp_prep_t) * rrdnew.stat_head->ds_cnt *
+             rrdnew.stat_head->rra_cnt, SEEK_CUR);
+    rrd_write(rrd_out_file, rrdnew.rra_ptr,
+              sizeof(rra_ptr_t) * rrdnew.stat_head->rra_cnt);
+
     rrd_free(&rrdold);
-    fclose(infile);
-    return(0);
+    rrd_close(rrd_file);
+
+    rrd_close(rrd_out_file);
+
+    return (0);
 }
index 4fb1dab4a49c8ed14e0ed4ccd15cb706f5e69ba3..fd9f813e137f7eb1568977aaed290a97c49ac57d 100644 (file)
 /*****************************************************************************
- * RRDtool 1.2.27  Copyright by Tobi Oetiker, 1997-2008
+ * RRDtool 1.3rc4  Copyright by Tobi Oetiker, 1997-2008
+ * This file:     Copyright 2008 Florian octo Forster
+ * Distributed under the GPL
  *****************************************************************************
- * rrd_restore.c  creates new rrd from data dumped by rrd_dump.c
- *****************************************************************************/
+ * rrd_restore.c   Contains logic to parse XML input and create an RRD file
+ *****************************************************************************
+ * $Id: rrd_restore.c 1366 2008-05-18 13:06:44Z oetiker $
+ *************************************************************************** */
 
-#include "rrd_tool.h"
-#include "rrd_rpncalc.h"
-#include <fcntl.h>
+/*
+ * This program is free software; you can redistribute it and / or modify it
+ * under the terms of the GNU General Public License as published by the Free
+ * Software Foundation; either version 2 of the License, or (t your option)
+ * any later version.
+ * 
+ * This program is distributed in the hope that it will be useful, but WITHOUT
+ * ANY WARRANTY; without even the implied warranty of MERCHANTABILITY or
+ * FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License for
+ * more details.
+ *
+ * You should have received a copy of the GNU General Public License along
+ * with this program; if not, write to the Free Software Foundation, Inc.,
+ * 51 Franklin St, Fifth Floor, Boston, MA 02110 - 1301 USA
+ *
+ * Authors:
+ *   Florian octo Forster <octo at verplant.org>
+ **/
 
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <ctype.h>
+#include <unistd.h>
+#include <fcntl.h>
 #if defined(_WIN32) && !defined(__CYGWIN__) && !defined(__CYGWIN32__)
-#include <io.h>
-#define open _open
-#define close _close
+# include <io.h>
+# define open _open
+# define close _close
 #endif
+#include <libxml/parser.h>
+#include "rrd_tool.h"
+#include "rrd_rpncalc.h"
+#define ARRAY_LENGTH(a) (sizeof (a) / sizeof ((a)[0]))
+static int opt_range_check = 0;
+static int opt_force_overwrite = 0;
 
-/* Prototypes */
-
-void xml_lc(char*);
-int skip(char **);
-int skipxml(char **);
-int eat_tag(char **, char *);
-int read_tag(char **, char *, char *, void *);
-int xml2rrd(char*, rrd_t*, char);
-int rrd_write(char *, rrd_t *, char);
-void parse_patch1028_RRA_params(char **buf, rrd_t *rrd, int rra_index);
-void parse_patch1028_CDP_params(char **buf, rrd_t *rrd, int rra_index, int ds_index);
-void parse_FAILURES_history(char **buf, rrd_t *rrd, int rra_index, int ds_index);
-
-/* convert all occurrences of <BlaBlaBla> to <blablabla> */
-
-void xml_lc(char* buf){
-  int intag=0;
-  while((*buf)){
-    if (intag ==0 && (*buf) == '<') {
-      intag = 1;
+/*
+ * Auxiliary functions
+ */
+static int get_string_from_node(
+    xmlDoc * doc,
+    xmlNode * node,
+    char *buffer,
+    size_t buffer_size)
+{
+    xmlChar  *temp0;
+    char     *begin_ptr;
+    char     *end_ptr;
+
+    temp0 = xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
+    if (temp0 == NULL) {
+        rrd_set_error("get_string_from_node: xmlNodeListGetString failed.");
+        return (-1);
     }
-    else if (intag ==1 && (*buf) == '>') {
-      intag = 0;
-      continue;
-    } else  if (intag ==1) {
-      *buf = tolower(*buf);
+
+    begin_ptr = (char *) temp0;
+    while ((begin_ptr[0] != 0) && (isspace(begin_ptr[0])))
+        begin_ptr++;
+
+    if (begin_ptr[0] == 0) {
+        xmlFree(temp0);
+        buffer[0] = 0;
+        return (0);
     }
-    buf++;    
-  }
-}
-
-int skipxml(char **buf){
-  char *ptr;  
-  ptr=(*buf);
-  do {
-    (*buf)=ptr;
-    while((*(ptr+1)) && ((*ptr)==' ' ||  (*ptr)=='\r' || (*ptr)=='\n' || (*ptr)=='\t')) ptr++;
-    if (strncmp(ptr,"<?xml",4) == 0) {
-      ptr= strstr(ptr,"?>");
-      if (ptr) ptr+=2; else {
-       rrd_set_error("Dangling XML header");
-       (*buf) = NULL;
-       return -1;
-      }
+
+    end_ptr = begin_ptr;
+    while ((end_ptr[0] != 0) && (!isspace(end_ptr[0])))
+        end_ptr++;
+    end_ptr[0] = 0;
+
+    strncpy(buffer, begin_ptr, buffer_size);
+    buffer[buffer_size - 1] = 0;
+
+    xmlFree(temp0);
+
+    return (0);
+}                       /* int get_string_from_node */
+
+static int get_int_from_node(
+    xmlDoc * doc,
+    xmlNode * node,
+    int *value)
+{
+    int       temp;
+    char     *str_ptr;
+    char     *end_ptr;
+
+    str_ptr = (char *) xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
+    if (str_ptr == NULL) {
+        rrd_set_error("get_int_from_node: xmlNodeListGetString failed.");
+        return (-1);
     }
-  } while ((*buf)!=ptr);  
-  return 1;
-}
-
-int skip(char **buf){
-  char *ptr;
-  if ((buf == NULL) || (*buf == NULL))
-    return -1;  
-  ptr=(*buf);
-  do {
-    (*buf)=ptr;
-    while((*(ptr+1)) && ((*ptr)==' ' ||  (*ptr)=='\r' || (*ptr)=='\n' || (*ptr)=='\t')) ptr++;
-    if (strncmp(ptr,"<!--",4) == 0) {
-      ptr= strstr(ptr,"-->");
-      if (ptr) ptr+=3; else {
-       rrd_set_error("Dangling Comment");
-       (*buf) = NULL;
-       return -1;
-      }
+
+    end_ptr = NULL;
+    temp = strtol(str_ptr, &end_ptr, 0);
+    xmlFree(str_ptr);
+
+    if (str_ptr == end_ptr) {
+        rrd_set_error("get_int_from_node: Cannot parse buffer as int: %s",
+                      str_ptr);
+        return (-1);
     }
-  } while ((*buf)!=ptr);  
-  return 1;
-}
-
-int eat_tag(char **buf, char *tag){ 
-  if ((*buf)==NULL) return -1;   /* fall though clause */
-
-  rrd_clear_error();
-  skip(buf);
-  if ((**buf)=='<' 
-      && strncmp((*buf)+1,tag,strlen(tag)) == 0 
-      && *((*buf)+strlen(tag)+1)=='>') {
-    (*buf) += strlen(tag)+2;
-  }
-  else {
-    rrd_set_error("No <%s> tag found",tag);
-    (*buf) = NULL;
-    return -1;
-  }
-  skip(buf);
-  return 1;
-}
-
-int read_tag(char **buf, char *tag, char *format, void *value){
-    char *end_tag;
-    int matches;
-    if ((*buf)==NULL) return -1;   /* fall though clause */
-    rrd_clear_error();
-    if (eat_tag(buf,tag)==1){
-       char *temp;
-       temp = (*buf);
-       while(*((*buf)+1) && (*(*buf) != '<')) (*buf)++; /*find start of endtag*/
-       *(*buf) = '\0';
-       matches =sscanf(temp,format,value);
-       *(*buf) = '<';
-       end_tag = malloc((strlen(tag)+2)*sizeof(char));
-       sprintf(end_tag,"/%s",tag);
-       eat_tag(buf,end_tag);
-       free(end_tag);
-       if (matches == 0 && strcmp(format,"%lf") == 0)
-           (*((double* )(value))) = DNAN;
-       if (matches != 1)       return 0;       
-       return 1;
+
+    *value = temp;
+
+    return (0);
+}                       /* int get_int_from_node */
+
+static int get_double_from_node(
+    xmlDoc * doc,
+    xmlNode * node,
+    double *value)
+{
+    double    temp;
+    char     *str_ptr;
+    char     *end_ptr;
+
+    str_ptr = (char *) xmlNodeListGetString(doc, node->xmlChildrenNode, 1);
+    if (str_ptr == NULL) {
+        rrd_set_error("get_double_from_node: xmlNodeListGetString failed.");
+        return (-1);
     }
-    return -1;
-}
-
-
-/* parse the data stored in buf and return a filled rrd structure */
-int xml2rrd(char* buf, rrd_t* rrd, char rc){
-  /* pass 1 identify number of RRAs  */
-  char *ptr,*ptr2,*ptr3; /* walks thought the buffer */
-  long rows=0,mempool=0,i=0;
-  int rra_index;
-  int input_version;
-  xml_lc(buf); /* lets lowercase all active parts of the xml */
-  ptr=buf;
-  ptr2=buf;
-  ptr3=buf;
-  /* start with an RRD tag */
-  
-  skipxml(&ptr);
-
-  eat_tag(&ptr,"rrd");
-  /* allocate static header */
-  if((rrd->stat_head = calloc(1,sizeof(stat_head_t)))==NULL){
-    rrd_set_error("allocating rrd.stat_head");
-    return -1;    
-  };
-
-  strcpy(rrd->stat_head->cookie,RRD_COOKIE);
-  read_tag(&ptr,"version","%4[0-9]",rrd->stat_head->version);
-  input_version = atoi(rrd->stat_head->version);
-  /* added primitive version checking */
-  if (input_version > atoi(RRD_VERSION) || input_version < 1)
-  {
-    rrd_set_error("Incompatible file version, detected version %s. This is not supported by the version %s restore tool.\n",
-                 rrd -> stat_head -> version, RRD_VERSION );
-    free(rrd -> stat_head); 
-    rrd->stat_head = NULL; 
-    return -1;
-  }
-  /* make sure we output the right version */
-  strcpy(rrd->stat_head->version,RRD_VERSION);
-
-  /*  if (atoi(rrd -> stat_head -> version) < 2) 
-  {
-    rrd_set_error("Can only restore version >= 2 (Not %s). Dump your old rrd using a current rrdtool dump.",  rrd -> stat_head -> version );
-    return -1;
-  } */
-
-  rrd->stat_head->float_cookie = FLOAT_COOKIE;
-  rrd->stat_head->ds_cnt = 0;
-  rrd->stat_head->rra_cnt = 0;
-  read_tag(&ptr,"step","%lu",&(rrd->stat_head->pdp_step));
-
-  /* allocate live head */
-  if((rrd->live_head = calloc(1,sizeof(live_head_t)))==NULL){
-    rrd_set_error("allocating rrd.live_head");
-    return -1;    
-  }
-  read_tag(&ptr,"lastupdate","%lu",&(rrd->live_head->last_up));
-
-  /* Data Source Definition Part */
-  ptr2 = ptr;
-  while (eat_tag(&ptr2,"ds") == 1){
-      rrd->stat_head->ds_cnt++;
-      if((rrd->ds_def = rrd_realloc(rrd->ds_def,rrd->stat_head->ds_cnt*sizeof(ds_def_t)))==NULL){
-         rrd_set_error("allocating rrd.ds_def");
-         return -1;
-      };
-      /* clean out memory to make sure no data gets stored from previous tasks */
-      memset(&(rrd->ds_def[rrd->stat_head->ds_cnt-1]), 0, sizeof(ds_def_t));
-      if((rrd->pdp_prep = rrd_realloc(rrd->pdp_prep,rrd->stat_head->ds_cnt
-                                 *sizeof(pdp_prep_t)))==NULL){
-       rrd_set_error("allocating pdp_prep");
-       return(-1);
-      }
-      /* clean out memory to make sure no data gets stored from previous tasks */
-      memset(&(rrd->pdp_prep[rrd->stat_head->ds_cnt-1]), 0, sizeof(pdp_prep_t));
-
-      read_tag(&ptr2,"name",DS_NAM_FMT,rrd->ds_def[rrd->stat_head->ds_cnt-1].ds_nam);
-
-      read_tag(&ptr2,"type",DST_FMT,rrd->ds_def[rrd->stat_head->ds_cnt-1].dst);
-      /* test for valid type */
-      if( (int)dst_conv(rrd->ds_def[rrd->stat_head->ds_cnt-1].dst) == -1) return -1;      
-
-         if (dst_conv(rrd->ds_def[rrd->stat_head->ds_cnt-1].dst) != DST_CDEF)
-         {
-      read_tag(&ptr2,"minimal_heartbeat","%lu",
-              &(rrd->ds_def[rrd->stat_head->ds_cnt-1].par[DS_mrhb_cnt].u_cnt));
-      read_tag(&ptr2,"min","%lf",&(rrd->ds_def[rrd->stat_head->ds_cnt-1].par[DS_min_val].u_val));
-      read_tag(&ptr2,"max","%lf",&(rrd->ds_def[rrd->stat_head->ds_cnt-1].par[DS_max_val].u_val));
-         } else { /* DST_CDEF */
-                char buffer[1024];
-                read_tag(&ptr2,"cdef","%1000s",buffer);
-                parseCDEF_DS(buffer,rrd,rrd -> stat_head -> ds_cnt - 1);
-                if (rrd_test_error()) return -1;
-         }
-
-      read_tag(&ptr2,"last_ds","%30s",rrd->pdp_prep[rrd->stat_head->ds_cnt-1].last_ds);
-      read_tag(&ptr2,"value","%lf",&(rrd->pdp_prep[rrd->stat_head->ds_cnt-1].scratch[PDP_val].u_val));
-      read_tag(&ptr2,"unknown_sec","%lu",&(rrd->pdp_prep[rrd->stat_head->ds_cnt-1].scratch[PDP_unkn_sec_cnt].u_cnt));      
-      eat_tag(&ptr2,"/ds");
-      ptr=ptr2;
-  }
-  
-  ptr2 = ptr;
-  while (eat_tag(&ptr2,"rra") == 1){
-      rrd->stat_head->rra_cnt++;
-
-      /* allocate and reset rra definition areas */
-      if((rrd->rra_def = rrd_realloc(rrd->rra_def,rrd->stat_head->rra_cnt*sizeof(rra_def_t)))==NULL){
-         rrd_set_error("allocating rra_def"); return -1; }      
-      memset(&(rrd->rra_def[rrd->stat_head->rra_cnt-1]), 0, sizeof(rra_def_t));
-
-      /* allocate and reset consolidation point areas */
-      if((rrd->cdp_prep = rrd_realloc(rrd->cdp_prep,
-                                 rrd->stat_head->rra_cnt
-                                 *rrd->stat_head->ds_cnt*sizeof(cdp_prep_t)))==NULL){
-         rrd_set_error("allocating cdp_prep"); return -1; }
-
-      memset(&(rrd->cdp_prep[rrd->stat_head->ds_cnt*(rrd->stat_head->rra_cnt-1)]), 
-            0, rrd->stat_head->ds_cnt*sizeof(cdp_prep_t));
-
-      
-      read_tag(&ptr2,"cf",CF_NAM_FMT,rrd->rra_def[rrd->stat_head->rra_cnt-1].cf_nam);
-      /* test for valid type */
-      if( (int)cf_conv(rrd->rra_def[rrd->stat_head->rra_cnt-1].cf_nam) == -1) return -1;
-
-      read_tag(&ptr2,"pdp_per_row","%lu",&(rrd->rra_def[rrd->stat_head->rra_cnt-1].pdp_cnt));
-      /* support to read RRA parameters */
-      rra_index = rrd->stat_head->rra_cnt - 1;
-      if ( input_version < 2 ){
-         read_tag(&ptr2, "xff","%lf",
-            &(rrd->rra_def[rra_index].par[RRA_cdp_xff_val].u_val));
-      } else {
-        if (eat_tag(&ptr2, "params") != 1) {
-         rrd_set_error("could not find params tag to eat and skip");
-          return -1;
+
+    end_ptr = NULL;
+    temp = strtod(str_ptr, &end_ptr);
+    xmlFree(str_ptr);
+
+    if (str_ptr == end_ptr) {
+        rrd_set_error
+            ("get_double_from_node: Cannot parse buffer as double: %s",
+             str_ptr);
+        return (-1);
+    }
+
+    *value = temp;
+
+    return (0);
+}                       /* int get_double_from_node */
+
+static int value_check_range(
+    rrd_value_t *rrd_value,
+    const ds_def_t *ds_def)
+{
+    double    min;
+    double    max;
+
+    if (opt_range_check == 0)
+        return (0);
+
+    min = ds_def->par[DS_min_val].u_val;
+    max = ds_def->par[DS_max_val].u_val;
+
+    if (((!isnan(min)) && (*rrd_value < min))
+        || ((!isnan(max)) && (*rrd_value > max)))
+        *rrd_value = NAN;
+
+    return (0);
+}                       /* int value_check_range */
+
+/*
+ * Parse the <database> block within an RRA definition
+ */
+static int parse_tag_rra_database_row(
+    xmlDoc * doc,
+    xmlNode * node,
+    rrd_t *rrd,
+    rrd_value_t *rrd_value)
+{
+    unsigned int values_count = 0;
+    xmlNode  *child;
+    int       status;
+
+    status = 0;
+    for (child = node->xmlChildrenNode; child != NULL; child = child->next) {
+        if ((xmlStrcmp(child->name, (const xmlChar *) "comment") == 0)
+            || (xmlStrcmp(child->name, (const xmlChar *) "text") == 0))
+            /* ignore */ ;
+        else if (xmlStrcmp(child->name, (const xmlChar *) "v") == 0) {
+            if (values_count < rrd->stat_head->ds_cnt) {
+                status =
+                    get_double_from_node(doc, child,
+                                         rrd_value + values_count);
+                if (status == 0)
+                    value_check_range(rrd_value + values_count,
+                                      rrd->ds_def + values_count);
+            }
+
+            values_count++;
+        } else {
+            rrd_set_error("parse_tag_rra_database_row: Unknown tag: %s",
+                          child->name);
+            status = -1;
         }
-        skip(&ptr2);
-        /* backwards compatibility w/ old patch */
-      if (strncmp(ptr2, "<value>",7) == 0) {
-          parse_patch1028_RRA_params(&ptr2,rrd,rra_index); 
-      } else {
-      switch(cf_conv(rrd -> rra_def[rra_index].cf_nam)) {
-      case CF_HWPREDICT:
-         read_tag(&ptr2, "hw_alpha", "%lf", 
-            &(rrd->rra_def[rra_index].par[RRA_hw_alpha].u_val));
-         read_tag(&ptr2, "hw_beta", "%lf", 
-            &(rrd->rra_def[rra_index].par[RRA_hw_beta].u_val));
-         read_tag(&ptr2, "dependent_rra_idx", "%lu", 
-            &(rrd->rra_def[rra_index].par[RRA_dependent_rra_idx].u_cnt));
-         break;
-      case CF_SEASONAL:
-      case CF_DEVSEASONAL:
-         read_tag(&ptr2, "seasonal_gamma", "%lf", 
-            &(rrd->rra_def[rra_index].par[RRA_seasonal_gamma].u_val));
-         read_tag(&ptr2, "seasonal_smooth_idx", "%lu", 
-            &(rrd->rra_def[rra_index].par[RRA_seasonal_smooth_idx].u_cnt));
-         read_tag(&ptr2, "dependent_rra_idx", "%lu", 
-            &(rrd->rra_def[rra_index].par[RRA_dependent_rra_idx].u_cnt));
-         break;
-      case CF_FAILURES:
-         read_tag(&ptr2, "delta_pos", "%lf", 
-            &(rrd->rra_def[rra_index].par[RRA_delta_pos].u_val));
-         read_tag(&ptr2, "delta_neg", "%lf", 
-            &(rrd->rra_def[rra_index].par[RRA_delta_neg].u_val));
-         read_tag(&ptr2, "window_len", "%lu", 
-            &(rrd->rra_def[rra_index].par[RRA_window_len].u_cnt));
-         read_tag(&ptr2, "failure_threshold", "%lu", 
-            &(rrd->rra_def[rra_index].par[RRA_failure_threshold].u_cnt));
-         /* fall thru */
-      case CF_DEVPREDICT:
-         read_tag(&ptr2, "dependent_rra_idx", "%lu", 
-            &(rrd->rra_def[rra_index].par[RRA_dependent_rra_idx].u_cnt));
-         break;
-      case CF_AVERAGE:
-      case CF_MAXIMUM:
-      case CF_MINIMUM:
-      case CF_LAST:
-      default:
-         read_tag(&ptr2, "xff","%lf",
-            &(rrd->rra_def[rra_index].par[RRA_cdp_xff_val].u_val));
-      }
-      }
-      eat_tag(&ptr2, "/params");
-   }
-
-
-      eat_tag(&ptr2,"cdp_prep");
-      for(i=0;i< (int)rrd->stat_head->ds_cnt;i++)
-      {
-      eat_tag(&ptr2,"ds");
-      /* support to read CDP parameters */
-      rra_index = rrd->stat_head->rra_cnt-1; 
-      skip(&ptr2);
-      if ( input_version < 2 ){
-          rrd->cdp_prep[rrd->stat_head->ds_cnt*(rra_index)+i].scratch[CDP_primary_val].u_val = 0.0;
-          rrd->cdp_prep[rrd->stat_head->ds_cnt*(rra_index)+i].scratch[CDP_secondary_val].u_val = 0.0;
-          read_tag(&ptr2,"value","%lf",&(rrd->cdp_prep[rrd->stat_head->ds_cnt
-               *(rra_index) +i].scratch[CDP_val].u_val));
-          read_tag(&ptr2,"unknown_datapoints","%lu",&(rrd->cdp_prep[rrd->stat_head->ds_cnt
-              *(rra_index) +i].scratch[CDP_unkn_pdp_cnt].u_cnt));
-      } else {
-
-      if (strncmp(ptr2, "<value>",7) == 0) {
-         parse_patch1028_CDP_params(&ptr2,rrd,rra_index,i);
-      } else {
-         read_tag(&ptr2, "primary_value","%lf",
-               &(rrd->cdp_prep[rrd->stat_head->ds_cnt*(rra_index)
-               +i].scratch[CDP_primary_val].u_val));
-         read_tag(&ptr2, "secondary_value","%lf",
-               &(rrd->cdp_prep[rrd->stat_head->ds_cnt*(rra_index)
-               +i].scratch[CDP_secondary_val].u_val));
-         switch(cf_conv(rrd->rra_def[rra_index].cf_nam)) {
-         case CF_HWPREDICT:
-            read_tag(&ptr2,"intercept","%lf", 
-               &(rrd->cdp_prep[rrd->stat_head->ds_cnt*(rra_index)
-               +i].scratch[CDP_hw_intercept].u_val));
-            read_tag(&ptr2,"last_intercept","%lf", 
-               &(rrd->cdp_prep[rrd->stat_head->ds_cnt*(rra_index)
-               +i].scratch[CDP_hw_last_intercept].u_val));
-            read_tag(&ptr2,"slope","%lf", 
-               &(rrd->cdp_prep[rrd->stat_head->ds_cnt*(rra_index)
-               +i].scratch[CDP_hw_slope].u_val));
-            read_tag(&ptr2,"last_slope","%lf", 
-               &(rrd->cdp_prep[rrd->stat_head->ds_cnt*(rra_index)
-               +i].scratch[CDP_hw_last_slope].u_val));
-            read_tag(&ptr2,"nan_count","%lu", 
-               &(rrd->cdp_prep[rrd->stat_head->ds_cnt*(rra_index)
-               +i].scratch[CDP_null_count].u_cnt));
-            read_tag(&ptr2,"last_nan_count","%lu", 
-               &(rrd->cdp_prep[rrd->stat_head->ds_cnt*(rra_index)
-               +i].scratch[CDP_last_null_count].u_cnt));
+
+        if (status != 0)
             break;
-         case CF_SEASONAL:
-         case CF_DEVSEASONAL:
-            read_tag(&ptr2,"seasonal","%lf", 
-               &(rrd->cdp_prep[rrd->stat_head->ds_cnt*(rra_index)
-               +i].scratch[CDP_hw_seasonal].u_val));
-            read_tag(&ptr2,"last_seasonal","%lf", 
-               &(rrd->cdp_prep[rrd->stat_head->ds_cnt*(rra_index)
-               +i].scratch[CDP_hw_last_seasonal].u_val));
-            read_tag(&ptr2,"init_flag","%lu", 
-               &(rrd->cdp_prep[rrd->stat_head->ds_cnt*(rra_index)
-               +i].scratch[CDP_init_seasonal].u_cnt));
+    }                   /* for (child = node->xmlChildrenNode) */
+
+    if (values_count != rrd->stat_head->ds_cnt) {
+        rrd_set_error("parse_tag_rra_database_row: Row has %u values "
+                      "and RRD has %lu data sources.",
+                      values_count, rrd->stat_head->ds_cnt);
+        status = -1;
+    }
+
+    return (status);
+}                       /* int parse_tag_rra_database_row */
+
+static int parse_tag_rra_database(
+    xmlDoc * doc,
+    xmlNode * node,
+    rrd_t *rrd)
+{
+    rra_def_t *cur_rra_def;
+    unsigned int total_row_cnt;
+    xmlNode  *child;
+    int       status;
+    int       i;
+
+    total_row_cnt = 0;
+    for (i = 0; i < (((int) rrd->stat_head->rra_cnt) - 1); i++)
+        total_row_cnt += rrd->rra_def[i].row_cnt;
+
+    cur_rra_def = rrd->rra_def + i;
+
+    status = 0;
+    for (child = node->xmlChildrenNode; child != NULL; child = child->next) {
+        if ((xmlStrcmp(child->name, (const xmlChar *) "comment") == 0)
+            || (xmlStrcmp(child->name, (const xmlChar *) "text") == 0))
+            /* ignore */ ;
+        else if (xmlStrcmp(child->name, (const xmlChar *) "row") == 0) {
+            rrd_value_t *temp;
+            rrd_value_t *cur_rrd_value;
+            unsigned int total_values_count = rrd->stat_head->ds_cnt
+                * (total_row_cnt + 1);
+
+            /* Allocate space for the new values.. */
+            temp = (rrd_value_t *) realloc(rrd->rrd_value,
+                                           sizeof(rrd_value_t) *
+                                           total_values_count);
+            if (temp == NULL) {
+                rrd_set_error("parse_tag_rra_database: realloc failed.");
+                status = -1;
+                break;
+            }
+            rrd->rrd_value = temp;
+            cur_rrd_value = rrd->rrd_value
+                + (rrd->stat_head->ds_cnt * total_row_cnt);
+            memset(cur_rrd_value, '\0',
+                   sizeof(rrd_value_t) * rrd->stat_head->ds_cnt);
+            total_row_cnt++;
+            cur_rra_def->row_cnt++;
+
+            status =
+                parse_tag_rra_database_row(doc, child, rrd, cur_rrd_value);
+        } /* if (xmlStrcmp (child->name, (const xmlChar *) "row") == 0) */
+        else {
+            rrd_set_error("parse_tag_rra_database: Unknown tag: %s",
+                          child->name);
+            status = -1;
+        }
+
+        if (status != 0)
             break;
-         case CF_DEVPREDICT:
+    }                   /* for (child = node->xmlChildrenNode) */
+
+    return (status);
+}                       /* int parse_tag_rra_database */
+
+/*
+ * Parse the <cdp_prep> block within an RRA definition
+ */
+static int parse_tag_rra_cdp_prep_ds_history(
+    xmlDoc * doc,
+    xmlNode * node,
+    cdp_prep_t *cdp_prep)
+{
+    /* Make `history_buffer' the same size as the scratch area, plus the
+     * terminating NULL byte. */
+    char      history_buffer[sizeof(((cdp_prep_t *)0)->scratch) + 1];
+    char     *history_ptr;
+    int       status;
+    int       i;
+
+    status = get_string_from_node(doc, node,
+                                  history_buffer, sizeof(history_buffer));
+    if (status != 0)
+        return (-1);
+
+    history_ptr = (char *) (&cdp_prep->scratch[0]);
+    for (i = 0; history_buffer[i] != '\0'; i++)
+        history_ptr[i] = (history_buffer[i] == '1') ? 1 : 0;
+
+    return (0);
+}                       /* int parse_tag_rra_cdp_prep_ds_history */
+
+static int parse_tag_rra_cdp_prep_ds(
+    xmlDoc * doc,
+    xmlNode * node,
+    rrd_t *rrd,
+    cdp_prep_t *cdp_prep)
+{
+    xmlNode  *child;
+    int       status;
+
+    memset(cdp_prep, '\0', sizeof(cdp_prep_t));
+
+    status = 0;
+    for (child = node->xmlChildrenNode; child != NULL; child = child->next) {
+        if ((xmlStrcmp(child->name, (const xmlChar *) "comment") == 0)
+            || (xmlStrcmp(child->name, (const xmlChar *) "text") == 0))
+            /* ignore */ ;
+        else if (xmlStrcmp(child->name, (const xmlChar *) "primary_value") ==
+                 0)
+            status =
+                get_double_from_node(doc, child,
+                                     &cdp_prep->scratch[CDP_primary_val].
+                                     u_val);
+        else if (xmlStrcmp(child->name, (const xmlChar *) "secondary_value")
+                 == 0)
+            status =
+                get_double_from_node(doc, child,
+                                     &cdp_prep->scratch[CDP_secondary_val].
+                                     u_val);
+        else if (xmlStrcmp(child->name, (const xmlChar *) "intercept") == 0)
+            status = get_double_from_node(doc, child,
+                                          &cdp_prep->
+                                          scratch[CDP_hw_intercept].u_val);
+        else if (xmlStrcmp(child->name, (const xmlChar *) "last_intercept") ==
+                 0)
+            status =
+                get_double_from_node(doc, child,
+                                     &cdp_prep->
+                                     scratch[CDP_hw_last_intercept].u_val);
+        else if (xmlStrcmp(child->name, (const xmlChar *) "slope") == 0)
+            status = get_double_from_node(doc, child,
+                                          &cdp_prep->scratch[CDP_hw_slope].
+                                          u_val);
+        else if (xmlStrcmp(child->name, (const xmlChar *) "last_slope") == 0)
+            status = get_double_from_node(doc, child,
+                                          &cdp_prep->
+                                          scratch[CDP_hw_last_slope].u_val);
+        else if (xmlStrcmp(child->name, (const xmlChar *) "nan_count") == 0)
+            status = get_int_from_node(doc, child,
+                                       (int *) &cdp_prep->
+                                       scratch[CDP_null_count].u_cnt);
+        else if (xmlStrcmp(child->name, (const xmlChar *) "last_nan_count") ==
+                 0)
+            status =
+                get_int_from_node(doc, child,
+                                  (int *) &cdp_prep->
+                                  scratch[CDP_last_null_count].u_cnt);
+        else if (xmlStrcmp(child->name, (const xmlChar *) "seasonal") == 0)
+            status = get_double_from_node(doc, child,
+                                          &cdp_prep->scratch[CDP_hw_seasonal].
+                                          u_val);
+        else if (xmlStrcmp(child->name, (const xmlChar *) "last_seasonal") ==
+                 0)
+            status =
+                get_double_from_node(doc, child,
+                                     &cdp_prep->scratch[CDP_hw_last_seasonal].
+                                     u_val);
+        else if (xmlStrcmp(child->name, (const xmlChar *) "init_flag") == 0)
+            status = get_int_from_node(doc, child,
+                                       (int *) &cdp_prep->
+                                       scratch[CDP_init_seasonal].u_cnt);
+        else if (xmlStrcmp(child->name, (const xmlChar *) "history") == 0)
+            status = parse_tag_rra_cdp_prep_ds_history(doc, child, cdp_prep);
+        else if (xmlStrcmp(child->name, (const xmlChar *) "value") == 0)
+            status = get_double_from_node(doc, child,
+                                          &cdp_prep->scratch[CDP_val].u_val);
+        else if (xmlStrcmp(child->name,
+                           (const xmlChar *) "unknown_datapoints") == 0)
+            status = get_int_from_node(doc, child,
+                                       (int *) &cdp_prep->
+                                       scratch[CDP_unkn_pdp_cnt].u_cnt);
+        /*
+         * Compatibility code for 1.0.49
+         */
+        else if (xmlStrcmp(child->name, (const xmlChar *) "value") == 0) {  /* {{{ */
+            unsigned int i = 0;
+            rra_def_t *rra_def = rrd->rra_def + (rrd->stat_head->rra_cnt - 1);
+
+            while (42) {
+                if (i >= ARRAY_LENGTH(cdp_prep->scratch)) {
+                    status = -1;
+                    break;
+                }
+
+                if ((cf_conv(rra_def->cf_nam) == CF_FAILURES)
+                    || (i == CDP_unkn_pdp_cnt)
+                    || (i == CDP_null_count)
+                    || (i == CDP_last_null_count))
+                    status = get_int_from_node(doc, child,
+                                               (int *) &cdp_prep->scratch[i].
+                                               u_cnt);
+                else
+                    status = get_double_from_node(doc, child,
+                                                  &cdp_prep->scratch[i].
+                                                  u_val);
+
+                if (status != 0)
+                    break;
+
+                /* When this loops exits (sucessfully) `child' points to the last
+                 * `value' tag in the list. */
+                if ((child->next == NULL)
+                    || (xmlStrcmp(child->name, (const xmlChar *) "value") !=
+                        0))
+                    break;
+
+                child = child->next;
+                i++;
+            }
+        } /* }}} */
+        else {
+            rrd_set_error("parse_tag_rra_cdp_prep: Unknown tag: %s",
+                          child->name);
+            status = -1;
+        }
+
+        if (status != 0)
             break;
-         case CF_FAILURES:
-            parse_FAILURES_history(&ptr2,rrd,rra_index,i); 
+    }
+
+    return (status);
+}                       /* int parse_tag_rra_cdp_prep_ds */
+
+static int parse_tag_rra_cdp_prep(
+    xmlDoc * doc,
+    xmlNode * node,
+    rrd_t *rrd,
+    cdp_prep_t *cdp_prep)
+{
+    xmlNode  *child;
+    int       status;
+
+    unsigned int ds_count = 0;
+
+    status = 0;
+    for (child = node->xmlChildrenNode; child != NULL; child = child->next) {
+        if ((xmlStrcmp(child->name, (const xmlChar *) "comment") == 0)
+            || (xmlStrcmp(child->name, (const xmlChar *) "text") == 0))
+            /* ignore */ ;
+        else if (xmlStrcmp(child->name, (const xmlChar *) "ds") == 0) {
+            if (ds_count >= rrd->stat_head->ds_cnt)
+                status = -1;
+            else {
+                status = parse_tag_rra_cdp_prep_ds(doc, child, rrd,
+                                                   cdp_prep + ds_count);
+                ds_count++;
+            }
+        } else {
+            rrd_set_error("parse_tag_rra_cdp_prep: Unknown tag: %s",
+                          child->name);
+            status = -1;
+        }
+
+        if (status != 0)
             break;
-         case CF_AVERAGE:
-         case CF_MAXIMUM:
-         case CF_MINIMUM:
-         case CF_LAST:
-         default:
-            read_tag(&ptr2,"value","%lf",&(rrd->cdp_prep[rrd->stat_head->ds_cnt
-               *(rra_index) +i].scratch[CDP_val].u_val));
-            read_tag(&ptr2,"unknown_datapoints","%lu",&(rrd->cdp_prep[rrd->stat_head->ds_cnt
-               *(rra_index) +i].scratch[CDP_unkn_pdp_cnt].u_cnt));
+    }
+
+    if (ds_count != rrd->stat_head->ds_cnt) {
+        rrd_set_error("parse_tag_rra_cdp_prep: There are %i data sources in "
+                      "the RRD file, but %i in this cdp_prep block!",
+                      (int) rrd->stat_head->ds_cnt, ds_count);
+        status = -1;
+    }
+
+    return (status);
+}                       /* int parse_tag_rra_cdp_prep */
+
+/*
+ * Parse the <params> block within an RRA definition
+ */
+static int parse_tag_rra_params(
+    xmlDoc * doc,
+    xmlNode * node,
+    rra_def_t *rra_def)
+{
+    xmlNode  *child;
+    int       status;
+
+    status = 0;
+    for (child = node->xmlChildrenNode; child != NULL; child = child->next) {
+        if ((xmlStrcmp(child->name, (const xmlChar *) "comment") == 0)
+            || (xmlStrcmp(child->name, (const xmlChar *) "text") == 0))
+            /* ignore */ ;
+        /*
+         * Parameters for CF_HWPREDICT
+         */
+        else if (xmlStrcmp(child->name, (const xmlChar *) "hw_alpha") == 0)
+            status = get_double_from_node(doc, child,
+                                          &rra_def->par[RRA_hw_alpha].u_val);
+        else if (xmlStrcmp(child->name, (const xmlChar *) "hw_beta") == 0)
+            status = get_double_from_node(doc, child,
+                                          &rra_def->par[RRA_hw_beta].u_val);
+        else if (xmlStrcmp(child->name,
+                           (const xmlChar *) "dependent_rra_idx") == 0)
+            status = get_int_from_node(doc, child,
+                                       (int *) &rra_def->
+                                       par[RRA_dependent_rra_idx].u_cnt);
+        /*
+         * Parameters for CF_SEASONAL and CF_DEVSEASONAL
+         */
+        else if (xmlStrcmp(child->name, (const xmlChar *) "seasonal_gamma") ==
+                 0)
+            status =
+                get_double_from_node(doc, child,
+                                     &rra_def->par[RRA_seasonal_gamma].u_val);
+        else if (xmlStrcmp
+                 (child->name, (const xmlChar *) "seasonal_smooth_idx") == 0)
+            status =
+                get_int_from_node(doc, child,
+                                  (int *) &rra_def->
+                                  par[RRA_seasonal_smooth_idx].u_cnt);
+        else if (xmlStrcmp(child->name, (const xmlChar *) "smoothing_window")
+                 == 0)
+            status =
+                get_double_from_node(doc, child,
+                                     &rra_def->
+                                     par[RRA_seasonal_smoothing_window].
+                                     u_val);
+        /* else if (dependent_rra_idx) ...; */
+        /*
+         * Parameters for CF_FAILURES
+         */
+        else if (xmlStrcmp(child->name, (const xmlChar *) "delta_pos") == 0)
+            status = get_double_from_node(doc, child,
+                                          &rra_def->par[RRA_delta_pos].u_val);
+        else if (xmlStrcmp(child->name, (const xmlChar *) "delta_neg") == 0)
+            status = get_double_from_node(doc, child,
+                                          &rra_def->par[RRA_delta_neg].u_val);
+        else if (xmlStrcmp(child->name, (const xmlChar *) "window_len") == 0)
+            status = get_int_from_node(doc, child,
+                                       (int *) &rra_def->par[RRA_window_len].
+                                       u_cnt);
+        else if (xmlStrcmp(child->name, (const xmlChar *) "failure_threshold")
+                 == 0)
+            status =
+                get_int_from_node(doc, child,
+                                  (int *) &rra_def->
+                                  par[RRA_failure_threshold].u_cnt);
+        /*
+         * Parameters for CF_AVERAGE, CF_MAXIMUM, CF_MINIMUM, and CF_LAST
+         */
+        else if (xmlStrcmp(child->name, (const xmlChar *) "xff") == 0)
+            status = get_double_from_node(doc, child,
+                                          &rra_def->par[RRA_cdp_xff_val].
+                                          u_val);
+        /*
+         * Compatibility code for 1.0.49
+         */
+        else if (xmlStrcmp(child->name, (const xmlChar *) "value") == 0) {  /* {{{ */
+            unsigned int i = 0;
+
+            while (42) {
+                if (i >= ARRAY_LENGTH(rra_def->par)) {
+                    status = -1;
+                    break;
+                }
+
+                if ((i == RRA_dependent_rra_idx)
+                    || (i == RRA_seasonal_smooth_idx)
+                    || (i == RRA_failure_threshold))
+                    status = get_int_from_node(doc, child,
+                                               (int *) &rra_def->par[i].
+                                               u_cnt);
+                else
+                    status = get_double_from_node(doc, child,
+                                                  &rra_def->par[i].u_val);
+
+                if (status != 0)
+                    break;
+
+                /* When this loops exits (sucessfully) `child' points to the last
+                 * `value' tag in the list. */
+                if ((child->next == NULL)
+                    || (xmlStrcmp(child->name, (const xmlChar *) "value") !=
+                        0))
+                    break;
+
+                child = child->next;
+                i++;
+            }
+        } /* }}} */
+        else {
+            rrd_set_error("parse_tag_rra_params: Unknown tag: %s",
+                          child->name);
+            status = -1;
+        }
+
+        if (status != 0)
             break;
-        }
-      }
-      }
-      eat_tag(&ptr2,"/ds");
-      }
-      eat_tag(&ptr2,"/cdp_prep");
-      rrd->rra_def[rrd->stat_head->rra_cnt-1].row_cnt=0;
-      eat_tag(&ptr2,"database");
-      ptr3 = ptr2;      
-      while (eat_tag(&ptr3,"row") == 1){
-       
-         if(mempool==0){
-           mempool = 1000;
-           if((rrd->rrd_value = rrd_realloc(rrd->rrd_value,
-                                        (rows+mempool)*(rrd->stat_head->ds_cnt)
-                                        *sizeof(rrd_value_t)))==NULL) {
-             rrd_set_error("allocating rrd_values"); return -1; }
-         }
-         rows++;
-         mempool--;
-         rrd->rra_def[rrd->stat_head->rra_cnt-1].row_cnt++;
-         for(i=0;i< (int)rrd->stat_head->ds_cnt;i++){
-
-                 rrd_value_t  * value = &(rrd->rrd_value[(rows-1)*rrd->stat_head->ds_cnt+i]);
-
-                 read_tag(&ptr3,"v","%lf", value);
-                 
-                 if (
-                         (rc == 1)                     /* do we have to check for the ranges */
-                         &&
-                     (!isnan(*value))  /* not a NAN value */
-                     &&
-                         (dst_conv(rrd->ds_def[i].dst) != DST_CDEF)
-                         &&
-                     (                                 /* min defined and in the range ? */
-                         (!isnan(rrd->ds_def[i].par[DS_min_val].u_val) 
-                               && (*value < rrd->ds_def[i].par[DS_min_val].u_val)) 
-                         ||                            /* max defined and in the range ? */
-                         (!isnan(rrd->ds_def[i].par[DS_max_val].u_val) 
-                               && (*value > rrd->ds_def[i].par[DS_max_val].u_val))
-                     )
-                 ) {
-                     fprintf (stderr, "out of range found [ds: %lu], [value : %0.10e]\n", i, *value);
-                     *value = DNAN;
-                 }
-         }
-         eat_tag(&ptr3,"/row");                  
-         ptr2=ptr3;
-      }
-      eat_tag(&ptr2,"/database");
-      eat_tag(&ptr2,"/rra");                  
-      ptr=ptr2;
-  }  
-  eat_tag(&ptr,"/rrd");
-
-  if((rrd->rra_ptr = calloc(1,sizeof(rra_ptr_t)*rrd->stat_head->rra_cnt)) == NULL) {
-      rrd_set_error("allocating rra_ptr");
-      return(-1);
-  }
-
-  for(i=0; i < (int)rrd->stat_head->rra_cnt; i++) {
-         /* last row in the xml file is the most recent; as
-          * rrd_update increments the current row pointer, set cur_row
-          * here to the last row. */
-      rrd->rra_ptr[i].cur_row = rrd->rra_def[i].row_cnt-1;
-  }
-  if (ptr==NULL)
-      return -1;
-  return 1;
-}
-  
-    
-
-
-
-/* create and empty rrd file according to the specs given */
-
-int
-rrd_write(char *file_name, rrd_t *rrd, char force_overwrite)
+    }
+
+    return (status);
+}                       /* int parse_tag_rra_params */
+
+/*
+ * Parse an RRA definition
+ */
+static int parse_tag_rra_cf(
+    xmlDoc * doc,
+    xmlNode * node,
+    rra_def_t *rra_def)
 {
-    unsigned long    i,ii,val_cnt;
-    FILE             *rrd_file=NULL;
-    int                        fdflags;
-    int                        fd;
-
-    if (strcmp("-",file_name)==0){
-      rrd_file= stdout;
-    } else {
-#if defined(_WIN32) && !defined(__CYGWIN__) && !defined(__CYGWIN32__)
-      fdflags = O_RDWR|O_BINARY|O_CREAT;
-#else
-      fdflags = O_WRONLY|O_CREAT;
-#endif            
-      if (force_overwrite == 0) {
-       fdflags |= O_EXCL;
-      }
-      fd = open(file_name,fdflags,0666);
-      if (fd == -1 || (rrd_file = fdopen(fd,"wb")) == NULL) {
-       rrd_set_error("creating '%s': %s",file_name,rrd_strerror(errno));
-        if (fd != -1)
-          close(fd);
-       return(-1);
-      }
+    int       status;
+
+    status = get_string_from_node(doc, node,
+                                  rra_def->cf_nam, sizeof(rra_def->cf_nam));
+    if (status != 0)
+        return (-1);
+
+    status = cf_conv(rra_def->cf_nam);
+    if (status == -1) {
+        rrd_set_error("parse_tag_rra_cf: Unknown consolidation function: %s",
+                      rra_def->cf_nam);
+        return (-1);
     }
-    fwrite(rrd->stat_head,
-          sizeof(stat_head_t), 1, rrd_file);
 
-    fwrite(rrd->ds_def,
-          sizeof(ds_def_t), rrd->stat_head->ds_cnt, rrd_file);
+    return (0);
+}                       /* int parse_tag_rra_cf */
 
-    fwrite(rrd->rra_def,
-          sizeof(rra_def_t), rrd->stat_head->rra_cnt, rrd_file);
+static int parse_tag_rra(
+    xmlDoc * doc,
+    xmlNode * node,
+    rrd_t *rrd)
+{
+    xmlNode  *child;
+    int       status;
 
-    fwrite(rrd->live_head, sizeof(live_head_t),1, rrd_file);
+    rra_def_t *cur_rra_def;
+    cdp_prep_t *cur_cdp_prep;
+    rra_ptr_t *cur_rra_ptr;
 
-    fwrite( rrd->pdp_prep, sizeof(pdp_prep_t),rrd->stat_head->ds_cnt,rrd_file);
-    
-    fwrite( rrd->cdp_prep, sizeof(cdp_prep_t),rrd->stat_head->rra_cnt*
-           rrd->stat_head->ds_cnt,rrd_file);
-    fwrite( rrd->rra_ptr, sizeof(rra_ptr_t), rrd->stat_head->rra_cnt,rrd_file);
+    /* Allocate more rra_def space for this RRA */
+    {                   /* {{{ */
+        rra_def_t *temp;
 
+        temp = (rra_def_t *) realloc(rrd->rra_def,
+                                     sizeof(rra_def_t) *
+                                     (rrd->stat_head->rra_cnt + 1));
+        if (temp == NULL) {
+            rrd_set_error("parse_tag_rra: realloc failed.");
+            return (-1);
+        }
+        rrd->rra_def = temp;
+        cur_rra_def = rrd->rra_def + rrd->stat_head->rra_cnt;
+        memset(cur_rra_def, '\0', sizeof(rra_def_t));
+    }                   /* }}} */
 
+    /* allocate cdp_prep_t */
+    {                   /* {{{ */
+        cdp_prep_t *temp;
 
-    /* calculate the number of rrd_values to dump */
-    val_cnt=0;
-    for(i=0; i <  rrd->stat_head->rra_cnt; i++)
-       for(ii=0; ii <  rrd->rra_def[i].row_cnt * rrd->stat_head->ds_cnt;ii++)
-           val_cnt++;
-    fwrite( rrd->rrd_value, sizeof(rrd_value_t),val_cnt,rrd_file);
+        temp = (cdp_prep_t *) realloc(rrd->cdp_prep, sizeof(cdp_prep_t)
+                                      * rrd->stat_head->ds_cnt
+                                      * (rrd->stat_head->rra_cnt + 1));
+        if (temp == NULL) {
+            rrd_set_error("parse_tag_rra: realloc failed.");
+            return (-1);
+        }
+        rrd->cdp_prep = temp;
+        cur_cdp_prep = rrd->cdp_prep
+            + (rrd->stat_head->ds_cnt * rrd->stat_head->rra_cnt);
+        memset(cur_cdp_prep, '\0',
+               sizeof(cdp_prep_t) * rrd->stat_head->ds_cnt);
+    }                   /* }}} */
 
-    /* lets see if we had an error */
-    if(ferror(rrd_file)){
-       rrd_set_error("a file error occurred while creating '%s'",file_name);
-       fclose(rrd_file);       
-       return(-1);
+    /* allocate rra_ptr_t */
+    {                   /* {{{ */
+        rra_ptr_t *temp;
+
+        temp = (rra_ptr_t *) realloc(rrd->rra_ptr,
+                                     sizeof(rra_ptr_t) *
+                                     (rrd->stat_head->rra_cnt + 1));
+        if (temp == NULL) {
+            rrd_set_error("parse_tag_rra: realloc failed.");
+            return (-1);
+        }
+        rrd->rra_ptr = temp;
+        cur_rra_ptr = rrd->rra_ptr + rrd->stat_head->rra_cnt;
+        memset(cur_rra_ptr, '\0', sizeof(rra_ptr_t));
+    }                   /* }}} */
+
+    /* All space successfully allocated, increment number of RRAs. */
+    rrd->stat_head->rra_cnt++;
+
+    status = 0;
+    for (child = node->xmlChildrenNode; child != NULL; child = child->next) {
+        if ((xmlStrcmp(child->name, (const xmlChar *) "comment") == 0)
+            || (xmlStrcmp(child->name, (const xmlChar *) "text") == 0))
+            /* ignore */ ;
+        else if (xmlStrcmp(child->name, (const xmlChar *) "cf") == 0)
+            status = parse_tag_rra_cf(doc, child, cur_rra_def);
+        else if (xmlStrcmp(child->name, (const xmlChar *) "pdp_per_row") == 0)
+            status = get_int_from_node(doc, child,
+                                       (int *) &cur_rra_def->pdp_cnt);
+        else if (xmlStrcmp(child->name, (const xmlChar *) "params") == 0)
+            status = parse_tag_rra_params(doc, child, cur_rra_def);
+        else if (xmlStrcmp(child->name, (const xmlChar *) "cdp_prep") == 0)
+            status = parse_tag_rra_cdp_prep(doc, child, rrd, cur_cdp_prep);
+        else if (xmlStrcmp(child->name, (const xmlChar *) "database") == 0)
+            status = parse_tag_rra_database(doc, child, rrd);
+        else {
+            rrd_set_error("parse_tag_rra: Unknown tag: %s", child->name);
+            status = -1;
+        }
+
+        if (status != 0)
+            break;
     }
-    
-    fclose(rrd_file);    
-    return 0;
-}
 
+    /* Set the RRA pointer to the last value in the archive */
+    cur_rra_ptr->cur_row = cur_rra_def->row_cnt - 1;
+
+    return (status);
+}                       /* int parse_tag_rra */
 
-int
-rrd_restore(int argc, char **argv) 
+/*
+ * Parse a DS definition
+ */
+static int parse_tag_ds_cdef(
+    xmlDoc * doc,
+    xmlNode * node,
+    rrd_t *rrd)
 {
-    rrd_t          rrd;
-    char          *buf;
-       char                    rc = 0;
-       char                    force_overwrite = 0;    
+    char      buffer[1024];
+    int       status;
 
-    /* init rrd clean */
-    optind = 0; opterr = 0;  /* initialize getopt */
-       while (1) {
-               static struct option long_options[] =
-               {
-                       {"range-check",      no_argument, 0,  'r'},
-                       {"force-overwrite",  no_argument, 0,  'f'},
-                       {0,0,0,0}
-               };
-               int option_index = 0;
-               int opt;
-               
-               
-               opt = getopt_long(argc, argv, "rf", long_options, &option_index);
-               
-               if (opt == EOF)
-                       break;
-               
-               switch(opt) {
-               case 'r':
-                       rc=1;
-                       break;
-               case 'f':
-                       force_overwrite=1;
-                       break;
-               default:
-                       rrd_set_error("usage rrdtool %s [--range-check|-r] [--force-overwrite/-f]  file.xml file.rrd",argv[0]);
-                       return -1;
-                       break;
-               }
-    }
+    status = get_string_from_node(doc, node, buffer, sizeof(buffer));
+    if (status != 0)
+        return (-1);
+
+    /* We're always working on the last DS that has been added to the structure
+     * when we get here */
+    parseCDEF_DS(buffer, rrd, rrd->stat_head->ds_cnt - 1);
+
+    return (0);
+}                       /* int parse_tag_ds_cdef */
+
+static int parse_tag_ds_type(
+    xmlDoc * doc,
+    xmlNode * node,
+    ds_def_t *ds_def)
+{
+    int       status;
 
-    if (argc-optind != 2) {
-               rrd_set_error("usage rrdtool %s [--range-check/-r] [--force-overwrite/-f] file.xml file.rrd",argv[0]);
-               return -1;
+    status = get_string_from_node(doc, node,
+                                  ds_def->dst, sizeof(ds_def->dst));
+    if (status != 0)
+        return (-1);
+
+    status = dst_conv(ds_def->dst);
+    if (status == -1) {
+        rrd_set_error("parse_tag_ds_type: Unknown data source type: %s",
+                      ds_def->dst);
+        return (-1);
     }
-       
-    if (readfile(argv[optind],&buf,0)==-1){
-      return -1;
+
+    return (0);
+}                       /* int parse_tag_ds_type */
+
+static int parse_tag_ds(
+    xmlDoc * doc,
+    xmlNode * node,
+    rrd_t *rrd)
+{
+    xmlNode  *child;
+    int       status;
+
+    ds_def_t *cur_ds_def;
+    pdp_prep_t *cur_pdp_prep;
+
+    /*
+     * If there are DS definitions after RRA definitions the number of values,
+     * cdp_prep areas and so on will be calculated wrong. Thus, enforce a
+     * specific order in this case.
+     */
+    if (rrd->stat_head->rra_cnt > 0) {
+        rrd_set_error("parse_tag_ds: All data source definitions MUST "
+                      "precede the RRA definitions!");
+        return (-1);
     }
 
-    rrd_init(&rrd);
+    /* Allocate space for the new DS definition */
+    {                   /* {{{ */
+        ds_def_t *temp;
 
-    if (xml2rrd(buf,&rrd,rc)==-1) {
-       rrd_free(&rrd);
-       free(buf);
-       return -1;
+        temp = (ds_def_t *) realloc(rrd->ds_def,
+                                    sizeof(ds_def_t) *
+                                    (rrd->stat_head->ds_cnt + 1));
+        if (temp == NULL) {
+            rrd_set_error("parse_tag_ds: malloc failed.");
+            return (-1);
+        }
+        rrd->ds_def = temp;
+        cur_ds_def = rrd->ds_def + rrd->stat_head->ds_cnt;
+        memset(cur_ds_def, '\0', sizeof(ds_def_t));
+    }                   /* }}} */
+
+    /* Allocate pdp_prep space for the new DS definition */
+    {                   /* {{{ */
+        pdp_prep_t *temp;
+
+        temp = (pdp_prep_t *) realloc(rrd->pdp_prep,
+                                      sizeof(pdp_prep_t) *
+                                      (rrd->stat_head->ds_cnt + 1));
+        if (temp == NULL) {
+            rrd_set_error("parse_tag_ds: malloc failed.");
+            return (-1);
+        }
+        rrd->pdp_prep = temp;
+        cur_pdp_prep = rrd->pdp_prep + rrd->stat_head->ds_cnt;
+        memset(cur_pdp_prep, '\0', sizeof(pdp_prep_t));
+    }                   /* }}} */
+
+    /* All allocations successful, let's increment the number of DSes. */
+    rrd->stat_head->ds_cnt++;
+
+    status = 0;
+    for (child = node->xmlChildrenNode; child != NULL; child = child->next) {
+        if ((xmlStrcmp(child->name, (const xmlChar *) "comment") == 0)
+            || (xmlStrcmp(child->name, (const xmlChar *) "text") == 0))
+            /* ignore */ ;
+        else if (xmlStrcmp(child->name, (const xmlChar *) "name") == 0)
+            status = get_string_from_node(doc, child,
+                                          cur_ds_def->ds_nam,
+                                          sizeof(cur_ds_def->ds_nam));
+        else if (xmlStrcmp(child->name, (const xmlChar *) "type") == 0)
+            status = parse_tag_ds_type(doc, child, cur_ds_def);
+        else if (xmlStrcmp(child->name,
+                           (const xmlChar *) "minimal_heartbeat") == 0)
+            status = get_int_from_node(doc, child,
+                                       (int *) &cur_ds_def->par[DS_mrhb_cnt].
+                                       u_cnt);
+        else if (xmlStrcmp(child->name, (const xmlChar *) "min") == 0)
+            status = get_double_from_node(doc, child,
+                                          &cur_ds_def->par[DS_min_val].u_val);
+        else if (xmlStrcmp(child->name, (const xmlChar *) "max") == 0)
+            status = get_double_from_node(doc, child,
+                                          &cur_ds_def->par[DS_max_val].u_val);
+        else if (xmlStrcmp(child->name, (const xmlChar *) "cdef") == 0)
+            status = parse_tag_ds_cdef(doc, child, rrd);
+        else if (xmlStrcmp(child->name, (const xmlChar *) "last_ds") == 0)
+            status = get_string_from_node(doc, child,
+                                          cur_pdp_prep->last_ds,
+                                          sizeof(cur_pdp_prep->last_ds));
+        else if (xmlStrcmp(child->name, (const xmlChar *) "value") == 0)
+            status = get_double_from_node(doc, child,
+                                          &cur_pdp_prep->scratch[PDP_val].
+                                          u_val);
+        else if (xmlStrcmp(child->name, (const xmlChar *) "unknown_sec") == 0)
+            status = get_int_from_node(doc, child,
+                                       (int *) &cur_pdp_prep->
+                                       scratch[PDP_unkn_sec_cnt].u_cnt);
+        else {
+            rrd_set_error("parse_tag_ds: Unknown tag: %s", child->name);
+            status = -1;
+        }
+
+        if (status != 0)
+            break;
     }
 
-    free(buf);
+    return (status);
+}                       /* int parse_tag_ds */
+
+/*
+ * Parse root nodes
+ */
+static int parse_tag_rrd(
+    xmlDoc * doc,
+    xmlNode * node,
+    rrd_t *rrd)
+{
+    xmlNode  *child;
+    int       status;
+
+    status = 0;
+    for (child = node->xmlChildrenNode; child != NULL; child = child->next) {
+        if ((xmlStrcmp(child->name, (const xmlChar *) "comment") == 0)
+            || (xmlStrcmp(child->name, (const xmlChar *) "text") == 0))
+            /* ignore */ ;
+        else if (xmlStrcmp(child->name, (const xmlChar *) "version") == 0)
+            status = get_string_from_node(doc, child,
+                                          rrd->stat_head->version,
+                                          sizeof(rrd->stat_head->version));
+        else if (xmlStrcmp(child->name, (const xmlChar *) "step") == 0)
+            status = get_int_from_node(doc, child,
+                                       (int *) &rrd->stat_head->pdp_step);
+        else if (xmlStrcmp(child->name, (const xmlChar *) "lastupdate") == 0)
+            status = get_int_from_node(doc, child,
+                                       (int *) &rrd->live_head->last_up);
+        else if (xmlStrcmp(child->name, (const xmlChar *) "ds") == 0)
+            status = parse_tag_ds(doc, child, rrd);
+        else if (xmlStrcmp(child->name, (const xmlChar *) "rra") == 0)
+            status = parse_tag_rra(doc, child, rrd);
+        else {
+            rrd_set_error("parse_tag_rrd: Unknown tag: %s", child->name);
+            status = -1;
+        }
 
-    if(rrd_write(argv[optind+1],&rrd,force_overwrite)==-1){
-       rrd_free(&rrd); 
-       return -1;      
-    };
-    rrd_free(&rrd);    
-    return 0;
-}
+        if (status != 0)
+            break;
+    }
 
-/* a backwards compatibility routine that will parse the RRA params section
- * generated by the aberrant patch to 1.0.28. */
+    return (status);
+}                       /* int parse_tag_rrd */
 
-void
-parse_patch1028_RRA_params(char **buf, rrd_t *rrd, int rra_index)
+static rrd_t *parse_file(
+    const char *filename)
 {
-   int i;
-   for (i = 0; i < MAX_RRA_PAR_EN; i++)
-   {
-   if (i == RRA_dependent_rra_idx ||
-       i == RRA_seasonal_smooth_idx ||
-       i == RRA_failure_threshold)
-      read_tag(buf, "value","%lu",
-         &(rrd->rra_def[rra_index].par[i].u_cnt));
-   else
-      read_tag(buf, "value","%lf",
-         &(rrd->rra_def[rra_index].par[i].u_val));
-   }
-}
-
-/* a backwards compatibility routine that will parse the CDP params section
- * generated by the aberrant patch to 1.0.28. */
-void
-parse_patch1028_CDP_params(char **buf, rrd_t *rrd, int rra_index, int ds_index)
+    xmlDoc   *doc;
+    xmlNode  *cur;
+    int       status;
+
+    rrd_t    *rrd;
+
+    doc = xmlParseFile(filename);
+    if (doc == NULL) {
+        rrd_set_error("Document not parsed successfully.");
+        return (NULL);
+    }
+
+    cur = xmlDocGetRootElement(doc);
+    if (cur == NULL) {
+        rrd_set_error("Document is empty.");
+        xmlFreeDoc(doc);
+        return (NULL);
+    }
+
+    if (xmlStrcmp(cur->name, (const xmlChar *) "rrd") != 0) {
+        rrd_set_error
+            ("Document of the wrong type, root node is not \"rrd\".");
+        xmlFreeDoc(doc);
+        return (NULL);
+    }
+
+    rrd = (rrd_t *) malloc(sizeof(rrd_t));
+    if (rrd == NULL) {
+        rrd_set_error("parse_file: malloc failed.");
+        xmlFreeDoc(doc);
+        return (NULL);
+    }
+    memset(rrd, '\0', sizeof(rrd_t));
+
+    rrd->stat_head = (stat_head_t *) malloc(sizeof(stat_head_t));
+    if (rrd->stat_head == NULL) {
+        rrd_set_error("parse_tag_rrd: malloc failed.");
+        xmlFreeDoc(doc);
+        free(rrd);
+        return (NULL);
+    }
+    memset(rrd->stat_head, '\0', sizeof(stat_head_t));
+
+    strncpy(rrd->stat_head->cookie, "RRD", sizeof(rrd->stat_head->cookie));
+    rrd->stat_head->float_cookie = FLOAT_COOKIE;
+
+    rrd->live_head = (live_head_t *) malloc(sizeof(live_head_t));
+    if (rrd->live_head == NULL) {
+        rrd_set_error("parse_tag_rrd: malloc failed.");
+        xmlFreeDoc(doc);
+        free(rrd->stat_head);
+        free(rrd);
+        return (NULL);
+    }
+    memset(rrd->live_head, '\0', sizeof(live_head_t));
+
+    status = parse_tag_rrd(doc, cur, rrd);
+
+    xmlFreeDoc(doc);
+    if (status != 0) {
+        rrd_free(rrd);
+        rrd = NULL;
+    }
+
+    return (rrd);
+}                       /* rrd_t *parse_file */
+
+static int write_file(
+    const char *file_name,
+    rrd_t *rrd)
 {
-   int ii;
-   for (ii = 0; ii < MAX_CDP_PAR_EN; ii++)
-   {
-   if (cf_conv(rrd->rra_def[rra_index].cf_nam) == CF_FAILURES ||
-       ii == CDP_unkn_pdp_cnt ||
-       ii == CDP_null_count ||
-       ii == CDP_last_null_count)
-   {
-      read_tag(buf,"value","%lu",
-       &(rrd->cdp_prep[rrd->stat_head->ds_cnt*(rra_index) + ds_index].scratch[ii].u_cnt));
-   } else {
-      read_tag(buf,"value","%lf",&(rrd->cdp_prep[rrd->stat_head->ds_cnt*
-       (rra_index) + ds_index].scratch[ii].u_val));
-   }
-   }
-}
-
-void
-parse_FAILURES_history(char **buf, rrd_t *rrd, int rra_index, int ds_index)
+    FILE     *fh;
+    unsigned int i;
+    unsigned int value_count;
+
+    if (strcmp("-", file_name) == 0)
+        fh = stdout;
+    else {
+        int       fd_flags = O_WRONLY | O_CREAT;
+        int       fd;
+
+#if defined(_WIN32) && !defined(__CYGWIN__) && !defined(__CYGWIN32__)
+        fd_flags |= O_BINARY;
+#endif
+
+        if (opt_force_overwrite == 0)
+            fd_flags |= O_EXCL;
+
+        fd = open(file_name, fd_flags, 0666);
+        if (fd == -1) {
+            rrd_set_error("creating '%s': %s", file_name,
+                          rrd_strerror(errno));
+            return (-1);
+        }
+
+        fh = fdopen(fd, "wb");
+        if (fh == NULL) {
+            rrd_set_error("fdopen failed: %s", rrd_strerror(errno));
+            close(fd);
+            return (-1);
+        }
+    }
+
+    fwrite(rrd->stat_head, sizeof(stat_head_t), 1, fh);
+    fwrite(rrd->ds_def, sizeof(ds_def_t), rrd->stat_head->ds_cnt, fh);
+    fwrite(rrd->rra_def, sizeof(rra_def_t), rrd->stat_head->rra_cnt, fh);
+    fwrite(rrd->live_head, sizeof(live_head_t), 1, fh);
+    fwrite(rrd->pdp_prep, sizeof(pdp_prep_t), rrd->stat_head->ds_cnt, fh);
+    fwrite(rrd->cdp_prep, sizeof(cdp_prep_t),
+           rrd->stat_head->rra_cnt * rrd->stat_head->ds_cnt, fh);
+    fwrite(rrd->rra_ptr, sizeof(rra_ptr_t), rrd->stat_head->rra_cnt, fh);
+
+    /* calculate the number of rrd_values to dump */
+    value_count = 0;
+    for (i = 0; i < rrd->stat_head->rra_cnt; i++)
+        value_count += (rrd->rra_def[i].row_cnt * rrd->stat_head->ds_cnt);
+
+    fwrite(rrd->rrd_value, sizeof(rrd_value_t), value_count, fh);
+
+    /* lets see if we had an error */
+    if (ferror(fh)) {
+        rrd_set_error("a file error occurred while creating '%s'", file_name);
+        fclose(fh);
+        return (-1);
+    }
+
+    fclose(fh);
+    return (0);
+}                       /* int write_file */
+
+int rrd_restore(
+    int argc,
+    char **argv)
 {
-   char history[MAX_FAILURES_WINDOW_LEN + 1];
-   char *violations_array;
-   unsigned short i;
-
-   /* 28 = MAX_FAILURES_WINDOW_LEN */ 
-   read_tag(buf, "history", "%28[0-1]", history);
-   violations_array = (char*) rrd -> cdp_prep[rrd->stat_head->ds_cnt*(rra_index)
-      + ds_index].scratch;
-   
-   for (i = 0; i < rrd -> rra_def[rra_index].par[RRA_window_len].u_cnt; ++i)
-      violations_array[i] = (history[i] == '1') ? 1 : 0;
-
-}
+    rrd_t    *rrd;
+
+    /* init rrd clean */
+    optind = 0;
+    opterr = 0;         /* initialize getopt */
+    while (42) {
+        int       opt;
+        int       option_index = 0;
+        static struct option long_options[] = {
+            {"range-check", no_argument, 0, 'r'},
+            {"force-overwrite", no_argument, 0, 'f'},
+            {0, 0, 0, 0}
+        };
+
+        opt = getopt_long(argc, argv, "rf", long_options, &option_index);
+
+        if (opt == EOF)
+            break;
+
+        switch (opt) {
+        case 'r':
+            opt_range_check = 1;
+            break;
+
+        case 'f':
+            opt_force_overwrite = 1;
+            break;
+
+        default:
+            rrd_set_error("usage rrdtool %s [--range-check|-r] "
+                          "[--force-overwrite/-f]  file.xml file.rrd",
+                          argv[0]);
+            return (-1);
+            break;
+        }
+    }                   /* while (42) */
+
+    if ((argc - optind) != 2) {
+        rrd_set_error("usage rrdtool %s [--range-check/-r] "
+                      "[--force-overwrite/-f] file.xml file.rrd", argv[0]);
+        return (-1);
+    }
+
+    rrd = parse_file(argv[optind]);
+    if (rrd == NULL)
+        return (-1);
+
+    if (write_file(argv[optind + 1], rrd) != 0) {
+        rrd_free(rrd);
+        return (-1);
+    }
+
+    rrd_free(rrd);
+    return (0);
+}                       /* int rrd_restore */
+
+/* vim: set sw=2 sts=2 ts=8 et fdm=marker : */
index db1c883d176e3b026012237eab513fc00f7a56c6..b19c7dab61dfbee5345eab3fd6ce65059b3efa5a 100644 (file)
@@ -1,48 +1,58 @@
 /****************************************************************************
- * RRDtool 1.2.27  Copyright by Tobi Oetiker, 1997-2008
+ * RRDtool 1.3rc4  Copyright by Tobi Oetiker, 1997-2008
  ****************************************************************************
  * rrd_rpncalc.c  RPN calculator functions
  ****************************************************************************/
 
 #include "rrd_tool.h"
 #include "rrd_rpncalc.h"
-#include "rrd_graph.h"
+// #include "rrd_graph.h"
 #include <limits.h>
+#include <locale.h>
 
-short addop2str(enum op_en op, enum op_en op_type, char *op_str, 
-           char **result_str, unsigned short *offset);
-int tzoffset(time_t); /* used to implement LTIME */
+short     addop2str(
+    enum op_en op,
+    enum op_en op_type,
+    char *op_str,
+    char **result_str,
+    unsigned short *offset);
+int       tzoffset(
+    time_t);            /* used to implement LTIME */
 
-short rpn_compact(rpnp_t *rpnp, rpn_cdefds_t **rpnc, short *count)
+short rpn_compact(
+    rpnp_t *rpnp,
+    rpn_cdefds_t **rpnc,
+    short *count)
 {
-    short i;
+    short     i;
+
     *count = 0;
     /* count the number of rpn nodes */
-    while(rpnp[*count].op != OP_END) (*count)++;
+    while (rpnp[*count].op != OP_END)
+        (*count)++;
     if (++(*count) > DS_CDEF_MAX_RPN_NODES) {
         rrd_set_error("Maximum %d RPN nodes permitted",
                       DS_CDEF_MAX_RPN_NODES);
         return -1;
     }
-    
+
     /* allocate memory */
-    *rpnc = (rpn_cdefds_t *) calloc(*count,sizeof(rpn_cdefds_t));
-    for (i = 0; rpnp[i].op != OP_END; i++)
-    {
+    *rpnc = (rpn_cdefds_t *) calloc(*count, sizeof(rpn_cdefds_t));
+    for (i = 0; rpnp[i].op != OP_END; i++) {
         (*rpnc)[i].op = (char) rpnp[i].op;
         if (rpnp[i].op == OP_NUMBER) {
             /* rpnp.val is a double, rpnc.val is a short */
-            double temp = floor(rpnp[i].val);
+            double    temp = floor(rpnp[i].val);
+
             if (temp < SHRT_MIN || temp > SHRT_MAX) {
-                rrd_set_error(
-                   "constants must be integers in the interval (%d, %d)",
-                    SHRT_MIN, SHRT_MAX);
-                free(*rpnc);   
+                rrd_set_error
+                    ("constants must be integers in the interval (%d, %d)",
+                     SHRT_MIN, SHRT_MAX);
+                free(*rpnc);
                 return -1;
             }
             (*rpnc)[i].val = (short) temp;
-         } else if (rpnp[i].op == OP_VARIABLE ||
-                                rpnp[i].op == OP_PREV_OTHER) {
+        } else if (rpnp[i].op == OP_VARIABLE || rpnp[i].op == OP_PREV_OTHER) {
             (*rpnc)[i].val = (short) rpnp[i].ptr;
         }
     }
@@ -51,22 +61,22 @@ short rpn_compact(rpnp_t *rpnp, rpn_cdefds_t **rpnc, short *count)
     return 0;
 }
 
-rpnp_t * rpn_expand(rpn_cdefds_t *rpnc)
+rpnp_t   *rpn_expand(
+    rpn_cdefds_t *rpnc)
 {
-    short i;
-    rpnp_t *rpnp;
-    
+    short     i;
+    rpnp_t   *rpnp;
+
     /* DS_CDEF_MAX_RPN_NODES is small, so at the expense of some wasted
      * memory we avoid any reallocs */
-    rpnp = (rpnp_t *) calloc(DS_CDEF_MAX_RPN_NODES,sizeof(rpnp_t));
-    if (rpnp == NULL) return NULL;
-    for (i = 0; rpnc[i].op != OP_END; ++i)
-    {
+    rpnp = (rpnp_t *) calloc(DS_CDEF_MAX_RPN_NODES, sizeof(rpnp_t));
+    if (rpnp == NULL)
+        return NULL;
+    for (i = 0; rpnc[i].op != OP_END; ++i) {
         rpnp[i].op = (long) rpnc[i].op;
         if (rpnp[i].op == OP_NUMBER) {
             rpnp[i].val = (double) rpnc[i].val;
-         } else if (rpnp[i].op == OP_VARIABLE ||
-                                rpnp[i].op == OP_PREV_OTHER) {
+        } else if (rpnp[i].op == OP_VARIABLE || rpnp[i].op == OP_PREV_OTHER) {
             rpnp[i].ptr = (long) rpnc[i].val;
         }
     }
@@ -83,118 +93,133 @@ rpnp_t * rpn_expand(rpn_cdefds_t *rpnc)
  *   for lookup of data source names by index
  *  str: out string, memory is allocated by the function, must be freed by the
  *   the caller */
-void rpn_compact2str(rpn_cdefds_t *rpnc,ds_def_t *ds_def,char **str)
+void rpn_compact2str(
+    rpn_cdefds_t *rpnc,
+    ds_def_t *ds_def,
+    char **str)
 {
-    unsigned short i,offset = 0;
-    char buffer[7]; /* short as a string */
-    
-    for (i = 0; rpnc[i].op != OP_END; i++)
-    {
-        if (i > 0) (*str)[offset++] = ',';
-        
+    unsigned short i, offset = 0;
+    char      buffer[7];    /* short as a string */
+
+    for (i = 0; rpnc[i].op != OP_END; i++) {
+        if (i > 0)
+            (*str)[offset++] = ',';
+
 #define add_op(VV,VVV) \
          if (addop2str(rpnc[i].op, VV, VVV, str, &offset) == 1) continue;
-        
+
         if (rpnc[i].op == OP_NUMBER) {
             /* convert a short into a string */
 #if defined(_WIN32) && !defined(__CYGWIN__) && !defined(__CYGWIN32__)
-            _itoa(rpnc[i].val,buffer,10);
+            _itoa(rpnc[i].val, buffer, 10);
 #else
-            sprintf(buffer,"%d",rpnc[i].val);
+            sprintf(buffer, "%d", rpnc[i].val);
 #endif
-            add_op(OP_NUMBER,buffer)
-                }
-        
+            add_op(OP_NUMBER, buffer)
+        }
+
         if (rpnc[i].op == OP_VARIABLE) {
-            char *ds_name = ds_def[rpnc[i].val].ds_nam;
+            char     *ds_name = ds_def[rpnc[i].val].ds_nam;
+
             add_op(OP_VARIABLE, ds_name)
-                }
+        }
 
-         if (rpnc[i].op == OP_PREV_OTHER) {
-               char *ds_name = ds_def[rpnc[i].val].ds_nam;
-               add_op(OP_VARIABLE, ds_name)
-         }
+        if (rpnc[i].op == OP_PREV_OTHER) {
+            char     *ds_name = ds_def[rpnc[i].val].ds_nam;
 
+            add_op(OP_VARIABLE, ds_name)
+        }
 #undef add_op
-        
+
 #define add_op(VV,VVV) \
          if (addop2str(rpnc[i].op, VV, #VVV, str, &offset) == 1) continue;
-        
-          add_op(OP_ADD,+)
-          add_op(OP_SUB,-)
-          add_op(OP_MUL,*)
-          add_op(OP_DIV,/)
-          add_op(OP_MOD,%)
-          add_op(OP_SIN,SIN)
-          add_op(OP_COS,COS)
-          add_op(OP_LOG,LOG)
-          add_op(OP_FLOOR,FLOOR)
-         add_op(OP_CEIL,CEIL)
-         add_op(OP_EXP,EXP)
-         add_op(OP_DUP,DUP)
-         add_op(OP_EXC,EXC)
-         add_op(OP_POP,POP)
-         add_op(OP_LT,LT)
-          add_op(OP_LE,LE)
-         add_op(OP_GT,GT)
-         add_op(OP_GE,GE)
-         add_op(OP_EQ,EQ)
-         add_op(OP_IF,IF)
-         add_op(OP_MIN,MIN)
-         add_op(OP_MAX,MAX)
-         add_op(OP_LIMIT,LIMIT)
-         add_op(OP_UNKN,UNKN)
-         add_op(OP_UN,UN)
-         add_op(OP_NEGINF,NEGINF)
-         add_op(OP_NE,NE)
-         add_op(OP_PREV,PREV)
-         add_op(OP_INF,INF)
-         add_op(OP_ISINF,ISINF)
-         add_op(OP_NOW,NOW)
-         add_op(OP_LTIME,LTIME)
-         add_op(OP_TIME,TIME)
-         add_op(OP_ATAN2,ATAN2)
-         add_op(OP_ATAN,ATAN)
-         add_op(OP_SQRT,SQRT)
-         add_op(OP_SORT,SORT)
-         add_op(OP_REV,REV)
-         add_op(OP_TREND,TREND)
-         add_op(OP_RAD2DEG,RAD2DEG)
-         add_op(OP_DEG2RAD,DEG2RAD)
-         add_op(OP_AVG,AVG)
-         add_op(OP_ABS,ABS)
+
+        add_op(OP_ADD, +)
+            add_op(OP_SUB, -)
+            add_op(OP_MUL, *)
+            add_op(OP_DIV, /)
+            add_op(OP_MOD, %)
+            add_op(OP_SIN, SIN)
+            add_op(OP_COS, COS)
+            add_op(OP_LOG, LOG)
+            add_op(OP_FLOOR, FLOOR)
+            add_op(OP_CEIL, CEIL)
+            add_op(OP_EXP, EXP)
+            add_op(OP_DUP, DUP)
+            add_op(OP_EXC, EXC)
+            add_op(OP_POP, POP)
+            add_op(OP_LT, LT)
+            add_op(OP_LE, LE)
+            add_op(OP_GT, GT)
+            add_op(OP_GE, GE)
+            add_op(OP_EQ, EQ)
+            add_op(OP_IF, IF)
+            add_op(OP_MIN, MIN)
+            add_op(OP_MAX, MAX)
+            add_op(OP_LIMIT, LIMIT)
+            add_op(OP_UNKN, UNKN)
+            add_op(OP_UN, UN)
+            add_op(OP_NEGINF, NEGINF)
+            add_op(OP_NE, NE)
+            add_op(OP_PREV, PREV)
+            add_op(OP_INF, INF)
+            add_op(OP_ISINF, ISINF)
+            add_op(OP_NOW, NOW)
+            add_op(OP_LTIME, LTIME)
+            add_op(OP_TIME, TIME)
+            add_op(OP_ATAN2, ATAN2)
+            add_op(OP_ATAN, ATAN)
+            add_op(OP_SQRT, SQRT)
+            add_op(OP_SORT, SORT)
+            add_op(OP_REV, REV)
+            add_op(OP_TREND, TREND)
+            add_op(OP_TRENDNAN, TRENDNAN)
+            add_op(OP_RAD2DEG, RAD2DEG)
+            add_op(OP_DEG2RAD, DEG2RAD)
+            add_op(OP_AVG, AVG)
+            add_op(OP_ABS, ABS)
+            add_op(OP_ADDNAN, ADDNAN)
 #undef add_op
-              }
+    }
     (*str)[offset] = '\0';
 
 }
 
-short addop2str(enum op_en op, enum op_en op_type, char *op_str, 
-                char **result_str, unsigned short *offset)
+short addop2str(
+    enum op_en op,
+    enum op_en op_type,
+    char *op_str,
+    char **result_str,
+    unsigned short *offset)
 {
     if (op == op_type) {
-        short op_len;
+        short     op_len;
+
         op_len = strlen(op_str);
-        *result_str =  (char *) rrd_realloc(*result_str,
-                                            (op_len + 1 + *offset)*sizeof(char));
+        *result_str = (char *) rrd_realloc(*result_str,
+                                           (op_len + 1 +
+                                            *offset) * sizeof(char));
         if (*result_str == NULL) {
             rrd_set_error("failed to alloc memory in addop2str");
             return -1;
         }
-        strncpy(&((*result_str)[*offset]),op_str,op_len);
+        strncpy(&((*result_str)[*offset]), op_str, op_len);
         *offset += op_len;
         return 1;
     }
     return 0;
 }
 
-void parseCDEF_DS(const char *def,rrd_t *rrd, int ds_idx)
+void parseCDEF_DS(
+    const char *def,
+    rrd_t *rrd,
+    int ds_idx)
 {
-    rpnp_t *rpnp = NULL;
+    rpnp_t   *rpnp = NULL;
     rpn_cdefds_t *rpnc = NULL;
-    short count, i;
-    
-    rpnp = rpn_parse((void*) rrd, def, &lookup_DS);
+    short     count, i;
+
+    rpnp = rpn_parse((void *) rrd, def, &lookup_DS);
     if (rpnp == NULL) {
         rrd_set_error("failed to parse computed data source");
         return;
@@ -204,22 +229,21 @@ void parseCDEF_DS(const char *def,rrd_t *rrd, int ds_idx)
      * COMPUTE DS specific. This is less efficient, but creation doesn't
      * occur too often. */
     for (i = 0; rpnp[i].op != OP_END; i++) {
-        if (rpnp[i].op == OP_TIME || rpnp[i].op == OP_LTIME || 
-            rpnp[i].op == OP_PREV || rpnp[i].op == OP_COUNT)
-        {
-            rrd_set_error(
-                "operators time, ltime, prev and count not supported with DS COMPUTE");
+        if (rpnp[i].op == OP_TIME || rpnp[i].op == OP_LTIME ||
+            rpnp[i].op == OP_PREV || rpnp[i].op == OP_COUNT) {
+            rrd_set_error
+                ("operators time, ltime, prev and count not supported with DS COMPUTE");
             free(rpnp);
             return;
         }
     }
-    if (rpn_compact(rpnp,&rpnc,&count) == -1) {
+    if (rpn_compact(rpnp, &rpnc, &count) == -1) {
         free(rpnp);
         return;
     }
     /* copy the compact rpn representation over the ds_def par array */
-    memcpy((void*) &(rrd -> ds_def[ds_idx].par[DS_cdef]),
-           (void*) rpnc, count*sizeof(rpn_cdefds_t));
+    memcpy((void *) &(rrd->ds_def[ds_idx].par[DS_cdef]),
+           (void *) rpnc, count * sizeof(rpn_cdefds_t));
     free(rpnp);
     free(rpnc);
 }
@@ -229,16 +253,17 @@ void parseCDEF_DS(const char *def,rrd_t *rrd, int ds_idx)
  * (1) need a void * pointer to the rrd
  * (2) error handling is left to the caller
  */
-long lookup_DS(void *rrd_vptr,char *ds_name)
+long lookup_DS(
+    void *rrd_vptr,
+    char *ds_name)
 {
     unsigned int i;
-    rrd_t *rrd; 
-    
+    rrd_t    *rrd;
+
     rrd = (rrd_t *) rrd_vptr;
-    
-    for (i = 0; i < rrd -> stat_head -> ds_cnt; ++i)
-    {
-        if(strcmp(ds_name,rrd -> ds_def[i].ds_nam) == 0)
+
+    for (i = 0; i < rrd->stat_head->ds_cnt; ++i) {
+        if (strcmp(ds_name, rrd->ds_def[i].ds_nam) == 0)
             return i;
     }
     /* the caller handles a bad data source name in the rpn string */
@@ -253,34 +278,41 @@ long lookup_DS(void *rrd_vptr,char *ds_name)
  * expr: the string RPN expression, including variable names
  * lookup(): a function that retrieves a numeric key given a variable name
  */
-rpnp_t * 
-rpn_parse(void *key_hash,const char *const expr_const,long (*lookup)(void *,char*)){
-    int pos=0;
-    char *expr;
-    long steps=-1;    
-    rpnp_t  *rpnp;
-    char vname[MAX_VNAME_LEN+10];
-    
-    rpnp=NULL;
-    expr=(char *)expr_const;
-    
-    while(*expr){
-       if ((rpnp = (rpnp_t *) rrd_realloc(rpnp, (++steps + 2)* 
-                                      sizeof(rpnp_t)))==NULL){
-           return NULL;
-       }
-        
-       else if((sscanf(expr,"%lf%n",&rpnp[steps].val,&pos) == 1) && (expr[pos] == ',')){
-           rpnp[steps].op = OP_NUMBER;
-           expr+=pos;
-       } 
-       
+rpnp_t   *rpn_parse(
+    void *key_hash,
+    const char *const expr_const,
+    long      (*lookup) (void *,
+                         char *))
+{
+    int       pos = 0;
+    char     *expr;
+    long      steps = -1;
+    rpnp_t   *rpnp;
+    char      vname[MAX_VNAME_LEN + 10];
+    char     *old_locale;
+
+    old_locale = setlocale(LC_NUMERIC, "C");
+
+    rpnp = NULL;
+    expr = (char *) expr_const;
+
+    while (*expr) {
+        if ((rpnp = (rpnp_t *) rrd_realloc(rpnp, (++steps + 2) *
+                                           sizeof(rpnp_t))) == NULL) {
+            setlocale(LC_NUMERIC, old_locale);
+            return NULL;
+        }
+
+        else if ((sscanf(expr, "%lf%n", &rpnp[steps].val, &pos) == 1)
+                 && (expr[pos] == ',')) {
+            rpnp[steps].op = OP_NUMBER;
+            expr += pos;
+        }
 #define match_op(VV,VVV) \
         else if (strncmp(expr, #VVV, strlen(#VVV))==0 && ( expr[strlen(#VVV)] == ',' || expr[strlen(#VVV)] == '\0' )){ \
             rpnp[steps].op = VV; \
             expr+=strlen(#VVV); \
-       }
-
+       }
 
 #define match_op_param(VV,VVV) \
         else if (sscanf(expr, #VVV "(" DEF_NAM_FMT ")",vname) == 1) { \
@@ -296,101 +328,106 @@ rpn_parse(void *key_hash,const char *const expr_const,long (*lookup)(void *,char
           } \
         }
 
-       match_op(OP_ADD,+)
-       match_op(OP_SUB,-)
-       match_op(OP_MUL,*)
-       match_op(OP_DIV,/)
-       match_op(OP_MOD,%)
-       match_op(OP_SIN,SIN)
-       match_op(OP_COS,COS)
-       match_op(OP_LOG,LOG)
-       match_op(OP_FLOOR,FLOOR)
-       match_op(OP_CEIL,CEIL)
-       match_op(OP_EXP,EXP)
-       match_op(OP_DUP,DUP)
-       match_op(OP_EXC,EXC)
-       match_op(OP_POP,POP)
-       match_op(OP_LTIME,LTIME)
-       match_op(OP_LT,LT)
-       match_op(OP_LE,LE)
-       match_op(OP_GT,GT)
-       match_op(OP_GE,GE)
-       match_op(OP_EQ,EQ)
-       match_op(OP_IF,IF)
-       match_op(OP_MIN,MIN)
-       match_op(OP_MAX,MAX)
-       match_op(OP_LIMIT,LIMIT)
-         /* order is important here ! .. match longest first */
-       match_op(OP_UNKN,UNKN)
-       match_op(OP_UN,UN)
-       match_op(OP_NEGINF,NEGINF)
-       match_op(OP_NE,NE)
-       match_op(OP_COUNT,COUNT)
-       match_op_param(OP_PREV_OTHER,PREV)
-       match_op(OP_PREV,PREV)
-       match_op(OP_INF,INF)
-       match_op(OP_ISINF,ISINF)
-       match_op(OP_NOW,NOW)
-       match_op(OP_TIME,TIME)
-       match_op(OP_ATAN2,ATAN2)
-       match_op(OP_ATAN,ATAN)
-       match_op(OP_SQRT,SQRT)
-       match_op(OP_SORT,SORT)
-       match_op(OP_REV,REV)
-       match_op(OP_TREND,TREND)
-       match_op(OP_RAD2DEG,RAD2DEG)
-       match_op(OP_DEG2RAD,DEG2RAD)
-       match_op(OP_AVG,AVG)
-       match_op(OP_ABS,ABS)
+        match_op(OP_ADD, +)
+            match_op(OP_SUB, -)
+            match_op(OP_MUL, *)
+            match_op(OP_DIV, /)
+            match_op(OP_MOD, %)
+            match_op(OP_SIN, SIN)
+            match_op(OP_COS, COS)
+            match_op(OP_LOG, LOG)
+            match_op(OP_FLOOR, FLOOR)
+            match_op(OP_CEIL, CEIL)
+            match_op(OP_EXP, EXP)
+            match_op(OP_DUP, DUP)
+            match_op(OP_EXC, EXC)
+            match_op(OP_POP, POP)
+            match_op(OP_LTIME, LTIME)
+            match_op(OP_LT, LT)
+            match_op(OP_LE, LE)
+            match_op(OP_GT, GT)
+            match_op(OP_GE, GE)
+            match_op(OP_EQ, EQ)
+            match_op(OP_IF, IF)
+            match_op(OP_MIN, MIN)
+            match_op(OP_MAX, MAX)
+            match_op(OP_LIMIT, LIMIT)
+            /* order is important here ! .. match longest first */
+            match_op(OP_UNKN, UNKN)
+            match_op(OP_UN, UN)
+            match_op(OP_NEGINF, NEGINF)
+            match_op(OP_NE, NE)
+            match_op(OP_COUNT, COUNT)
+            match_op_param(OP_PREV_OTHER, PREV)
+            match_op(OP_PREV, PREV)
+            match_op(OP_INF, INF)
+            match_op(OP_ISINF, ISINF)
+            match_op(OP_NOW, NOW)
+            match_op(OP_TIME, TIME)
+            match_op(OP_ATAN2, ATAN2)
+            match_op(OP_ATAN, ATAN)
+            match_op(OP_SQRT, SQRT)
+            match_op(OP_SORT, SORT)
+            match_op(OP_REV, REV)
+            match_op(OP_TREND, TREND)
+            match_op(OP_TRENDNAN, TRENDNAN)
+            match_op(OP_RAD2DEG, RAD2DEG)
+            match_op(OP_DEG2RAD, DEG2RAD)
+            match_op(OP_AVG, AVG)
+            match_op(OP_ABS, ABS)
+            match_op(OP_ADDNAN, ADDNAN)
 #undef match_op
+            else if ((sscanf(expr, DEF_NAM_FMT "%n", vname, &pos) == 1)
+                     && ((rpnp[steps].ptr = (*lookup) (key_hash, vname)) !=
+                         -1)) {
+            rpnp[steps].op = OP_VARIABLE;
+            expr += pos;
+        }
 
+        else {
+            setlocale(LC_NUMERIC, old_locale);
+            free(rpnp);
+            return NULL;
+        }
 
-            else if ((sscanf(expr, DEF_NAM_FMT "%n",
-                             vname,&pos) == 1) 
-                     && ((rpnp[steps].ptr = (*lookup)(key_hash,vname)) != -1)){
-                rpnp[steps].op = OP_VARIABLE;
-                expr+=pos;
-            }     
-        
-       else {
-           free(rpnp);
-           return NULL;
-       }
-       if (*expr == 0)
-            break;
-       if (*expr == ',')
-           expr++;
-       else {
-           free(rpnp);
-           return NULL;
-       }  
+        if (*expr == 0)
+            break;
+        if (*expr == ',')
+            expr++;
+        else {
+            setlocale(LC_NUMERIC, old_locale);
+            free(rpnp);
+            return NULL;
+        }
     }
-    rpnp[steps+1].op = OP_END;
+    rpnp[steps + 1].op = OP_END;
+    setlocale(LC_NUMERIC, old_locale);
     return rpnp;
 }
 
-void
-rpnstack_init(rpnstack_t *rpnstack)
+void rpnstack_init(
+    rpnstack_t *rpnstack)
 {
-    rpnstack -> s = NULL;
-    rpnstack -> dc_stacksize = 0;
-    rpnstack -> dc_stackblock = 100;
+    rpnstack->s = NULL;
+    rpnstack->dc_stacksize = 0;
+    rpnstack->dc_stackblock = 100;
 }
 
-void
-rpnstack_free(rpnstack_t *rpnstack)
+void rpnstack_free(
+    rpnstack_t *rpnstack)
 {
-   if (rpnstack -> s != NULL)
-         free(rpnstack -> s);
-   rpnstack -> dc_stacksize = 0;
+    if (rpnstack->s != NULL)
+        free(rpnstack->s);
+    rpnstack->dc_stacksize = 0;
 }
 
-static int
-rpn_compare_double(const void *x, const void *y)
+static int rpn_compare_double(
+    const void *x,
+    const void *y)
 {
-       double  diff = *((const double *)x) - *((const double *)y);
-       
-       return (diff < 0) ? -1 : (diff > 0) ? 1 : 0;
+    double    diff = *((const double *) x) - *((const double *) y);
+
+    return (diff < 0) ? -1 : (diff > 0) ? 1 : 0;
 }
 
 /* rpn_calc: run the RPN calculator; also performs variable substitution;
@@ -408,405 +445,432 @@ rpn_compare_double(const void *x, const void *y)
  * returns: -1 if the computation failed (also calls rrd_set_error)
  *           0 on success
  */
-short
-rpn_calc(rpnp_t *rpnp, rpnstack_t *rpnstack, long data_idx, 
-               rrd_value_t *output, int output_idx)
+short rpn_calc(
+    rpnp_t *rpnp,
+    rpnstack_t *rpnstack,
+    long data_idx,
+    rrd_value_t *output,
+    int output_idx)
 {
-    int rpi;
-    long stptr = -1;
-   
-    /* process each op from the rpn in turn */
-    for (rpi=0; rpnp[rpi].op != OP_END; rpi++){
-       /* allocate or grow the stack */
-       if (stptr + 5 > rpnstack -> dc_stacksize){
-           /* could move this to a separate function */
-           rpnstack -> dc_stacksize += rpnstack -> dc_stackblock;              
-           rpnstack -> s = rrd_realloc(rpnstack -> s,
-                       (rpnstack -> dc_stacksize)*sizeof(*(rpnstack -> s)));
-           if (rpnstack -> s == NULL){
-               rrd_set_error("RPN stack overflow");
-               return -1;
-           }
-       }
+    int       rpi;
+    long      stptr = -1;
 
+    /* process each op from the rpn in turn */
+    for (rpi = 0; rpnp[rpi].op != OP_END; rpi++) {
+        /* allocate or grow the stack */
+        if (stptr + 5 > rpnstack->dc_stacksize) {
+            /* could move this to a separate function */
+            rpnstack->dc_stacksize += rpnstack->dc_stackblock;
+            rpnstack->s = rrd_realloc(rpnstack->s,
+                                      (rpnstack->dc_stacksize) *
+                                      sizeof(*(rpnstack->s)));
+            if (rpnstack->s == NULL) {
+                rrd_set_error("RPN stack overflow");
+                return -1;
+            }
+        }
 #define stackunderflow(MINSIZE)                                \
        if(stptr<MINSIZE){                              \
            rrd_set_error("RPN stack underflow");       \
            return -1;                                  \
        }
 
-       switch (rpnp[rpi].op){
-           case OP_NUMBER:
-               rpnstack -> s[++stptr] = rpnp[rpi].val;
-               break;
-           case OP_VARIABLE:
-            case OP_PREV_OTHER:
-           /* Sanity check: VDEFs shouldn't make it here */
-               if (rpnp[rpi].ds_cnt == 0) {
-                   rrd_set_error("VDEF made it into rpn_calc... aborting");
-                   return -1;
-               } else {
-                   /* make sure we pull the correct value from
-                    * the *.data array. Adjust the pointer into
-                    * the array acordingly. Advance the ptr one
-                    * row in the rra (skip over non-relevant
-                    * data sources)
-                    */
-                   if (rpnp[rpi].op == OP_VARIABLE) {
-                       rpnstack -> s[++stptr] =  *(rpnp[rpi].data);
-                   } else {
-                       if ((output_idx) <= 0) {
-                           rpnstack -> s[++stptr] = DNAN;
-                       } else {                            
-                           rpnstack -> s[++stptr] =  *(rpnp[rpi].data-rpnp[rpi].ds_cnt);
-                       }
-                      
-                   }              
-                   if (data_idx % rpnp[rpi].step == 0){
-                       rpnp[rpi].data += rpnp[rpi].ds_cnt;
-                   }
-               }
-               break;
-           case OP_COUNT:
-               rpnstack -> s[++stptr] = (output_idx+1); /* Note: Counter starts at 1 */
-               break;
-           case OP_PREV:
-               if ((output_idx) <= 0) {
-                   rpnstack -> s[++stptr] = DNAN;
-               } else {
-                   rpnstack -> s[++stptr] = output[output_idx-1];
-               }
-               break;
-        case OP_UNKN:
-               rpnstack -> s[++stptr] = DNAN; 
-               break;
-           case OP_INF:
-               rpnstack -> s[++stptr] = DINF; 
-               break;
-           case OP_NEGINF:
-               rpnstack -> s[++stptr] = -DINF; 
-               break;
-           case OP_NOW:
-               rpnstack -> s[++stptr] = (double)time(NULL);
-               break;
-           case OP_TIME:
-               /* HACK: this relies on the data_idx being the time,
-               ** which the within-function scope is unaware of */
-               rpnstack -> s[++stptr] = (double) data_idx;
-               break;
-           case OP_LTIME:
-               rpnstack -> s[++stptr] =
-                       (double) tzoffset(data_idx) + (double)data_idx;
-               break;
-           case OP_ADD:
-               stackunderflow(1);
-               rpnstack -> s[stptr-1]  = rpnstack -> s[stptr-1] 
-                                       + rpnstack -> s[stptr];
-               stptr--;
-               break;
-           case OP_SUB:
-               stackunderflow(1);
-               rpnstack -> s[stptr-1]  = rpnstack -> s[stptr-1]
-                                       - rpnstack -> s[stptr];
-               stptr--;
-               break;
-           case OP_MUL:
-               stackunderflow(1);
-               rpnstack -> s[stptr-1]  = (rpnstack -> s[stptr-1])
-                                       * (rpnstack -> s[stptr]);
-               stptr--;
-               break;
-           case OP_DIV:
-               stackunderflow(1);
-               rpnstack -> s[stptr-1]  = rpnstack -> s[stptr-1]
-                                       / rpnstack -> s[stptr];
-               stptr--;
-               break;
-           case OP_MOD:
-               stackunderflow(1);
-               rpnstack -> s[stptr-1]= fmod(   rpnstack -> s[stptr-1]
-                                               ,rpnstack -> s[stptr]);
-               stptr--;
-               break;
-           case OP_SIN:
-               stackunderflow(0);
-               rpnstack -> s[stptr] = sin(rpnstack -> s[stptr]);
-               break;
-           case OP_ATAN:
-               stackunderflow(0);
-               rpnstack -> s[stptr] = atan(rpnstack -> s[stptr]);
-               break;
-           case OP_RAD2DEG:
-               stackunderflow(0);
-               rpnstack -> s[stptr] = 57.29577951 * rpnstack -> s[stptr];
-               break;
-           case OP_DEG2RAD:
-               stackunderflow(0);
-               rpnstack -> s[stptr] = 0.0174532952 * rpnstack -> s[stptr];
-               break;
-           case OP_ATAN2:
-               stackunderflow(1);
-               rpnstack -> s[stptr-1]= atan2(
-                               rpnstack -> s[stptr-1],
-                               rpnstack -> s[stptr]);
-               stptr--;
-               break;
-           case OP_COS:
-               stackunderflow(0);
-               rpnstack -> s[stptr] = cos(rpnstack -> s[stptr]);
-               break;
-           case OP_CEIL:
-               stackunderflow(0);
-               rpnstack -> s[stptr] = ceil(rpnstack -> s[stptr]);
-               break;
-           case OP_FLOOR:
-               stackunderflow(0);
-               rpnstack -> s[stptr] = floor(rpnstack -> s[stptr]);
-               break;
-           case OP_LOG:
-               stackunderflow(0);
-               rpnstack -> s[stptr] = log(rpnstack -> s[stptr]);
-               break;
-           case OP_DUP:
-               stackunderflow(0);
-               rpnstack -> s[stptr+1] = rpnstack -> s[stptr];
-               stptr++;
-               break;
-           case OP_POP:
-               stackunderflow(0);
-               stptr--;
-               break;
-           case OP_EXC:
-               stackunderflow(1);
-               {
-                   double dummy;
-                   dummy = rpnstack -> s[stptr] ;
-                   rpnstack -> s[stptr] = rpnstack -> s[stptr-1];
-                   rpnstack -> s[stptr-1] = dummy;
-               }
-               break;
-           case OP_EXP:
-               stackunderflow(0);
-               rpnstack -> s[stptr] = exp(rpnstack -> s[stptr]);
-               break;
-           case OP_LT:
-               stackunderflow(1);
-               if (isnan(rpnstack -> s[stptr-1])) 
-                   ;
-               else if (isnan(rpnstack -> s[stptr]))
-                   rpnstack -> s[stptr-1] = rpnstack -> s[stptr];
-               else
-                   rpnstack -> s[stptr-1] = rpnstack -> s[stptr-1] <
-                                       rpnstack -> s[stptr] ? 1.0 : 0.0;
-               stptr--;
-               break;
-           case OP_LE:
-               stackunderflow(1);
-               if (isnan(rpnstack -> s[stptr-1])) 
-                   ;
-               else if (isnan(rpnstack -> s[stptr]))
-                   rpnstack -> s[stptr-1] = rpnstack -> s[stptr];
-               else
-                   rpnstack -> s[stptr-1] = rpnstack -> s[stptr-1] <=
-                                       rpnstack -> s[stptr] ? 1.0 : 0.0;
-               stptr--;
-               break;
-           case OP_GT:
-               stackunderflow(1);
-               if (isnan(rpnstack -> s[stptr-1])) 
-                   ;
-               else if (isnan(rpnstack -> s[stptr]))
-                   rpnstack -> s[stptr-1] = rpnstack -> s[stptr];
-               else
-                   rpnstack -> s[stptr-1] = rpnstack -> s[stptr-1] >
-                                       rpnstack -> s[stptr] ? 1.0 : 0.0;
-               stptr--;
-               break;
-           case OP_GE:
-               stackunderflow(1);
-               if (isnan(rpnstack -> s[stptr-1])) 
-                   ;
-               else if (isnan(rpnstack -> s[stptr]))
-                           rpnstack -> s[stptr-1] = rpnstack -> s[stptr];
-               else
-                   rpnstack -> s[stptr-1] = rpnstack -> s[stptr-1] >=
-                                       rpnstack -> s[stptr] ? 1.0 : 0.0;
-               stptr--;
-               break;
-           case OP_NE:
-               stackunderflow(1);
-               if (isnan(rpnstack -> s[stptr-1]))
-                   ;
-               else if (isnan(rpnstack -> s[stptr]))
-                   rpnstack -> s[stptr-1] = rpnstack -> s[stptr];
-               else
-                   rpnstack -> s[stptr-1] = rpnstack -> s[stptr-1] ==
-                                       rpnstack -> s[stptr] ? 0.0 : 1.0;
-               stptr--;
-               break;
-           case OP_EQ:
-               stackunderflow(1);
-               if (isnan(rpnstack -> s[stptr-1])) 
-                   ;
-               else if (isnan(rpnstack -> s[stptr]))
-                   rpnstack -> s[stptr-1] = rpnstack -> s[stptr];
-               else
-                   rpnstack -> s[stptr-1] = rpnstack -> s[stptr-1] ==
-                                       rpnstack -> s[stptr] ? 1.0 : 0.0;
-               stptr--;
-               break;
-           case OP_IF:
-               stackunderflow(2);
-               rpnstack->s[stptr-2] = rpnstack->s[stptr-2] != 0.0 ?
-                               rpnstack->s[stptr-1] : rpnstack->s[stptr];
-               stptr--;
-               stptr--;
-               break;
-           case OP_MIN:
-               stackunderflow(1);
-               if (isnan(rpnstack->s[stptr-1])) 
-                   ;
-               else if (isnan(rpnstack->s[stptr]))
-                   rpnstack->s[stptr-1] = rpnstack->s[stptr];
-               else if (rpnstack->s[stptr-1] > rpnstack->s[stptr])
-                   rpnstack->s[stptr-1] = rpnstack->s[stptr];
-               stptr--;
-               break;
-           case OP_MAX:
-               stackunderflow(1);
-               if (isnan(rpnstack->s[stptr-1])) 
-               ;
-               else if (isnan(rpnstack->s[stptr]))
-                   rpnstack->s[stptr-1] = rpnstack->s[stptr];
-               else if (rpnstack->s[stptr-1] < rpnstack->s[stptr])
-                   rpnstack->s[stptr-1] = rpnstack->s[stptr];
-               stptr--;
-               break;
-           case OP_LIMIT:
-               stackunderflow(2);
-               if (isnan(rpnstack->s[stptr-2])) 
-                   ;
-               else if (isnan(rpnstack->s[stptr-1]))
-                   rpnstack->s[stptr-2] = rpnstack->s[stptr-1];
-               else if (isnan(rpnstack->s[stptr]))
-                   rpnstack->s[stptr-2] = rpnstack->s[stptr];
-               else if (rpnstack->s[stptr-2] < rpnstack->s[stptr-1])
-                   rpnstack->s[stptr-2] = DNAN;
-               else if (rpnstack->s[stptr-2] > rpnstack->s[stptr])
-                   rpnstack->s[stptr-2] = DNAN;
-               stptr-=2;
-                       break;
-           case OP_UN:
-               stackunderflow(0);
-               rpnstack->s[stptr] = isnan(rpnstack->s[stptr]) ? 1.0 : 0.0;
-               break;
-           case OP_ISINF:
-               stackunderflow(0);
-               rpnstack->s[stptr] = isinf(rpnstack->s[stptr]) ? 1.0 : 0.0;
-               break;
-           case OP_SQRT:
-               stackunderflow(0);
-               rpnstack -> s[stptr] = sqrt(rpnstack -> s[stptr]);
-               break;
-           case OP_SORT:
-               stackunderflow(0);
-               {
-                   int spn = (int)rpnstack -> s[stptr--];
-
-                   stackunderflow(spn-1);
-                   qsort(rpnstack -> s + stptr-spn+1, spn, sizeof(double),
-                         rpn_compare_double);
-               }
-               break;
-           case OP_REV:
-               stackunderflow(0);
-               {
-                   int spn = (int)rpnstack -> s[stptr--];
-                   double *p, *q;
-
-                   stackunderflow(spn-1);
-
-                   p = rpnstack -> s + stptr-spn+1;
-                   q = rpnstack -> s + stptr;
-                   while (p < q) {
-                           double      x = *q;
-                           
-                           *q-- = *p;
-                           *p++ = x;
-                   }
-               }
-               break;
-           case OP_TREND:
-               stackunderflow(1);
-               if ((rpi < 2) || (rpnp[rpi-2].op != OP_VARIABLE)) {
-                   rrd_set_error("malformed trend arguments");
-                   return -1;
-               } else {
-                   time_t dur = (time_t)rpnstack -> s[stptr];
-                   time_t step = (time_t)rpnp[rpi-2].step;
-
-                   if (output_idx > (int)ceil((float)dur / (float)step)) {
-                       double accum = 0.0;
-                       int i = 0;
-               
-                       do {
-                           accum += rpnp[rpi-2].data[rpnp[rpi-2].ds_cnt * i--];
-                           dur -= step;
-                       } while (dur > 0);
-
-                       rpnstack -> s[--stptr] = (accum / -i);
-                   } else
-                       rpnstack -> s[--stptr] = DNAN;
-               }
-               break;
-           case OP_AVG:
-               stackunderflow(0);
-                {
-                   int i=(int)rpnstack -> s[stptr--];
-                   double sum=0;
-                   int count=0;
-                   stackunderflow(i-1);
-                   while(i>0) {
-                     double val=rpnstack -> s[stptr--];
-                     i--;
-                    if (isnan(val)) { continue; }
-                     count++;
-                     sum+=val;
-                   }
-                   /* now push the result back on stack */
-                   if (count>0) {
-                     rpnstack -> s[++stptr]=sum/count;
-                   } else {
-                     rpnstack -> s[++stptr]=DNAN;
-                   }
+        switch (rpnp[rpi].op) {
+        case OP_NUMBER:
+            rpnstack->s[++stptr] = rpnp[rpi].val;
+            break;
+        case OP_VARIABLE:
+        case OP_PREV_OTHER:
+            /* Sanity check: VDEFs shouldn't make it here */
+            if (rpnp[rpi].ds_cnt == 0) {
+                rrd_set_error("VDEF made it into rpn_calc... aborting");
+                return -1;
+            } else {
+                /* make sure we pull the correct value from
+                 * the *.data array. Adjust the pointer into
+                 * the array acordingly. Advance the ptr one
+                 * row in the rra (skip over non-relevant
+                 * data sources)
+                 */
+                if (rpnp[rpi].op == OP_VARIABLE) {
+                    rpnstack->s[++stptr] = *(rpnp[rpi].data);
+                } else {
+                    if ((output_idx) <= 0) {
+                        rpnstack->s[++stptr] = DNAN;
+                    } else {
+                        rpnstack->s[++stptr] =
+                            *(rpnp[rpi].data - rpnp[rpi].ds_cnt);
+                    }
+
                 }
-                break;
-            case OP_ABS:
-                stackunderflow(0);
-                rpnstack -> s[stptr] = fabs(rpnstack -> s[stptr]);
-                break;
-           case OP_END:
-               break;
-       }
+                if (data_idx % rpnp[rpi].step == 0) {
+                    rpnp[rpi].data += rpnp[rpi].ds_cnt;
+                }
+            }
+            break;
+        case OP_COUNT:
+            rpnstack->s[++stptr] = (output_idx + 1);    /* Note: Counter starts at 1 */
+            break;
+        case OP_PREV:
+            if ((output_idx) <= 0) {
+                rpnstack->s[++stptr] = DNAN;
+            } else {
+                rpnstack->s[++stptr] = output[output_idx - 1];
+            }
+            break;
+        case OP_UNKN:
+            rpnstack->s[++stptr] = DNAN;
+            break;
+        case OP_INF:
+            rpnstack->s[++stptr] = DINF;
+            break;
+        case OP_NEGINF:
+            rpnstack->s[++stptr] = -DINF;
+            break;
+        case OP_NOW:
+            rpnstack->s[++stptr] = (double) time(NULL);
+            break;
+        case OP_TIME:
+            /* HACK: this relies on the data_idx being the time,
+             ** which the within-function scope is unaware of */
+            rpnstack->s[++stptr] = (double) data_idx;
+            break;
+        case OP_LTIME:
+            rpnstack->s[++stptr] =
+                (double) tzoffset(data_idx) + (double) data_idx;
+            break;
+        case OP_ADD:
+            stackunderflow(1);
+            rpnstack->s[stptr - 1] = rpnstack->s[stptr - 1]
+                + rpnstack->s[stptr];
+            stptr--;
+            break;
+        case OP_ADDNAN:
+            stackunderflow(1);
+            if (isnan(rpnstack->s[stptr - 1])) {
+                rpnstack->s[stptr - 1] = rpnstack->s[stptr];
+            } else if (isnan(rpnstack->s[stptr])) {
+                /* NOOP */
+                /* rpnstack->s[stptr - 1] = rpnstack->s[stptr - 1]; */
+            } else {
+                rpnstack->s[stptr - 1] = rpnstack->s[stptr - 1]
+                    + rpnstack->s[stptr];
+            }
+
+            stptr--;
+            break;
+        case OP_SUB:
+            stackunderflow(1);
+            rpnstack->s[stptr - 1] = rpnstack->s[stptr - 1]
+                - rpnstack->s[stptr];
+            stptr--;
+            break;
+        case OP_MUL:
+            stackunderflow(1);
+            rpnstack->s[stptr - 1] = (rpnstack->s[stptr - 1])
+                * (rpnstack->s[stptr]);
+            stptr--;
+            break;
+        case OP_DIV:
+            stackunderflow(1);
+            rpnstack->s[stptr - 1] = rpnstack->s[stptr - 1]
+                / rpnstack->s[stptr];
+            stptr--;
+            break;
+        case OP_MOD:
+            stackunderflow(1);
+            rpnstack->s[stptr - 1] = fmod(rpnstack->s[stptr - 1]
+                                          , rpnstack->s[stptr]);
+            stptr--;
+            break;
+        case OP_SIN:
+            stackunderflow(0);
+            rpnstack->s[stptr] = sin(rpnstack->s[stptr]);
+            break;
+        case OP_ATAN:
+            stackunderflow(0);
+            rpnstack->s[stptr] = atan(rpnstack->s[stptr]);
+            break;
+        case OP_RAD2DEG:
+            stackunderflow(0);
+            rpnstack->s[stptr] = 57.29577951 * rpnstack->s[stptr];
+            break;
+        case OP_DEG2RAD:
+            stackunderflow(0);
+            rpnstack->s[stptr] = 0.0174532952 * rpnstack->s[stptr];
+            break;
+        case OP_ATAN2:
+            stackunderflow(1);
+            rpnstack->s[stptr - 1] = atan2(rpnstack->s[stptr - 1],
+                                           rpnstack->s[stptr]);
+            stptr--;
+            break;
+        case OP_COS:
+            stackunderflow(0);
+            rpnstack->s[stptr] = cos(rpnstack->s[stptr]);
+            break;
+        case OP_CEIL:
+            stackunderflow(0);
+            rpnstack->s[stptr] = ceil(rpnstack->s[stptr]);
+            break;
+        case OP_FLOOR:
+            stackunderflow(0);
+            rpnstack->s[stptr] = floor(rpnstack->s[stptr]);
+            break;
+        case OP_LOG:
+            stackunderflow(0);
+            rpnstack->s[stptr] = log(rpnstack->s[stptr]);
+            break;
+        case OP_DUP:
+            stackunderflow(0);
+            rpnstack->s[stptr + 1] = rpnstack->s[stptr];
+            stptr++;
+            break;
+        case OP_POP:
+            stackunderflow(0);
+            stptr--;
+            break;
+        case OP_EXC:
+            stackunderflow(1);
+            {
+                double    dummy;
+
+                dummy = rpnstack->s[stptr];
+                rpnstack->s[stptr] = rpnstack->s[stptr - 1];
+                rpnstack->s[stptr - 1] = dummy;
+            }
+            break;
+        case OP_EXP:
+            stackunderflow(0);
+            rpnstack->s[stptr] = exp(rpnstack->s[stptr]);
+            break;
+        case OP_LT:
+            stackunderflow(1);
+            if (isnan(rpnstack->s[stptr - 1]));
+            else if (isnan(rpnstack->s[stptr]))
+                rpnstack->s[stptr - 1] = rpnstack->s[stptr];
+            else
+                rpnstack->s[stptr - 1] = rpnstack->s[stptr - 1] <
+                    rpnstack->s[stptr] ? 1.0 : 0.0;
+            stptr--;
+            break;
+        case OP_LE:
+            stackunderflow(1);
+            if (isnan(rpnstack->s[stptr - 1]));
+            else if (isnan(rpnstack->s[stptr]))
+                rpnstack->s[stptr - 1] = rpnstack->s[stptr];
+            else
+                rpnstack->s[stptr - 1] = rpnstack->s[stptr - 1] <=
+                    rpnstack->s[stptr] ? 1.0 : 0.0;
+            stptr--;
+            break;
+        case OP_GT:
+            stackunderflow(1);
+            if (isnan(rpnstack->s[stptr - 1]));
+            else if (isnan(rpnstack->s[stptr]))
+                rpnstack->s[stptr - 1] = rpnstack->s[stptr];
+            else
+                rpnstack->s[stptr - 1] = rpnstack->s[stptr - 1] >
+                    rpnstack->s[stptr] ? 1.0 : 0.0;
+            stptr--;
+            break;
+        case OP_GE:
+            stackunderflow(1);
+            if (isnan(rpnstack->s[stptr - 1]));
+            else if (isnan(rpnstack->s[stptr]))
+                rpnstack->s[stptr - 1] = rpnstack->s[stptr];
+            else
+                rpnstack->s[stptr - 1] = rpnstack->s[stptr - 1] >=
+                    rpnstack->s[stptr] ? 1.0 : 0.0;
+            stptr--;
+            break;
+        case OP_NE:
+            stackunderflow(1);
+            if (isnan(rpnstack->s[stptr - 1]));
+            else if (isnan(rpnstack->s[stptr]))
+                rpnstack->s[stptr - 1] = rpnstack->s[stptr];
+            else
+                rpnstack->s[stptr - 1] = rpnstack->s[stptr - 1] ==
+                    rpnstack->s[stptr] ? 0.0 : 1.0;
+            stptr--;
+            break;
+        case OP_EQ:
+            stackunderflow(1);
+            if (isnan(rpnstack->s[stptr - 1]));
+            else if (isnan(rpnstack->s[stptr]))
+                rpnstack->s[stptr - 1] = rpnstack->s[stptr];
+            else
+                rpnstack->s[stptr - 1] = rpnstack->s[stptr - 1] ==
+                    rpnstack->s[stptr] ? 1.0 : 0.0;
+            stptr--;
+            break;
+        case OP_IF:
+            stackunderflow(2);
+            rpnstack->s[stptr - 2] = (isnan(rpnstack->s[stptr - 2])
+                                      || rpnstack->s[stptr - 2] ==
+                                      0.0) ? rpnstack->s[stptr] : rpnstack->
+                s[stptr - 1];
+            stptr--;
+            stptr--;
+            break;
+        case OP_MIN:
+            stackunderflow(1);
+            if (isnan(rpnstack->s[stptr - 1]));
+            else if (isnan(rpnstack->s[stptr]))
+                rpnstack->s[stptr - 1] = rpnstack->s[stptr];
+            else if (rpnstack->s[stptr - 1] > rpnstack->s[stptr])
+                rpnstack->s[stptr - 1] = rpnstack->s[stptr];
+            stptr--;
+            break;
+        case OP_MAX:
+            stackunderflow(1);
+            if (isnan(rpnstack->s[stptr - 1]));
+            else if (isnan(rpnstack->s[stptr]))
+                rpnstack->s[stptr - 1] = rpnstack->s[stptr];
+            else if (rpnstack->s[stptr - 1] < rpnstack->s[stptr])
+                rpnstack->s[stptr - 1] = rpnstack->s[stptr];
+            stptr--;
+            break;
+        case OP_LIMIT:
+            stackunderflow(2);
+            if (isnan(rpnstack->s[stptr - 2]));
+            else if (isnan(rpnstack->s[stptr - 1]))
+                rpnstack->s[stptr - 2] = rpnstack->s[stptr - 1];
+            else if (isnan(rpnstack->s[stptr]))
+                rpnstack->s[stptr - 2] = rpnstack->s[stptr];
+            else if (rpnstack->s[stptr - 2] < rpnstack->s[stptr - 1])
+                rpnstack->s[stptr - 2] = DNAN;
+            else if (rpnstack->s[stptr - 2] > rpnstack->s[stptr])
+                rpnstack->s[stptr - 2] = DNAN;
+            stptr -= 2;
+            break;
+        case OP_UN:
+            stackunderflow(0);
+            rpnstack->s[stptr] = isnan(rpnstack->s[stptr]) ? 1.0 : 0.0;
+            break;
+        case OP_ISINF:
+            stackunderflow(0);
+            rpnstack->s[stptr] = isinf(rpnstack->s[stptr]) ? 1.0 : 0.0;
+            break;
+        case OP_SQRT:
+            stackunderflow(0);
+            rpnstack->s[stptr] = sqrt(rpnstack->s[stptr]);
+            break;
+        case OP_SORT:
+            stackunderflow(0);
+            {
+                int       spn = (int) rpnstack->s[stptr--];
+
+                stackunderflow(spn - 1);
+                qsort(rpnstack->s + stptr - spn + 1, spn, sizeof(double),
+                      rpn_compare_double);
+            }
+            break;
+        case OP_REV:
+            stackunderflow(0);
+            {
+                int       spn = (int) rpnstack->s[stptr--];
+                double   *p, *q;
+
+                stackunderflow(spn - 1);
+
+                p = rpnstack->s + stptr - spn + 1;
+                q = rpnstack->s + stptr;
+                while (p < q) {
+                    double    x = *q;
+
+                    *q-- = *p;
+                    *p++ = x;
+                }
+            }
+            break;
+        case OP_TREND:
+        case OP_TRENDNAN:
+            stackunderflow(1);
+            if ((rpi < 2) || (rpnp[rpi - 2].op != OP_VARIABLE)) {
+                rrd_set_error("malformed trend arguments");
+                return -1;
+            } else {
+                time_t    dur = (time_t) rpnstack->s[stptr];
+                time_t    step = (time_t) rpnp[rpi - 2].step;
+
+                if (output_idx > (int) ceil((float) dur / (float) step)) {
+                    int       ignorenan = (rpnp[rpi].op == OP_TREND);
+                    double    accum = 0.0;
+                    int       i = 0;
+                    int       count = 0;
+
+                    do {
+                        double    val =
+                            rpnp[rpi - 2].data[rpnp[rpi - 2].ds_cnt * i--];
+                        if (ignorenan || !isnan(val)) {
+                            accum += val;
+                            ++count;
+                        }
+
+                        dur -= step;
+                    } while (dur > 0);
+
+                    rpnstack->s[--stptr] =
+                        (count == 0) ? DNAN : (accum / count);
+                } else
+                    rpnstack->s[--stptr] = DNAN;
+            }
+            break;
+        case OP_AVG:
+            stackunderflow(0);
+            {
+                int       i = (int) rpnstack->s[stptr--];
+                double    sum = 0;
+                int       count = 0;
+
+                stackunderflow(i - 1);
+                while (i > 0) {
+                    double    val = rpnstack->s[stptr--];
+
+                    i--;
+                    if (isnan(val)) {
+                        continue;
+                    }
+                    count++;
+                    sum += val;
+                }
+                /* now push the result back on stack */
+                if (count > 0) {
+                    rpnstack->s[++stptr] = sum / count;
+                } else {
+                    rpnstack->s[++stptr] = DNAN;
+                }
+            }
+            break;
+        case OP_ABS:
+            stackunderflow(0);
+            rpnstack->s[stptr] = fabs(rpnstack->s[stptr]);
+            break;
+        case OP_END:
+            break;
+        }
 #undef stackunderflow
-   }
-   if(stptr!=0){
-       rrd_set_error("RPN final stack size != 1");
-       return -1;
-   }
-   
-   output[output_idx] = rpnstack->s[0];
-   return 0;
+    }
+    if (stptr != 0) {
+        rrd_set_error("RPN final stack size != 1");
+        return -1;
+    }
+
+    output[output_idx] = rpnstack->s[0];
+    return 0;
 }
 
 /* figure out what the local timezone offset for any point in
    time was. Return it in seconds */
-int
-tzoffset( time_t now ){
-    int gm_sec, gm_min, gm_hour, gm_yday, gm_year,
+int tzoffset(
+    time_t now)
+{
+    int       gm_sec, gm_min, gm_hour, gm_yday, gm_year,
         l_sec, l_min, l_hour, l_yday, l_year;
     struct tm t;
-    int off;
+    int       off;
+
     gmtime_r(&now, &t);
     gm_sec = t.tm_sec;
     gm_min = t.tm_min;
@@ -819,12 +883,12 @@ tzoffset( time_t now ){
     l_hour = t.tm_hour;
     l_yday = t.tm_yday;
     l_year = t.tm_year;
-    off = (l_sec-gm_sec)+(l_min-gm_min)*60+(l_hour-gm_hour)*3600; 
-    if ( l_yday > gm_yday || l_year > gm_year){
-        off += 24*3600;
-    } else if ( l_yday < gm_yday || l_year < gm_year){
-        off -= 24*3600;
+    off =
+        (l_sec - gm_sec) + (l_min - gm_min) * 60 + (l_hour - gm_hour) * 3600;
+    if (l_yday > gm_yday || l_year > gm_year) {
+        off += 24 * 3600;
+    } else if (l_yday < gm_yday || l_year < gm_year) {
+        off -= 24 * 3600;
     }
-   return off;
+    return off;
 }
-
index b00cca928e5743614829246488cb41c20e13e296..1930e92cad7a0cd67acfbb511e9aaa7a65b39d52 100644 (file)
@@ -1,5 +1,5 @@
 /****************************************************************************
- * RRDtool 1.2.27  Copyright by Tobi Oetiker, 1997-2008
+ * RRDtool 1.3rc4  Copyright by Tobi Oetiker, 1997-2008
  ****************************************************************************
  * rrd_rpncalc.h  RPN calculator functions
  ****************************************************************************/
  * This is because COMPUTE (CDEF) DS store OP nodes by number (name is not
  * an option due to limited par array size). OP nodes must have the same
  * numeric values, otherwise the stored numbers will mean something different. */
-enum op_en {OP_NUMBER=0,OP_VARIABLE,OP_INF,OP_PREV,OP_NEGINF,
-           OP_UNKN,OP_NOW,OP_TIME,OP_ADD,OP_MOD,OP_SUB,OP_MUL,
-           OP_DIV,OP_SIN, OP_DUP, OP_EXC, OP_POP,
-           OP_COS,OP_LOG,OP_EXP,OP_LT,OP_LE,OP_GT,OP_GE,OP_EQ,OP_IF,
-           OP_MIN,OP_MAX,OP_LIMIT, OP_FLOOR, OP_CEIL,
-           OP_UN,OP_END,OP_LTIME,OP_NE,OP_ISINF,OP_PREV_OTHER,OP_COUNT,
-           OP_ATAN,OP_SQRT,OP_SORT,OP_REV,OP_TREND,
-           OP_ATAN2,OP_RAD2DEG,OP_DEG2RAD,
-           OP_AVG,OP_ABS};
+enum op_en { OP_NUMBER = 0, OP_VARIABLE, OP_INF, OP_PREV, OP_NEGINF,
+    OP_UNKN, OP_NOW, OP_TIME, OP_ADD, OP_MOD, OP_SUB, OP_MUL,
+    OP_DIV, OP_SIN, OP_DUP, OP_EXC, OP_POP,
+    OP_COS, OP_LOG, OP_EXP, OP_LT, OP_LE, OP_GT, OP_GE, OP_EQ, OP_IF,
+    OP_MIN, OP_MAX, OP_LIMIT, OP_FLOOR, OP_CEIL,
+    OP_UN, OP_END, OP_LTIME, OP_NE, OP_ISINF, OP_PREV_OTHER, OP_COUNT,
+    OP_ATAN, OP_SQRT, OP_SORT, OP_REV, OP_TREND, OP_TRENDNAN,
+    OP_ATAN2, OP_RAD2DEG, OP_DEG2RAD,
+    OP_AVG, OP_ABS, OP_ADDNAN
+};
 
 typedef struct rpnp_t {
-    enum op_en   op;
-    double val; /* value for a OP_NUMBER */
-    long ptr; /* pointer into the gdes array for OP_VAR */
-    double *data; /* pointer to the current value from OP_VAR DAS*/
-    long ds_cnt;   /* data source count for data pointer */
-    long step; /* time step for OP_VAR das */
+    enum op_en op;
+    double    val;      /* value for a OP_NUMBER */
+    long      ptr;      /* pointer into the gdes array for OP_VAR */
+    double   *data;     /* pointer to the current value from OP_VAR DAS */
+    long      ds_cnt;   /* data source count for data pointer */
+    long      step;     /* time step for OP_VAR das */
 } rpnp_t;
 
 /* a compact representation of rpnp_t for computed data sources */
 typedef struct rpn_cdefds_t {
-    char op;  /* rpn operator type */
-    short val; /* used by OP_NUMBER and OP_VARIABLE */
+    char      op;       /* rpn operator type */
+    short     val;      /* used by OP_NUMBER and OP_VARIABLE */
 } rpn_cdefds_t;
 
+#define MAX_VNAME_LEN 255
+#define DEF_NAM_FMT "%255[-_A-Za-z0-9]"
+
 /* limit imposed by sizeof(rpn_cdefs_t) and rrd.ds_def.par */
-#define DS_CDEF_MAX_RPN_NODES 26 
+#define DS_CDEF_MAX_RPN_NODES 26
 
 typedef struct rpnstack_t {
-    double *s;
-    long dc_stacksize;
-    long dc_stackblock;
+    double   *s;
+    long      dc_stacksize;
+    long      dc_stackblock;
 } rpnstack_t;
 
-void rpnstack_init(rpnstack_t *rpnstack);
-void rpnstack_free(rpnstack_t *rpnstack);
+void      rpnstack_init(
+    rpnstack_t *rpnstack);
+void      rpnstack_free(
+    rpnstack_t *rpnstack);
 
-void parseCDEF_DS(const char *def, rrd_t *rrd, int ds_idx);
-long lookup_DS(void *rrd_vptr, char *ds_name);
+void      parseCDEF_DS(
+    const char *def,
+    rrd_t *rrd,
+    int ds_idx);
+long      lookup_DS(
+    void *rrd_vptr,
+    char *ds_name);
 
-short rpn_compact(rpnp_t *rpnp,rpn_cdefds_t **rpnc,short *count);
-rpnp_t * rpn_expand(rpn_cdefds_t *rpnc);
-void rpn_compact2str(rpn_cdefds_t *rpnc,ds_def_t *ds_def,char **str);
-rpnp_t * rpn_parse(void *key_hash,const char *const expr, long (*lookup)(void *,char *));
-short rpn_calc(rpnp_t *rpnp, rpnstack_t *rpnstack, long data_idx, rrd_value_t *output, int output_idx);
+short     rpn_compact(
+    rpnp_t *rpnp,
+    rpn_cdefds_t **rpnc,
+    short *count);
+rpnp_t   *rpn_expand(
+    rpn_cdefds_t *rpnc);
+void      rpn_compact2str(
+    rpn_cdefds_t *rpnc,
+    ds_def_t *ds_def,
+    char **str);
+rpnp_t   *rpn_parse(
+    void *key_hash,
+    const char *const expr,
+    long      (*lookup) (void *,
+                         char *));
+short     rpn_calc(
+    rpnp_t *rpnp,
+    rpnstack_t *rpnstack,
+    long data_idx,
+    rrd_value_t *output,
+    int output_idx);
 
 #endif
index f4e6a5482aee6bbeaf298563df08f542ef6e9fea..3eed4a8c51e2946c5d35d183e05100243592e527 100644 (file)
@@ -1,12 +1,12 @@
 /*****************************************************************************
- * RRDtool 1.2.27  Copyright by Tobi Oetiker, 1997-2008
+ * RRDtool 1.3rc4  Copyright by Tobi Oetiker, 1997-2008
  * This file:     Copyright 2003 Peter Stamfest <peter@stamfest.at> 
  *                             & Tobias Oetiker
  * Distributed under the GPL
  *****************************************************************************
  * rrd_thread_safe.c   Contains routines used when thread safety is required
  *****************************************************************************
- * $Id: rrd_thread_safe.c 1286 2008-02-17 10:08:10Z oetiker $
+ * $Id: rrd_thread_safe.c 1366 2008-05-18 13:06:44Z oetiker $
  *************************************************************************** */
 
 #include <pthread.h>
@@ -24,49 +24,60 @@ static pthread_once_t context_key_once = PTHREAD_ONCE_INIT;
 /* Free the thread-specific rrd_context - we might actually use
    rrd_free_context instead...
  */
-static void context_destroy_context(void *ctx_)
+static void context_destroy_context(
+    void *ctx_)
 {
     struct rrd_context *ctx = ctx_;
-    if (ctx) rrd_free_context(ctx);
+
+    if (ctx)
+        rrd_free_context(ctx);
 }
 
 /* Allocate the key */
-static void context_get_key()
+static void context_get_key(
+    void)
 {
     pthread_key_create(&context_key, context_destroy_context);
 }
 
-struct rrd_context *rrd_get_context(void) {
+struct rrd_context *rrd_get_context(
+    void)
+{
     struct rrd_context *ctx;
 
     pthread_once(&context_key_once, context_get_key);
     ctx = pthread_getspecific(context_key);
     if (!ctx) {
-       ctx = rrd_new_context();
-       pthread_setspecific(context_key, ctx);
-    } 
+        ctx = rrd_new_context();
+        pthread_setspecific(context_key, ctx);
+    }
     return ctx;
 }
 
 #ifdef HAVE_STRERROR_R
-const char *rrd_strerror(int err) {
+const char *rrd_strerror(
+    int err)
+{
     struct rrd_context *ctx = rrd_get_context();
-    if (strerror_r(err, ctx->lib_errstr, ctx->errlen)) 
-         return "strerror_r faild. sorry!"; 
-    else 
-         return ctx->lib_errstr; 
+
+    if (strerror_r(err, ctx->lib_errstr, ctx->errlen))
+        return "strerror_r failed. sorry!";
+    else
+        return ctx->lib_errstr;
 }
 #else
 #undef strerror
-const char *rrd_strerror(int err) {
+const char *rrd_strerror(
+    int err)
+{
     static pthread_mutex_t mtx = PTHREAD_MUTEX_INITIALIZER;
     struct rrd_context *ctx;
+
     ctx = rrd_get_context();
     pthread_mutex_lock(&mtx);
     strncpy(ctx->lib_errstr, strerror(err), ctx->errlen);
-    ctx->lib_errstr[ctx->errlen]='\0';
+    ctx->lib_errstr[ctx->errlen] = '\0';
     pthread_mutex_unlock(&mtx);
     return ctx->lib_errstr;
 }
 #endif
-
index 13780abab762f1a5fd01a12679257354f8116820..fa55cf515cfb2b43798ce448d918e5ea4a1f9822 100644 (file)
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * RRDtool 1.2.27  Copyright by Tobi Oetiker, 1997-2008
+ * RRDtool 1.3rc4  Copyright by Tobi Oetiker, 1997-2008
  * This file:     Copyright 2003 Peter Stamfest <peter@stamfest.at> 
  *                             & Tobias Oetiker
  * Distributed under the GPL
@@ -7,7 +7,7 @@
  * rrd_thread_safe.c   Contains routines used when thread safety is required
  *                     for win32
  *****************************************************************************
- * $Id: rrd_thread_safe_nt.c 1286 2008-02-17 10:08:10Z oetiker $
+ * $Id: rrd_thread_safe_nt.c 1366 2008-05-18 13:06:44Z oetiker $
  *************************************************************************** */
 
 #include <windows.h>
@@ -18,7 +18,7 @@
 
 /* Key for the thread-specific rrd_context */
 static DWORD context_key;
-static CRITICAL_SECTION CriticalSection; 
+static CRITICAL_SECTION CriticalSection;
 
 
 /* Once-only initialisation of the key */
@@ -28,89 +28,112 @@ static DWORD context_key_once = 0;
 /* Free the thread-specific rrd_context - we might actually use
    rrd_free_context instead...
  */
-static void context_destroy_context(void)
+static void context_destroy_context(
+    void)
 {
-       DeleteCriticalSection(&CriticalSection);
+    DeleteCriticalSection(&CriticalSection);
     TlsFree(context_key);
-       context_key_once=0;
+    context_key_once = 0;
 }
-static void context_init_context(void)
+static void context_init_context(
+    void)
 {
-       if (!InterlockedExchange(&context_key_once, 1)) {
-               context_key = TlsAlloc();
-               InitializeCriticalSection(&CriticalSection);
-               atexit(context_destroy_context);
-       }
+    if (!InterlockedExchange(&context_key_once, 1)) {
+        context_key = TlsAlloc();
+        InitializeCriticalSection(&CriticalSection);
+        atexit(context_destroy_context);
+    }
 }
-struct rrd_context *rrd_get_context(void) {
+struct rrd_context *rrd_get_context(
+    void)
+{
     struct rrd_context *ctx;
-               
-       context_init_context();
+
+    context_init_context();
+
     ctx = TlsGetValue(context_key);
     if (!ctx) {
-               ctx = rrd_new_context();
-               TlsSetValue(context_key, ctx);
-    } 
+        ctx = rrd_new_context();
+        TlsSetValue(context_key, ctx);
+    }
     return ctx;
 }
+
 #undef strerror
-const char *rrd_strerror(int err) {
+const char *rrd_strerror(
+    int err)
+{
     struct rrd_context *ctx;
-       context_init_context();
 
-       ctx = rrd_get_context();
+    context_init_context();
+
+    ctx = rrd_get_context();
 
-    EnterCriticalSection(&CriticalSection); 
+    EnterCriticalSection(&CriticalSection);
     strncpy(ctx->lib_errstr, strerror(err), ctx->errlen);
     ctx->lib_errstr[ctx->errlen] = '\0';
-    LeaveCriticalSection(&CriticalSection); 
+    LeaveCriticalSection(&CriticalSection);
 
     return ctx->lib_errstr;
 }
+
 /*
  * there much be a re-entrant version of these somewhere in win32 land
  */
-struct tm* localtime_r(const time_t *timep, struct tm* result)
+struct tm *localtime_r(
+    const time_t *timep,
+    struct tm *result)
 {
-       struct tm *local;
-       context_init_context();
-
-       EnterCriticalSection(&CriticalSection);
-       local = localtime(timep);
-       memcpy(result,local,sizeof(struct tm));
-       LeaveCriticalSection(&CriticalSection);
-       return result;
+    struct tm *local;
+
+    context_init_context();
+
+    EnterCriticalSection(&CriticalSection);
+    local = localtime(timep);
+    memcpy(result, local, sizeof(struct tm));
+    LeaveCriticalSection(&CriticalSection);
+    return result;
 }
-char* ctime_r(const time_t *timep, char* result)
+
+char     *ctime_r(
+    const time_t *timep,
+    char *result)
 {
-       char *local;
-       context_init_context();
-
-       EnterCriticalSection(&CriticalSection);
-       local = ctime(timep);
-       strcpy(result,local);
-       LeaveCriticalSection(&CriticalSection);
-       return result;
+    char     *local;
+
+    context_init_context();
+
+    EnterCriticalSection(&CriticalSection);
+    local = ctime(timep);
+    strcpy(result, local);
+    LeaveCriticalSection(&CriticalSection);
+    return result;
 }
 
-struct tm* gmtime_r(const time_t *timep, struct tm* result)
+struct tm *gmtime_r(
+    const time_t *timep,
+    struct tm *result)
 {
-       struct tm *local;
-       context_init_context();
-
-       EnterCriticalSection(&CriticalSection);
-       local = gmtime(timep);
-       memcpy(result,local,sizeof(struct tm));
-       LeaveCriticalSection(&CriticalSection);
-       return result;
+    struct tm *local;
+
+    context_init_context();
+
+    EnterCriticalSection(&CriticalSection);
+    local = gmtime(timep);
+    memcpy(result, local, sizeof(struct tm));
+    LeaveCriticalSection(&CriticalSection);
+    return result;
 }
 
 /* implementation from Apache's APR library */
-char *strtok_r(char *str, const char *sep, char **last)
+char     *strtok_r(
+    char *str,
+    const char *sep,
+    char **last)
 {
-    char *token;
-       context_init_context();
+    char     *token;
+
+    context_init_context();
 
 
     if (!str)           /* subsequent call */
@@ -130,7 +153,7 @@ char *strtok_r(char *str, const char *sep, char **last)
      */
     *last = token + 1;
     while (**last && !strchr(sep, **last))
-        ++*last;
+        ++ * last;
 
     if (**last) {
         **last = '\0';
@@ -139,4 +162,3 @@ char *strtok_r(char *str, const char *sep, char **last)
 
     return token;
 }
-
index 894b4df2c0f4de5ba9f7a599475d344844214dcc..c981e4a7397258de2709b80972a9a925ae00755f 100644 (file)
 /*****************************************************************************
- * RRDtool 1.2.27  Copyright by Tobi Oetiker, 1997-2008
+ * RRDtool 1.3rc4  Copyright by Tobi Oetiker, 1997-2008
  *****************************************************************************
  * rrd_tool.c  Startup wrapper
  *****************************************************************************/
 
+#if defined(_WIN32) && !defined(__CYGWIN__) && !defined(__CYGWIN32__) && !defined(HAVE_CONFIG_H)
+#include "../win32/config.h"
+#else
+#ifdef HAVE_CONFIG_H
+#include "../rrd_config.h"
+#endif
+#endif
+
 #include "rrd_tool.h"
 #include "rrd_xport.h"
+#include "rrd_i18n.h"
+
+#ifdef HAVE_LOCALE_H
+#include <locale.h>
+#endif
+
+void      PrintUsage(
+    char *cmd);
+int       CountArgs(
+    char *aLine);
+int       CreateArgs(
+    char *,
+    char *,
+    int,
+    char **);
+int       HandleInputLine(
+    int,
+    char **,
+    FILE *);
+int       RemoteMode = 0;
+int       ChangeRoot = 0;
 
-void PrintUsage(char *cmd);
-int CountArgs(char *aLine);
-int CreateArgs(char *, char *, int, char **);
-int HandleInputLine(int, char **, FILE*);
-int RemoteMode=0;
-int ChangeRoot=0;
 #define TRUE           1
 #define FALSE          0
 #define MAX_LENGTH     10000
 
 
-void PrintUsage(char *cmd)
+void PrintUsage(
+    char *cmd)
 {
 
-    char help_main[] =
-          "RRDtool " PACKAGE_VERSION "  Copyright 1997-2008 by Tobias Oetiker <tobi@oetiker.ch>\n"
-           "               Compiled " __DATE__ " " __TIME__ "\n\n"
-          "Usage: rrdtool [options] command command_options\n\n";
-
-    char help_list[] =
-          "Valid commands: create, update, updatev, graph, dump, restore,\n"
-          "\t\tlast, lastupdate, first, info, fetch, tune,\n"
-          "\t\tresize, xport\n\n";
-
-    char help_listremote[] =
-           "Valid remote commands: quit, ls, cd, mkdir, pwd\n\n";
-
-
-    char help_create[] =
-          "* create - create a new RRD\n\n"
-          "\trrdtool create filename [--start|-b start time]\n"
-          "\t\t[--step|-s step]\n"
-          "\t\t[DS:ds-name:DST:dst arguments]\n" 
-          "\t\t[RRA:CF:cf arguments]\n\n";
-
-    char help_dump[] =
-          "* dump - dump an RRD to XML\n\n"
-          "\trrdtool dump filename.rrd >filename.xml\n\n";
-
-    char help_info[] =
-          "* info - returns the configuration and status of the RRD\n\n"
-          "\trrdtool info filename.rrd\n\n";
-
-    char help_restore[] =
-          "* restore - restore an RRD file from its XML form\n\n"
-          "\trrdtool restore [--range-check|-r] [--force-overwrite|-f] filename.xml filename.rrd\n\n";
-
-    char help_last[] =
-           "* last - show last update time for RRD\n\n"
-           "\trrdtool last filename.rrd\n\n";
-
-    char help_lastupdate[] =
-          "* lastupdate - returns the most recent datum stored for\n"
-          "  each DS in an RRD\n\n"
-          "\trrdtool lastupdate filename.rrd\n\n"; 
-
-    char help_first[] =
-           "* first - show first update time for RRA within an RRD\n\n"
-           "\trrdtool first filename.rrd [--rraindex number]\n\n";
-
-    char help_update[] =
-          "* update - update an RRD\n\n"
-          "\trrdtool update filename\n"
-          "\t\t--template|-t ds-name:ds-name:...\n"
-          "\t\ttime|N:value[:value...]\n\n"
+    const char *help_main =
+        N_("RRDtool %s"
+           "  Copyright 1997-2008 by Tobias Oetiker <tobi@oetiker.ch>\n"
+           "               Compiled %s %s\n\n"
+           "Usage: rrdtool [options] command command_options\n\n");
+
+    const char *help_list =
+        N_
+        ("Valid commands: create, update, updatev, graph, graphv,  dump, restore,\n"
+         "\t\tlast, lastupdate, first, info, fetch, tune,\n"
+         "\t\tresize, xport\n\n");
+
+    const char *help_listremote =
+        N_("Valid remote commands: quit, ls, cd, mkdir, pwd\n\n");
+
+
+    const char *help_create =
+        N_("* create - create a new RRD\n\n"
+           "\trrdtool create filename [--start|-b start time]\n"
+           "\t\t[--step|-s step]\n"
+           "\t\t[DS:ds-name:DST:dst arguments]\n"
+           "\t\t[RRA:CF:cf arguments]\n\n");
+
+    const char *help_dump =
+        N_("* dump - dump an RRD to XML\n\n"
+           "\trrdtool dump filename.rrd >filename.xml\n\n");
+
+    const char *help_info =
+        N_("* info - returns the configuration and status of the RRD\n\n"
+           "\trrdtool info filename.rrd\n\n");
+
+    const char *help_restore =
+        N_("* restore - restore an RRD file from its XML form\n\n"
+           "\trrdtool restore [--range-check|-r] [--force-overwrite|-f] filename.xml filename.rrd\n\n");
+
+    const char *help_last =
+        N_("* last - show last update time for RRD\n\n"
+           "\trrdtool last filename.rrd\n\n");
+
+    const char *help_lastupdate =
+        N_("* lastupdate - returns the most recent datum stored for\n"
+           "  each DS in an RRD\n\n" "\trrdtool lastupdate filename.rrd\n\n");
+
+    const char *help_first =
+        N_("* first - show first update time for RRA within an RRD\n\n"
+           "\trrdtool first filename.rrd [--rraindex number]\n\n");
+
+    const char *help_update =
+        N_("* update - update an RRD\n\n"
+           "\trrdtool update filename\n"
+           "\t\t--template|-t ds-name:ds-name:...\n"
+           "\t\ttime|N:value[:value...]\n\n"
            "\t\tat-time@value[:value...]\n\n"
-          "\t\t[ time:value[:value...] ..]\n\n";
-    
-       char help_updatev[] =
-          "* updatev - a verbose version of update\n"
-          "\treturns information about values, RRAs, and datasources updated\n\n"
-          "\trrdtool updatev filename\n"
-          "\t\t--template|-t ds-name:ds-name:...\n"
-          "\t\ttime|N:value[:value...]\n\n"
+           "\t\t[ time:value[:value...] ..]\n\n");
+
+    const char *help_updatev =
+        N_("* updatev - a verbose version of update\n"
+           "\treturns information about values, RRAs, and datasources updated\n\n"
+           "\trrdtool updatev filename\n"
+           "\t\t--template|-t ds-name:ds-name:...\n"
+           "\t\ttime|N:value[:value...]\n\n"
            "\t\tat-time@value[:value...]\n\n"
-          "\t\t[ time:value[:value...] ..]\n\n";
-    char help_fetch[] =
-          "* fetch - fetch data out of an RRD\n\n"
-          "\trrdtool fetch filename.rrd CF\n"
-          "\t\t[-r|--resolution resolution]\n"
-          "\t\t[-s|--start start] [-e|--end end]\n\n";
+           "\t\t[ time:value[:value...] ..]\n\n");
+
+    const char *help_fetch =
+        N_("* fetch - fetch data out of an RRD\n\n"
+           "\trrdtool fetch filename.rrd CF\n"
+           "\t\t[-r|--resolution resolution]\n"
+           "\t\t[-s|--start start] [-e|--end end]\n\n");
 
 /* break up very large strings (help_graph, help_tune) for ISO C89 compliance*/
 
-    char help_graph1[] =
-          "* graph - generate a graph from one or several RRD\n\n"
-          "\trrdtool graph filename [-s|--start seconds] [-e|--end seconds]\n"
-          "\t\t[-x|--x-grid x-axis grid and label]\n"
-          "\t\t[-Y|--alt-y-grid]\n"
-          "\t\t[-y|--y-grid y-axis grid and label]\n"
-          "\t\t[-v|--vertical-label string] [-w|--width pixels]\n"
-          "\t\t[-h|--height pixels] [-o|--logarithmic]\n"
-          "\t\t[-u|--upper-limit value] [-z|--lazy]\n"
-          "\t\t[-l|--lower-limit value] [-r|--rigid]\n"
+    const char *help_graph0 =
+        N_("* graph - generate a graph from one or several RRD\n\n"
+           "\trrdtool graph filename [-s|--start seconds] [-e|--end seconds]\n");
+    const char *help_graphv0 =
+        N_("* graphv - generate a graph from one or several RRD\n"
+           "           with meta data printed before the graph\n\n"
+           "\trrdtool graphv filename [-s|--start seconds] [-e|--end seconds]\n");
+    const char *help_graph1 =
+        N_("\t\t[-x|--x-grid x-axis grid and label]\n"
+           "\t\t[-Y|--alt-y-grid]\n"
+           "\t\t[-y|--y-grid y-axis grid and label]\n"
+           "\t\t[-v|--vertical-label string] [-w|--width pixels]\n"
+           "\t\t[-h|--height pixels] [-o|--logarithmic]\n"
+           "\t\t[-u|--upper-limit value] [-z|--lazy]\n"
+           "\t\t[-l|--lower-limit value] [-r|--rigid]\n"
            "\t\t[-g|--no-legend]\n"
-          "\t\t[-F|--force-rules-legend]\n"
-           "\t\t[-j|--only-graph]\n";
-    char help_graph2[] =
-          "\t\t[-n|--font FONTTAG:size:font]\n"
-           "\t\t[-m|--zoom factor]\n"       
-          "\t\t[-A|--alt-autoscale]\n"
-          "\t\t[-M|--alt-autoscale-max]\n"
-          "\t\t[-R|--font-render-mode {normal,light,mono}]\n"
-          "\t\t[-B|--font-smoothing-threshold size]\n"
-          "\t\t[-E|--slope-mode]\n"
-          "\t\t[-N|--no-gridfit]\n"
-          "\t\t[-X|--units-exponent value]\n"
-          "\t\t[-L|--units-length value]\n"
-          "\t\t[-S|--step seconds]\n"     
-          "\t\t[-f|--imginfo printfstr]\n"
-          "\t\t[-a|--imgformat PNG]\n"
-          "\t\t[-c|--color COLORTAG#rrggbb[aa]] [-t|--title string]\n"
-          "\t\t[-W|--watermark string]\n"
-          "\t\t[DEF:vname=rrd:ds-name:CF]\n";
-    char help_graph3[] =
-          "\t\t[CDEF:vname=rpn-expression]\n"
-          "\t\t[VDEF:vdefname=rpn-expression]\n"
-          "\t\t[PRINT:vdefname:format]\n"
-          "\t\t[GPRINT:vdefname:format]\n"
-          "\t\t[COMMENT:text]\n"
-          "\t\t[SHIFT:vname:offset]\n"
-          "\t\t[TICK:vname#rrggbb[aa][:[fraction][:legend]]]\n"
-          "\t\t[HRULE:value#rrggbb[aa][:legend]]\n"
-          "\t\t[VRULE:value#rrggbb[aa][:legend]]\n"
-          "\t\t[LINE[width]:vname[#rrggbb[aa][:[legend][:STACK]]]]\n"
-          "\t\t[AREA:vname[#rrggbb[aa][:[legend][:STACK]]]]\n"
-          "\t\t[PRINT:vname:CF:format] (deprecated)\n"
-          "\t\t[GPRINT:vname:CF:format] (deprecated)\n"
-          "\t\t[STACK:vname[#rrggbb[aa][:legend]]] (deprecated)\n\n";
-
-    char help_tune1[] =
-          " * tune -  Modify some basic properties of an RRD\n\n"
-          "\trrdtool tune filename\n"
-          "\t\t[--heartbeat|-h ds-name:heartbeat]\n"
-          "\t\t[--data-source-type|-d ds-name:DST]\n"
-          "\t\t[--data-source-rename|-r old-name:new-name]\n"
-          "\t\t[--minimum|-i ds-name:min] [--maximum|-a ds-name:max]\n"
-          "\t\t[--deltapos scale-value] [--deltaneg scale-value]\n"
-          "\t\t[--failure-threshold integer]\n"
-          "\t\t[--window-length integer]\n"
-          "\t\t[--alpha adaptation-parameter]\n";
-    char help_tune2[] =
-          " * tune -  Modify some basic properties of an RRD\n\n"
-          "\t\t[--beta adaptation-parameter]\n"
-          "\t\t[--gamma adaptation-parameter]\n"
-          "\t\t[--gamma-deviation adaptation-parameter]\n"
-          "\t\t[--aberrant-reset ds-name]\n\n";
-
-    char help_resize[] =
-          " * resize - alter the length of one of the RRAs in an RRD\n\n"
-          "\trrdtool resize filename rranum GROW|SHRINK rows\n\n";
-
-    char help_xport[] =
-          "* xport - generate XML dump from one or several RRD\n\n"
-          "\trrdtool xport [-s|--start seconds] [-e|--end seconds]\n"
-          "\t\t[-m|--maxrows rows]\n"
-          "\t\t[--step seconds]\n"        
-          "\t\t[--enumds]\n"      
-          "\t\t[DEF:vname=rrd:ds-name:CF]\n"
-          "\t\t[CDEF:vname=rpn-expression]\n"
-           "\t\t[XPORT:vname:legend]\n\n";
-
-    char help_quit[] =
-          " * quit - closing a session in remote mode\n\n"
-          "\trrdtool quit\n\n";
-
-    char help_ls[] =
-          " * ls - lists all *.rrd files in current directory\n\n"
-          "\trrdtool ls\n\n";
-
-    char help_cd[] =
-          " * cd - changes the current directory\n\n"
-          "\trrdtool cd new directory\n\n";
-
-    char help_mkdir[] =
-          " * mkdir - creates a new directory\n\n"
-          "\trrdtool mkdir newdirectoryname\n\n";
-
-    char help_pwd[] =
-          " * pwd - returns the current working directory\n\n"
-          "\trrdtool pwd\n\n";
-
-    char help_lic[] =
-          "RRDtool is distributed under the Terms of the GNU General\n"
-          "Public License Version 2. (www.gnu.org/copyleft/gpl.html)\n\n"
-
-          "For more information read the RRD manpages\n\n";
-
+           "\t\t[-F|--force-rules-legend]\n" "\t\t[-j|--only-graph]\n");
+    const char *help_graph2 =
+        N_("\t\t[-n|--font FONTTAG:size:font]\n"
+           "\t\t[-m|--zoom factor]\n"
+           "\t\t[-A|--alt-autoscale]\n"
+           "\t\t[-M|--alt-autoscale-max]\n"
+           "\t\t[-R|--font-render-mode {normal,light,mono}]\n"
+           "\t\t[-B|--font-smoothing-threshold size]\n"
+           "\t\t[-E|--slope-mode]\n"
+           "\t\t[-N|--no-gridfit]\n"
+           "\t\t[-X|--units-exponent value]\n"
+           "\t\t[-L|--units-length value]\n"
+           "\t\t[-S|--step seconds]\n"
+           "\t\t[-f|--imginfo printfstr]\n"
+           "\t\t[-a|--imgformat PNG]\n"
+           "\t\t[-c|--color COLORTAG#rrggbb[aa]] [-t|--title string]\n"
+           "\t\t[-W|--watermark string]\n"
+           "\t\t[DEF:vname=rrd:ds-name:CF]\n");
+    const char *help_graph3 =
+        N_("\t\t[CDEF:vname=rpn-expression]\n"
+           "\t\t[VDEF:vdefname=rpn-expression]\n"
+           "\t\t[PRINT:vdefname:format]\n"
+           "\t\t[GPRINT:vdefname:format]\n" "\t\t[COMMENT:text]\n"
+           "\t\t[SHIFT:vname:offset]\n"
+           "\t\t[TICK:vname#rrggbb[aa][:[fraction][:legend]]]\n"
+           "\t\t[HRULE:value#rrggbb[aa][:legend]]\n"
+           "\t\t[VRULE:value#rrggbb[aa][:legend]]\n"
+           "\t\t[LINE[width]:vname[#rrggbb[aa][:[legend][:STACK]]]]\n"
+           "\t\t[AREA:vname[#rrggbb[aa][:[legend][:STACK]]]]\n"
+           "\t\t[PRINT:vname:CF:format] (deprecated)\n"
+           "\t\t[GPRINT:vname:CF:format] (deprecated)\n"
+           "\t\t[STACK:vname[#rrggbb[aa][:legend]]] (deprecated)\n\n");
+    const char *help_tune1 =
+        N_(" * tune -  Modify some basic properties of an RRD\n\n"
+           "\trrdtool tune filename\n"
+           "\t\t[--heartbeat|-h ds-name:heartbeat]\n"
+           "\t\t[--data-source-type|-d ds-name:DST]\n"
+           "\t\t[--data-source-rename|-r old-name:new-name]\n"
+           "\t\t[--minimum|-i ds-name:min] [--maximum|-a ds-name:max]\n"
+           "\t\t[--deltapos scale-value] [--deltaneg scale-value]\n"
+           "\t\t[--failure-threshold integer]\n"
+           "\t\t[--window-length integer]\n"
+           "\t\t[--alpha adaptation-parameter]\n");
+    const char *help_tune2 =
+        N_(" * tune -  Modify some basic properties of an RRD\n\n"
+           "\t\t[--beta adaptation-parameter]\n"
+           "\t\t[--gamma adaptation-parameter]\n"
+           "\t\t[--gamma-deviation adaptation-parameter]\n"
+           "\t\t[--aberrant-reset ds-name]\n\n");
+    const char *help_resize =
+        N_
+        (" * resize - alter the length of one of the RRAs in an RRD\n\n"
+         "\trrdtool resize filename rranum GROW|SHRINK rows\n\n");
+    const char *help_xport =
+        N_("* xport - generate XML dump from one or several RRD\n\n"
+           "\trrdtool xport [-s|--start seconds] [-e|--end seconds]\n"
+           "\t\t[-m|--maxrows rows]\n" "\t\t[--step seconds]\n"
+           "\t\t[--enumds]\n" "\t\t[DEF:vname=rrd:ds-name:CF]\n"
+           "\t\t[CDEF:vname=rpn-expression]\n"
+           "\t\t[XPORT:vname:legend]\n\n");
+    const char *help_quit =
+        N_(" * quit - closing a session in remote mode\n\n"
+           "\trrdtool quit\n\n");
+    const char *help_ls =
+        N_(" * ls - lists all *.rrd files in current directory\n\n"
+           "\trrdtool ls\n\n");
+    const char *help_cd =
+        N_(" * cd - changes the current directory\n\n"
+           "\trrdtool cd new directory\n\n");
+    const char *help_mkdir =
+        N_(" * mkdir - creates a new directory\n\n"
+           "\trrdtool mkdir newdirectoryname\n\n");
+    const char *help_pwd =
+        N_(" * pwd - returns the current working directory\n\n"
+           "\trrdtool pwd\n\n");
+    const char *help_lic =
+        N_("RRDtool is distributed under the Terms of the GNU General\n"
+           "Public License Version 2. (www.gnu.org/copyleft/gpl.html)\n\n"
+           "For more information read the RRD manpages\n\n");
     enum { C_NONE, C_CREATE, C_DUMP, C_INFO, C_RESTORE, C_LAST,
-          C_LASTUPDATE, C_FIRST, C_UPDATE, C_FETCH, C_GRAPH, C_TUNE,
-          C_RESIZE, C_XPORT, C_QUIT, C_LS, C_CD, C_MKDIR, C_PWD,
-          C_UPDATEV };
-
-    int help_cmd = C_NONE;
-
-    if (cmd)
-       {
-           if (!strcmp(cmd,"create"))
-               help_cmd = C_CREATE;
-           else if (!strcmp(cmd,"dump"))
-               help_cmd = C_DUMP;
-           else if (!strcmp(cmd,"info"))
-               help_cmd = C_INFO;
-           else if (!strcmp(cmd,"restore"))
-               help_cmd = C_RESTORE;
-           else if (!strcmp(cmd,"last"))
-               help_cmd = C_LAST;
-           else if (!strcmp(cmd,"lastupdate"))
-               help_cmd = C_LASTUPDATE;
-           else if (!strcmp(cmd,"first"))
-               help_cmd = C_FIRST;
-           else if (!strcmp(cmd,"update"))
-               help_cmd = C_UPDATE;
-           else if (!strcmp(cmd,"updatev"))
-               help_cmd = C_UPDATEV;
-           else if (!strcmp(cmd,"fetch"))
-               help_cmd = C_FETCH;
-           else if (!strcmp(cmd,"graph"))
-               help_cmd = C_GRAPH;
-           else if (!strcmp(cmd,"tune"))
-               help_cmd = C_TUNE;
-           else if (!strcmp(cmd,"resize"))
-               help_cmd = C_RESIZE;
-           else if (!strcmp(cmd,"xport"))
-               help_cmd = C_XPORT;
-            else if (!strcmp(cmd,"quit"))
-                help_cmd = C_QUIT;
-            else if (!strcmp(cmd,"ls"))
-                help_cmd = C_LS;
-            else if (!strcmp(cmd,"cd"))
-                help_cmd = C_CD;
-            else if (!strcmp(cmd,"mkdir"))
-                help_cmd = C_MKDIR;
-            else if (!strcmp(cmd,"pwd"))
-                help_cmd = C_PWD;
-       }
-    fputs(help_main, stdout);
-    switch (help_cmd)
-       {
-           case C_NONE:
-               fputs(help_list, stdout);
-                if (RemoteMode){
-                   fputs(help_listremote, stdout);
-                }
-               break;
-           case C_CREATE:
-               fputs(help_create, stdout);
-               break;
-           case C_DUMP:
-               fputs(help_dump, stdout);
-               break;
-           case C_INFO:
-               fputs(help_info, stdout);
-               break;
-           case C_RESTORE:
-               fputs(help_restore, stdout);
-               break;
-           case C_LAST:
-               fputs(help_last, stdout);
-               break;
-           case C_LASTUPDATE:
-               fputs(help_lastupdate, stdout);
-               break;
-           case C_FIRST:
-               fputs(help_first, stdout);
-               break;
-           case C_UPDATE:
-               fputs(help_update, stdout);
-               break;
-           case C_UPDATEV:
-               fputs(help_updatev, stdout);
-               break;
-           case C_FETCH:
-               fputs(help_fetch, stdout);
-               break;
-           case C_GRAPH:
-               fputs(help_graph1, stdout);
-               fputs(help_graph2, stdout);
-               fputs(help_graph3, stdout);
-               break;
-           case C_TUNE:
-               fputs(help_tune1, stdout);
-               fputs(help_tune2, stdout);
-               break;
-           case C_RESIZE:
-               fputs(help_resize, stdout);
-               break;
-           case C_XPORT:
-               fputs(help_xport, stdout);
-               break;
-           case C_QUIT:
-               fputs(help_quit, stdout);
-               break;
-           case C_LS:
-               fputs(help_ls, stdout);
-               break;
-           case C_CD:
-               fputs(help_cd, stdout);
-               break;
-           case C_MKDIR:
-               fputs(help_mkdir, stdout);
-               break;
-           case C_PWD:
-               fputs(help_pwd, stdout);
-               break;
-       }
-    fputs(help_lic, stdout);
+        C_LASTUPDATE, C_FIRST, C_UPDATE, C_FETCH, C_GRAPH, C_GRAPHV,
+        C_TUNE,
+        C_RESIZE, C_XPORT, C_QUIT, C_LS, C_CD, C_MKDIR, C_PWD,
+        C_UPDATEV
+    };
+    int       help_cmd = C_NONE;
+
+    if (cmd) {
+        if (!strcmp(cmd, "create"))
+            help_cmd = C_CREATE;
+        else if (!strcmp(cmd, "dump"))
+            help_cmd = C_DUMP;
+        else if (!strcmp(cmd, "info"))
+            help_cmd = C_INFO;
+        else if (!strcmp(cmd, "restore"))
+            help_cmd = C_RESTORE;
+        else if (!strcmp(cmd, "last"))
+            help_cmd = C_LAST;
+        else if (!strcmp(cmd, "lastupdate"))
+            help_cmd = C_LASTUPDATE;
+        else if (!strcmp(cmd, "first"))
+            help_cmd = C_FIRST;
+        else if (!strcmp(cmd, "update"))
+            help_cmd = C_UPDATE;
+        else if (!strcmp(cmd, "updatev"))
+            help_cmd = C_UPDATEV;
+        else if (!strcmp(cmd, "fetch"))
+            help_cmd = C_FETCH;
+        else if (!strcmp(cmd, "graph"))
+            help_cmd = C_GRAPH;
+        else if (!strcmp(cmd, "graphv"))
+            help_cmd = C_GRAPHV;
+        else if (!strcmp(cmd, "tune"))
+            help_cmd = C_TUNE;
+        else if (!strcmp(cmd, "resize"))
+            help_cmd = C_RESIZE;
+        else if (!strcmp(cmd, "xport"))
+            help_cmd = C_XPORT;
+        else if (!strcmp(cmd, "quit"))
+            help_cmd = C_QUIT;
+        else if (!strcmp(cmd, "ls"))
+            help_cmd = C_LS;
+        else if (!strcmp(cmd, "cd"))
+            help_cmd = C_CD;
+        else if (!strcmp(cmd, "mkdir"))
+            help_cmd = C_MKDIR;
+        else if (!strcmp(cmd, "pwd"))
+            help_cmd = C_PWD;
+    }
+    fprintf(stdout, _(help_main), PACKAGE_VERSION, __DATE__, __TIME__);
+    fflush(stdout);
+    switch (help_cmd) {
+    case C_NONE:
+        fputs(_(help_list), stdout);
+        if (RemoteMode) {
+            fputs(_(help_listremote), stdout);
+        }
+        break;
+    case C_CREATE:
+        fputs(_(help_create), stdout);
+        break;
+    case C_DUMP:
+        fputs(_(help_dump), stdout);
+        break;
+    case C_INFO:
+        fputs(_(help_info), stdout);
+        break;
+    case C_RESTORE:
+        fputs(_(help_restore), stdout);
+        break;
+    case C_LAST:
+        fputs(_(help_last), stdout);
+        break;
+    case C_LASTUPDATE:
+        fputs(_(help_lastupdate), stdout);
+        break;
+    case C_FIRST:
+        fputs(_(help_first), stdout);
+        break;
+    case C_UPDATE:
+        fputs(_(help_update), stdout);
+        break;
+    case C_UPDATEV:
+        fputs(_(help_updatev), stdout);
+        break;
+    case C_FETCH:
+        fputs(_(help_fetch), stdout);
+        break;
+    case C_GRAPH:
+        fputs(_(help_graph0), stdout);
+        fputs(_(help_graph1), stdout);
+        fputs(_(help_graph2), stdout);
+        fputs(_(help_graph3), stdout);
+        break;
+    case C_GRAPHV:
+        fputs(_(help_graphv0), stdout);
+        fputs(_(help_graph1), stdout);
+        fputs(_(help_graph2), stdout);
+        fputs(_(help_graph3), stdout);
+        break;
+    case C_TUNE:
+        fputs(_(help_tune1), stdout);
+        fputs(_(help_tune2), stdout);
+        break;
+    case C_RESIZE:
+        fputs(_(help_resize), stdout);
+        break;
+    case C_XPORT:
+        fputs(_(help_xport), stdout);
+        break;
+    case C_QUIT:
+        fputs(_(help_quit), stdout);
+        break;
+    case C_LS:
+        fputs(_(help_ls), stdout);
+        break;
+    case C_CD:
+        fputs(_(help_cd), stdout);
+        break;
+    case C_MKDIR:
+        fputs(_(help_mkdir), stdout);
+        break;
+    case C_PWD:
+        fputs(_(help_pwd), stdout);
+        break;
+    }
+    fputs(_(help_lic), stdout);
 }
 
-static char *fgetslong(char **aLinePtr, FILE *stream)
+static char *fgetslong(
+    char **aLinePtr,
+    FILE * stream)
 {
-   char *linebuf;
-   size_t bufsize = MAX_LENGTH;
-   int eolpos = 0;
-
-   if (feof(stream)) return *aLinePtr = 0;
-   if (!(linebuf = malloc(bufsize))) {
-      perror("fgetslong: malloc");
-      exit(1);
-   }
-   linebuf[0] = '\0';
-   while (fgets(linebuf + eolpos, MAX_LENGTH, stream)) {
-      eolpos += strlen(linebuf + eolpos);
-      if (linebuf[eolpos - 1] == '\n') return *aLinePtr = linebuf;
-      bufsize += MAX_LENGTH;
-      if (!(linebuf = realloc(linebuf, bufsize))) {
-         perror("fgetslong: realloc");
-         exit(1);
-      }
-   }
-   return *aLinePtr = linebuf[0] ? linebuf : 0;
+    char     *linebuf;
+    size_t    bufsize = MAX_LENGTH;
+    int       eolpos = 0;
+
+    if (feof(stream))
+        return *aLinePtr = 0;
+    if (!(linebuf = malloc(bufsize))) {
+        perror("fgetslong: malloc");
+        exit(1);
+    }
+    linebuf[0] = '\0';
+    while (fgets(linebuf + eolpos, MAX_LENGTH, stream)) {
+        eolpos += strlen(linebuf + eolpos);
+        if (linebuf[eolpos - 1] == '\n')
+            return *aLinePtr = linebuf;
+        bufsize += MAX_LENGTH;
+        if (!(linebuf = realloc(linebuf, bufsize))) {
+            perror("fgetslong: realloc");
+            exit(1);
+        }
+    }
+    return *aLinePtr = linebuf[0] ? linebuf : 0;
 }
 
-int main(int argc, char *argv[])
+int main(
+    int argc,
+    char *argv[])
 {
-    char **myargv;
-    char *aLine;
-    char *firstdir="";
+    char    **myargv;
+    char     *aLine;
+    char     *firstdir = "";
+
 #ifdef MUST_DISABLE_SIGFPE
-    signal(SIGFPE,SIG_IGN);
+    signal(SIGFPE, SIG_IGN);
 #endif
 #ifdef MUST_DISABLE_FPMASK
     fpsetmask(0);
 #endif
-    if (argc == 1)
-       {
-           PrintUsage("");
-           return 0;
-       }
-    
-    if (((argc == 2)||(argc == 3)) && !strcmp("-",argv[1]))
-       {
+#ifdef HAVE_LOCALE_H
+    setlocale(LC_ALL, "");
+#endif
+
+#if defined(HAVE_LIBINTL_H) && defined(BUILD_LIBINTL)
+    bindtextdomain(GETTEXT_PACKAGE, LOCALEDIR);
+    bind_textdomain_codeset(GETTEXT_PACKAGE, "UTF-8");
+    textdomain(GETTEXT_PACKAGE);
+#endif
+    if (argc == 1) {
+        PrintUsage("");
+        return 0;
+    }
+
+    if (((argc == 2) || (argc == 3)) && !strcmp("-", argv[1])) {
 #if HAVE_GETRUSAGE
-         struct rusage  myusage;
-         struct timeval starttime;
-         struct timeval currenttime;
+        struct rusage myusage;
+        struct timeval starttime;
+        struct timeval currenttime;
 
-         gettimeofday(&starttime, NULL);
+        gettimeofday(&starttime, NULL);
 #endif
-         RemoteMode=1;
-          if ((argc == 3) && strcmp("",argv[2])){
+        RemoteMode = 1;
+        if ((argc == 3) && strcmp("", argv[2])) {
 
-             if (
+            if (
 #ifdef HAVE_GETUID
-                getuid()
+                   getuid()
 #else
-                1
+                   1
 #endif
-                == 0 ){
+                   == 0) {
 
 #ifdef HAVE_CHROOT
                 chroot(argv[2]);
-                if (errno!=0){
-                   fprintf(stderr,"ERROR: can't change root to '%s' errno=%d\n",
-                           argv[2],errno);
+                if (errno != 0) {
+                    fprintf(stderr,
+                            "ERROR: can't change root to '%s' errno=%d\n",
+                            argv[2], errno);
                     exit(errno);
                 }
-                ChangeRoot=1;
-                firstdir="/";
+                ChangeRoot = 1;
+                firstdir = "/";
 #else
-                fprintf(stderr,"ERROR: change root is not supported by your OS "
-                         "or at least by this copy of rrdtool\n");
+                fprintf(stderr,
+                        "ERROR: change root is not supported by your OS "
+                        "or at least by this copy of rrdtool\n");
                 exit(1);
 #endif
-             } else {
-                firstdir=argv[2];
-             }
-          }
-          if (strcmp(firstdir,"")){
-             chdir(firstdir);
-             if (errno!=0){
-                fprintf(stderr,"ERROR: %s\n",rrd_strerror(errno));
+            } else {
+                firstdir = argv[2];
+            }
+        }
+        if (strcmp(firstdir, "")) {
+            chdir(firstdir);
+            if (errno != 0) {
+                fprintf(stderr, "ERROR: %s\n", rrd_strerror(errno));
                 exit(errno);
-             }
-          }
-
-           while (fgetslong(&aLine, stdin)){
-               if ((argc = CountArgs(aLine)) == 0)  {
-                   printf("ERROR: not enough arguments\n");
-               }
-               if ((myargv = (char **) malloc((argc+1) * 
-                                              sizeof(char *))) == NULL)   {
-                   perror("malloc");
-                   exit(1);
-               }
-               if ((argc=CreateArgs(argv[0], aLine, argc, myargv)) < 0) {
-                   printf("ERROR: creating arguments\n");
-               } else {
-                   int ret = HandleInputLine(argc, myargv, stdout);
-                   free(myargv);
-                   if (ret == 0){
-                       
-
+            }
+        }
+
+        while (fgetslong(&aLine, stdin)) {
+            if ((argc = CountArgs(aLine)) == 0) {
+                printf("ERROR: not enough arguments\n");
+            }
+            if ((myargv = (char **) malloc((argc + 1) *
+                                           sizeof(char *))) == NULL) {
+                perror("malloc");
+                exit(1);
+            }
+            if ((argc = CreateArgs(argv[0], aLine, argc, myargv)) < 0) {
+                printf("ERROR: creating arguments\n");
+            } else {
+                int       ret = HandleInputLine(argc, myargv, stdout);
+
+                free(myargv);
+                if (ret == 0) {
 #if HAVE_GETRUSAGE
-                    getrusage(RUSAGE_SELF,&myusage);
-                    gettimeofday(&currenttime,NULL);
-                    printf("OK u:%1.2f s:%1.2f r:%1.2f\n",
-                      (double)myusage.ru_utime.tv_sec+
-                      (double)myusage.ru_utime.tv_usec/1000000.0,
-                      (double)myusage.ru_stime.tv_sec+
-                      (double)myusage.ru_stime.tv_usec/1000000.0,
-                      (double)(currenttime.tv_sec-starttime.tv_sec)
-                      +(double)(currenttime.tv_usec-starttime.tv_usec)
-                      /1000000.0);
+                    getrusage(RUSAGE_SELF, &myusage);
+                    gettimeofday(&currenttime, NULL);
+                    printf("OK u:%1.2f s:%1.2f r:%1.2f\n",
+                           (double) myusage.ru_utime.tv_sec +
+                           (double) myusage.ru_utime.tv_usec / 1000000.0,
+                           (double) myusage.ru_stime.tv_sec +
+                           (double) myusage.ru_stime.tv_usec / 1000000.0,
+                           (double) (currenttime.tv_sec - starttime.tv_sec)
+                           + (double) (currenttime.tv_usec -
+                                       starttime.tv_usec)
+                           / 1000000.0);
 #else
-                     printf("OK\n");
-                   
-#endif          
-                 }
-               }
-               fflush(stdout); /* this is important for pipes to work */
-                free(aLine);
-           }
-       }
-    else if (argc == 2)
-       {
-               PrintUsage(argv[1]);
-               exit(0);
-       }
-    else if (argc == 3 && !strcmp(argv[1],"help"))
-       {
-               PrintUsage(argv[2]);
-               exit(0);
-       }
-    else {
+                    printf("OK\n");
+#endif
+                }
+            }
+            fflush(stdout); /* this is important for pipes to work */
+            free(aLine);
+        }
+    } else if (argc == 2) {
+        PrintUsage(argv[1]);
+        exit(0);
+    } else if (argc == 3 && !strcmp(argv[1], "help")) {
+        PrintUsage(argv[2]);
+        exit(0);
+    } else {
         exit(HandleInputLine(argc, argv, stderr));
     }
     return 0;
@@ -460,344 +495,352 @@ int main(int argc, char *argv[])
 
 /* HandleInputLine is NOT thread safe - due to readdir issues,
    resolving them portably is not really simple. */
-int HandleInputLine(int argc, char **argv, FILE* out)
+int HandleInputLine(
+    int argc,
+    char **argv,
+    FILE * out)
 {
 #if defined(HAVE_OPENDIR) && defined (HAVE_READDIR)
-    DIR           *curdir; /* to read current dir with ls */
+    DIR      *curdir;   /* to read current dir with ls */
     struct dirent *dent;
 #endif
 #if defined(HAVE_SYS_STAT_H)
-    struct stat   st;
+    struct stat st;
 #endif
-    char* cwd; /* To hold current working dir on call to pwd */
+    char     *cwd;      /* To hold current working dir on call to pwd */
 
     /* Reset errno to 0 before we start.
-    */
+     */
     errno = 0;
-
-    if (RemoteMode){
-       if (argc>1 && strcmp("quit", argv[1]) == 0){
-          if (argc>2){
-             printf("ERROR: invalid parameter count for quit\n");
-             return(1);
-          }
-          exit(0);
-       }
+    if (RemoteMode) {
+        if (argc > 1 && strcmp("quit", argv[1]) == 0) {
+            if (argc > 2) {
+                printf("ERROR: invalid parameter count for quit\n");
+                return (1);
+            }
+            exit(0);
+        }
 #if defined(HAVE_OPENDIR) && defined(HAVE_READDIR) && defined(HAVE_CHDIR)
-       if (argc>1 && strcmp("cd", argv[1]) == 0){
-          if (argc>3){
-             printf("ERROR: invalid parameter count for cd\n");
-             return(1);
-          }
+        if (argc > 1 && strcmp("cd", argv[1]) == 0) {
+            if (argc > 3) {
+                printf("ERROR: invalid parameter count for cd\n");
+                return (1);
+            }
 #if ! defined(HAVE_CHROOT) || ! defined(HAVE_GETUID)
-          if (getuid()==0 && ! ChangeRoot){
-             printf("ERROR: chdir security problem - rrdtool is running as "
-                    "root but not chroot!\n");
-             return(1); 
-          }
+            if (getuid() == 0 && !ChangeRoot) {
+                printf
+                    ("ERROR: chdir security problem - rrdtool is running as "
+                     "root but not chroot!\n");
+                return (1);
+            }
 #endif
-          chdir(argv[2]);
-          if (errno!=0){
-             printf("ERROR: %s\n",rrd_strerror(errno));
-            return(1);
-          }
-          return(0);
-       }
-       if (argc>1 && strcmp("pwd", argv[1]) == 0){
-          if (argc>2){
-             printf("ERROR: invalid parameter count for pwd\n");
-             return(1);
-          }
-          cwd = getcwd(NULL, MAXPATH);
-          if(cwd == NULL) {
-             printf("ERROR: %s\n",rrd_strerror(errno));
-             return(1);
-          }
-          printf("%s\n", cwd);
-          free(cwd);
-          return(0);
-       }
-       if (argc>1 && strcmp("mkdir", argv[1]) == 0){
-          if (argc>3){
-             printf("ERROR: invalid parameter count for mkdir\n");
-             return(1);
-          }
+            chdir(argv[2]);
+            if (errno != 0) {
+                printf("ERROR: %s\n", rrd_strerror(errno));
+                return (1);
+            }
+            return (0);
+        }
+        if (argc > 1 && strcmp("pwd", argv[1]) == 0) {
+            if (argc > 2) {
+                printf("ERROR: invalid parameter count for pwd\n");
+                return (1);
+            }
+            cwd = getcwd(NULL, MAXPATH);
+            if (cwd == NULL) {
+                printf("ERROR: %s\n", rrd_strerror(errno));
+                return (1);
+            }
+            printf("%s\n", cwd);
+            free(cwd);
+            return (0);
+        }
+        if (argc > 1 && strcmp("mkdir", argv[1]) == 0) {
+            if (argc > 3) {
+                printf("ERROR: invalid parameter count for mkdir\n");
+                return (1);
+            }
 #if ! defined(HAVE_CHROOT) || ! defined(HAVE_GETUID)
-          if (getuid()==0 && ! ChangeRoot){
-             printf("ERROR: mkdir security problem - rrdtool is running as "
-                    "root but not chroot!\n");
-             return(1); 
-          }
+            if (getuid() == 0 && !ChangeRoot) {
+                printf
+                    ("ERROR: mkdir security problem - rrdtool is running as "
+                     "root but not chroot!\n");
+                return (1);
+            }
 #endif
-          mkdir(argv[2],0777);
-          if (errno!=0){
-             printf("ERROR: %s\n",rrd_strerror(errno));
-             return(1);
-          }
-          return(0);
-       }
-       if (argc>1 && strcmp("ls", argv[1]) == 0){
-          if (argc>2){
-             printf("ERROR: invalid parameter count for ls\n");
-             return(1);
-          }
-          if ((curdir=opendir("."))!=NULL){
-             while((dent=readdir(curdir))!=NULL){
-                if (!stat(dent->d_name,&st)){
-                   if (S_ISDIR(st.st_mode)){
-                      printf("d %s\n",dent->d_name);
-                   }
-                   if (strlen(dent->d_name)>4 && S_ISREG(st.st_mode)){
-                      if (!strcmp(dent->d_name+NAMLEN(dent)-4,".rrd") ||
-                          !strcmp(dent->d_name+NAMLEN(dent)-4,".RRD")){
-                         printf("- %s\n",dent->d_name);
-                      }
-                   }
+            mkdir(argv[2], 0777);
+            if (errno != 0) {
+                printf("ERROR: %s\n", rrd_strerror(errno));
+                return (1);
+            }
+            return (0);
+        }
+        if (argc > 1 && strcmp("ls", argv[1]) == 0) {
+            if (argc > 2) {
+                printf("ERROR: invalid parameter count for ls\n");
+                return (1);
+            }
+            if ((curdir = opendir(".")) != NULL) {
+                while ((dent = readdir(curdir)) != NULL) {
+                    if (!stat(dent->d_name, &st)) {
+                        if (S_ISDIR(st.st_mode)) {
+                            printf("d %s\n", dent->d_name);
+                        }
+                        if (strlen(dent->d_name) > 4 && S_ISREG(st.st_mode)) {
+                            if (!strcmp
+                                (dent->d_name + NAMLEN(dent) - 4, ".rrd")
+                                || !strcmp(dent->d_name + NAMLEN(dent) - 4,
+                                           ".RRD")) {
+                                printf("- %s\n", dent->d_name);
+                            }
+                        }
+                    }
                 }
-             }
-            closedir(curdir);
-          }
-          else{
-             printf("ERROR: %s\n",rrd_strerror(errno));
-             return(errno);
-          }
-          return(0);
-       }
-#endif /* opendir and readdir */
+                closedir(curdir);
+            } else {
+                printf("ERROR: %s\n", rrd_strerror(errno));
+                return (errno);
+            }
+            return (0);
+        }
+#endif                          /* opendir and readdir */
 
     }
-    if (argc < 3 
-       || strcmp("help", argv[1]) == 0
-       || strcmp("--help", argv[1]) == 0
-       || strcmp("-help", argv[1]) == 0
-       || strcmp("-?", argv[1]) == 0
-       || strcmp("-h", argv[1]) == 0 ) {
-       PrintUsage("");
-       return 0;
+    if (argc < 3
+        || strcmp("help", argv[1]) == 0
+        || strcmp("--help", argv[1]) == 0
+        || strcmp("-help", argv[1]) == 0
+        || strcmp("-?", argv[1]) == 0 || strcmp("-h", argv[1]) == 0) {
+        PrintUsage("");
+        return 0;
     }
-    
-    if (strcmp("create", argv[1]) == 0)        
-       rrd_create(argc-1, &argv[1]);
+
+    if (strcmp("create", argv[1]) == 0)
+        rrd_create(argc - 1, &argv[1]);
     else if (strcmp("dump", argv[1]) == 0)
-       rrd_dump(argc-1, &argv[1]);
-    else if (strcmp("info", argv[1]) == 0 
-               || strcmp("updatev", argv[1]) == 0){
-       info_t *data,*save;
-       if (strcmp("info",argv[1]) == 0)
-          data=rrd_info(argc-1, &argv[1]);
-    else
-          data=rrd_update_v(argc-1, &argv[1]);
-       while (data) {
-           save=data;
-           printf ("%s = ", data->key);
-           free(data->key);
-           
-           switch (data->type) {
-           case RD_I_VAL:
-               if (isnan (data->value.u_val))
-                   printf("NaN");
-               else
-                   printf ("%0.10e", data->value.u_val);
-               break;
-           case RD_I_CNT:
-               printf ("%lu", data->value.u_cnt);
-               break;
-           case RD_I_INT:
-               printf ("%d", data->value.u_int);
-               break;
-           case RD_I_STR:
-               printf ("\"%s\"", data->value.u_str);
-               free(data->value.u_str);
-               break;
-           }
-           data = data->next;
-           free(save);
-           printf ("\n");
-       }
-       free(data);
+        rrd_dump(argc - 1, &argv[1]);
+    else if (strcmp("info", argv[1]) == 0 || strcmp("updatev", argv[1]) == 0) {
+        info_t   *data;
+
+        if (strcmp("info", argv[1]) == 0)
+
+            data = rrd_info(argc - 1, &argv[1]);
+        else
+            data = rrd_update_v(argc - 1, &argv[1]);
+        info_print(data);
+        info_free(data);
     }
 
     else if (strcmp("--version", argv[1]) == 0 ||
-            strcmp("version", argv[1]) == 0 || 
-            strcmp("v", argv[1]) == 0 ||
-            strcmp("-v", argv[1]) == 0  ||
-            strcmp("-version", argv[1]) == 0  )
-        printf("RRDtool " PACKAGE_VERSION "  Copyright by Tobi Oetiker, 1997-2005 (%f)\n",
+             strcmp("version", argv[1]) == 0 ||
+             strcmp("v", argv[1]) == 0 ||
+             strcmp("-v", argv[1]) == 0 || strcmp("-version", argv[1]) == 0)
+        printf("RRDtool " PACKAGE_VERSION
+               "  Copyright by Tobi Oetiker, 1997-2008 (%f)\n",
                rrd_version());
     else if (strcmp("restore", argv[1]) == 0)
-       rrd_restore(argc-1, &argv[1]);
+        rrd_restore(argc - 1, &argv[1]);
     else if (strcmp("resize", argv[1]) == 0)
-       rrd_resize(argc-1, &argv[1]);
+        rrd_resize(argc - 1, &argv[1]);
     else if (strcmp("last", argv[1]) == 0)
-        printf("%ld\n",rrd_last(argc-1, &argv[1]));
+        printf("%ld\n", rrd_last(argc - 1, &argv[1]));
     else if (strcmp("lastupdate", argv[1]) == 0) {
-          time_t      last_update;
-           char        **ds_namv;
-           char        **last_ds;
-           unsigned long ds_cnt,
-                       i;
-          if (rrd_lastupdate(argc-1, &argv[1], &last_update,
-                       &ds_cnt, &ds_namv, &last_ds) == 0) {
-               for (i=0; i<ds_cnt; i++)
-                       printf(" %s", ds_namv[i]);
-               printf("\n\n");
-               printf("%10lu:", last_update);
-               for (i=0; i<ds_cnt; i++) {
-                       printf(" %s", last_ds[i]);
-                       free(last_ds[i]);
-                       free(ds_namv[i]);
-               }
-               printf("\n");
-               free(last_ds);
-               free(ds_namv);
-          }
+        time_t    last_update;
+        char    **ds_namv;
+        char    **last_ds;
+        unsigned long ds_cnt, i;
+
+        if (rrd_lastupdate(argc - 1, &argv[1], &last_update,
+                           &ds_cnt, &ds_namv, &last_ds) == 0) {
+            for (i = 0; i < ds_cnt; i++)
+                printf(" %s", ds_namv[i]);
+            printf("\n\n");
+            printf("%10lu:", last_update);
+            for (i = 0; i < ds_cnt; i++) {
+                printf(" %s", last_ds[i]);
+                free(last_ds[i]);
+                free(ds_namv[i]);
+            }
+            printf("\n");
+            free(last_ds);
+            free(ds_namv);
+        }
     } else if (strcmp("first", argv[1]) == 0)
-        printf("%ld\n",rrd_first(argc-1, &argv[1]));
+        printf("%ld\n", rrd_first(argc - 1, &argv[1]));
     else if (strcmp("update", argv[1]) == 0)
-       rrd_update(argc-1, &argv[1]);
+        rrd_update(argc - 1, &argv[1]);
     else if (strcmp("fetch", argv[1]) == 0) {
-       time_t        start,end, ti;
-       unsigned long step, ds_cnt,i,ii;
-       rrd_value_t   *data,*datai;
-       char          **ds_namv;
-       if (rrd_fetch(argc-1, &argv[1],&start,&end,&step,&ds_cnt,&ds_namv,&data) != -1) {
-           datai=data;
-           printf("           ");
-           for (i = 0; i<ds_cnt;i++)
-               printf("%20s",ds_namv[i]);
-           printf ("\n\n");
-           for (ti = start+step; ti <= end; ti += step){
-               printf("%10lu:", ti);
-               for (ii = 0; ii < ds_cnt; ii++)
-                   printf(" %0.10e", *(datai++));
-               printf("\n");
-           }
-           for (i=0;i<ds_cnt;i++)
-                 free(ds_namv[i]);
-           free(ds_namv);
-           free (data);
-       }
+        time_t    start, end, ti;
+        unsigned long step, ds_cnt, i, ii;
+        rrd_value_t *data, *datai;
+        char    **ds_namv;
+
+        if (rrd_fetch
+            (argc - 1, &argv[1], &start, &end, &step, &ds_cnt, &ds_namv,
+             &data) != -1) {
+            datai = data;
+            printf("           ");
+            for (i = 0; i < ds_cnt; i++)
+                printf("%20s", ds_namv[i]);
+            printf("\n\n");
+            for (ti = start + step; ti <= end; ti += step) {
+                printf("%10lu:", ti);
+                for (ii = 0; ii < ds_cnt; ii++)
+                    printf(" %0.10e", *(datai++));
+                printf("\n");
+            }
+            for (i = 0; i < ds_cnt; i++)
+                free(ds_namv[i]);
+            free(ds_namv);
+            free(data);
+        }
     } else if (strcmp("xport", argv[1]) == 0) {
-        int xxsize;
-       unsigned long int j = 0;
-       time_t        start,end, ti;
-       unsigned long step, col_cnt,row_cnt;
-       rrd_value_t   *data,*ptr;
-       char          **legend_v;
-        int           enumds = 0;
-        int           i;
-        size_t       vtag_s = strlen(COL_DATA_TAG) + 10; 
-        char         *vtag = malloc(vtag_s); 
-       for ( i = 2; i < argc; i++){
-               if (strcmp("--enumds", argv[i]) == 0)
-                       enumds = 1;
-       }
-
-        if(rrd_xport(argc-1, &argv[1], &xxsize,&start,&end,&step,&col_cnt,&legend_v,&data) != -1) {
-         row_cnt = (end-start)/step;
-         ptr = data;
-         printf("<?xml version=\"1.0\" encoding=\"%s\"?>\n\n", XML_ENCODING);
-         printf("<%s>\n", ROOT_TAG);
-         printf("  <%s>\n", META_TAG);
-         printf("    <%s>%lu</%s>\n", META_START_TAG, start+step, META_START_TAG);
-         printf("    <%s>%lu</%s>\n", META_STEP_TAG, step, META_STEP_TAG);
-         printf("    <%s>%lu</%s>\n", META_END_TAG, end, META_END_TAG);
-         printf("    <%s>%lu</%s>\n", META_ROWS_TAG, row_cnt, META_ROWS_TAG);
-         printf("    <%s>%lu</%s>\n", META_COLS_TAG, col_cnt, META_COLS_TAG);
-         printf("    <%s>\n", LEGEND_TAG);
-         for (j = 0; j < col_cnt; j++) {
-           char *entry = NULL;
-           entry = legend_v[j];
-           printf("      <%s>%s</%s>\n", LEGEND_ENTRY_TAG, entry, LEGEND_ENTRY_TAG);
-           free(entry);
-         }
-         free(legend_v);
-         printf("    </%s>\n", LEGEND_TAG);
-         printf("  </%s>\n", META_TAG);
-         printf("  <%s>\n", DATA_TAG);
-         for (ti = start+step; ti <= end; ti += step) {
-           printf ("    <%s>", DATA_ROW_TAG);
-           printf ("<%s>%lu</%s>", COL_TIME_TAG, ti, COL_TIME_TAG);
-           for (j = 0; j < col_cnt; j++) {
-             rrd_value_t newval = DNAN;
-              if (enumds == 1)
-               snprintf(vtag,vtag_s,"%s%lu", COL_DATA_TAG, j);
-             else
-               snprintf(vtag,vtag_s,"%s",COL_DATA_TAG);
-              
-             newval = *ptr;
-             if(isnan(newval)){
-                printf("<%s>NaN</%s>", vtag,vtag);
-             } else {
-               printf("<%s>%0.10e</%s>", vtag, newval, vtag);
-             };
-             ptr++;
-           }
-           printf("</%s>\n", DATA_ROW_TAG);
-         }
-         free(data);
-         printf("  </%s>\n", DATA_TAG);
-         printf("</%s>\n", ROOT_TAG);
-       }
+        int       xxsize;
+        unsigned long int j = 0;
+        time_t    start, end, ti;
+        unsigned long step, col_cnt, row_cnt;
+        rrd_value_t *data, *ptr;
+        char    **legend_v;
+        int       enumds = 0;
+        int       i;
+        size_t    vtag_s = strlen(COL_DATA_TAG) + 10;
+        char     *vtag = malloc(vtag_s);
+
+        for (i = 2; i < argc; i++) {
+            if (strcmp("--enumds", argv[i]) == 0)
+                enumds = 1;
+        }
+
+        if (rrd_xport
+            (argc - 1, &argv[1], &xxsize, &start, &end, &step, &col_cnt,
+             &legend_v, &data) != -1) {
+            row_cnt = (end - start) / step;
+            ptr = data;
+            printf("<?xml version=\"1.0\" encoding=\"%s\"?>\n\n",
+                   XML_ENCODING);
+            printf("<%s>\n", ROOT_TAG);
+            printf("  <%s>\n", META_TAG);
+            printf("    <%s>%lu</%s>\n", META_START_TAG,
+                   (unsigned long) start + step, META_START_TAG);
+            printf("    <%s>%lu</%s>\n", META_STEP_TAG, step, META_STEP_TAG);
+            printf("    <%s>%lu</%s>\n", META_END_TAG, (unsigned long) end,
+                   META_END_TAG);
+            printf("    <%s>%lu</%s>\n", META_ROWS_TAG, row_cnt,
+                   META_ROWS_TAG);
+            printf("    <%s>%lu</%s>\n", META_COLS_TAG, col_cnt,
+                   META_COLS_TAG);
+            printf("    <%s>\n", LEGEND_TAG);
+            for (j = 0; j < col_cnt; j++) {
+                char     *entry = NULL;
+
+                entry = legend_v[j];
+                printf("      <%s>%s</%s>\n", LEGEND_ENTRY_TAG, entry,
+                       LEGEND_ENTRY_TAG);
+                free(entry);
+            }
+            free(legend_v);
+            printf("    </%s>\n", LEGEND_TAG);
+            printf("  </%s>\n", META_TAG);
+            printf("  <%s>\n", DATA_TAG);
+            for (ti = start + step; ti <= end; ti += step) {
+                printf("    <%s>", DATA_ROW_TAG);
+                printf("<%s>%lu</%s>", COL_TIME_TAG, ti, COL_TIME_TAG);
+                for (j = 0; j < col_cnt; j++) {
+                    rrd_value_t newval = DNAN;
+
+                    if (enumds == 1)
+
+                        snprintf(vtag, vtag_s, "%s%lu", COL_DATA_TAG, j);
+                    else
+                        snprintf(vtag, vtag_s, "%s", COL_DATA_TAG);
+                    newval = *ptr;
+                    if (isnan(newval)) {
+                        printf("<%s>NaN</%s>", vtag, vtag);
+                    } else {
+                        printf("<%s>%0.10e</%s>", vtag, newval, vtag);
+                    };
+                    ptr++;
+                }
+                printf("</%s>\n", DATA_ROW_TAG);
+            }
+            free(data);
+            printf("  </%s>\n", DATA_TAG);
+            printf("</%s>\n", ROOT_TAG);
+        }
         free(vtag);
-    }
-    else if (strcmp("graph", argv[1]) == 0) {
-       char **calcpr;
-#ifdef notused  /*XXX*/
-       const char *imgfile = argv[2]; /* rrd_graph changes argv pointer */
+    } else if (strcmp("graph", argv[1]) == 0) {
+        char    **calcpr;
+
+#ifdef notused /*XXX*/
+        const char *imgfile = argv[2];  /* rrd_graph changes argv pointer */
 #endif
-       int xsize, ysize;
-       double ymin,ymax;
-       int i;
-       int tostdout = (strcmp(argv[2],"-") == 0);      
-       int imginfo = 0;
-       for (i=2;i<argc;i++){
-               if (strcmp(argv[i],"--imginfo") == 0 || strcmp(argv[i],"-f") == 0){
-                       imginfo = 1;
-                       break;
-               }
-       }
-       if( rrd_graph(argc-1, &argv[1], &calcpr, &xsize, &ysize, NULL, &ymin, &ymax) != -1 ) {
-           if (!tostdout && !imginfo) 
-               printf ("%dx%d\n",xsize,ysize);
-           if (calcpr) {
-               for(i=0;calcpr[i];i++){
-                   if (!tostdout) 
-                       printf("%s\n",calcpr[i]);
-                   free(calcpr[i]);
-               } 
-               free(calcpr);
-           }
-       }
-       
-    } else if (strcmp("tune", argv[1]) == 0) 
-               rrd_tune(argc-1, &argv[1]);
+        int       xsize, ysize;
+        double    ymin, ymax;
+        int       i;
+        int       tostdout = (strcmp(argv[2], "-") == 0);
+        int       imginfo = 0;
+
+        for (i = 2; i < argc; i++) {
+            if (strcmp(argv[i], "--imginfo") == 0
+                || strcmp(argv[i], "-f") == 0) {
+                imginfo = 1;
+                break;
+            }
+        }
+        if (rrd_graph
+            (argc - 1, &argv[1], &calcpr, &xsize, &ysize, NULL, &ymin,
+             &ymax) != -1) {
+            if (!tostdout && !imginfo)
+                printf("%dx%d\n", xsize, ysize);
+            if (calcpr) {
+                for (i = 0; calcpr[i]; i++) {
+                    if (!tostdout)
+                        printf("%s\n", calcpr[i]);
+                    free(calcpr[i]);
+                }
+                free(calcpr);
+            }
+        }
+
+    } else if (strcmp("graphv", argv[1]) == 0) {
+        info_t   *grinfo = NULL;    /* 1 to distinguish it from the NULL that rrd_graph sends in */
+        grinfo = rrd_graph_v(argc - 1, &argv[1]);
+        if (grinfo) {
+            info_print(grinfo);
+            info_free(grinfo);
+        }
+
+    } else if (strcmp("tune", argv[1]) == 0)
+        rrd_tune(argc - 1, &argv[1]);
     else {
-               rrd_set_error("unknown function '%s'",argv[1]);
+        rrd_set_error("unknown function '%s'", argv[1]);
     }
     if (rrd_test_error()) {
-       fprintf(out, "ERROR: %s\n",rrd_get_error());
-       rrd_clear_error();
-       return 1;
+        fprintf(out, "ERROR: %s\n", rrd_get_error());
+        rrd_clear_error();
+        return 1;
     }
-    return(0);
+    return (0);
 }
 
-int CountArgs(char *aLine)
+int CountArgs(
+    char *aLine)
 {
-    int i=0;
-    int aCount = 0;
-    int inarg = 0;
-    while (aLine[i] == ' ') i++;
-    while (aLine[i] != 0){       
-       if((aLine[i]== ' ') && inarg){
-           inarg = 0;
-       }
-       if((aLine[i]!= ' ') && ! inarg){
-           inarg = 1;
-           aCount++;
-       }
-       i++;
+    int       i = 0;
+    int       aCount = 0;
+    int       inarg = 0;
+
+    while (aLine[i] == ' ')
+        i++;
+    while (aLine[i] != 0) {
+        if ((aLine[i] == ' ') && inarg) {
+            inarg = 0;
+        }
+        if ((aLine[i] != ' ') && !inarg) {
+            inarg = 1;
+            aCount++;
+        }
+        i++;
     }
     return aCount;
 }
@@ -805,70 +848,71 @@ int CountArgs(char *aLine)
 /*
  * CreateArgs - take a string (aLine) and tokenize
  */
-int CreateArgs(char *pName, char *aLine, int argc, char **argv)
+int CreateArgs(
+    char *pName,
+    char *aLine,
+    int argc,
+    char **argv)
 {
-    char       *getP, *putP;
-    char       **pargv = argv;
-    char        Quote = 0;
-    int inArg = 0;
-    int        len;
+    char     *getP, *putP;
+    char    **pargv = argv;
+    char      Quote = 0;
+    int       inArg = 0;
+    int       len;
 
     len = strlen(aLine);
     /* remove trailing space and newlines */
     while (len && aLine[len] <= ' ') {
-       aLine[len] = 0 ; len--;
+        aLine[len] = 0;
+        len--;
     }
     /* sikp leading blanks */
-    while (*aLine && *aLine <= ' ') aLine++;
-
+    while (*aLine && *aLine <= ' ')
+        aLine++;
     pargv[0] = pName;
     argc = 1;
     getP = aLine;
     putP = aLine;
-    while (*getP){
-       switch (*getP) {
-       case ' ': 
-           if (Quote){
-               *(putP++)=*getP;
-           } else 
-               if(inArg) {
-                   *(putP++) = 0;
-                   inArg = 0;
-               }
-           break;
-       case '"':
-       case '\'':
-           if (Quote != 0) {
-               if (Quote == *getP) 
-                   Quote = 0;
-               else {
-                   *(putP++)=*getP;
-               }
-           } else {
-               if(!inArg){
-                   pargv[argc++] = putP;
-                   inArg=1;
-               }           
-               Quote = *getP;
-           }
-           break;
-       default:
-           if(!inArg){
-               pargv[argc++] = putP;
-               inArg=1;
-           }
-           *(putP++)=*getP;
-           break;
-       }
-       getP++;
+    while (*getP) {
+        switch (*getP) {
+        case ' ':
+            if (Quote) {
+                *(putP++) = *getP;
+            } else if (inArg) {
+                *(putP++) = 0;
+                inArg = 0;
+            }
+            break;
+        case '"':
+        case '\'':
+            if (Quote != 0) {
+                if (Quote == *getP)
+                    Quote = 0;
+                else {
+                    *(putP++) = *getP;
+                }
+            } else {
+                if (!inArg) {
+                    pargv[argc++] = putP;
+                    inArg = 1;
+                }
+                Quote = *getP;
+            }
+            break;
+        default:
+            if (!inArg) {
+                pargv[argc++] = putP;
+                inArg = 1;
+            }
+            *(putP++) = *getP;
+            break;
+        }
+        getP++;
     }
 
     *putP = '\0';
-
-    if (Quote) 
-       return -1;
+    if (Quote)
+        return -1;
     else
-       return argc;
+        return argc;
 }
-
-
index 22c404f960cb4e15794fd37449c6d3b700d869ce..5182898ef7f3ee4c443a6c0c0a8b21b41d36ecd2 100644 (file)
@@ -1,13 +1,12 @@
 /*****************************************************************************
- * RRDtool 1.2.27  Copyright by Tobi Oetiker, 1997-2008
+ * RRDtool 1.3rc4  Copyright by Tobi Oetiker, 1997-2008
  *****************************************************************************
  * rrd_tool.h   Common Header File
  *****************************************************************************/
 #ifdef  __cplusplus
-extern "C" {
+extern    "C" {
 #endif
 
-
 #ifndef _RRD_TOOL_H
 #define _RRD_TOOL_H
 
@@ -17,83 +16,35 @@ extern "C" {
 #include "../win32/config.h"
 #endif
 
-#ifdef MUST_DISABLE_SIGFPE
-#include <signal.h>
-#endif
-
-#ifdef MUST_DISABLE_FPMASK
-#include <floatingpoint.h>
-#endif
-
-#include <stdio.h>
-#include <stdlib.h>
-#include <errno.h>
-#include <string.h>
-#include <ctype.h>
-
-#if HAVE_SYS_PARAM_H
-#  include <sys/param.h>
-#endif
-
-#ifndef MAXPATH
-#  define MAXPATH 1024
-#endif
-
-#if HAVE_MATH_H
-# include <math.h>
-#endif
-/* Sorry: don't know autoconf as well how to check the exist of
-   dirent.h ans sys/stat.h
-*/
-
-#if HAVE_DIRENT_H
-# include <dirent.h>
-# define NAMLEN(dirent) strlen((dirent)->d_name)
-#else
-# define dirent direct
-# define NAMLEN(dirent) (dirent)->d_namlen
-# if HAVE_SYS_NDIR_H
-#  include <sys/ndir.h>
-# endif
-# if HAVE_SYS_DIR_H
-#  include <sys/dir.h>
-# endif
-# if HAVE_NDIR_H
-#  include <ndir.h>
-# endif
-#endif
-
-#if HAVE_SYS_TYPES_H
-# include <sys/types.h>
-#endif
-
-#if HAVE_SYS_STAT_H
-# include <sys/stat.h>
-#endif
-
-#if HAVE_STRINGS_H
-# include <strings.h>
-#endif
-
 #include "rrd.h"
 
 #if defined(_WIN32) && !defined(__CYGWIN__) && !defined(__CYGWIN32__)
 
 /* Win32 only includes */
 
-#include <float.h>        /* for _isnan  */
-#include <io.h>           /* for chdir   */
-
-struct tm* localtime_r(const time_t *timep, struct tm* result);
-char* ctime_r(const time_t *timep, char* result);
-struct tm* gmtime_r(const time_t *timep, struct tm* result);
-char *strtok_r(char *str, const char *sep, char **last);
+#include <float.h>      /* for _isnan  */
+#include <io.h>         /* for chdir   */
+
+    struct tm *localtime_r(
+    const time_t *timep,
+    struct tm *result);
+    char     *ctime_r(
+    const time_t *timep,
+    char *result);
+    struct tm *gmtime_r(
+    const time_t *timep,
+    struct tm *result);
+    char     *strtok_r(
+    char *str,
+    const char *sep,
+    char **last);
 
 #else
 
 /* unix-only includes */
 #if !defined isnan && !defined HAVE_ISNAN
-int isnan(double value);
+    int       isnan(
+    double value);
 #endif
 
 #endif
@@ -108,68 +59,115 @@ int isnan(double value);
 
 #ifndef min
 #define min(a,b) ((a) < (b) ? (a) : (b))
-#endif                                                   
+#endif
 
 #define DIM(x) (sizeof(x)/sizeof(x[0]))
 
-/* rrd info interface */
-enum info_type   { RD_I_VAL=0,
-              RD_I_CNT,
-              RD_I_STR, 
-                  RD_I_INT };
-
-typedef union infoval { 
-    unsigned long u_cnt; 
-    rrd_value_t   u_val;
-    char         *u_str;
-    int                  u_int;
-} infoval;
-
-typedef struct info_t {
-    char            *key;
-    enum info_type  type;
-    union infoval   value;
-    struct info_t   *next;
-} info_t;
-
-info_t *rrd_info(int, char **);
-int rrd_lastupdate(int argc, char **argv, time_t *last_update,
-                unsigned long *ds_cnt, char ***ds_namv, char ***last_ds);
-info_t *rrd_update_v(int, char **);
-char * sprintf_alloc(char *, ...);
-info_t *info_push(info_t *, char *, enum info_type, infoval);
+    info_t   *rrd_info(
+    int,
+    char **);
+    int       rrd_lastupdate(
+    int argc,
+    char **argv,
+    time_t *last_update,
+    unsigned long *ds_cnt,
+    char ***ds_namv,
+    char ***last_ds);
+    info_t   *rrd_update_v(
+    int,
+    char **);
+    char     *sprintf_alloc(
+    char *,
+    ...);
+    info_t   *info_push(
+    info_t *,
+    char *,
+    enum info_type,
+    infoval);
+    void      info_print(
+    info_t *data);
+    void      info_free(
+    info_t *);
 
 /* HELPER FUNCTIONS */
 
-int PngSize(FILE *, long *, long *);
-
-int rrd_create_fn(const char *file_name, rrd_t *rrd);
-int rrd_fetch_fn(const char *filename, enum cf_en cf_idx,
-                time_t *start,time_t *end,
-                unsigned long *step,
-                unsigned long *ds_cnt,
-                char        ***ds_namv,
-                rrd_value_t **data);
-
-void rrd_free(rrd_t *rrd);
-void rrd_freemem(void *mem);
-void rrd_init(rrd_t *rrd);
-
-int rrd_open(const char *file_name, FILE **in_file, rrd_t *rrd, int rdwr);
-int readfile(const char *file, char **buffer, int skipfirst);
-
-#define RRD_READONLY    0
-#define RRD_READWRITE   1
-
-enum cf_en cf_conv(const char *string);
-enum dst_en dst_conv(char *string);
-long ds_match(rrd_t *rrd,char *ds_nam);
-double rrd_diff(char *a, char *b);
+    int       PngSize(
+    FILE *,
+    long *,
+    long *);
+
+    int       rrd_create_fn(
+    const char *file_name,
+    rrd_t *rrd);
+    int       rrd_fetch_fn(
+    const char *filename,
+    enum cf_en cf_idx,
+    time_t *start,
+    time_t *end,
+    unsigned long *step,
+    unsigned long *ds_cnt,
+    char ***ds_namv,
+    rrd_value_t **data);
+
+    void      rrd_free(
+    rrd_t *rrd);
+    void      rrd_freemem(
+    void *mem);
+    void      rrd_init(
+    rrd_t *rrd);
+
+    rrd_file_t *rrd_open(
+    const char *const file_name,
+    rrd_t *rrd,
+    unsigned rdwr);
+    void      rrd_dontneed(
+    rrd_file_t *rrd_file,
+    rrd_t *rrd);
+    int       rrd_close(
+    rrd_file_t *rrd_file);
+    ssize_t   rrd_read(
+    rrd_file_t *rrd_file,
+    void *buf,
+    size_t count);
+    ssize_t   rrd_write(
+    rrd_file_t *rrd_file,
+    const void *buf,
+    size_t count);
+    void      rrd_flush(
+    rrd_file_t *rrd_file);
+    off_t     rrd_seek(
+    rrd_file_t *rrd_file,
+    off_t off,
+    int whence);
+    off_t     rrd_tell(
+    rrd_file_t *rrd_file);
+    int       readfile(
+    const char *file,
+    char **buffer,
+    int skipfirst);
+
+#define RRD_READONLY    (1<<0)
+#define RRD_READWRITE   (1<<1)
+#define RRD_CREAT       (1<<2)
+#define RRD_READAHEAD   (1<<3)
+#define RRD_COPY        (1<<4)
+
+    enum cf_en cf_conv(
+    const char *string);
+    enum dst_en dst_conv(
+    char *string);
+    long      ds_match(
+    rrd_t *rrd,
+    char *ds_nam);
+    double    rrd_diff(
+    char *a,
+    char *b);
 
     /* rrd_strerror is thread safe, but still it uses a global buffer
        (but one per thread), thus subsequent calls within a single
        thread overwrite the same buffer */
-const char *rrd_strerror(int err);
+    const char *rrd_strerror(
+    int err);
 
 #endif
 
index d7f08fd05323ea0cc1f03a439c556a010d58ec58..ed0f0baf57ba87c9161f153a91013608a8b70b26 100644 (file)
@@ -1,9 +1,9 @@
 /*****************************************************************************
- * RRDtool 1.2.27  Copyright by Tobi Oetiker, 1997-2008
+ * RRDtool 1.3rc4  Copyright by Tobi Oetiker, 1997-2008
  *****************************************************************************
  * change header parameters of an rrd
  *****************************************************************************
- * $Id: rrd_tune.c 1286 2008-02-17 10:08:10Z oetiker $
+ * $Id: rrd_tune.c 1366 2008-05-18 13:06:44Z oetiker $
  * $Log$
  * Revision 1.6  2004/05/26 22:11:12  oetiker
  * reduce compiler warnings. Many small fixes. -- Mike Slifcak <slif@bellsouth.net>
 #include "rrd_tool.h"
 #include "rrd_rpncalc.h"
 #include "rrd_hw.h"
+#include <locale.h>
 
-int set_hwarg(rrd_t *rrd,enum cf_en cf,enum rra_par_en rra_par,char *arg);
-int set_deltaarg(rrd_t *rrd,enum rra_par_en rra_par,char *arg);
-int set_windowarg(rrd_t *rrd,enum rra_par_en,char *arg);
+int       set_hwarg(
+    rrd_t *rrd,
+    enum cf_en cf,
+    enum rra_par_en rra_par,
+    char *arg);
+int       set_deltaarg(
+    rrd_t *rrd,
+    enum rra_par_en rra_par,
+    char *arg);
+int       set_windowarg(
+    rrd_t *rrd,
+    enum rra_par_en,
+    char *arg);
 
-int
-rrd_tune(int argc, char **argv)    
-{   
-    rrd_t               rrd;
-    FILE               *rrd_file;
-    int                 matches;
-    int                 optcnt = 0;
-    long                ds;
-    char                ds_nam[DS_NAM_SIZE];
-    char                ds_new[DS_NAM_SIZE];
-    long                heartbeat;
-    double              min;
-    double              max;
-    char                dst[DST_SIZE];
-    optind = 0; opterr = 0;  /* initialize getopt */
+int rrd_tune(
+    int argc,
+    char **argv)
+{
+    rrd_t     rrd;
+    int       matches;
+    int       optcnt = 0;
+    long      ds;
+    char      ds_nam[DS_NAM_SIZE];
+    char      ds_new[DS_NAM_SIZE];
+    long      heartbeat;
+    double    min;
+    double    max;
+    char      dst[DST_SIZE];
+    rrd_file_t *rrd_file;
+    struct option long_options[] = {
+        {"heartbeat", required_argument, 0, 'h'},
+        {"minimum", required_argument, 0, 'i'},
+        {"maximum", required_argument, 0, 'a'},
+        {"data-source-type", required_argument, 0, 'd'},
+        {"data-source-rename", required_argument, 0, 'r'},
+        /* added parameter tuning options for aberrant behavior detection */
+        {"deltapos", required_argument, 0, 'p'},
+        {"deltaneg", required_argument, 0, 'n'},
+        {"window-length", required_argument, 0, 'w'},
+        {"failure-threshold", required_argument, 0, 'f'},
+        {"alpha", required_argument, 0, 'x'},
+        {"beta", required_argument, 0, 'y'},
+        {"gamma", required_argument, 0, 'z'},
+        {"gamma-deviation", required_argument, 0, 'v'},
+        {"smoothing-window", required_argument, 0, 's'},
+        {"smoothing-window-deviation", required_argument, 0, 'S'},
+        {"aberrant-reset", required_argument, 0, 'b'},
+        {0, 0, 0, 0}
+    };
+
+    optind = 0;
+    opterr = 0;         /* initialize getopt */
 
 
-    if(rrd_open(argv[1],&rrd_file,&rrd, RRD_READWRITE)==-1){
+    rrd_file = rrd_open(argv[1], &rrd, RRD_READWRITE);
+    if (rrd_file == NULL) {
+        rrd_free(&rrd);
         return -1;
     }
 
-    
-    while (1){
-       static struct option long_options[] =
-       {
-           {"heartbeat",        required_argument, 0, 'h'},
-           {"minimum",          required_argument, 0, 'i'},
-           {"maximum",          required_argument, 0, 'a'},
-           {"data-source-type", required_argument, 0, 'd'},
-           {"data-source-rename", required_argument, 0, 'r'},
-           /* added parameter tuning options for aberrant behavior detection */
-               {"deltapos",required_argument,0,'p'},
-               {"deltaneg",required_argument,0,'n'},
-               {"window-length",required_argument,0,'w'},
-               {"failure-threshold",required_argument,0,'f'},
-           {"alpha",required_argument,0,'x'},
-           {"beta",required_argument,0,'y'},
-           {"gamma",required_argument,0,'z'},
-           {"gamma-deviation",required_argument,0,'v'},
-               {"aberrant-reset",required_argument,0,'b'},
-           {0,0,0,0}
-       };
-       int option_index = 0;
-       int opt;
-       opt = getopt_long(argc, argv, "h:i:a:d:r:p:n:w:f:x:y:z:v:b:", 
-                         long_options, &option_index);
-       if (opt == EOF)
-           break;
-       
-       optcnt++;
-       switch(opt) {       
-       case 'h':
-           if ((matches = sscanf(optarg, DS_NAM_FMT ":%ld",ds_nam,&heartbeat)) != 2){
-               rrd_set_error("invalid arguments for heartbeat");
-               rrd_free(&rrd);
-               fclose(rrd_file);
-               return -1;
-           }
-           if ((ds=ds_match(&rrd,ds_nam))==-1){
-               rrd_free(&rrd);
-                fclose(rrd_file);
-               return -1;
-           }
-           rrd.ds_def[ds].par[DS_mrhb_cnt].u_cnt = heartbeat;
-           break;
+    while (1) {
+        int       option_index = 0;
+        int       opt;
+        char     *old_locale = "";
+
+        opt = getopt_long(argc, argv, "h:i:a:d:r:p:n:w:f:x:y:z:v:b:",
+                          long_options, &option_index);
+        if (opt == EOF)
+            break;
+
+        optcnt++;
+        switch (opt) {
+        case 'h':
+            old_locale = setlocale(LC_NUMERIC, "C");
+            if ((matches =
+                 sscanf(optarg, DS_NAM_FMT ":%ld", ds_nam,
+                        &heartbeat)) != 2) {
+                rrd_set_error("invalid arguments for heartbeat");
+                rrd_free(&rrd);
+                rrd_close(rrd_file);
+                setlocale(LC_NUMERIC, old_locale);
+                return -1;
+            }
+            setlocale(LC_NUMERIC, old_locale);
+            if ((ds = ds_match(&rrd, ds_nam)) == -1) {
+                rrd_free(&rrd);
+                rrd_close(rrd_file);
+                return -1;
+            }
+            rrd.ds_def[ds].par[DS_mrhb_cnt].u_cnt = heartbeat;
+            break;
 
-       case 'i':
-           if ((matches = sscanf(optarg,DS_NAM_FMT ":%lf",ds_nam,&min)) <1){
-               rrd_set_error("invalid arguments for minimum ds value");
-               rrd_free(&rrd);
-                fclose(rrd_file);
-               return -1;
-           }
-           if ((ds=ds_match(&rrd,ds_nam))==-1){
-               rrd_free(&rrd);
-                fclose(rrd_file);
-               return -1;
-           }
+        case 'i':
+            old_locale = setlocale(LC_NUMERIC, "C");
+            if ((matches =
+                 sscanf(optarg, DS_NAM_FMT ":%lf", ds_nam, &min)) < 1) {
+                rrd_set_error("invalid arguments for minimum ds value");
+                rrd_free(&rrd);
+                rrd_close(rrd_file);
+                setlocale(LC_NUMERIC, old_locale);
+                return -1;
+            }
+            setlocale(LC_NUMERIC, old_locale);
+            if ((ds = ds_match(&rrd, ds_nam)) == -1) {
+                rrd_free(&rrd);
+                rrd_close(rrd_file);
+                return -1;
+            }
 
-           if(matches == 1)
-               min= DNAN;
-           rrd.ds_def[ds].par[DS_min_val].u_val = min;
-           break;
+            if (matches == 1)
+                min = DNAN;
+            rrd.ds_def[ds].par[DS_min_val].u_val = min;
+            break;
 
-       case 'a':
-           if ((matches = sscanf(optarg, DS_NAM_FMT ":%lf",ds_nam,&max)) <1){
-               rrd_set_error("invalid arguments for maximum ds value");
-               rrd_free(&rrd);
-               fclose(rrd_file);
-               return -1;
-           }
-           if ((ds=ds_match(&rrd,ds_nam))==-1){
-               rrd_free(&rrd);
-               fclose(rrd_file);
-               return -1;
-           }
-           if(matches == 1) 
-               max= DNAN; 
-           rrd.ds_def[ds].par[DS_max_val].u_val = max;
-           break;
+        case 'a':
+            old_locale = setlocale(LC_NUMERIC, "C");
+            if ((matches =
+                 sscanf(optarg, DS_NAM_FMT ":%lf", ds_nam, &max)) < 1) {
+                rrd_set_error("invalid arguments for maximum ds value");
+                rrd_free(&rrd);
+                rrd_close(rrd_file);
+                setlocale(LC_NUMERIC, old_locale);
+                return -1;
+            }
+            setlocale(LC_NUMERIC, old_locale);
+            if ((ds = ds_match(&rrd, ds_nam)) == -1) {
+                rrd_free(&rrd);
+                rrd_close(rrd_file);
+                return -1;
+            }
+            if (matches == 1)
+                max = DNAN;
+            rrd.ds_def[ds].par[DS_max_val].u_val = max;
+            break;
 
-       case 'd':
-           if ((matches = sscanf(optarg, DS_NAM_FMT ":" DST_FMT ,ds_nam,dst)) != 2){
-               rrd_set_error("invalid arguments for data source type");
-               rrd_free(&rrd);
-               fclose(rrd_file);
-               return -1;
-           }
-           if ((ds=ds_match(&rrd,ds_nam))==-1){
-               rrd_free(&rrd);
-               fclose(rrd_file);
-               return -1;
-           }
-           if ((int)dst_conv(dst) == -1){
-               rrd_free(&rrd);
-               fclose(rrd_file);
-               return -1;
-           }
-           strncpy(rrd.ds_def[ds].dst,dst,DST_SIZE-1);
-           rrd.ds_def[ds].dst[DST_SIZE-1]='\0';
+        case 'd':
+            if ((matches =
+                 sscanf(optarg, DS_NAM_FMT ":" DST_FMT, ds_nam, dst)) != 2) {
+                rrd_set_error("invalid arguments for data source type");
+                rrd_free(&rrd);
+                rrd_close(rrd_file);
+                return -1;
+            }
+            if ((ds = ds_match(&rrd, ds_nam)) == -1) {
+                rrd_free(&rrd);
+                rrd_close(rrd_file);
+                return -1;
+            }
+            if ((int) dst_conv(dst) == -1) {
+                rrd_free(&rrd);
+                rrd_close(rrd_file);
+                return -1;
+            }
+            /* only reset when something is changed */
+            if (strncmp(rrd.ds_def[ds].dst, dst, DST_SIZE - 1) != 0) {
+                strncpy(rrd.ds_def[ds].dst, dst, DST_SIZE - 1);
+                rrd.ds_def[ds].dst[DST_SIZE - 1] = '\0';
 
-           rrd.pdp_prep[ds].last_ds[0] = 'U';
-           rrd.pdp_prep[ds].last_ds[1] = 'N';
-           rrd.pdp_prep[ds].last_ds[2] = 'K';
-           rrd.pdp_prep[ds].last_ds[3] = 'N';
-           rrd.pdp_prep[ds].last_ds[4] = '\0';
-           
-           break;
-       case 'r':
-           if ((matches = 
-                sscanf(optarg,DS_NAM_FMT ":" DS_NAM_FMT , ds_nam,ds_new)) != 2){
-               rrd_set_error("invalid arguments for data source type");
-               rrd_free(&rrd);
-               fclose(rrd_file);
-               return -1;
-           }
-           if ((ds=ds_match(&rrd,ds_nam))==-1){
-               rrd_free(&rrd);
-               fclose(rrd_file);
-               return -1;
-           }
-           strncpy(rrd.ds_def[ds].ds_nam,ds_new,DS_NAM_SIZE-1);
-           rrd.ds_def[ds].ds_nam[DS_NAM_SIZE-1]='\0';
-           break;
-    case 'p':
-               if (set_deltaarg(&rrd,RRA_delta_pos,optarg)) {
-                  rrd_free(&rrd);
-                  return -1;
-               }
-               break;
-       case 'n':
-               if (set_deltaarg(&rrd,RRA_delta_neg,optarg)) {
-                  rrd_free(&rrd);
-                  return -1;
-               }
-               break;
-       case 'f':
-               if (set_windowarg(&rrd,RRA_failure_threshold,optarg)) {
-                  rrd_free(&rrd);
-                  return -1;
-               }
-               break;
-       case 'w':
-               if (set_windowarg(&rrd,RRA_window_len,optarg)) {
-                  rrd_free(&rrd);
-                  return -1;
-               }
-               break;
-       case 'x':
-               if (set_hwarg(&rrd,CF_HWPREDICT,RRA_hw_alpha,optarg)) {
-                  rrd_free(&rrd);
-                  return -1;
-               }
-               break;
-       case 'y':
-               if (set_hwarg(&rrd,CF_HWPREDICT,RRA_hw_beta,optarg)) {
-                  rrd_free(&rrd);
-                  return -1;
-               }
-               break;
-       case 'z':
-               if (set_hwarg(&rrd,CF_SEASONAL,RRA_seasonal_gamma,optarg)) {
-                  rrd_free(&rrd);
-                  return -1;
-               }
-               break;
-       case 'v':
-               if (set_hwarg(&rrd,CF_DEVSEASONAL,RRA_seasonal_gamma,optarg)) {
-                  rrd_free(&rrd);
-                  return -1;
-               }
-               break;
-       case 'b':
-               if (sscanf(optarg,DS_NAM_FMT,ds_nam) != 1){
-               rrd_set_error("invalid argument for aberrant-reset");
-               rrd_free(&rrd);
-               fclose(rrd_file);
-               return -1;
-           }
-           if ((ds=ds_match(&rrd,ds_nam))==-1){
-           /* ds_match handles it own errors */        
-               rrd_free(&rrd);
-               fclose(rrd_file);
-               return -1;
-           }
-           reset_aberrant_coefficients(&rrd,rrd_file,(unsigned long) ds);
-               if (rrd_test_error()) {
-                  rrd_free(&rrd);
-                  fclose(rrd_file);
-                  return -1;
-               }
-               break;
-       case '?':
+                rrd.pdp_prep[ds].last_ds[0] = 'U';
+                rrd.pdp_prep[ds].last_ds[1] = 'N';
+                rrd.pdp_prep[ds].last_ds[2] = 'K';
+                rrd.pdp_prep[ds].last_ds[3] = 'N';
+                rrd.pdp_prep[ds].last_ds[4] = '\0';
+            }
+            break;
+        case 'r':
+            if ((matches =
+                 sscanf(optarg, DS_NAM_FMT ":" DS_NAM_FMT, ds_nam,
+                        ds_new)) != 2) {
+                rrd_set_error("invalid arguments for data source type");
+                rrd_free(&rrd);
+                rrd_close(rrd_file);
+                return -1;
+            }
+            if ((ds = ds_match(&rrd, ds_nam)) == -1) {
+                rrd_free(&rrd);
+                rrd_close(rrd_file);
+                return -1;
+            }
+            strncpy(rrd.ds_def[ds].ds_nam, ds_new, DS_NAM_SIZE - 1);
+            rrd.ds_def[ds].ds_nam[DS_NAM_SIZE - 1] = '\0';
+            break;
+        case 'p':
+            if (set_deltaarg(&rrd, RRA_delta_pos, optarg)) {
+                rrd_free(&rrd);
+                return -1;
+            }
+            break;
+        case 'n':
+            if (set_deltaarg(&rrd, RRA_delta_neg, optarg)) {
+                rrd_free(&rrd);
+                return -1;
+            }
+            break;
+        case 'f':
+            if (set_windowarg(&rrd, RRA_failure_threshold, optarg)) {
+                rrd_free(&rrd);
+                return -1;
+            }
+            break;
+        case 'w':
+            if (set_windowarg(&rrd, RRA_window_len, optarg)) {
+                rrd_free(&rrd);
+                return -1;
+            }
+            break;
+        case 'x':
+            if (set_hwarg(&rrd, CF_HWPREDICT, RRA_hw_alpha, optarg)) {
+                if (set_hwarg(&rrd, CF_MHWPREDICT, RRA_hw_alpha, optarg)) {
+                    rrd_free(&rrd);
+                    return -1;
+                }
+                rrd_clear_error();
+            }
+            break;
+        case 'y':
+            if (set_hwarg(&rrd, CF_HWPREDICT, RRA_hw_beta, optarg)) {
+                if (set_hwarg(&rrd, CF_MHWPREDICT, RRA_hw_beta, optarg)) {
+                    rrd_free(&rrd);
+                    return -1;
+                }
+                rrd_clear_error();
+            }
+            break;
+        case 'z':
+            if (set_hwarg(&rrd, CF_SEASONAL, RRA_seasonal_gamma, optarg)) {
+                rrd_free(&rrd);
+                return -1;
+            }
+            break;
+        case 'v':
+            if (set_hwarg(&rrd, CF_DEVSEASONAL, RRA_seasonal_gamma, optarg)) {
+                rrd_free(&rrd);
+                return -1;
+            }
+            break;
+        case 'b':
+            if (sscanf(optarg, DS_NAM_FMT, ds_nam) != 1) {
+                rrd_set_error("invalid argument for aberrant-reset");
+                rrd_free(&rrd);
+                rrd_close(rrd_file);
+                return -1;
+            }
+            if ((ds = ds_match(&rrd, ds_nam)) == -1) {
+                /* ds_match handles it own errors */
+                rrd_free(&rrd);
+                rrd_close(rrd_file);
+                return -1;
+            }
+            reset_aberrant_coefficients(&rrd, rrd_file, (unsigned long) ds);
+            if (rrd_test_error()) {
+                rrd_free(&rrd);
+                rrd_close(rrd_file);
+                return -1;
+            }
+            break;
+        case 's':
+            strcpy(rrd.stat_head->version, RRD_VERSION);    /* smoothing_window causes Version 4 */
+            if (set_hwarg
+                (&rrd, CF_SEASONAL, RRA_seasonal_smoothing_window, optarg)) {
+                rrd_free(&rrd);
+                return -1;
+            }
+            break;
+        case 'S':
+            strcpy(rrd.stat_head->version, RRD_VERSION);    /* smoothing_window causes Version 4 */
+            if (set_hwarg
+                (&rrd, CF_DEVSEASONAL, RRA_seasonal_smoothing_window,
+                 optarg)) {
+                rrd_free(&rrd);
+                return -1;
+            }
+            break;
+        case '?':
             if (optopt != 0)
                 rrd_set_error("unknown option '%c'", optopt);
             else
-                rrd_set_error("unknown option '%s'",argv[optind-1]);
-           rrd_free(&rrd);         
-            fclose(rrd_file);
+                rrd_set_error("unknown option '%s'", argv[optind - 1]);
+            rrd_free(&rrd);
+            rrd_close(rrd_file);
             return -1;
         }
     }
-       if(optcnt>0){
-       
-       fseek(rrd_file,0,SEEK_SET);
-       fwrite(rrd.stat_head,
-              sizeof(stat_head_t),1, rrd_file);
-       fwrite(rrd.ds_def,
-              sizeof(ds_def_t), rrd.stat_head->ds_cnt, rrd_file);
-       /* need to write rra_defs for RRA parameter changes */
-       fwrite(rrd.rra_def, sizeof(rra_def_t), rrd.stat_head->rra_cnt,
-                  rrd_file);
+    if (optcnt > 0) {
+        rrd_seek(rrd_file, 0, SEEK_SET);
+        rrd_write(rrd_file, rrd.stat_head, sizeof(stat_head_t) * 1);
+        rrd_write(rrd_file, rrd.ds_def,
+                  sizeof(ds_def_t) * rrd.stat_head->ds_cnt);
+        /* need to write rra_defs for RRA parameter changes */
+        rrd_write(rrd_file, rrd.rra_def,
+                  sizeof(rra_def_t) * rrd.stat_head->rra_cnt);
     } else {
-       int i;
-       for(i=0;i< (int)rrd.stat_head->ds_cnt;i++)
-               if (dst_conv(rrd.ds_def[i].dst) != DST_CDEF) {
-           printf("DS[%s] typ: %s\thbt: %ld\tmin: %1.4f\tmax: %1.4f\n",
-                  rrd.ds_def[i].ds_nam,
-                  rrd.ds_def[i].dst,
-                  rrd.ds_def[i].par[DS_mrhb_cnt].u_cnt,
-                  rrd.ds_def[i].par[DS_min_val].u_val,
-                  rrd.ds_def[i].par[DS_max_val].u_val);
-               } else {
-               char *buffer = NULL;
-               rpn_compact2str((rpn_cdefds_t *) &(rrd.ds_def[i].par[DS_cdef]),rrd.ds_def,&buffer);
-               printf("DS[%s] typ: %s\tcdef: %s\n", rrd.ds_def[i].ds_nam,rrd.ds_def[i].dst,buffer);
-           free(buffer);
-               }
+        int       i;
+
+        for (i = 0; i < (int) rrd.stat_head->ds_cnt; i++)
+            if (dst_conv(rrd.ds_def[i].dst) != DST_CDEF) {
+                printf("DS[%s] typ: %s\thbt: %ld\tmin: %1.4f\tmax: %1.4f\n",
+                       rrd.ds_def[i].ds_nam,
+                       rrd.ds_def[i].dst,
+                       rrd.ds_def[i].par[DS_mrhb_cnt].u_cnt,
+                       rrd.ds_def[i].par[DS_min_val].u_val,
+                       rrd.ds_def[i].par[DS_max_val].u_val);
+            } else {
+                char     *buffer = NULL;
+
+                rpn_compact2str((rpn_cdefds_t *) &
+                                (rrd.ds_def[i].par[DS_cdef]), rrd.ds_def,
+                                &buffer);
+                printf("DS[%s] typ: %s\tcdef: %s\n", rrd.ds_def[i].ds_nam,
+                       rrd.ds_def[i].dst, buffer);
+                free(buffer);
+            }
     }
-    fclose(rrd_file);
+    rrd_close(rrd_file);
     rrd_free(&rrd);
     return 0;
 }
 
-int set_hwarg(rrd_t *rrd,enum cf_en cf,enum rra_par_en rra_par,char *arg)
+int set_hwarg(
+    rrd_t *rrd,
+    enum cf_en cf,
+    enum rra_par_en rra_par,
+    char *arg)
 {
-   double param;
-   unsigned long i;
-   signed short rra_idx = -1;
-   /* read the value */
-   param = atof(arg);
-   if (param <= 0.0 || param >= 1.0)
-   {
-         rrd_set_error("Holt-Winters parameter must be between 0 and 1");
-         return -1;
-   }
-   /* does the appropriate RRA exist?  */
-   for (i =  0; i < rrd -> stat_head -> rra_cnt; ++i)
-   {
-         if (cf_conv(rrd -> rra_def[i].cf_nam) == cf)
-         {
-                rra_idx = i;
-                break;
-         }
-   }
-   if (rra_idx == -1) 
-   {
-         rrd_set_error("Holt-Winters RRA does not exist in this RRD");
-         return -1;
-   }
-   
-   /* set the value */
-   rrd -> rra_def[rra_idx].par[rra_par].u_val = param;
-   return 0;
+    double    param;
+    unsigned long i;
+    signed short rra_idx = -1;
+
+    /* read the value */
+    param = atof(arg);
+    if (param <= 0.0 || param >= 1.0) {
+        rrd_set_error("Holt-Winters parameter must be between 0 and 1");
+        return -1;
+    }
+    /* does the appropriate RRA exist?  */
+    for (i = 0; i < rrd->stat_head->rra_cnt; ++i) {
+        if (cf_conv(rrd->rra_def[i].cf_nam) == cf) {
+            rra_idx = i;
+            break;
+        }
+    }
+    if (rra_idx == -1) {
+        rrd_set_error("Holt-Winters RRA does not exist in this RRD");
+        return -1;
+    }
+
+    /* set the value */
+    rrd->rra_def[rra_idx].par[rra_par].u_val = param;
+    return 0;
 }
 
-int set_deltaarg(rrd_t *rrd,enum rra_par_en rra_par,char *arg)
+int set_deltaarg(
+    rrd_t *rrd,
+    enum rra_par_en rra_par,
+    char *arg)
 {
-   rrd_value_t param;
-   unsigned long i;
-   signed short rra_idx = -1;
+    rrd_value_t param;
+    unsigned long i;
+    signed short rra_idx = -1;
 
-   param = atof(arg);
-   if (param < 0.1)
-   {
-         rrd_set_error("Parameter specified is too small");
-         return -1;
-   }
-   /* does the appropriate RRA exist?  */
-   for (i = 0; i < rrd -> stat_head -> rra_cnt; ++i)
-   {
-         if (cf_conv(rrd -> rra_def[i].cf_nam) == CF_FAILURES) 
-         {
-                rra_idx = i;
-                break;
-         }
-   }
-   if (rra_idx == -1) 
-   {
-         rrd_set_error("Failures RRA does not exist in this RRD");
-         return -1;
-   }
+    param = atof(arg);
+    if (param < 0.1) {
+        rrd_set_error("Parameter specified is too small");
+        return -1;
+    }
+    /* does the appropriate RRA exist?  */
+    for (i = 0; i < rrd->stat_head->rra_cnt; ++i) {
+        if (cf_conv(rrd->rra_def[i].cf_nam) == CF_FAILURES) {
+            rra_idx = i;
+            break;
+        }
+    }
+    if (rra_idx == -1) {
+        rrd_set_error("Failures RRA does not exist in this RRD");
+        return -1;
+    }
 
-   /* set the value */
-   rrd -> rra_def[rra_idx].par[rra_par].u_val = param;
-   return 0;
+    /* set the value */
+    rrd->rra_def[rra_idx].par[rra_par].u_val = param;
+    return 0;
 }
 
-int set_windowarg(rrd_t *rrd,enum rra_par_en rra_par,char *arg)
+int set_windowarg(
+    rrd_t *rrd,
+    enum rra_par_en rra_par,
+    char *arg)
 {
-   unsigned long param;
-   unsigned long i, cdp_idx;
-   signed short rra_idx = -1;
-   /* read the value */
-   param = atoi(arg);
-   if (param < 1 || param > MAX_FAILURES_WINDOW_LEN)
-   {
-         rrd_set_error("Parameter must be between %d and %d",
-                1, MAX_FAILURES_WINDOW_LEN);
-         return -1;
-   }
-   /* does the appropriate RRA exist?  */
-   for (i = 0; i < rrd -> stat_head -> rra_cnt; ++i)
-   {
-         if (cf_conv(rrd -> rra_def[i].cf_nam) == CF_FAILURES) 
-         {
-                rra_idx = i;
-                break;
-         }
-   }
-   if (rra_idx == -1) 
-   {
-         rrd_set_error("Failures RRA does not exist in this RRD");
-         return -1;
-   }
-   
-   /* set the value */
-   rrd -> rra_def[rra_idx].par[rra_par].u_cnt = param;
+    unsigned long param;
+    unsigned long i, cdp_idx;
+    signed short rra_idx = -1;
+
+    /* read the value */
+    param = atoi(arg);
+    if (param < 1 || param > MAX_FAILURES_WINDOW_LEN) {
+        rrd_set_error("Parameter must be between %d and %d",
+                      1, MAX_FAILURES_WINDOW_LEN);
+        return -1;
+    }
+    /* does the appropriate RRA exist?  */
+    for (i = 0; i < rrd->stat_head->rra_cnt; ++i) {
+        if (cf_conv(rrd->rra_def[i].cf_nam) == CF_FAILURES) {
+            rra_idx = i;
+            break;
+        }
+    }
+    if (rra_idx == -1) {
+        rrd_set_error("Failures RRA does not exist in this RRD");
+        return -1;
+    }
+
+    /* set the value */
+    rrd->rra_def[rra_idx].par[rra_par].u_cnt = param;
 
-   /* erase existing violations */
-   for (i = 0; i < rrd -> stat_head -> ds_cnt; i++)
-   {
-         cdp_idx = rra_idx * (rrd -> stat_head -> ds_cnt) + i;
-         erase_violations(rrd,cdp_idx,rra_idx);
-   }
-   return 0;
+    /* erase existing violations */
+    for (i = 0; i < rrd->stat_head->ds_cnt; i++) {
+        cdp_idx = rra_idx * (rrd->stat_head->ds_cnt) + i;
+        erase_violations(rrd, cdp_idx, rra_idx);
+    }
+    return 0;
 }
index 57e0fbbeb74318496fc62425825eb0884db4de1a..c830c6afabd19cde9cf2adde624eeb8c01d9fa02 100644 (file)
@@ -1,21 +1,22 @@
+
 /*****************************************************************************
- * RRDtool 1.2.27  Copyright by Tobi Oetiker, 1997-2008
+ * RRDtool 1.3rc4  Copyright by Tobi Oetiker, 1997-2008
  *****************************************************************************
  * rrd_update.c  RRD Update Function
  *****************************************************************************
- * $Id: rrd_update.c 1286 2008-02-17 10:08:10Z oetiker $
+ * $Id: rrd_update.c 1366 2008-05-18 13:06:44Z oetiker $
  *****************************************************************************/
 
 #include "rrd_tool.h"
-#include <sys/types.h>
-#include <fcntl.h>
 
 #if defined(_WIN32) && !defined(__CYGWIN__) && !defined(__CYGWIN32__)
- #include <sys/locking.h>
- #include <sys/stat.h>
- #include <io.h>
+#include <sys/locking.h>
+#include <sys/stat.h>
+#include <io.h>
 #endif
 
+#include <locale.h>
+
 #include "rrd_hw.h"
 #include "rrd_rpncalc.h"
 
  */
 #include <sys/timeb.h>
 
-#if (defined(__MINGW32__) && \
-       ((__MINGW32_MAJOR_VERSION == 3 && __MINGW32_MINOR_VERSION >= 12) || __MINGW32_MAJOR_VERSION > 3))
-#include <sys/time.h>
-#else
-
+#ifndef __MINGW32__
 struct timeval {
-       time_t tv_sec; /* seconds */
-       long tv_usec;  /* microseconds */
+    time_t    tv_sec;   /* seconds */
+    long      tv_usec;  /* microseconds */
 };
+#endif
 
 struct __timezone {
-       int  tz_minuteswest; /* minutes W of Greenwich */
-       int  tz_dsttime;     /* type of dst correction */
+    int       tz_minuteswest;   /* minutes W of Greenwich */
+    int       tz_dsttime;   /* type of dst correction */
 };
 
-static int gettimeofday(struct timeval *t, struct __timezone *tz) {
+static int gettimeofday(
+    struct timeval *t,
+    struct __timezone *tz)
+{
 
-       struct _timeb current_time;
+    struct _timeb current_time;
 
-       _ftime(&current_time);
+    _ftime(&current_time);
 
-       t->tv_sec  = current_time.time;
-       t->tv_usec = current_time.millitm * 1000;
+    t->tv_sec = current_time.time;
+    t->tv_usec = current_time.millitm * 1000;
 
-       return 0;
+    return 0;
 }
 
-#endif /* mingw32 3.4.5 */
+#endif
+
+/* FUNCTION PROTOTYPES */
+
+int       rrd_update_r(
+    const char *filename,
+    const char *tmplt,
+    int argc,
+    const char **argv);
+int       _rrd_update(
+    const char *filename,
+    const char *tmplt,
+    int argc,
+    const char **argv,
+    info_t *);
+
+static int allocate_data_structures(
+    rrd_t *rrd,
+    char ***updvals,
+    rrd_value_t **pdp_temp,
+    const char *tmplt,
+    long **tmpl_idx,
+    unsigned long *tmpl_cnt,
+    unsigned long **rra_step_cnt,
+    unsigned long **skip_update,
+    rrd_value_t **pdp_new);
+
+static int parse_template(
+    rrd_t *rrd,
+    const char *tmplt,
+    unsigned long *tmpl_cnt,
+    long *tmpl_idx);
+
+static int process_arg(
+    char *step_start,
+    rrd_t *rrd,
+    rrd_file_t *rrd_file,
+    unsigned long rra_begin,
+    unsigned long *rra_current,
+    time_t *current_time,
+    unsigned long *current_time_usec,
+    rrd_value_t *pdp_temp,
+    rrd_value_t *pdp_new,
+    unsigned long *rra_step_cnt,
+    char **updvals,
+    long *tmpl_idx,
+    unsigned long tmpl_cnt,
+    info_t **pcdp_summary,
+    int version,
+    unsigned long *skip_update,
+    int *schedule_smooth);
+
+static int parse_ds(
+    rrd_t *rrd,
+    char **updvals,
+    long *tmpl_idx,
+    char *input,
+    unsigned long tmpl_cnt,
+    time_t *current_time,
+    unsigned long *current_time_usec,
+    int version);
+
+static int get_time_from_reading(
+    rrd_t *rrd,
+    char timesyntax,
+    char **updvals,
+    time_t *current_time,
+    unsigned long *current_time_usec,
+    int version);
+
+static int update_pdp_prep(
+    rrd_t *rrd,
+    char **updvals,
+    rrd_value_t *pdp_new,
+    double interval);
+
+static int calculate_elapsed_steps(
+    rrd_t *rrd,
+    unsigned long current_time,
+    unsigned long current_time_usec,
+    double interval,
+    double *pre_int,
+    double *post_int,
+    unsigned long *proc_pdp_cnt);
+
+static void simple_update(
+    rrd_t *rrd,
+    double interval,
+    rrd_value_t *pdp_new);
+
+static int process_all_pdp_st(
+    rrd_t *rrd,
+    double interval,
+    double pre_int,
+    double post_int,
+    unsigned long elapsed_pdp_st,
+    rrd_value_t *pdp_new,
+    rrd_value_t *pdp_temp);
+
+static int process_pdp_st(
+    rrd_t *rrd,
+    unsigned long ds_idx,
+    double interval,
+    double pre_int,
+    double post_int,
+    long diff_pdp_st,
+    rrd_value_t *pdp_new,
+    rrd_value_t *pdp_temp);
+
+static int update_all_cdp_prep(
+    rrd_t *rrd,
+    unsigned long *rra_step_cnt,
+    unsigned long rra_begin,
+    rrd_file_t *rrd_file,
+    unsigned long elapsed_pdp_st,
+    unsigned long proc_pdp_cnt,
+    rrd_value_t **last_seasonal_coef,
+    rrd_value_t **seasonal_coef,
+    rrd_value_t *pdp_temp,
+    unsigned long *rra_current,
+    unsigned long *skip_update,
+    int *schedule_smooth);
+
+static int do_schedule_smooth(
+    rrd_t *rrd,
+    unsigned long rra_idx,
+    unsigned long elapsed_pdp_st);
+
+static int update_cdp_prep(
+    rrd_t *rrd,
+    unsigned long elapsed_pdp_st,
+    unsigned long start_pdp_offset,
+    unsigned long *rra_step_cnt,
+    int rra_idx,
+    rrd_value_t *pdp_temp,
+    rrd_value_t *last_seasonal_coef,
+    rrd_value_t *seasonal_coef,
+    int current_cf);
+
+static void update_cdp(
+    unival *scratch,
+    int current_cf,
+    rrd_value_t pdp_temp_val,
+    unsigned long rra_step_cnt,
+    unsigned long elapsed_pdp_st,
+    unsigned long start_pdp_offset,
+    unsigned long pdp_cnt,
+    rrd_value_t xff,
+    int i,
+    int ii);
+
+static void initialize_cdp_val(
+    unival *scratch,
+    int current_cf,
+    rrd_value_t pdp_temp_val,
+    unsigned long elapsed_pdp_st,
+    unsigned long start_pdp_offset,
+    unsigned long pdp_cnt);
+
+static void reset_cdp(
+    rrd_t *rrd,
+    unsigned long elapsed_pdp_st,
+    rrd_value_t *pdp_temp,
+    rrd_value_t *last_seasonal_coef,
+    rrd_value_t *seasonal_coef,
+    int rra_idx,
+    int ds_idx,
+    int cdp_idx,
+    enum cf_en current_cf);
+
+static rrd_value_t initialize_average_carry_over(
+    rrd_value_t pdp_temp_val,
+    unsigned long elapsed_pdp_st,
+    unsigned long start_pdp_offset,
+    unsigned long pdp_cnt);
+
+static rrd_value_t calculate_cdp_val(
+    rrd_value_t cdp_val,
+    rrd_value_t pdp_temp_val,
+    unsigned long elapsed_pdp_st,
+    int current_cf,
+    int i,
+    int ii);
+
+static int update_aberrant_cdps(
+    rrd_t *rrd,
+    rrd_file_t *rrd_file,
+    unsigned long rra_begin,
+    unsigned long *rra_current,
+    unsigned long elapsed_pdp_st,
+    rrd_value_t *pdp_temp,
+    rrd_value_t **seasonal_coef);
+
+static int write_to_rras(
+    rrd_t *rrd,
+    rrd_file_t *rrd_file,
+    unsigned long *rra_step_cnt,
+    unsigned long rra_begin,
+    unsigned long *rra_current,
+    time_t current_time,
+    unsigned long *skip_update,
+    info_t **pcdp_summary);
+
+static int write_RRA_row(
+    rrd_file_t *rrd_file,
+    rrd_t *rrd,
+    unsigned long rra_idx,
+    unsigned long *rra_current,
+    unsigned short CDP_scratch_idx,
+    info_t **pcdp_summary,
+    time_t rra_time);
+
+static int smooth_all_rras(
+    rrd_t *rrd,
+    rrd_file_t *rrd_file,
+    unsigned long rra_begin);
+
+#ifndef HAVE_MMAP
+static int write_changes_to_disk(
+    rrd_t *rrd,
+    rrd_file_t *rrd_file,
+    int version);
 #endif
 
 /*
- * normilize time as returned by gettimeofday. usec part must
+ * normalize time as returned by gettimeofday. usec part must
  * be always >= 0
  */
-static void normalize_time(struct timeval *t)
+static inline void normalize_time(
+    struct timeval *t)
 {
-       if(t->tv_usec < 0) {
-               t->tv_sec--;
-               t->tv_usec += 1000000L;
-       }
+    if (t->tv_usec < 0) {
+        t->tv_sec--;
+        t->tv_usec += 1e6L;
+    }
 }
 
-/* Local prototypes */
-int LockRRD(FILE *rrd_file);
-#ifdef HAVE_MMAP
-info_t *write_RRA_row (rrd_t *rrd, unsigned long rra_idx, 
-                                       unsigned long *rra_current,
-                                       unsigned short CDP_scratch_idx,
-#ifndef DEBUG
-FILE UNUSED(*rrd_file),
-#else
-FILE *rrd_file,
-#endif
-                                       info_t *pcdp_summary, time_t *rra_time, void *rrd_mmaped_file);
-#else
-info_t *write_RRA_row (rrd_t *rrd, unsigned long rra_idx, 
-                                       unsigned long *rra_current,
-                                       unsigned short CDP_scratch_idx, FILE *rrd_file,
-                                       info_t *pcdp_summary, time_t *rra_time);
-#endif
-int rrd_update_r(const char *filename, const char *tmplt, int argc, const char **argv);
-int _rrd_update(const char *filename, const char *tmplt, int argc, const char **argv, 
-                                       info_t*);
+/*
+ * Sets current_time and current_time_usec based on the current time.
+ * current_time_usec is set to 0 if the version number is 1 or 2.
+ */
+static inline void initialize_time(
+    time_t *current_time,
+    unsigned long *current_time_usec,
+    int version)
+{
+    struct timeval tmp_time;    /* used for time conversion */
 
-#define IFDNAN(X,Y) (isnan(X) ? (Y) : (X));
+    gettimeofday(&tmp_time, 0);
+    normalize_time(&tmp_time);
+    *current_time = tmp_time.tv_sec;
+    if (version >= 3) {
+        *current_time_usec = tmp_time.tv_usec;
+    } else {
+        *current_time_usec = 0;
+    }
+}
 
+#define IFDNAN(X,Y) (isnan(X) ? (Y) : (X));
 
-info_t *rrd_update_v(int argc, char **argv)
+info_t   *rrd_update_v(
+    int argc,
+    char **argv)
 {
-    char             *tmplt = NULL;          
-       info_t *result = NULL;
-       infoval rc;
-      rc.u_int = -1;
-    optind = 0; opterr = 0;  /* initialize getopt */
+    char     *tmplt = NULL;
+    info_t   *result = NULL;
+    infoval   rc;
+    struct option long_options[] = {
+        {"template", required_argument, 0, 't'},
+        {0, 0, 0, 0}
+    };
+
+    rc.u_int = -1;
+    optind = 0;
+    opterr = 0;         /* initialize getopt */
 
     while (1) {
-               static struct option long_options[] =
-                       {
-                               {"template",      required_argument, 0, 't'},
-                               {0,0,0,0}
-                       };
-               int option_index = 0;
-               int opt;
-               opt = getopt_long(argc, argv, "t:", 
-                                                 long_options, &option_index);
-               
-               if (opt == EOF)
-                       break;
-               
-               switch(opt) {
-               case 't':
-                       tmplt = optarg;
-                       break;
-               
-               case '?':
-                       rrd_set_error("unknown option '%s'",argv[optind-1]);
-                       goto end_tag;
-               }
+        int       option_index = 0;
+        int       opt;
+
+        opt = getopt_long(argc, argv, "t:", long_options, &option_index);
+
+        if (opt == EOF)
+            break;
+
+        switch (opt) {
+        case 't':
+            tmplt = optarg;
+            break;
+
+        case '?':
+            rrd_set_error("unknown option '%s'", argv[optind - 1]);
+            goto end_tag;
+        }
     }
 
     /* need at least 2 arguments: filename, data. */
-    if (argc-optind < 2) {
-               rrd_set_error("Not enough arguments");
-               goto end_tag;
+    if (argc - optind < 2) {
+        rrd_set_error("Not enough arguments");
+        goto end_tag;
     }
     rc.u_int = 0;
-    result = info_push(NULL,sprintf_alloc("return_value"),RD_I_INT,rc);
-       rc.u_int = _rrd_update(argv[optind], tmplt,
-                     argc - optind - 1, (const char **)(argv + optind + 1), result);
+    result = info_push(NULL, sprintf_alloc("return_value"), RD_I_INT, rc);
+    rc.u_int = _rrd_update(argv[optind], tmplt,
+                           argc - optind - 1,
+                           (const char **) (argv + optind + 1), result);
     result->value.u_int = rc.u_int;
-end_tag:
+  end_tag:
     return result;
 }
 
-int
-rrd_update(int argc, char **argv)
+int rrd_update(
+    int argc,
+    char **argv)
 {
-    char             *tmplt = NULL;          
-    int rc;
-    optind = 0; opterr = 0;  /* initialize getopt */
+    struct option long_options[] = {
+        {"template", required_argument, 0, 't'},
+        {0, 0, 0, 0}
+    };
+    int       option_index = 0;
+    int       opt;
+    char     *tmplt = NULL;
+    int       rc = -1;
+
+    optind = 0;
+    opterr = 0;         /* initialize getopt */
 
     while (1) {
-               static struct option long_options[] =
-                       {
-                               {"template",      required_argument, 0, 't'},
-                               {0,0,0,0}
-                       };
-               int option_index = 0;
-               int opt;
-               opt = getopt_long(argc, argv, "t:", 
-                                                 long_options, &option_index);
-               
-               if (opt == EOF)
-                       break;
-               
-               switch(opt) {
-               case 't':
-                       tmplt = optarg;
-                       break;
-               
-               case '?':
-                       rrd_set_error("unknown option '%s'",argv[optind-1]);
-                       return(-1);
-               }
+        opt = getopt_long(argc, argv, "t:", long_options, &option_index);
+
+        if (opt == EOF)
+            break;
+
+        switch (opt) {
+        case 't':
+            tmplt = strdup(optarg);
+            break;
+
+        case '?':
+            rrd_set_error("unknown option '%s'", argv[optind - 1]);
+            goto out;
+        }
     }
 
     /* need at least 2 arguments: filename, data. */
-    if (argc-optind < 2) {
-               rrd_set_error("Not enough arguments");
-
-               return -1;
+    if (argc - optind < 2) {
+        rrd_set_error("Not enough arguments");
+        goto out;
     }
-       rc = rrd_update_r(argv[optind], tmplt,
-                     argc - optind - 1, (const char **)(argv + optind + 1));
+
+    rc = rrd_update_r(argv[optind], tmplt,
+                      argc - optind - 1, (const char **) (argv + optind + 1));
+  out:
+    free(tmplt);
     return rc;
 }
 
-int
-rrd_update_r(const char *filename, const char *tmplt, int argc, const char **argv)
+int rrd_update_r(
+    const char *filename,
+    const char *tmplt,
+    int argc,
+    const char **argv)
 {
-   return _rrd_update(filename, tmplt, argc, argv, NULL);
+    return _rrd_update(filename, tmplt, argc, argv, NULL);
 }
 
-int
-_rrd_update(const char *filename, const char *tmplt, int argc, const char **argv, 
-   info_t *pcdp_summary)
+int _rrd_update(
+    const char *filename,
+    const char *tmplt,
+    int argc,
+    const char **argv,
+    info_t *pcdp_summary)
 {
 
-    int              arg_i = 2;
-    short            j;
-    unsigned long    i,ii,iii=1;
-
-    unsigned long    rra_begin;          /* byte pointer to the rra
-                                         * area in the rrd file.  this
-                                         * pointer never changes value */
-    unsigned long    rra_start;          /* byte pointer to the rra
-                                         * area in the rrd file.  this
-                                         * pointer changes as each rrd is
-                                         * processed. */
-    unsigned long    rra_current;        /* byte pointer to the current write
-                                         * spot in the rrd file. */
-    unsigned long    rra_pos_tmp;        /* temporary byte pointer. */
-    double           interval,
-                     pre_int,post_int;   /* interval between this and
-                                         * the last run */
-    unsigned long    proc_pdp_st;        /* which pdp_st was the last
-                                         * to be processed */
-    unsigned long    occu_pdp_st;        /* when was the pdp_st
-                                         * before the last update
-                                         * time */
-    unsigned long    proc_pdp_age;       /* how old was the data in
-                                         * the pdp prep area when it
-                                         * was last updated */
-    unsigned long    occu_pdp_age;       /* how long ago was the last
-                                         * pdp_step time */
-    rrd_value_t      *pdp_new;           /* prepare the incoming data
-                                         * to be added the the
-                                         * existing entry */
-    rrd_value_t      *pdp_temp;          /* prepare the pdp values 
-                                         * to be added the the
-                                         * cdp values */
-
-    long             *tmpl_idx;          /* index representing the settings
-                                           transported by the tmplt index */
-    unsigned long    tmpl_cnt = 2;       /* time and data */
-
-    FILE             *rrd_file;
-    rrd_t            rrd;
-    time_t           current_time = 0;
-    time_t           rra_time = 0;      /* time of update for a RRA */
-    unsigned long    current_time_usec=0;/* microseconds part of current time */
-    struct timeval   tmp_time;           /* used for time conversion */
-
-    char             **updvals;
-    int              schedule_smooth = 0;
-       rrd_value_t      *seasonal_coef = NULL, *last_seasonal_coef = NULL;
-                                        /* a vector of future Holt-Winters seasonal coefs */
-    unsigned long    elapsed_pdp_st;
-                                        /* number of elapsed PDP steps since last update */
-    unsigned long    *rra_step_cnt = NULL;
-                                        /* number of rows to be updated in an RRA for a data
-                                         * value. */
-    unsigned long    start_pdp_offset;
-                                        /* number of PDP steps since the last update that
-                                         * are assigned to the first CDP to be generated
-                                         * since the last update. */
-    unsigned short   scratch_idx;
-                                        /* index into the CDP scratch array */
-    enum cf_en       current_cf;
-                                        /* numeric id of the current consolidation function */
-    rpnstack_t       rpnstack; /* used for COMPUTE DS */
-    int                     version;  /* rrd version */
-    char             *endptr; /* used in the conversion */
-
-#ifdef HAVE_MMAP
-    void            *rrd_mmaped_file;
-    unsigned long    rrd_filesize;
-#endif
-
-
-    rpnstack_init(&rpnstack);
+    int       arg_i = 2;
+
+    unsigned long rra_begin;    /* byte pointer to the rra
+                                 * area in the rrd file.  this
+                                 * pointer never changes value */
+    unsigned long rra_current;  /* byte pointer to the current write
+                                 * spot in the rrd file. */
+    rrd_value_t *pdp_new;   /* prepare the incoming data to be added 
+                             * to the existing entry */
+    rrd_value_t *pdp_temp;  /* prepare the pdp values to be added 
+                             * to the cdp values */
+
+    long     *tmpl_idx; /* index representing the settings
+                         * transported by the tmplt index */
+    unsigned long tmpl_cnt = 2; /* time and data */
+    rrd_t     rrd;
+    time_t    current_time = 0;
+    unsigned long current_time_usec = 0;    /* microseconds part of current time */
+    char    **updvals;
+    int       schedule_smooth = 0;
+
+    /* number of elapsed PDP steps since last update */
+    unsigned long *rra_step_cnt = NULL;
+
+    int       version;  /* rrd version */
+    rrd_file_t *rrd_file;
+    char     *arg_copy; /* for processing the argv */
+    unsigned long *skip_update; /* RRAs to advance but not write */
 
     /* need at least 1 arguments: data. */
     if (argc < 1) {
-       rrd_set_error("Not enough arguments");
-       return -1;
+        rrd_set_error("Not enough arguments");
+        goto err_out;
     }
-    
-    
 
-    if(rrd_open(filename,&rrd_file,&rrd, RRD_READWRITE)==-1){
-       return -1;
+    if ((rrd_file = rrd_open(filename, &rrd, RRD_READWRITE)) == NULL) {
+        goto err_free;
     }
+    /* We are now at the beginning of the rra's */
+    rra_current = rra_begin = rrd_file->header_len;
 
-    /* initialize time */
     version = atoi(rrd.stat_head->version);
-    gettimeofday(&tmp_time, 0);
-    normalize_time(&tmp_time);
-    current_time = tmp_time.tv_sec;
-    if(version >= 3) {
-        current_time_usec = tmp_time.tv_usec;
-    }
-    else {
-       current_time_usec = 0;
-    }
 
-    rra_current = rra_start = rra_begin = ftell(rrd_file);
-    /* This is defined in the ANSI C standard, section 7.9.5.3:
-
-        When a file is opened with udpate mode ('+' as the second
-        or third character in the ... list of mode argument
-        variables), both input and ouptut may be performed on the
-        associated stream.  However, ...  input may not be directly
-        followed by output without an intervening call to a file
-        positioning function, unless the input oepration encounters
-        end-of-file. */
-#ifdef HAVE_MMAP
-    fseek(rrd_file, 0, SEEK_END);
-    rrd_filesize = ftell(rrd_file);
-    fseek(rrd_file, rra_current, SEEK_SET);
-#else
-    fseek(rrd_file, 0, SEEK_CUR);
-#endif
+    initialize_time(&current_time, &current_time_usec, version);
 
-    
     /* get exclusive lock to whole file.
      * lock gets removed when we close the file.
      */
-    if (LockRRD(rrd_file) != 0) {
-      rrd_set_error("could not lock RRD");
-      rrd_free(&rrd);
-      fclose(rrd_file);
-      return(-1);   
-    } 
-
-    if((updvals = malloc( sizeof(char*) * (rrd.stat_head->ds_cnt+1)))==NULL){
-       rrd_set_error("allocating updvals pointer array");
-       rrd_free(&rrd);
-        fclose(rrd_file);
-       return(-1);
+    if (LockRRD(rrd_file->fd) != 0) {
+        rrd_set_error("could not lock RRD");
+        goto err_close;
     }
 
-    if ((pdp_temp = malloc(sizeof(rrd_value_t)
-                          *rrd.stat_head->ds_cnt))==NULL){
-       rrd_set_error("allocating pdp_temp ...");
-       free(updvals);
-       rrd_free(&rrd);
-        fclose(rrd_file);
-       return(-1);
+    if (allocate_data_structures(&rrd, &updvals,
+                                 &pdp_temp, tmplt, &tmpl_idx, &tmpl_cnt,
+                                 &rra_step_cnt, &skip_update,
+                                 &pdp_new) == -1) {
+        goto err_close;
     }
 
-    if ((tmpl_idx = malloc(sizeof(unsigned long)
-                          *(rrd.stat_head->ds_cnt+1)))==NULL){
-       rrd_set_error("allocating tmpl_idx ...");
-       free(pdp_temp);
-       free(updvals);
-       rrd_free(&rrd);
-        fclose(rrd_file);
-       return(-1);
+    /* loop through the arguments. */
+    for (arg_i = 0; arg_i < argc; arg_i++) {
+        if ((arg_copy = strdup(argv[arg_i])) == NULL) {
+            rrd_set_error("failed duplication argv entry");
+            break;
+        }
+        if (process_arg(arg_copy, &rrd, rrd_file, rra_begin, &rra_current,
+                        &current_time, &current_time_usec, pdp_temp, pdp_new,
+                        rra_step_cnt, updvals, tmpl_idx, tmpl_cnt,
+                        &pcdp_summary, version, skip_update,
+                        &schedule_smooth) == -1) {
+            free(arg_copy);
+            break;
+        }
+        free(arg_copy);
+    }
+
+    free(rra_step_cnt);
+
+    /* if we got here and if there is an error and if the file has not been
+     * written to, then close things up and return. */
+    if (rrd_test_error()) {
+        goto err_free_structures;
+    }
+#ifndef HAVE_MMAP
+    if (write_changes_to_disk(&rrd, rrd_file, version) == -1) {
+        goto err_free_structures;
+    }
+#endif
+
+    /* calling the smoothing code here guarantees at most one smoothing
+     * operation per rrd_update call. Unfortunately, it is possible with bulk
+     * updates, or a long-delayed update for smoothing to occur off-schedule.
+     * This really isn't critical except during the burn-in cycles. */
+    if (schedule_smooth) {
+        smooth_all_rras(&rrd, rrd_file, rra_begin);
+    }
+
+/*    rrd_dontneed(rrd_file,&rrd); */
+    rrd_free(&rrd);
+    rrd_close(rrd_file);
+
+    free(pdp_new);
+    free(tmpl_idx);
+    free(pdp_temp);
+    free(skip_update);
+    free(updvals);
+    return 0;
+
+  err_free_structures:
+    free(pdp_new);
+    free(tmpl_idx);
+    free(pdp_temp);
+    free(skip_update);
+    free(updvals);
+  err_close:
+    rrd_close(rrd_file);
+  err_free:
+    rrd_free(&rrd);
+  err_out:
+    return -1;
+}
+
+/*
+ * get exclusive lock to whole file.
+ * lock gets removed when we close the file
+ *
+ * returns 0 on success
+ */
+int LockRRD(
+    int in_file)
+{
+    int       rcstat;
+
+    {
+#if defined(_WIN32) && !defined(__CYGWIN__) && !defined(__CYGWIN32__)
+        struct _stat st;
+
+        if (_fstat(in_file, &st) == 0) {
+            rcstat = _locking(in_file, _LK_NBLCK, st.st_size);
+        } else {
+            rcstat = -1;
+        }
+#else
+        struct flock lock;
+
+        lock.l_type = F_WRLCK;  /* exclusive write lock */
+        lock.l_len = 0; /* whole file */
+        lock.l_start = 0;   /* start of file */
+        lock.l_whence = SEEK_SET;   /* end of file */
+
+        rcstat = fcntl(in_file, F_SETLK, &lock);
+#endif
+    }
+
+    return (rcstat);
+}
+
+/*
+ * Allocate some important arrays used, and initialize the template.
+ *
+ * When it returns, either all of the structures are allocated
+ * or none of them are.
+ *
+ * Returns 0 on success, -1 on error.
+ */
+static int allocate_data_structures(
+    rrd_t *rrd,
+    char ***updvals,
+    rrd_value_t **pdp_temp,
+    const char *tmplt,
+    long **tmpl_idx,
+    unsigned long *tmpl_cnt,
+    unsigned long **rra_step_cnt,
+    unsigned long **skip_update,
+    rrd_value_t **pdp_new)
+{
+    unsigned  i, ii;
+    if ((*updvals = (char **) malloc(sizeof(char *)
+                                     * (rrd->stat_head->ds_cnt + 1))) == NULL) {
+        rrd_set_error("allocating updvals pointer array.");
+        return -1;
     }
+    if ((*pdp_temp = (rrd_value_t *) malloc(sizeof(rrd_value_t)
+                                            * rrd->stat_head->ds_cnt)) ==
+        NULL) {
+        rrd_set_error("allocating pdp_temp.");
+        goto err_free_updvals;
+    }
+    if ((*skip_update = (unsigned long *) malloc(sizeof(unsigned long)
+                                                 *
+                                                 rrd->stat_head->rra_cnt)) ==
+        NULL) {
+        rrd_set_error("allocating skip_update.");
+        goto err_free_pdp_temp;
+    }
+    if ((*tmpl_idx = (long *) malloc(sizeof(unsigned long)
+                                     * (rrd->stat_head->ds_cnt + 1))) == NULL) {
+        rrd_set_error("allocating tmpl_idx.");
+        goto err_free_skip_update;
+    }
+    if ((*rra_step_cnt = (unsigned long *) malloc(sizeof(unsigned long)
+                                                  *
+                                                  (rrd->stat_head->
+                                                   rra_cnt))) == NULL) {
+        rrd_set_error("allocating rra_step_cnt.");
+        goto err_free_tmpl_idx;
+    }
+
     /* initialize tmplt redirector */
     /* default config example (assume DS 1 is a CDEF DS)
        tmpl_idx[0] -> 0; (time)
        tmpl_idx[1] -> 1; (DS 0)
        tmpl_idx[2] -> 3; (DS 2)
        tmpl_idx[3] -> 4; (DS 3) */
-    tmpl_idx[0] = 0; /* time */
-    for (i = 1, ii = 1 ; i <= rrd.stat_head->ds_cnt ; i++) 
-       {
-          if (dst_conv(rrd.ds_def[i-1].dst) != DST_CDEF)
-             tmpl_idx[ii++]=i;
-       }
-    tmpl_cnt= ii;
-
-    if (tmplt) {
-       /* we should work on a writeable copy here */
-       char *dsname;
-       unsigned int tmpl_len;
-       char *tmplt_copy = strdup(tmplt);
-       dsname = tmplt_copy;
-       tmpl_cnt = 1; /* the first entry is the time */
-       tmpl_len = strlen(tmplt_copy);
-       for(i=0;i<=tmpl_len ;i++) {
-           if (tmplt_copy[i] == ':' || tmplt_copy[i] == '\0') {
-               tmplt_copy[i] = '\0';
-               if (tmpl_cnt>rrd.stat_head->ds_cnt){
-                   rrd_set_error("tmplt contains more DS definitions than RRD");
-                   free(updvals); free(pdp_temp);
-                   free(tmpl_idx); rrd_free(&rrd);
-                   fclose(rrd_file); return(-1);
-               }
-               if ((tmpl_idx[tmpl_cnt++] = ds_match(&rrd,dsname)) == -1){
-                   rrd_set_error("unknown DS name '%s'",dsname);
-                   free(updvals); free(pdp_temp);
-                   free(tmplt_copy);
-                   free(tmpl_idx); rrd_free(&rrd);
-                   fclose(rrd_file); return(-1);
-               } else {
-                 /* the first element is always the time */
-                 tmpl_idx[tmpl_cnt-1]++; 
-                 /* go to the next entry on the tmplt_copy */
-                 dsname = &tmplt_copy[i+1];
-                  /* fix the damage we did before */
-                  if (i<tmpl_len) {
-                     tmplt_copy[i]=':';
-                  } 
-
-               }
-           }       
-       }
-       free(tmplt_copy);
+    (*tmpl_idx)[0] = 0; /* time */
+    for (i = 1, ii = 1; i <= rrd->stat_head->ds_cnt; i++) {
+        if (dst_conv(rrd->ds_def[i - 1].dst) != DST_CDEF)
+            (*tmpl_idx)[ii++] = i;
     }
-    if ((pdp_new = malloc(sizeof(rrd_value_t)
-                         *rrd.stat_head->ds_cnt))==NULL){
-       rrd_set_error("allocating pdp_new ...");
-       free(updvals);
-       free(pdp_temp);
-       free(tmpl_idx);
-       rrd_free(&rrd);
-        fclose(rrd_file);
-       return(-1);
+    *tmpl_cnt = ii;
+
+    if (tmplt != NULL) {
+        if (parse_template(rrd, tmplt, tmpl_cnt, *tmpl_idx) == -1) {
+            goto err_free_rra_step_cnt;
+        }
     }
 
-#ifdef HAVE_MMAP
-    rrd_mmaped_file = mmap(0, 
-                       rrd_filesize, 
-                       PROT_READ | PROT_WRITE, 
-                       MAP_SHARED, 
-                       fileno(rrd_file), 
-                       0);
-    if (rrd_mmaped_file == MAP_FAILED) {
-        rrd_set_error("error mmapping file %s", filename);
-       free(updvals);
-       free(pdp_temp);
-       free(tmpl_idx);
-       rrd_free(&rrd);
-        fclose(rrd_file);
-       return(-1);
+    if ((*pdp_new = (rrd_value_t *) malloc(sizeof(rrd_value_t)
+                                           * rrd->stat_head->ds_cnt)) == NULL) {
+        rrd_set_error("allocating pdp_new.");
+        goto err_free_rra_step_cnt;
     }
-#ifdef USE_MADVISE
-    /* when we use mmaping we tell the kernel the mmap equivalent
-       of POSIX_FADV_RANDOM */
-    madvise(rrd_mmaped_file,rrd_filesize,MADV_RANDOM);
-#endif
-#endif
-    /* loop through the arguments. */
-    for(arg_i=0; arg_i<argc;arg_i++) {
-       char *stepper = strdup(argv[arg_i]);
-        char *step_start = stepper;
-       char *p;
-       char *parsetime_error = NULL;
-       enum {atstyle, normal} timesyntax;
-       struct rrd_time_value ds_tv;
-        if (stepper == NULL){
-                rrd_set_error("failed duplication argv entry");
-               free(step_start);
-                free(updvals);
-                free(pdp_temp);  
-                free(tmpl_idx);
-                rrd_free(&rrd);
-#ifdef HAVE_MMAP
-               munmap(rrd_mmaped_file, rrd_filesize);
-#endif
-                fclose(rrd_file);
-                return(-1);
-         }
-       /* initialize all ds input to unknown except the first one
-           which has always got to be set */
-       for(ii=1;ii<=rrd.stat_head->ds_cnt;ii++) updvals[ii] = "U";
-       updvals[0]=stepper;
-       /* separate all ds elements; first must be examined separately
-          due to alternate time syntax */
-       if ((p=strchr(stepper,'@'))!=NULL) {
-           timesyntax = atstyle;
-           *p = '\0';
-           stepper = p+1;
-       } else if ((p=strchr(stepper,':'))!=NULL) {
-           timesyntax = normal;
-           *p = '\0';
-           stepper = p+1;
-       } else {
-           rrd_set_error("expected timestamp not found in data source from %s",
-                         argv[arg_i]);
-           free(step_start);
-           break;
-       }
-       ii=1;
-       updvals[tmpl_idx[ii]] = stepper;
-       while (*stepper) {
-           if (*stepper == ':') {
-               *stepper = '\0';
-               ii++;
-               if (ii<tmpl_cnt){                   
-                   updvals[tmpl_idx[ii]] = stepper+1;
-               }
-           }
-           stepper++;
-       }
-
-       if (ii != tmpl_cnt-1) {
-           rrd_set_error("expected %lu data source readings (got %lu) from %s",
-                         tmpl_cnt-1, ii, argv[arg_i]);
-           free(step_start);
-           break;
-       }
-       
-        /* get the time from the reading ... handle N */
-       if (timesyntax == atstyle) {
-            if ((parsetime_error = parsetime(updvals[0], &ds_tv))) {
-                rrd_set_error("ds time: %s: %s", updvals[0], parsetime_error );
-               free(step_start);
-               break;
-           }
-           if (ds_tv.type == RELATIVE_TO_END_TIME ||
-               ds_tv.type == RELATIVE_TO_START_TIME) {
-               rrd_set_error("specifying time relative to the 'start' "
-                             "or 'end' makes no sense here: %s",
-                             updvals[0]);
-               free(step_start);
-               break;
-           }
-
-           current_time = mktime(&ds_tv.tm) + ds_tv.offset;
-           current_time_usec = 0; /* FIXME: how to handle usecs here ? */
-           
-       } else if (strcmp(updvals[0],"N")==0){
-           gettimeofday(&tmp_time, 0);
-           normalize_time(&tmp_time);
-           current_time = tmp_time.tv_sec;
-           current_time_usec = tmp_time.tv_usec;
-       } else {
-           double tmp;
-           tmp = strtod(updvals[0], 0);
-           current_time = floor(tmp);
-           current_time_usec = (long)((tmp-(double)current_time) * 1000000.0);
-       }
-       /* dont do any correction for old version RRDs */
-       if(version < 3) 
-           current_time_usec = 0;
-       
-       if(current_time < rrd.live_head->last_up || 
-         (current_time == rrd.live_head->last_up && 
-          (long)current_time_usec <= (long)rrd.live_head->last_up_usec)) {
-           rrd_set_error("illegal attempt to update using time %ld when "
-                         "last update time is %ld (minimum one second step)",
-                         current_time, rrd.live_head->last_up);
-           free(step_start);
-           break;
-       }
-       
-       
-       /* seek to the beginning of the rra's */
-       if (rra_current != rra_begin) {
+
+    return 0;
+
+  err_free_rra_step_cnt:
+    free(*rra_step_cnt);
+  err_free_tmpl_idx:
+    free(*tmpl_idx);
+  err_free_skip_update:
+    free(*skip_update);
+  err_free_pdp_temp:
+    free(*pdp_temp);
+  err_free_updvals:
+    free(*updvals);
+    return -1;
+}
+
+/*
+ * Parses tmplt and puts an ordered list of DS's into tmpl_idx.
+ *
+ * Returns 0 on success.
+ */
+static int parse_template(
+    rrd_t *rrd,
+    const char *tmplt,
+    unsigned long *tmpl_cnt,
+    long *tmpl_idx)
+{
+    char     *dsname, *tmplt_copy;
+    unsigned int tmpl_len, i;
+    int       ret = 0;
+
+    *tmpl_cnt = 1;      /* the first entry is the time */
+
+    /* we should work on a writeable copy here */
+    if ((tmplt_copy = strdup(tmplt)) == NULL) {
+        rrd_set_error("error copying tmplt '%s'", tmplt);
+        ret = -1;
+        goto out;
+    }
+
+    dsname = tmplt_copy;
+    tmpl_len = strlen(tmplt_copy);
+    for (i = 0; i <= tmpl_len; i++) {
+        if (tmplt_copy[i] == ':' || tmplt_copy[i] == '\0') {
+            tmplt_copy[i] = '\0';
+            if (*tmpl_cnt > rrd->stat_head->ds_cnt) {
+                rrd_set_error("tmplt contains more DS definitions than RRD");
+                ret = -1;
+                goto out_free_tmpl_copy;
+            }
+            if ((tmpl_idx[(*tmpl_cnt)++] = ds_match(rrd, dsname) + 1) == 0) {
+                rrd_set_error("unknown DS name '%s'", dsname);
+                ret = -1;
+                goto out_free_tmpl_copy;
+            }
+            /* go to the next entry on the tmplt_copy */
+            if (i < tmpl_len)
+                dsname = &tmplt_copy[i + 1];
+        }
+    }
+  out_free_tmpl_copy:
+    free(tmplt_copy);
+  out:
+    return ret;
+}
+
+/*
+ * Parse an update string, updates the primary data points (PDPs)
+ * and consolidated data points (CDPs), and writes changes to the RRAs.
+ *
+ * Returns 0 on success, -1 on error.
+ */
+static int process_arg(
+    char *step_start,
+    rrd_t *rrd,
+    rrd_file_t *rrd_file,
+    unsigned long rra_begin,
+    unsigned long *rra_current,
+    time_t *current_time,
+    unsigned long *current_time_usec,
+    rrd_value_t *pdp_temp,
+    rrd_value_t *pdp_new,
+    unsigned long *rra_step_cnt,
+    char **updvals,
+    long *tmpl_idx,
+    unsigned long tmpl_cnt,
+    info_t **pcdp_summary,
+    int version,
+    unsigned long *skip_update,
+    int *schedule_smooth)
+{
+    rrd_value_t *seasonal_coef = NULL, *last_seasonal_coef = NULL;
+
+    /* a vector of future Holt-Winters seasonal coefs */
+    unsigned long elapsed_pdp_st;
+
+    double    interval, pre_int, post_int;  /* interval between this and
+                                             * the last run */
+    unsigned long proc_pdp_cnt;
+    unsigned long rra_start;
+
+    if (parse_ds(rrd, updvals, tmpl_idx, step_start, tmpl_cnt,
+                 current_time, current_time_usec, version) == -1) {
+        return -1;
+    }
+    /* seek to the beginning of the rra's */
+    if (*rra_current != rra_begin) {
 #ifndef HAVE_MMAP
-           if(fseek(rrd_file, rra_begin, SEEK_SET) != 0) {
-               rrd_set_error("seek error in rrd");
-               free(step_start);
-               break;
-           }
+        if (rrd_seek(rrd_file, rra_begin, SEEK_SET) != 0) {
+            rrd_set_error("seek error in rrd");
+            return -1;
+        }
 #endif
-           rra_current = rra_begin;
-       }
-       rra_start = rra_begin;
-
-       /* when was the current pdp started */
-       proc_pdp_age = rrd.live_head->last_up % rrd.stat_head->pdp_step;
-       proc_pdp_st = rrd.live_head->last_up - proc_pdp_age;
-
-       /* when did the last pdp_st occur */
-       occu_pdp_age = current_time % rrd.stat_head->pdp_step;
-       occu_pdp_st = current_time - occu_pdp_age;
-
-       /* interval = current_time - rrd.live_head->last_up; */
-       interval    = (double)(current_time - rrd.live_head->last_up) 
-                   + (double)((long)current_time_usec - (long)rrd.live_head->last_up_usec)/1000000.0;
-
-       if (occu_pdp_st > proc_pdp_st){
-           /* OK we passed the pdp_st moment*/
-           pre_int =  (long)occu_pdp_st - rrd.live_head->last_up; /* how much of the input data
-                                                             * occurred before the latest
-                                                             * pdp_st moment*/
-           pre_int -= ((double)rrd.live_head->last_up_usec)/1000000.0; /* adjust usecs */
-           post_int = occu_pdp_age;                         /* how much after it */
-           post_int += ((double)current_time_usec)/1000000.0;  /* adjust usecs */
-       } else {
-           pre_int = interval;
-           post_int = 0;
-       }
+        *rra_current = rra_begin;
+    }
+    rra_start = rra_begin;
 
-#ifdef DEBUG
-       printf(
-              "proc_pdp_age %lu\t"
-              "proc_pdp_st %lu\t" 
-              "occu_pfp_age %lu\t" 
-              "occu_pdp_st %lu\t"
-              "int %lf\t"
-              "pre_int %lf\t"
-              "post_int %lf\n", proc_pdp_age, proc_pdp_st, 
-               occu_pdp_age, occu_pdp_st,
-              interval, pre_int, post_int);
-#endif
-    
-       /* process the data sources and update the pdp_prep 
-        * area accordingly */
-       for(i=0;i<rrd.stat_head->ds_cnt;i++){
-           enum dst_en dst_idx;
-           dst_idx= dst_conv(rrd.ds_def[i].dst);
-
-            /* make sure we do not build diffs with old last_ds values */
-           if(rrd.ds_def[i].par[DS_mrhb_cnt].u_cnt < interval) {
-               strncpy(rrd.pdp_prep[i].last_ds,"U",LAST_DS_LEN-1);
-               rrd.pdp_prep[i].last_ds[LAST_DS_LEN-1]='\0';
-           }
-
-           /* NOTE: DST_CDEF should never enter this if block, because
-             * updvals[i+1][0] is initialized to 'U'; unless the caller
-            * accidently specified a value for the DST_CDEF. To handle 
-             * this case, an extra check is required. */
-
-           if((updvals[i+1][0] != 'U') &&
-                  (dst_idx != DST_CDEF) &&
-              rrd.ds_def[i].par[DS_mrhb_cnt].u_cnt >= interval) {
-              double rate = DNAN;
-              /* the data source type defines how to process the data */
-               /* pdp_new contains rate * time ... eg the bytes
-                * transferred during the interval. Doing it this way saves
-                * a lot of math operations */
-               
-
-               switch(dst_idx){
-               case DST_COUNTER:
-               case DST_DERIVE:
-            for(ii=0;updvals[i+1][ii] != '\0';ii++){
-                 if((updvals[i+1][ii] < '0' || updvals[i+1][ii] > '9') && (ii != 0 && updvals[i+1][ii] != '-')){
-                      rrd_set_error("not a simple integer: '%s'",updvals[i+1]);
-                      break;
-                 }
-            }
-            if (rrd_test_error()){
-                   break;
+    interval = (double) (*current_time - rrd->live_head->last_up)
+        + (double) ((long) *current_time_usec -
+                    (long) rrd->live_head->last_up_usec) / 1e6f;
+
+    /* process the data sources and update the pdp_prep 
+     * area accordingly */
+    if (update_pdp_prep(rrd, updvals, pdp_new, interval) == -1) {
+        return -1;
+    }
+
+    elapsed_pdp_st = calculate_elapsed_steps(rrd,
+                                             *current_time,
+                                             *current_time_usec, interval,
+                                             &pre_int, &post_int,
+                                             &proc_pdp_cnt);
+
+    /* has a pdp_st moment occurred since the last run ? */
+    if (elapsed_pdp_st == 0) {
+        /* no we have not passed a pdp_st moment. therefore update is simple */
+        simple_update(rrd, interval, pdp_new);
+    } else {
+        /* an pdp_st has occurred. */
+        if (process_all_pdp_st(rrd, interval,
+                               pre_int, post_int,
+                               elapsed_pdp_st, pdp_new, pdp_temp) == -1) {
+            return -1;
+        }
+        if (update_all_cdp_prep(rrd, rra_step_cnt,
+                                rra_begin, rrd_file,
+                                elapsed_pdp_st,
+                                proc_pdp_cnt,
+                                &last_seasonal_coef,
+                                &seasonal_coef,
+                                pdp_temp, rra_current,
+                                skip_update, schedule_smooth) == -1) {
+            goto err_free_coefficients;
+        }
+        if (update_aberrant_cdps(rrd, rrd_file, rra_begin, rra_current,
+                                 elapsed_pdp_st, pdp_temp,
+                                 &seasonal_coef) == -1) {
+            goto err_free_coefficients;
+        }
+        if (write_to_rras(rrd, rrd_file, rra_step_cnt, rra_begin,
+                          rra_current, *current_time, skip_update,
+                          pcdp_summary) == -1) {
+            goto err_free_coefficients;
+        }
+    }                   /* endif a pdp_st has occurred */
+    rrd->live_head->last_up = *current_time;
+    rrd->live_head->last_up_usec = *current_time_usec;
+
+    free(seasonal_coef);
+    free(last_seasonal_coef);
+    return 0;
+
+  err_free_coefficients:
+    free(seasonal_coef);
+    free(last_seasonal_coef);
+    return -1;
+}
+
+/*
+ * Parse a DS string (time + colon-separated values), storing the
+ * results in current_time, current_time_usec, and updvals.
+ *
+ * Returns 0 on success, -1 on error.
+ */
+static int parse_ds(
+    rrd_t *rrd,
+    char **updvals,
+    long *tmpl_idx,
+    char *input,
+    unsigned long tmpl_cnt,
+    time_t *current_time,
+    unsigned long *current_time_usec,
+    int version)
+{
+    char     *p;
+    unsigned long i;
+    char      timesyntax;
+
+    updvals[0] = input;
+    /* initialize all ds input to unknown except the first one
+       which has always got to be set */
+    for (i = 1; i <= rrd->stat_head->ds_cnt; i++)
+        updvals[i] = "U";
+
+    /* separate all ds elements; first must be examined separately
+       due to alternate time syntax */
+    if ((p = strchr(input, '@')) != NULL) {
+        timesyntax = '@';
+    } else if ((p = strchr(input, ':')) != NULL) {
+        timesyntax = ':';
+    } else {
+        rrd_set_error("expected timestamp not found in data source from %s",
+                      input);
+        return -1;
+    }
+    *p = '\0';
+    i = 1;
+    updvals[tmpl_idx[i++]] = p + 1;
+    while (*(++p)) {
+        if (*p == ':') {
+            *p = '\0';
+            if (i < tmpl_cnt) {
+                updvals[tmpl_idx[i++]] = p + 1;
             }
-                   if(rrd.pdp_prep[i].last_ds[0] != 'U'){
-                      pdp_new[i]= rrd_diff(updvals[i+1],rrd.pdp_prep[i].last_ds);
-                      if(dst_idx == DST_COUNTER) {
-                         /* simple overflow catcher suggested by Andres Kroonmaa */
-                         /* this will fail terribly for non 32 or 64 bit counters ... */
-                         /* are there any others in SNMP land ? */
-                         if (pdp_new[i] < (double)0.0 ) 
-                           pdp_new[i] += (double)4294967296.0 ;  /* 2^32 */
-                         if (pdp_new[i] < (double)0.0 ) 
-                           pdp_new[i] += (double)18446744069414584320.0; /* 2^64-2^32 */;
-                      }
-                      rate = pdp_new[i] / interval;
-                   }
-                  else {
-                    pdp_new[i]= DNAN;          
-                  }
-                  break;
-               case DST_ABSOLUTE:
-                    errno = 0;
-                    pdp_new[i] = strtod(updvals[i+1],&endptr);
-                    if (errno > 0){
-                        rrd_set_error("converting  '%s' to float: %s",updvals[i+1],rrd_strerror(errno));
-                        break;
-                    };
-                    if (endptr[0] != '\0'){
-                        rrd_set_error("conversion of '%s' to float not complete: tail '%s'",updvals[i+1],endptr);
-                        break;
+        }
+    }
+
+    if (i != tmpl_cnt) {
+        rrd_set_error("expected %lu data source readings (got %lu) from %s",
+                      tmpl_cnt - 1, i, input);
+        return -1;
+    }
+
+    if (get_time_from_reading(rrd, timesyntax, updvals,
+                              current_time, current_time_usec,
+                              version) == -1) {
+        return -1;
+    }
+    return 0;
+}
+
+/*
+ * Parse the time in a DS string, store it in current_time and 
+ * current_time_usec and verify that it's later than the last
+ * update for this DS.
+ *
+ * Returns 0 on success, -1 on error.
+ */
+static int get_time_from_reading(
+    rrd_t *rrd,
+    char timesyntax,
+    char **updvals,
+    time_t *current_time,
+    unsigned long *current_time_usec,
+    int version)
+{
+    double    tmp;
+    char     *parsetime_error = NULL;
+    char     *old_locale;
+    struct rrd_time_value ds_tv;
+    struct timeval tmp_time;    /* used for time conversion */
+
+    /* get the time from the reading ... handle N */
+    if (timesyntax == '@') {    /* at-style */
+        if ((parsetime_error = parsetime(updvals[0], &ds_tv))) {
+            rrd_set_error("ds time: %s: %s", updvals[0], parsetime_error);
+            return -1;
+        }
+        if (ds_tv.type == RELATIVE_TO_END_TIME ||
+            ds_tv.type == RELATIVE_TO_START_TIME) {
+            rrd_set_error("specifying time relative to the 'start' "
+                          "or 'end' makes no sense here: %s", updvals[0]);
+            return -1;
+        }
+        *current_time = mktime(&ds_tv.tm) +ds_tv.offset;
+        *current_time_usec = 0; /* FIXME: how to handle usecs here ? */
+    } else if (strcmp(updvals[0], "N") == 0) {
+        gettimeofday(&tmp_time, 0);
+        normalize_time(&tmp_time);
+        *current_time = tmp_time.tv_sec;
+        *current_time_usec = tmp_time.tv_usec;
+    } else {
+        old_locale = setlocale(LC_NUMERIC, "C");
+        tmp = strtod(updvals[0], 0);
+        setlocale(LC_NUMERIC, old_locale);
+        *current_time = floor(tmp);
+        *current_time_usec = (long) ((tmp - (double) *current_time) * 1e6f);
+    }
+    /* dont do any correction for old version RRDs */
+    if (version < 3)
+        *current_time_usec = 0;
+
+    if (*current_time < rrd->live_head->last_up ||
+        (*current_time == rrd->live_head->last_up &&
+         (long) *current_time_usec <= (long) rrd->live_head->last_up_usec)) {
+        rrd_set_error("illegal attempt to update using time %ld when "
+                      "last update time is %ld (minimum one second step)",
+                      *current_time, rrd->live_head->last_up);
+        return -1;
+    }
+    return 0;
+}
+
+/*
+ * Update pdp_new by interpreting the updvals according to the DS type
+ * (COUNTER, GAUGE, etc.).
+ *
+ * Returns 0 on success, -1 on error.
+ */
+static int update_pdp_prep(
+    rrd_t *rrd,
+    char **updvals,
+    rrd_value_t *pdp_new,
+    double interval)
+{
+    unsigned long ds_idx;
+    int       ii;
+    char     *endptr;   /* used in the conversion */
+    double    rate;
+    char     *old_locale;
+    enum dst_en dst_idx;
+
+    for (ds_idx = 0; ds_idx < rrd->stat_head->ds_cnt; ds_idx++) {
+        dst_idx = dst_conv(rrd->ds_def[ds_idx].dst);
+
+        /* make sure we do not build diffs with old last_ds values */
+        if (rrd->ds_def[ds_idx].par[DS_mrhb_cnt].u_cnt < interval) {
+            strncpy(rrd->pdp_prep[ds_idx].last_ds, "U", LAST_DS_LEN - 1);
+            rrd->pdp_prep[ds_idx].last_ds[LAST_DS_LEN - 1] = '\0';
+        }
+
+        /* NOTE: DST_CDEF should never enter this if block, because
+         * updvals[ds_idx+1][0] is initialized to 'U'; unless the caller
+         * accidently specified a value for the DST_CDEF. To handle this case,
+         * an extra check is required. */
+
+        if ((updvals[ds_idx + 1][0] != 'U') &&
+            (dst_idx != DST_CDEF) &&
+            rrd->ds_def[ds_idx].par[DS_mrhb_cnt].u_cnt >= interval) {
+            rate = DNAN;
+
+            /* pdp_new contains rate * time ... eg the bytes transferred during
+             * the interval. Doing it this way saves a lot of math operations
+             */
+            switch (dst_idx) {
+            case DST_COUNTER:
+            case DST_DERIVE:
+                for (ii = 0; updvals[ds_idx + 1][ii] != '\0'; ii++) {
+                    if ((updvals[ds_idx + 1][ii] < '0'
+                         || updvals[ds_idx + 1][ii] > '9')
+                        && (ii != 0 && updvals[ds_idx + 1][ii] != '-')) {
+                        rrd_set_error("not a simple integer: '%s'",
+                                      updvals[ds_idx + 1]);
+                        return -1;
                     }
-                   rate = pdp_new[i] / interval;                 
-                   break;
-               case DST_GAUGE:
-                    errno = 0;
-                    pdp_new[i] = strtod(updvals[i+1],&endptr) * interval;
-                    if (errno > 0){
-                        rrd_set_error("converting  '%s' to float: %s",updvals[i+1],rrd_strerror(errno));
-                        break;
-                    };
-                    if (endptr[0] != '\0'){
-                        rrd_set_error("conversion of '%s' to float not complete: tail '%s'",updvals[i+1],endptr);
-                        break;
+                }
+                if (rrd->pdp_prep[ds_idx].last_ds[0] != 'U') {
+                    pdp_new[ds_idx] =
+                        rrd_diff(updvals[ds_idx + 1],
+                                 rrd->pdp_prep[ds_idx].last_ds);
+                    if (dst_idx == DST_COUNTER) {
+                        /* simple overflow catcher. This will fail
+                         * terribly for non 32 or 64 bit counters
+                         * ... are there any others in SNMP land?
+                         */
+                        if (pdp_new[ds_idx] < (double) 0.0)
+                            pdp_new[ds_idx] += (double) 4294967296.0;   /* 2^32 */
+                        if (pdp_new[ds_idx] < (double) 0.0)
+                            pdp_new[ds_idx] += (double) 18446744069414584320.0; /* 2^64-2^32 */
                     }
-                   rate = pdp_new[i] / interval;                  
-                   break;
-               default:
-                   rrd_set_error("rrd contains unknown DS type : '%s'",
-                                 rrd.ds_def[i].dst);
-                   break;
-               }
-               /* break out of this for loop if the error string is set */
-               if (rrd_test_error()){
-                   break;
-               }
-              /* make sure pdp_temp is neither too large or too small
-               * if any of these occur it becomes unknown ...
-               * sorry folks ... */
-              if ( ! isnan(rate) && 
-                   (( ! isnan(rrd.ds_def[i].par[DS_max_val].u_val) &&
-                        rate > rrd.ds_def[i].par[DS_max_val].u_val ) ||     
-                   ( ! isnan(rrd.ds_def[i].par[DS_min_val].u_val) &&
-                       rate < rrd.ds_def[i].par[DS_min_val].u_val ))){
-                 pdp_new[i] = DNAN;
-              }               
-           } else {
-               /* no news is news all the same */
-               pdp_new[i] = DNAN;
-           }
-
-           
-           /* make a copy of the command line argument for the next run */
+                    rate = pdp_new[ds_idx] / interval;
+                } else {
+                    pdp_new[ds_idx] = DNAN;
+                }
+                break;
+            case DST_ABSOLUTE:
+                old_locale = setlocale(LC_NUMERIC, "C");
+                errno = 0;
+                pdp_new[ds_idx] = strtod(updvals[ds_idx + 1], &endptr);
+                setlocale(LC_NUMERIC, old_locale);
+                if (errno > 0) {
+                    rrd_set_error("converting '%s' to float: %s",
+                                  updvals[ds_idx + 1], rrd_strerror(errno));
+                    return -1;
+                };
+                if (endptr[0] != '\0') {
+                    rrd_set_error
+                        ("conversion of '%s' to float not complete: tail '%s'",
+                         updvals[ds_idx + 1], endptr);
+                    return -1;
+                }
+                rate = pdp_new[ds_idx] / interval;
+                break;
+            case DST_GAUGE:
+                errno = 0;
+                old_locale = setlocale(LC_NUMERIC, "C");
+                pdp_new[ds_idx] =
+                    strtod(updvals[ds_idx + 1], &endptr) * interval;
+                setlocale(LC_NUMERIC, old_locale);
+                if (errno) {
+                    rrd_set_error("converting '%s' to float: %s",
+                                  updvals[ds_idx + 1], rrd_strerror(errno));
+                    return -1;
+                };
+                if (endptr[0] != '\0') {
+                    rrd_set_error
+                        ("conversion of '%s' to float not complete: tail '%s'",
+                         updvals[ds_idx + 1], endptr);
+                    return -1;
+                }
+                rate = pdp_new[ds_idx] / interval;
+                break;
+            default:
+                rrd_set_error("rrd contains unknown DS type : '%s'",
+                              rrd->ds_def[ds_idx].dst);
+                return -1;
+            }
+            /* break out of this for loop if the error string is set */
+            if (rrd_test_error()) {
+                return -1;
+            }
+            /* make sure pdp_temp is neither too large or too small
+             * if any of these occur it becomes unknown ...
+             * sorry folks ... */
+            if (!isnan(rate) &&
+                ((!isnan(rrd->ds_def[ds_idx].par[DS_max_val].u_val) &&
+                  rate > rrd->ds_def[ds_idx].par[DS_max_val].u_val) ||
+                 (!isnan(rrd->ds_def[ds_idx].par[DS_min_val].u_val) &&
+                  rate < rrd->ds_def[ds_idx].par[DS_min_val].u_val))) {
+                pdp_new[ds_idx] = DNAN;
+            }
+        } else {
+            /* no news is news all the same */
+            pdp_new[ds_idx] = DNAN;
+        }
+
+
+        /* make a copy of the command line argument for the next run */
 #ifdef DEBUG
-           fprintf(stderr,
-                   "prep ds[%lu]\t"
-                   "last_arg '%s'\t"
-                   "this_arg '%s'\t"
-                   "pdp_new %10.2f\n",
-                   i,
-                   rrd.pdp_prep[i].last_ds,
-                   updvals[i+1], pdp_new[i]);
+        fprintf(stderr, "prep ds[%lu]\t"
+                "last_arg '%s'\t"
+                "this_arg '%s'\t"
+                "pdp_new %10.2f\n",
+                ds_idx, rrd->pdp_prep[ds_idx].last_ds, updvals[ds_idx + 1],
+                pdp_new[ds_idx]);
 #endif
-           strncpy(rrd.pdp_prep[i].last_ds, updvals[i+1],LAST_DS_LEN-1);
-           rrd.pdp_prep[i].last_ds[LAST_DS_LEN-1]='\0';
-       }
-       /* break out of the argument parsing loop if the error_string is set */
-       if (rrd_test_error()){
-           free(step_start);
-           break;
-       }
-       /* has a pdp_st moment occurred since the last run ? */
-
-       if (proc_pdp_st == occu_pdp_st){
-           /* no we have not passed a pdp_st moment. therefore update is simple */
-
-           for(i=0;i<rrd.stat_head->ds_cnt;i++){
-               if(isnan(pdp_new[i])) {            
-                   /* this is not realy accurate if we use subsecond data arival time
-                      should have thought of it when going subsecond resolution ...
-                       sorry next format change we will have it! */
-                   rrd.pdp_prep[i].scratch[PDP_unkn_sec_cnt].u_cnt += floor(interval);          
-               } else {
-                    if (isnan( rrd.pdp_prep[i].scratch[PDP_val].u_val )){
-                       rrd.pdp_prep[i].scratch[PDP_val].u_val= pdp_new[i];
-                    } else {
-                       rrd.pdp_prep[i].scratch[PDP_val].u_val+= pdp_new[i];
-                    }
-               }
+        strncpy(rrd->pdp_prep[ds_idx].last_ds, updvals[ds_idx + 1],
+                LAST_DS_LEN - 1);
+        rrd->pdp_prep[ds_idx].last_ds[LAST_DS_LEN - 1] = '\0';
+    }
+    return 0;
+}
+
+/*
+ * How many PDP steps have elapsed since the last update? Returns the answer,
+ * and stores the time between the last update and the last PDP in pre_time,
+ * and the time between the last PDP and the current time in post_int.
+ */
+static int calculate_elapsed_steps(
+    rrd_t *rrd,
+    unsigned long current_time,
+    unsigned long current_time_usec,
+    double interval,
+    double *pre_int,
+    double *post_int,
+    unsigned long *proc_pdp_cnt)
+{
+    unsigned long proc_pdp_st;  /* which pdp_st was the last to be processed */
+    unsigned long occu_pdp_st;  /* when was the pdp_st before the last update
+                                 * time */
+    unsigned long proc_pdp_age; /* how old was the data in the pdp prep area 
+                                 * when it was last updated */
+    unsigned long occu_pdp_age; /* how long ago was the last pdp_step time */
+
+    /* when was the current pdp started */
+    proc_pdp_age = rrd->live_head->last_up % rrd->stat_head->pdp_step;
+    proc_pdp_st = rrd->live_head->last_up - proc_pdp_age;
+
+    /* when did the last pdp_st occur */
+    occu_pdp_age = current_time % rrd->stat_head->pdp_step;
+    occu_pdp_st = current_time - occu_pdp_age;
+
+    if (occu_pdp_st > proc_pdp_st) {
+        /* OK we passed the pdp_st moment */
+        *pre_int = (long) occu_pdp_st - rrd->live_head->last_up;    /* how much of the input data
+                                                                     * occurred before the latest
+                                                                     * pdp_st moment*/
+        *pre_int -= ((double) rrd->live_head->last_up_usec) / 1e6f; /* adjust usecs */
+        *post_int = occu_pdp_age;   /* how much after it */
+        *post_int += ((double) current_time_usec) / 1e6f;   /* adjust usecs */
+    } else {
+        *pre_int = interval;
+        *post_int = 0;
+    }
+
+    *proc_pdp_cnt = proc_pdp_st / rrd->stat_head->pdp_step;
+
 #ifdef DEBUG
-               fprintf(stderr,
-                       "NO PDP  ds[%lu]\t"
-                       "value %10.2f\t"
-                       "unkn_sec %5lu\n",
-                       i,
-                       rrd.pdp_prep[i].scratch[PDP_val].u_val,
-                       rrd.pdp_prep[i].scratch[PDP_unkn_sec_cnt].u_cnt);
+    printf("proc_pdp_age %lu\t"
+           "proc_pdp_st %lu\t"
+           "occu_pfp_age %lu\t"
+           "occu_pdp_st %lu\t"
+           "int %lf\t"
+           "pre_int %lf\t"
+           "post_int %lf\n", proc_pdp_age, proc_pdp_st,
+           occu_pdp_age, occu_pdp_st, interval, *pre_int, *post_int);
 #endif
-           }   
-       } else {
-           /* an pdp_st has occurred. */
-
-           /* in pdp_prep[].scratch[PDP_val].u_val we have collected rate*seconds which 
-            * occurred up to the last run.        
-           pdp_new[] contains rate*seconds from the latest run.
-           pdp_temp[] will contain the rate for cdp */
-
-           for(i=0;i<rrd.stat_head->ds_cnt;i++){
-               /* update pdp_prep to the current pdp_st. */
-                double pre_unknown = 0.0;              
-               if(isnan(pdp_new[i]))
-                    /* a final bit of unkonwn to be added bevore calculation
-                    * we use a tempaorary variable for this so that we 
-                    * don't have to turn integer lines before using the value */                
-                   pre_unknown = pre_int;
-               else {
-                    if (isnan( rrd.pdp_prep[i].scratch[PDP_val].u_val )){
-                       rrd.pdp_prep[i].scratch[PDP_val].u_val=         pdp_new[i]/interval*pre_int;
-                    } else {
-                       rrd.pdp_prep[i].scratch[PDP_val].u_val+= pdp_new[i]/interval*pre_int;
-                    }
-                }
-               
-
-               /* if too much of the pdp_prep is unknown we dump it */
-               if ( 
-                   /* removed because this does not agree with the definition
-                      a heart beat can be unknown */
-                   /* (rrd.pdp_prep[i].scratch[PDP_unkn_sec_cnt].u_cnt 
-                    > rrd.ds_def[i].par[DS_mrhb_cnt].u_cnt) || */
-                   /* if the interval is larger thatn mrhb we get NAN */
-                   (interval > rrd.ds_def[i].par[DS_mrhb_cnt].u_cnt) ||
-                   (occu_pdp_st-proc_pdp_st <= 
-                    rrd.pdp_prep[i].scratch[PDP_unkn_sec_cnt].u_cnt)) {
-                   pdp_temp[i] = DNAN;
-               } else {
-                   pdp_temp[i] = rrd.pdp_prep[i].scratch[PDP_val].u_val
-                       / ((double)(occu_pdp_st - proc_pdp_st
-                                    - rrd.pdp_prep[i].scratch[PDP_unkn_sec_cnt].u_cnt)
-                            -pre_unknown);
-               }
-
-               /* process CDEF data sources; remember each CDEF DS can
-                * only reference other DS with a lower index number */
-           if (dst_conv(rrd.ds_def[i].dst) == DST_CDEF) {
-                  rpnp_t *rpnp;
-                  rpnp = rpn_expand((rpn_cdefds_t *) &(rrd.ds_def[i].par[DS_cdef]));
-                  /* substitue data values for OP_VARIABLE nodes */
-                  for (ii = 0; rpnp[ii].op != OP_END; ii++)
-                  {
-                         if (rpnp[ii].op == OP_VARIABLE) {
-                                rpnp[ii].op = OP_NUMBER;
-                                rpnp[ii].val =  pdp_temp[rpnp[ii].ptr];
-                         }
-                  }
-                  /* run the rpn calculator */
-                  if (rpn_calc(rpnp,&rpnstack,0,pdp_temp,i) == -1) {
-                         free(rpnp);
-                         break; /* exits the data sources pdp_temp loop */
-                  }
-               }
-        
-               /* make pdp_prep ready for the next run */
-               if(isnan(pdp_new[i])){
-                   /* this is not realy accurate if we use subsecond data arival time
-                      should have thought of it when going subsecond resolution ...
-                       sorry next format change we will have it! */
-                   rrd.pdp_prep[i].scratch[PDP_unkn_sec_cnt].u_cnt = floor(post_int);
-                   rrd.pdp_prep[i].scratch[PDP_val].u_val = DNAN;
-               } else {
-                   rrd.pdp_prep[i].scratch[PDP_unkn_sec_cnt].u_cnt = 0;
-                   rrd.pdp_prep[i].scratch[PDP_val].u_val = 
-                       pdp_new[i]/interval*post_int;
-               }
 
+    /* compute the number of elapsed pdp_st moments */
+    return (occu_pdp_st - proc_pdp_st) / rrd->stat_head->pdp_step;
+}
+
+/*
+ * Increment the PDP values by the values in pdp_new, or else initialize them.
+ */
+static void simple_update(
+    rrd_t *rrd,
+    double interval,
+    rrd_value_t *pdp_new)
+{
+    int       i;
+
+    for (i = 0; i < (signed) rrd->stat_head->ds_cnt; i++) {
+        if (isnan(pdp_new[i])) {
+            /* this is not really accurate if we use subsecond data arrival time
+               should have thought of it when going subsecond resolution ...
+               sorry next format change we will have it! */
+            rrd->pdp_prep[i].scratch[PDP_unkn_sec_cnt].u_cnt +=
+                floor(interval);
+        } else {
+            if (isnan(rrd->pdp_prep[i].scratch[PDP_val].u_val)) {
+                rrd->pdp_prep[i].scratch[PDP_val].u_val = pdp_new[i];
+            } else {
+                rrd->pdp_prep[i].scratch[PDP_val].u_val += pdp_new[i];
+            }
+        }
 #ifdef DEBUG
-               fprintf(stderr,
-                       "PDP UPD ds[%lu]\t"
-                       "pdp_temp %10.2f\t"
-                       "new_prep %10.2f\t"
-                       "new_unkn_sec %5lu\n",
-                       i, pdp_temp[i],
-                       rrd.pdp_prep[i].scratch[PDP_val].u_val,
-                       rrd.pdp_prep[i].scratch[PDP_unkn_sec_cnt].u_cnt);
+        fprintf(stderr,
+                "NO PDP  ds[%i]\t"
+                "value %10.2f\t"
+                "unkn_sec %5lu\n",
+                i,
+                rrd->pdp_prep[i].scratch[PDP_val].u_val,
+                rrd->pdp_prep[i].scratch[PDP_unkn_sec_cnt].u_cnt);
 #endif
-           }
-
-               /* if there were errors during the last loop, bail out here */
-           if (rrd_test_error()){
-              free(step_start);
-              break;
-           }
+    }
+}
 
-               /* compute the number of elapsed pdp_st moments */
-               elapsed_pdp_st = (occu_pdp_st - proc_pdp_st) / rrd.stat_head -> pdp_step;
+/*
+ * Call process_pdp_st for each DS.
+ *
+ * Returns 0 on success, -1 on error.
+ */
+static int process_all_pdp_st(
+    rrd_t *rrd,
+    double interval,
+    double pre_int,
+    double post_int,
+    unsigned long elapsed_pdp_st,
+    rrd_value_t *pdp_new,
+    rrd_value_t *pdp_temp)
+{
+    unsigned long ds_idx;
+
+    /* in pdp_prep[].scratch[PDP_val].u_val we have collected
+       rate*seconds which occurred up to the last run.
+       pdp_new[] contains rate*seconds from the latest run.
+       pdp_temp[] will contain the rate for cdp */
+
+    for (ds_idx = 0; ds_idx < rrd->stat_head->ds_cnt; ds_idx++) {
+        if (process_pdp_st(rrd, ds_idx, interval, pre_int, post_int,
+                           elapsed_pdp_st * rrd->stat_head->pdp_step,
+                           pdp_new, pdp_temp) == -1) {
+            return -1;
+        }
 #ifdef DEBUG
-               fprintf(stderr,"elapsed PDP steps: %lu\n", elapsed_pdp_st);
+        fprintf(stderr, "PDP UPD ds[%lu]\t"
+                "elapsed_pdp_st %lu\t"
+                "pdp_temp %10.2f\t"
+                "new_prep %10.2f\t"
+                "new_unkn_sec %5lu\n",
+                ds_idx,
+                elapsed_pdp_st,
+                pdp_temp[ds_idx],
+                rrd->pdp_prep[ds_idx].scratch[PDP_val].u_val,
+                rrd->pdp_prep[ds_idx].scratch[PDP_unkn_sec_cnt].u_cnt);
 #endif
-               if (rra_step_cnt == NULL)
-               {
-                  rra_step_cnt = (unsigned long *) 
-                         malloc((rrd.stat_head->rra_cnt)* sizeof(unsigned long));
-               }
-
-           for(i = 0, rra_start = rra_begin;
-               i < rrd.stat_head->rra_cnt;
-           rra_start += rrd.rra_def[i].row_cnt * rrd.stat_head -> ds_cnt * sizeof(rrd_value_t),
-               i++)
-               {
-               current_cf = cf_conv(rrd.rra_def[i].cf_nam);
-               start_pdp_offset = rrd.rra_def[i].pdp_cnt -
-                  (proc_pdp_st / rrd.stat_head -> pdp_step) % rrd.rra_def[i].pdp_cnt;
+    }
+    return 0;
+}
+
+/*
+ * Process an update that occurs after one of the PDP moments.
+ * Increments the PDP value, sets NAN if time greater than the
+ * heartbeats have elapsed, processes CDEFs.
+ *
+ * Returns 0 on success, -1 on error.
+ */
+static int process_pdp_st(
+    rrd_t *rrd,
+    unsigned long ds_idx,
+    double interval,
+    double pre_int,
+    double post_int,
+    long diff_pdp_st,   /* number of seconds in full steps passed since last update */
+    rrd_value_t *pdp_new,
+    rrd_value_t *pdp_temp)
+{
+    int       i;
+
+    /* update pdp_prep to the current pdp_st. */
+    double    pre_unknown = 0.0;
+    unival   *scratch = rrd->pdp_prep[ds_idx].scratch;
+    unsigned long mrhb = rrd->ds_def[ds_idx].par[DS_mrhb_cnt].u_cnt;
+
+    rpnstack_t rpnstack;    /* used for COMPUTE DS */
+
+    rpnstack_init(&rpnstack);
+
+
+    if (isnan(pdp_new[ds_idx])) {
+        /* a final bit of unknown to be added before calculation
+           we use a temporary variable for this so that we
+           don't have to turn integer lines before using the value */
+        pre_unknown = pre_int;
+    } else {
+        if (isnan(scratch[PDP_val].u_val)) {
+            scratch[PDP_val].u_val = 0;
+        }
+        scratch[PDP_val].u_val += pdp_new[ds_idx] / interval * pre_int;
+    }
+
+    /* if too much of the pdp_prep is unknown we dump it */
+    /* if the interval is larger thatn mrhb we get NAN */
+    if ((interval > mrhb) ||
+        (rrd->stat_head->pdp_step / 2.0 <
+         (signed) scratch[PDP_unkn_sec_cnt].u_cnt)) {
+        pdp_temp[ds_idx] = DNAN;
+    } else {
+        pdp_temp[ds_idx] = scratch[PDP_val].u_val /
+            ((double) (diff_pdp_st - scratch[PDP_unkn_sec_cnt].u_cnt) -
+             pre_unknown);
+    }
+
+    /* process CDEF data sources; remember each CDEF DS can
+     * only reference other DS with a lower index number */
+    if (dst_conv(rrd->ds_def[ds_idx].dst) == DST_CDEF) {
+        rpnp_t   *rpnp;
+
+        rpnp =
+            rpn_expand((rpn_cdefds_t *) &(rrd->ds_def[ds_idx].par[DS_cdef]));
+        /* substitute data values for OP_VARIABLE nodes */
+        for (i = 0; rpnp[i].op != OP_END; i++) {
+            if (rpnp[i].op == OP_VARIABLE) {
+                rpnp[i].op = OP_NUMBER;
+                rpnp[i].val = pdp_temp[rpnp[i].ptr];
+            }
+        }
+        /* run the rpn calculator */
+        if (rpn_calc(rpnp, &rpnstack, 0, pdp_temp, ds_idx) == -1) {
+            free(rpnp);
+            rpnstack_free(&rpnstack);
+            return -1;
+        }
+    }
+
+    /* make pdp_prep ready for the next run */
+    if (isnan(pdp_new[ds_idx])) {
+        /* this is not realy accurate if we use subsecond data arival time
+           should have thought of it when going subsecond resolution ...
+           sorry next format change we will have it! */
+        scratch[PDP_unkn_sec_cnt].u_cnt = floor(post_int);
+        scratch[PDP_val].u_val = DNAN;
+    } else {
+        scratch[PDP_unkn_sec_cnt].u_cnt = 0;
+        scratch[PDP_val].u_val = pdp_new[ds_idx] / interval * post_int;
+    }
+    rpnstack_free(&rpnstack);
+    return 0;
+}
+
+/*
+ * Iterate over all the RRAs for a given DS and:
+ * 1. Decide whether to schedule a smooth later
+ * 2. Decide whether to skip updating SEASONAL and DEVSEASONAL
+ * 3. Update the CDP
+ *
+ * Returns 0 on success, -1 on error
+ */
+static int update_all_cdp_prep(
+    rrd_t *rrd,
+    unsigned long *rra_step_cnt,
+    unsigned long rra_begin,
+    rrd_file_t *rrd_file,
+    unsigned long elapsed_pdp_st,
+    unsigned long proc_pdp_cnt,
+    rrd_value_t **last_seasonal_coef,
+    rrd_value_t **seasonal_coef,
+    rrd_value_t *pdp_temp,
+    unsigned long *rra_current,
+    unsigned long *skip_update,
+    int *schedule_smooth)
+{
+    unsigned long rra_idx;
+
+    /* index into the CDP scratch array */
+    enum cf_en current_cf;
+    unsigned long rra_start;
+
+    /* number of rows to be updated in an RRA for a data value. */
+    unsigned long start_pdp_offset;
+
+    rra_start = rra_begin;
+    for (rra_idx = 0; rra_idx < rrd->stat_head->rra_cnt; rra_idx++) {
+        current_cf = cf_conv(rrd->rra_def[rra_idx].cf_nam);
+        start_pdp_offset =
+            rrd->rra_def[rra_idx].pdp_cnt -
+            proc_pdp_cnt % rrd->rra_def[rra_idx].pdp_cnt;
+        skip_update[rra_idx] = 0;
         if (start_pdp_offset <= elapsed_pdp_st) {
-           rra_step_cnt[i] = (elapsed_pdp_st - start_pdp_offset) / 
-                     rrd.rra_def[i].pdp_cnt + 1;
-           } else {
-                  rra_step_cnt[i] = 0;
-               }
-
-               if (current_cf == CF_SEASONAL || current_cf == CF_DEVSEASONAL) 
-               {
-                  /* If this is a bulk update, we need to skip ahead in the seasonal
-                       * arrays so that they will be correct for the next observed value;
-                       * note that for the bulk update itself, no update will occur to
-                       * DEVSEASONAL or SEASONAL; futhermore, HWPREDICT and DEVPREDICT will
-                       * be set to DNAN. */
-           if (rra_step_cnt[i] > 2) 
-                  {
-                         /* skip update by resetting rra_step_cnt[i],
-                          * note that this is not data source specific; this is due
-                          * to the bulk update, not a DNAN value for the specific data
-                          * source. */
-                         rra_step_cnt[i] = 0;
-              lookup_seasonal(&rrd,i,rra_start,rrd_file,elapsed_pdp_st, 
-                            &last_seasonal_coef);
-                     lookup_seasonal(&rrd,i,rra_start,rrd_file,elapsed_pdp_st + 1,
-                            &seasonal_coef);
-                  }
-               
-                 /* periodically run a smoother for seasonal effects */
-                 /* Need to use first cdp parameter buffer to track
-                  * burnin (burnin requires a specific smoothing schedule).
-                  * The CDP_init_seasonal parameter is really an RRA level,
-                  * not a data source within RRA level parameter, but the rra_def
-                  * is read only for rrd_update (not flushed to disk). */
-                 iii = i*(rrd.stat_head -> ds_cnt);
-                 if (rrd.cdp_prep[iii].scratch[CDP_init_seasonal].u_cnt 
-                         <= BURNIN_CYCLES)
-                 {
-                    if (rrd.rra_ptr[i].cur_row + elapsed_pdp_st 
-                                > rrd.rra_def[i].row_cnt - 1) {
-                          /* mark off one of the burnin cycles */
-                          ++(rrd.cdp_prep[iii].scratch[CDP_init_seasonal].u_cnt);
-                      schedule_smooth = 1;
-                        }  
-                 } else {
-                        /* someone has no doubt invented a trick to deal with this
-                         * wrap around, but at least this code is clear. */
-                        if (rrd.rra_def[i].par[RRA_seasonal_smooth_idx].u_cnt >
-                            rrd.rra_ptr[i].cur_row)
-                        {
-                                /* here elapsed_pdp_st = rra_step_cnt[i] because of 1-1
-                                 * mapping between PDP and CDP */
-                                if (rrd.rra_ptr[i].cur_row + elapsed_pdp_st
-                                       >= rrd.rra_def[i].par[RRA_seasonal_smooth_idx].u_cnt)
-                                {
+            rra_step_cnt[rra_idx] = (elapsed_pdp_st - start_pdp_offset) /
+                rrd->rra_def[rra_idx].pdp_cnt + 1;
+        } else {
+            rra_step_cnt[rra_idx] = 0;
+        }
+
+        if (current_cf == CF_SEASONAL || current_cf == CF_DEVSEASONAL) {
+            /* If this is a bulk update, we need to skip ahead in the seasonal arrays
+             * so that they will be correct for the next observed value; note that for
+             * the bulk update itself, no update will occur to DEVSEASONAL or SEASONAL;
+             * futhermore, HWPREDICT and DEVPREDICT will be set to DNAN. */
+            if (rra_step_cnt[rra_idx] > 1) {
+                skip_update[rra_idx] = 1;
+                lookup_seasonal(rrd, rra_idx, rra_start, rrd_file,
+                                elapsed_pdp_st, last_seasonal_coef);
+                lookup_seasonal(rrd, rra_idx, rra_start, rrd_file,
+                                elapsed_pdp_st + 1, seasonal_coef);
+            }
+            /* periodically run a smoother for seasonal effects */
+            if (do_schedule_smooth(rrd, rra_idx, elapsed_pdp_st)) {
 #ifdef DEBUG
-                                       fprintf(stderr,
-                                       "schedule_smooth 1: cur_row %lu, elapsed_pdp_st %lu, smooth idx %lu\n",
-                    rrd.rra_ptr[i].cur_row, elapsed_pdp_st, 
-                                       rrd.rra_def[i].par[RRA_seasonal_smooth_idx].u_cnt);
+                fprintf(stderr,
+                        "schedule_smooth: cur_row %lu, elapsed_pdp_st %lu, smooth idx %lu\n",
+                        rrd->rra_ptr[rra_idx].cur_row, elapsed_pdp_st,
+                        rrd->rra_def[rra_idx].par[RRA_seasonal_smooth_idx].
+                        u_cnt);
 #endif
-                                       schedule_smooth = 1;
-                                }
-             } else {
-                                /* can't rely on negative numbers because we are working with
-                                 * unsigned values */
-                                /* Don't need modulus here. If we've wrapped more than once, only
-                                 * one smooth is executed at the end. */
-                                if (rrd.rra_ptr[i].cur_row + elapsed_pdp_st >= rrd.rra_def[i].row_cnt
-                                       && rrd.rra_ptr[i].cur_row + elapsed_pdp_st - rrd.rra_def[i].row_cnt
-                                       >= rrd.rra_def[i].par[RRA_seasonal_smooth_idx].u_cnt)
-                                {
+                *schedule_smooth = 1;
+            }
+            *rra_current = rrd_tell(rrd_file);
+        }
+        if (rrd_test_error())
+            return -1;
+
+        if (update_cdp_prep
+            (rrd, elapsed_pdp_st, start_pdp_offset, rra_step_cnt, rra_idx,
+             pdp_temp, *last_seasonal_coef, *seasonal_coef,
+             current_cf) == -1) {
+            return -1;
+        }
+        rra_start +=
+            rrd->rra_def[rra_idx].row_cnt * rrd->stat_head->ds_cnt *
+            sizeof(rrd_value_t);
+    }
+    return 0;
+}
+
+/* 
+ * Are we due for a smooth? Also increments our position in the burn-in cycle.
+ */
+static int do_schedule_smooth(
+    rrd_t *rrd,
+    unsigned long rra_idx,
+    unsigned long elapsed_pdp_st)
+{
+    unsigned long cdp_idx = rra_idx * (rrd->stat_head->ds_cnt);
+    unsigned long cur_row = rrd->rra_ptr[rra_idx].cur_row;
+    unsigned long row_cnt = rrd->rra_def[rra_idx].row_cnt;
+    unsigned long seasonal_smooth_idx =
+        rrd->rra_def[rra_idx].par[RRA_seasonal_smooth_idx].u_cnt;
+    unsigned long *init_seasonal =
+        &(rrd->cdp_prep[cdp_idx].scratch[CDP_init_seasonal].u_cnt);
+
+    /* Need to use first cdp parameter buffer to track burnin (burnin requires
+     * a specific smoothing schedule).  The CDP_init_seasonal parameter is
+     * really an RRA level, not a data source within RRA level parameter, but
+     * the rra_def is read only for rrd_update (not flushed to disk). */
+    if (*init_seasonal > BURNIN_CYCLES) {
+        /* someone has no doubt invented a trick to deal with this wrap around,
+         * but at least this code is clear. */
+        if (seasonal_smooth_idx > cur_row) {
+            /* here elapsed_pdp_st = rra_step_cnt[rra_idx] because of 1-1 mapping
+             * between PDP and CDP */
+            return (cur_row + elapsed_pdp_st >= seasonal_smooth_idx);
+        }
+        /* can't rely on negative numbers because we are working with
+         * unsigned values */
+        return (cur_row + elapsed_pdp_st >= row_cnt
+                && cur_row + elapsed_pdp_st >= row_cnt + seasonal_smooth_idx);
+    }
+    /* mark off one of the burn-in cycles */
+    return (cur_row + elapsed_pdp_st >= row_cnt && ++(*init_seasonal));
+}
+
+/*
+ * For a given RRA, iterate over the data sources and call the appropriate
+ * consolidation function.
+ *
+ * Returns 0 on success, -1 on error.
+ */
+static int update_cdp_prep(
+    rrd_t *rrd,
+    unsigned long elapsed_pdp_st,
+    unsigned long start_pdp_offset,
+    unsigned long *rra_step_cnt,
+    int rra_idx,
+    rrd_value_t *pdp_temp,
+    rrd_value_t *last_seasonal_coef,
+    rrd_value_t *seasonal_coef,
+    int current_cf)
+{
+    unsigned long ds_idx, cdp_idx;
+
+    /* update CDP_PREP areas */
+    /* loop over data soures within each RRA */
+    for (ds_idx = 0; ds_idx < rrd->stat_head->ds_cnt; ds_idx++) {
+
+        cdp_idx = rra_idx * rrd->stat_head->ds_cnt + ds_idx;
+
+        if (rrd->rra_def[rra_idx].pdp_cnt > 1) {
+            update_cdp(rrd->cdp_prep[cdp_idx].scratch, current_cf,
+                       pdp_temp[ds_idx], rra_step_cnt[rra_idx],
+                       elapsed_pdp_st, start_pdp_offset,
+                       rrd->rra_def[rra_idx].pdp_cnt,
+                       rrd->rra_def[rra_idx].par[RRA_cdp_xff_val].u_val,
+                       rra_idx, ds_idx);
+        } else {
+            /* Nothing to consolidate if there's one PDP per CDP. However, if
+             * we've missed some PDPs, let's update null counters etc. */
+            if (elapsed_pdp_st > 2) {
+                reset_cdp(rrd, elapsed_pdp_st, pdp_temp, last_seasonal_coef,
+                          seasonal_coef, rra_idx, ds_idx, cdp_idx,
+                          current_cf);
+            }
+        }
+
+        if (rrd_test_error())
+            return -1;
+    }                   /* endif data sources loop */
+    return 0;
+}
+
+/*
+ * Given the new reading (pdp_temp_val), update or initialize the CDP value,
+ * primary value, secondary value, and # of unknowns.
+ */
+static void update_cdp(
+    unival *scratch,
+    int current_cf,
+    rrd_value_t pdp_temp_val,
+    unsigned long rra_step_cnt,
+    unsigned long elapsed_pdp_st,
+    unsigned long start_pdp_offset,
+    unsigned long pdp_cnt,
+    rrd_value_t xff,
+    int i,
+    int ii)
+{
+    /* shorthand variables */
+    rrd_value_t *cdp_val = &scratch[CDP_val].u_val;
+    rrd_value_t *cdp_primary_val = &scratch[CDP_primary_val].u_val;
+    rrd_value_t *cdp_secondary_val = &scratch[CDP_secondary_val].u_val;
+    unsigned long *cdp_unkn_pdp_cnt = &scratch[CDP_unkn_pdp_cnt].u_cnt;
+
+    if (rra_step_cnt) {
+        /* If we are in this block, as least 1 CDP value will be written to
+         * disk, this is the CDP_primary_val entry. If more than 1 value needs
+         * to be written, then the "fill in" value is the CDP_secondary_val
+         * entry. */
+        if (isnan(pdp_temp_val)) {
+            *cdp_unkn_pdp_cnt += start_pdp_offset;
+            *cdp_secondary_val = DNAN;
+        } else {
+            /* CDP_secondary value is the RRA "fill in" value for intermediary
+             * CDP data entries. No matter the CF, the value is the same because
+             * the average, max, min, and last of a list of identical values is
+             * the same, namely, the value itself. */
+            *cdp_secondary_val = pdp_temp_val;
+        }
+
+        if (*cdp_unkn_pdp_cnt > pdp_cnt * xff) {
+            *cdp_primary_val = DNAN;
+            if (current_cf == CF_AVERAGE) {
+                *cdp_val =
+                    initialize_average_carry_over(pdp_temp_val,
+                                                  elapsed_pdp_st,
+                                                  start_pdp_offset, pdp_cnt);
+            } else {
+                *cdp_val = pdp_temp_val;
+            }
+        } else {
+            initialize_cdp_val(scratch, current_cf, pdp_temp_val,
+                               elapsed_pdp_st, start_pdp_offset, pdp_cnt);
+        }               /* endif meets xff value requirement for a valid value */
+        /* initialize carry over CDP_unkn_pdp_cnt, this must after CDP_primary_val
+         * is set because CDP_unkn_pdp_cnt is required to compute that value. */
+        if (isnan(pdp_temp_val))
+            *cdp_unkn_pdp_cnt = (elapsed_pdp_st - start_pdp_offset) % pdp_cnt;
+        else
+            *cdp_unkn_pdp_cnt = 0;
+    } else {            /* rra_step_cnt[i]  == 0 */
+
 #ifdef DEBUG
-                                       fprintf(stderr,
-                                       "schedule_smooth 2: cur_row %lu, elapsed_pdp_st %lu, smooth idx %lu\n",
-                    rrd.rra_ptr[i].cur_row, elapsed_pdp_st, 
-                                       rrd.rra_def[i].par[RRA_seasonal_smooth_idx].u_cnt);
+        if (isnan(*cdp_val)) {
+            fprintf(stderr, "schedule CDP_val update, RRA %d DS %d, DNAN\n",
+                    i, ii);
+        } else {
+            fprintf(stderr, "schedule CDP_val update, RRA %d DS %d, %10.2f\n",
+                    i, ii, *cdp_val);
+        }
 #endif
-                                       schedule_smooth = 1;
-                                }
-                        }
-                 }
-
-             rra_current = ftell(rrd_file); 
-               } /* if cf is DEVSEASONAL or SEASONAL */
-
-        if (rrd_test_error()) break;
-
-                   /* update CDP_PREP areas */
-                   /* loop over data soures within each RRA */
-                   for(ii = 0;
-                       ii < rrd.stat_head->ds_cnt;
-                       ii++)
-                       {
-                       
-                       /* iii indexes the CDP prep area for this data source within the RRA */
-                       iii=i*rrd.stat_head->ds_cnt+ii;
-
-                       if (rrd.rra_def[i].pdp_cnt > 1) {
-                         
-                          if (rra_step_cnt[i] > 0) {
-                          /* If we are in this block, as least 1 CDP value will be written to
-                               * disk, this is the CDP_primary_val entry. If more than 1 value needs
-                               * to be written, then the "fill in" value is the CDP_secondary_val
-                               * entry. */
-                                 if (isnan(pdp_temp[ii]))
-                  {
-                                        rrd.cdp_prep[iii].scratch[CDP_unkn_pdp_cnt].u_cnt += start_pdp_offset;
-                                        rrd.cdp_prep[iii].scratch[CDP_secondary_val].u_val = DNAN;
-                                 } else {
-                                        /* CDP_secondary value is the RRA "fill in" value for intermediary
-                                         * CDP data entries. No matter the CF, the value is the same because
-                                         * the average, max, min, and last of a list of identical values is
-                                         * the same, namely, the value itself. */
-                                        rrd.cdp_prep[iii].scratch[CDP_secondary_val].u_val = pdp_temp[ii];
-                                 }
-                     
-                                 if (rrd.cdp_prep[iii].scratch[CDP_unkn_pdp_cnt].u_cnt
-                                     > rrd.rra_def[i].pdp_cnt*
-                                     rrd.rra_def[i].par[RRA_cdp_xff_val].u_val)
-                                 {
-                                        rrd.cdp_prep[iii].scratch[CDP_primary_val].u_val = DNAN;
-                                        /* initialize carry over */
-                                        if (current_cf == CF_AVERAGE) {
-                                                  if (isnan(pdp_temp[ii])) { 
-                                                         rrd.cdp_prep[iii].scratch[CDP_val].u_val = DNAN;
-                                                  } else {
-                                                         rrd.cdp_prep[iii].scratch[CDP_val].u_val = pdp_temp[ii] *
-                                                                ((elapsed_pdp_st - start_pdp_offset) % rrd.rra_def[i].pdp_cnt);
-                                                  }
-                                        } else {
-                                               rrd.cdp_prep[iii].scratch[CDP_val].u_val = pdp_temp[ii];
-                                        }
-                                 } else {
-                                        rrd_value_t cum_val, cur_val; 
-                                    switch (current_cf) {
-                                               case CF_AVERAGE:
-                                                 cum_val = IFDNAN(rrd.cdp_prep[iii].scratch[CDP_val].u_val, 0.0);
-                                                 cur_val = IFDNAN(pdp_temp[ii],0.0);
-                          rrd.cdp_prep[iii].scratch[CDP_primary_val].u_val =
-                                              (cum_val + cur_val * start_pdp_offset) /
-                                          (rrd.rra_def[i].pdp_cnt
-                                              -rrd.cdp_prep[iii].scratch[CDP_unkn_pdp_cnt].u_cnt);
-                                                  /* initialize carry over value */
-                                                  if (isnan(pdp_temp[ii])) { 
-                                                         rrd.cdp_prep[iii].scratch[CDP_val].u_val = DNAN;
-                                                  } else {
-                                                         rrd.cdp_prep[iii].scratch[CDP_val].u_val = pdp_temp[ii] *
-                                                                ((elapsed_pdp_st - start_pdp_offset) % rrd.rra_def[i].pdp_cnt);
-                                                  }
-                                                  break;
-                                               case CF_MAXIMUM:
-                                                 cum_val = IFDNAN(rrd.cdp_prep[iii].scratch[CDP_val].u_val, -DINF);
-                                                 cur_val = IFDNAN(pdp_temp[ii],-DINF);
+        if (isnan(pdp_temp_val)) {
+            *cdp_unkn_pdp_cnt += elapsed_pdp_st;
+        } else {
+            *cdp_val =
+                calculate_cdp_val(*cdp_val, pdp_temp_val, elapsed_pdp_st,
+                                  current_cf, i, ii);
+        }
+    }
+}
+
+/*
+ * Set the CDP_primary_val and CDP_val to the appropriate initial value based
+ * on the type of consolidation function.
+ */
+static void initialize_cdp_val(
+    unival *scratch,
+    int current_cf,
+    rrd_value_t pdp_temp_val,
+    unsigned long elapsed_pdp_st,
+    unsigned long start_pdp_offset,
+    unsigned long pdp_cnt)
+{
+    rrd_value_t cum_val, cur_val;
+
+    switch (current_cf) {
+    case CF_AVERAGE:
+        cum_val = IFDNAN(scratch[CDP_val].u_val, 0.0);
+        cur_val = IFDNAN(pdp_temp_val, 0.0);
+        scratch[CDP_primary_val].u_val =
+            (cum_val + cur_val * start_pdp_offset) /
+            (pdp_cnt - scratch[CDP_unkn_pdp_cnt].u_cnt);
+        scratch[CDP_val].u_val =
+            initialize_average_carry_over(pdp_temp_val, elapsed_pdp_st,
+                                          start_pdp_offset, pdp_cnt);
+        break;
+    case CF_MAXIMUM:
+        cum_val = IFDNAN(scratch[CDP_val].u_val, -DINF);
+        cur_val = IFDNAN(pdp_temp_val, -DINF);
+#if 0
 #ifdef DEBUG
-                                                 if (isnan(rrd.cdp_prep[iii].scratch[CDP_val].u_val) &&
-                                                         isnan(pdp_temp[ii])) {
-                                                    fprintf(stderr,
-                                                               "RRA %lu, DS %lu, both CDP_val and pdp_temp are DNAN!",
-                                                               i,ii);
-                                                        exit(-1);
-                                                 }
+        if (isnan(scratch[CDP_val].u_val) && isnan(pdp_temp)) {
+            fprintf(stderr,
+                    "RRA %lu, DS %lu, both CDP_val and pdp_temp are DNAN!",
+                    i, ii);
+            exit(-1);
+        }
 #endif
-                                                 if (cur_val > cum_val)
-                                                        rrd.cdp_prep[iii].scratch[CDP_primary_val].u_val = cur_val;
-                                                 else
-                                                        rrd.cdp_prep[iii].scratch[CDP_primary_val].u_val = cum_val;
-                                                 /* initialize carry over value */
-                                                 rrd.cdp_prep[iii].scratch[CDP_val].u_val = pdp_temp[ii];
-                                                 break;
-                                               case CF_MINIMUM:
-                                                 cum_val = IFDNAN(rrd.cdp_prep[iii].scratch[CDP_val].u_val, DINF);
-                                                 cur_val = IFDNAN(pdp_temp[ii],DINF);
-#ifdef DEBUG
-                                                 if (isnan(rrd.cdp_prep[iii].scratch[CDP_val].u_val) &&
-                                                         isnan(pdp_temp[ii])) {
-                                                    fprintf(stderr,
-                                                               "RRA %lu, DS %lu, both CDP_val and pdp_temp are DNAN!",
-                                                               i,ii);
-                                                        exit(-1);
-                                                 }
 #endif
-                                                 if (cur_val < cum_val)
-                                                        rrd.cdp_prep[iii].scratch[CDP_primary_val].u_val = cur_val;
-                                                 else
-                                                        rrd.cdp_prep[iii].scratch[CDP_primary_val].u_val = cum_val;
-                                                 /* initialize carry over value */
-                                                 rrd.cdp_prep[iii].scratch[CDP_val].u_val = pdp_temp[ii];
-                                                 break;
-                                               case CF_LAST:
-                                               default:
-                                                  rrd.cdp_prep[iii].scratch[CDP_primary_val].u_val = pdp_temp[ii];
-                                                  /* initialize carry over value */
-                                                  rrd.cdp_prep[iii].scratch[CDP_val].u_val = pdp_temp[ii];
-                                               break;
-                                        }
-                                 } /* endif meets xff value requirement for a valid value */
-                                 /* initialize carry over CDP_unkn_pdp_cnt, this must after CDP_primary_val
-                                  * is set because CDP_unkn_pdp_cnt is required to compute that value. */
-                                 if (isnan(pdp_temp[ii]))
-                                        rrd.cdp_prep[iii].scratch[CDP_unkn_pdp_cnt].u_cnt = 
-                                               (elapsed_pdp_st - start_pdp_offset) % rrd.rra_def[i].pdp_cnt;
-                                 else
-                                        rrd.cdp_prep[iii].scratch[CDP_unkn_pdp_cnt].u_cnt = 0;
-               } else  /* rra_step_cnt[i]  == 0 */
-                          {
+        if (cur_val > cum_val)
+            scratch[CDP_primary_val].u_val = cur_val;
+        else
+            scratch[CDP_primary_val].u_val = cum_val;
+        /* initialize carry over value */
+        scratch[CDP_val].u_val = pdp_temp_val;
+        break;
+    case CF_MINIMUM:
+        cum_val = IFDNAN(scratch[CDP_val].u_val, DINF);
+        cur_val = IFDNAN(pdp_temp_val, DINF);
+#if 0
 #ifdef DEBUG
-                                 if (isnan(rrd.cdp_prep[iii].scratch[CDP_val].u_val)) {
-                                 fprintf(stderr,"schedule CDP_val update, RRA %lu DS %lu, DNAN\n",
-                                        i,ii);
-                                 } else {
-                                 fprintf(stderr,"schedule CDP_val update, RRA %lu DS %lu, %10.2f\n",
-                                        i,ii,rrd.cdp_prep[iii].scratch[CDP_val].u_val);
-                                 }
+        if (isnan(scratch[CDP_val].u_val) && isnan(pdp_temp)) {
+            fprintf(stderr,
+                    "RRA %lu, DS %lu, both CDP_val and pdp_temp are DNAN!", i,
+                    ii);
+            exit(-1);
+        }
 #endif
-                                 if (isnan(pdp_temp[ii])) {
-                                rrd.cdp_prep[iii].scratch[CDP_unkn_pdp_cnt].u_cnt += elapsed_pdp_st;
-                                 } else if (isnan(rrd.cdp_prep[iii].scratch[CDP_val].u_val))
-                                 {
-                                        if (current_cf == CF_AVERAGE) {
-                                           rrd.cdp_prep[iii].scratch[CDP_val].u_val = pdp_temp[ii] *
-                                                  elapsed_pdp_st;
-                                        } else {
-                                           rrd.cdp_prep[iii].scratch[CDP_val].u_val = pdp_temp[ii];
-                                        }
-#ifdef DEBUG
-                                        fprintf(stderr,"Initialize CDP_val for RRA %lu DS %lu: %10.2f\n",
-                                           i,ii,rrd.cdp_prep[iii].scratch[CDP_val].u_val);
 #endif
-                                 } else {
-                                        switch (current_cf) {
-                                        case CF_AVERAGE:
-                                           rrd.cdp_prep[iii].scratch[CDP_val].u_val += pdp_temp[ii] *
-                                                  elapsed_pdp_st;
-                                               break;
-                                        case CF_MINIMUM:
-                                               if (pdp_temp[ii] < rrd.cdp_prep[iii].scratch[CDP_val].u_val)
-                                                  rrd.cdp_prep[iii].scratch[CDP_val].u_val = pdp_temp[ii];
-                                               break; 
-                                        case CF_MAXIMUM:
-                                               if (pdp_temp[ii] > rrd.cdp_prep[iii].scratch[CDP_val].u_val)
-                                                  rrd.cdp_prep[iii].scratch[CDP_val].u_val = pdp_temp[ii];
-                                               break; 
-                                        case CF_LAST:
-                                        default:
-                                               rrd.cdp_prep[iii].scratch[CDP_val].u_val = pdp_temp[ii];
-                                               break;
-                                        }
-                                 }
-                          }
-                       } else { /* rrd.rra_def[i].pdp_cnt == 1 */
-                          if (elapsed_pdp_st > 2)
-                          {
-                                  switch (current_cf) {
-                                  case CF_AVERAGE:
-                                  default:
-                                 rrd.cdp_prep[iii].scratch[CDP_primary_val].u_val=pdp_temp[ii];
-                                 rrd.cdp_prep[iii].scratch[CDP_secondary_val].u_val=pdp_temp[ii];
-                                         break;
-                   case CF_SEASONAL:
-                                  case CF_DEVSEASONAL:
-                                         /* need to update cached seasonal values, so they are consistent
-                                          * with the bulk update */
-                      /* WARNING: code relies on the fact that CDP_hw_last_seasonal and
-                                          * CDP_last_deviation are the same. */
-                      rrd.cdp_prep[iii].scratch[CDP_hw_last_seasonal].u_val =
-                                                last_seasonal_coef[ii];
-                                         rrd.cdp_prep[iii].scratch[CDP_hw_seasonal].u_val =
-                                                seasonal_coef[ii];
-                                         break;
-                   case CF_HWPREDICT:
-                                         /* need to update the null_count and last_null_count.
-                                          * even do this for non-DNAN pdp_temp because the
-                                          * algorithm is not learning from batch updates. */
-                                         rrd.cdp_prep[iii].scratch[CDP_null_count].u_cnt += 
-                                                elapsed_pdp_st;
-                                         rrd.cdp_prep[iii].scratch[CDP_last_null_count].u_cnt += 
-                                                elapsed_pdp_st - 1;
-                                         /* fall through */
-                                  case CF_DEVPREDICT:
-                                 rrd.cdp_prep[iii].scratch[CDP_primary_val].u_val = DNAN;
-                                 rrd.cdp_prep[iii].scratch[CDP_secondary_val].u_val = DNAN;
-                                         break;
-                   case CF_FAILURES:
-                                         /* do not count missed bulk values as failures */
-                                 rrd.cdp_prep[iii].scratch[CDP_primary_val].u_val = 0;
-                                 rrd.cdp_prep[iii].scratch[CDP_secondary_val].u_val = 0;
-                                         /* need to reset violations buffer.
-                                          * could do this more carefully, but for now, just
-                                          * assume a bulk update wipes away all violations. */
-                      erase_violations(&rrd, iii, i);
-                                         break;
-                                  }
-                          } 
-                       } /* endif rrd.rra_def[i].pdp_cnt == 1 */
-
-                       if (rrd_test_error()) break;
-
-                       } /* endif data sources loop */
-        } /* end RRA Loop */
-
-               /* this loop is only entered if elapsed_pdp_st < 3 */
-               for (j = elapsed_pdp_st, scratch_idx = CDP_primary_val; 
-                        j > 0 && j < 3; j--, scratch_idx = CDP_secondary_val)
-               {
-              for(i = 0, rra_start = rra_begin;
-                  i < rrd.stat_head->rra_cnt;
-              rra_start += rrd.rra_def[i].row_cnt * rrd.stat_head -> ds_cnt * sizeof(rrd_value_t),
-                  i++)
-                  {
-                         if (rrd.rra_def[i].pdp_cnt > 1) continue;
-
-                 current_cf = cf_conv(rrd.rra_def[i].cf_nam);
-                         if (current_cf == CF_SEASONAL || current_cf == CF_DEVSEASONAL)
-                         {
-                        lookup_seasonal(&rrd,i,rra_start,rrd_file,
-                                   elapsed_pdp_st + (scratch_idx == CDP_primary_val ? 1 : 2),
-                               &seasonal_coef);
-                 rra_current = ftell(rrd_file);
-                         }
-                         if (rrd_test_error()) break;
-                     /* loop over data soures within each RRA */
-                     for(ii = 0;
-                         ii < rrd.stat_head->ds_cnt;
-                         ii++)
-                         {
-                            update_aberrant_CF(&rrd,pdp_temp[ii],current_cf,
-                                       i*(rrd.stat_head->ds_cnt) + ii,i,ii,
-                                   scratch_idx, seasonal_coef);
-                         }
-           } /* end RRA Loop */
-                  if (rrd_test_error()) break;
-           } /* end elapsed_pdp_st loop */
-
-               if (rrd_test_error()) break;
-
-               /* Ready to write to disk */
-               /* Move sequentially through the file, writing one RRA at a time.
-                * Note this architecture divorces the computation of CDP with
-                * flushing updated RRA entries to disk. */
-           for(i = 0, rra_start = rra_begin;
-               i < rrd.stat_head->rra_cnt;
-           rra_start += rrd.rra_def[i].row_cnt * rrd.stat_head -> ds_cnt * sizeof(rrd_value_t),
-               i++) {
-               /* is th5Aere anything to write for this RRA? If not, continue. */
-        if (rra_step_cnt[i] == 0) continue;
-
-               /* write the first row */
+        if (cur_val < cum_val)
+            scratch[CDP_primary_val].u_val = cur_val;
+        else
+            scratch[CDP_primary_val].u_val = cum_val;
+        /* initialize carry over value */
+        scratch[CDP_val].u_val = pdp_temp_val;
+        break;
+    case CF_LAST:
+    default:
+        scratch[CDP_primary_val].u_val = pdp_temp_val;
+        /* initialize carry over value */
+        scratch[CDP_val].u_val = pdp_temp_val;
+        break;
+    }
+}
+
+/*
+ * Update the consolidation function for Holt-Winters functions as
+ * well as other functions that don't actually consolidate multiple
+ * PDPs.
+ */
+static void reset_cdp(
+    rrd_t *rrd,
+    unsigned long elapsed_pdp_st,
+    rrd_value_t *pdp_temp,
+    rrd_value_t *last_seasonal_coef,
+    rrd_value_t *seasonal_coef,
+    int rra_idx,
+    int ds_idx,
+    int cdp_idx,
+    enum cf_en current_cf)
+{
+    unival   *scratch = rrd->cdp_prep[cdp_idx].scratch;
+
+    switch (current_cf) {
+    case CF_AVERAGE:
+    default:
+        scratch[CDP_primary_val].u_val = pdp_temp[ds_idx];
+        scratch[CDP_secondary_val].u_val = pdp_temp[ds_idx];
+        break;
+    case CF_SEASONAL:
+    case CF_DEVSEASONAL:
+        /* need to update cached seasonal values, so they are consistent
+         * with the bulk update */
+        /* WARNING: code relies on the fact that CDP_hw_last_seasonal and
+         * CDP_last_deviation are the same. */
+        scratch[CDP_hw_last_seasonal].u_val = last_seasonal_coef[ds_idx];
+        scratch[CDP_hw_seasonal].u_val = seasonal_coef[ds_idx];
+        break;
+    case CF_HWPREDICT:
+    case CF_MHWPREDICT:
+        /* need to update the null_count and last_null_count.
+         * even do this for non-DNAN pdp_temp because the
+         * algorithm is not learning from batch updates. */
+        scratch[CDP_null_count].u_cnt += elapsed_pdp_st;
+        scratch[CDP_last_null_count].u_cnt += elapsed_pdp_st - 1;
+        /* fall through */
+    case CF_DEVPREDICT:
+        scratch[CDP_primary_val].u_val = DNAN;
+        scratch[CDP_secondary_val].u_val = DNAN;
+        break;
+    case CF_FAILURES:
+        /* do not count missed bulk values as failures */
+        scratch[CDP_primary_val].u_val = 0;
+        scratch[CDP_secondary_val].u_val = 0;
+        /* need to reset violations buffer.
+         * could do this more carefully, but for now, just
+         * assume a bulk update wipes away all violations. */
+        erase_violations(rrd, cdp_idx, rra_idx);
+        break;
+    }
+}
+
+static rrd_value_t initialize_average_carry_over(
+    rrd_value_t pdp_temp_val,
+    unsigned long elapsed_pdp_st,
+    unsigned long start_pdp_offset,
+    unsigned long pdp_cnt)
+{
+    /* initialize carry over value */
+    if (isnan(pdp_temp_val)) {
+        return DNAN;
+    }
+    return pdp_temp_val * ((elapsed_pdp_st - start_pdp_offset) % pdp_cnt);
+}
+
+/*
+ * Update or initialize a CDP value based on the consolidation
+ * function.
+ *
+ * Returns the new value.
+ */
+static rrd_value_t calculate_cdp_val(
+    rrd_value_t cdp_val,
+    rrd_value_t pdp_temp_val,
+    unsigned long elapsed_pdp_st,
+    int current_cf,
 #ifdef DEBUG
-        fprintf(stderr,"  -- RRA Preseek %ld\n",ftell(rrd_file));
+    int i,
+    int ii
+#else
+    int UNUSED(i),
+    int UNUSED(ii)
 #endif
-           rrd.rra_ptr[i].cur_row++;
-           if (rrd.rra_ptr[i].cur_row >= rrd.rra_def[i].row_cnt)
-                  rrd.rra_ptr[i].cur_row = 0; /* wrap around */
-               /* positition on the first row */
-               rra_pos_tmp = rra_start +
-                  (rrd.stat_head->ds_cnt)*(rrd.rra_ptr[i].cur_row)*sizeof(rrd_value_t);
-               if(rra_pos_tmp != rra_current) {
-#ifndef HAVE_MMAP
-                  if(fseek(rrd_file, rra_pos_tmp, SEEK_SET) != 0){
-                     rrd_set_error("seek error in rrd");
-                     break;
-                  }
+    )
+{
+    if (isnan(cdp_val)) {
+        if (current_cf == CF_AVERAGE) {
+            pdp_temp_val *= elapsed_pdp_st;
+        }
+#ifdef DEBUG
+        fprintf(stderr, "Initialize CDP_val for RRA %d DS %d: %10.2f\n",
+                i, ii, pdp_temp_val);
 #endif
-                  rra_current = rra_pos_tmp;
-               }
+        return pdp_temp_val;
+    }
+    if (current_cf == CF_AVERAGE)
+        return cdp_val + pdp_temp_val * elapsed_pdp_st;
+    if (current_cf == CF_MINIMUM)
+        return (pdp_temp_val < cdp_val) ? pdp_temp_val : cdp_val;
+    if (current_cf == CF_MAXIMUM)
+        return (pdp_temp_val > cdp_val) ? pdp_temp_val : cdp_val;
+
+    return pdp_temp_val;
+}
 
+/*
+ * For each RRA, update the seasonal values and then call update_aberrant_CF
+ * for each data source.
+ *
+ * Return 0 on success, -1 on error.
+ */
+static int update_aberrant_cdps(
+    rrd_t *rrd,
+    rrd_file_t *rrd_file,
+    unsigned long rra_begin,
+    unsigned long *rra_current,
+    unsigned long elapsed_pdp_st,
+    rrd_value_t *pdp_temp,
+    rrd_value_t **seasonal_coef)
+{
+    unsigned long rra_idx, ds_idx, j;
+
+    /* number of PDP steps since the last update that
+     * are assigned to the first CDP to be generated
+     * since the last update. */
+    unsigned short scratch_idx;
+    unsigned long rra_start;
+    enum cf_en current_cf;
+
+    /* this loop is only entered if elapsed_pdp_st < 3 */
+    for (j = elapsed_pdp_st, scratch_idx = CDP_primary_val;
+         j > 0 && j < 3; j--, scratch_idx = CDP_secondary_val) {
+        rra_start = rra_begin;
+        for (rra_idx = 0; rra_idx < rrd->stat_head->rra_cnt; rra_idx++) {
+            if (rrd->rra_def[rra_idx].pdp_cnt == 1) {
+                current_cf = cf_conv(rrd->rra_def[rra_idx].cf_nam);
+                if (current_cf == CF_SEASONAL || current_cf == CF_DEVSEASONAL) {
+                    if (scratch_idx == CDP_primary_val) {
+                        lookup_seasonal(rrd, rra_idx, rra_start, rrd_file,
+                                        elapsed_pdp_st + 1, seasonal_coef);
+                    } else {
+                        lookup_seasonal(rrd, rra_idx, rra_start, rrd_file,
+                                        elapsed_pdp_st + 2, seasonal_coef);
+                    }
+                    *rra_current = rrd_tell(rrd_file);
+                }
+                if (rrd_test_error())
+                    return -1;
+                /* loop over data soures within each RRA */
+                for (ds_idx = 0; ds_idx < rrd->stat_head->ds_cnt; ds_idx++) {
+                    update_aberrant_CF(rrd, pdp_temp[ds_idx], current_cf,
+                                       rra_idx * (rrd->stat_head->ds_cnt) +
+                                       ds_idx, rra_idx, ds_idx, scratch_idx,
+                                       *seasonal_coef);
+                }
+            }
+            rra_start += rrd->rra_def[rra_idx].row_cnt
+                * rrd->stat_head->ds_cnt * sizeof(rrd_value_t);
+        }
+    }
+    return 0;
+}
+
+/* 
+ * Move sequentially through the file, writing one RRA at a time.  Note this
+ * architecture divorces the computation of CDP with flushing updated RRA
+ * entries to disk.
+ *
+ * Return 0 on success, -1 on error.
+ */
+static int write_to_rras(
+    rrd_t *rrd,
+    rrd_file_t *rrd_file,
+    unsigned long *rra_step_cnt,
+    unsigned long rra_begin,
+    unsigned long *rra_current,
+    time_t current_time,
+    unsigned long *skip_update,
+    info_t **pcdp_summary)
+{
+    unsigned long rra_idx;
+    unsigned long rra_start;
+    unsigned long rra_pos_tmp;  /* temporary byte pointer. */
+    time_t    rra_time = 0; /* time of update for a RRA */
+
+    /* Ready to write to disk */
+    rra_start = rra_begin;
+    for (rra_idx = 0; rra_idx < rrd->stat_head->rra_cnt; rra_idx++) {
+        /* skip unless there's something to write */
+        if (rra_step_cnt[rra_idx]) {
+            /* write the first row */
 #ifdef DEBUG
-           fprintf(stderr,"  -- RRA Postseek %ld\n",ftell(rrd_file));
+            fprintf(stderr, "  -- RRA Preseek %ld\n", rrd_file->pos);
 #endif
-               scratch_idx = CDP_primary_val;
-               if (pcdp_summary != NULL)
-               {
-                  rra_time = (current_time - current_time 
-                  % (rrd.rra_def[i].pdp_cnt*rrd.stat_head->pdp_step))
-                  - ((rra_step_cnt[i]-1)*rrd.rra_def[i].pdp_cnt*rrd.stat_head->pdp_step);
-               }
-#ifdef HAVE_MMAP
-               pcdp_summary = write_RRA_row(&rrd, i, &rra_current, scratch_idx, rrd_file, 
-                  pcdp_summary, &rra_time, rrd_mmaped_file);
-#else
-               pcdp_summary = write_RRA_row(&rrd, i, &rra_current, scratch_idx, rrd_file, 
-                  pcdp_summary, &rra_time);
-#endif
-               if (rrd_test_error()) break;
-
-               /* write other rows of the bulk update, if any */
-               scratch_idx = CDP_secondary_val;
-               for ( ; rra_step_cnt[i] > 1; rra_step_cnt[i]--)
-               {
-                  if (++rrd.rra_ptr[i].cur_row == rrd.rra_def[i].row_cnt)
-                  {
+            rrd->rra_ptr[rra_idx].cur_row++;
+            if (rrd->rra_ptr[rra_idx].cur_row >=
+                rrd->rra_def[rra_idx].row_cnt)
+                rrd->rra_ptr[rra_idx].cur_row = 0;  /* wrap around */
+            /* position on the first row */
+            rra_pos_tmp = rra_start +
+                (rrd->stat_head->ds_cnt) * (rrd->rra_ptr[rra_idx].cur_row) *
+                sizeof(rrd_value_t);
+            if (rra_pos_tmp != *rra_current) {
+                if (rrd_seek(rrd_file, rra_pos_tmp, SEEK_SET) != 0) {
+                    rrd_set_error("seek error in rrd");
+                    return -1;
+                }
+                *rra_current = rra_pos_tmp;
+            }
 #ifdef DEBUG
-              fprintf(stderr,"Wraparound for RRA %s, %lu updates left\n",
-                         rrd.rra_def[i].cf_nam, rra_step_cnt[i] - 1);
+            fprintf(stderr, "  -- RRA Postseek %ld\n", rrd_file->pos);
 #endif
-                         /* wrap */
-                         rrd.rra_ptr[i].cur_row = 0;
-                         /* seek back to beginning of current rra */
-                     if (fseek(rrd_file, rra_start, SEEK_SET) != 0)
-                         {
-                        rrd_set_error("seek error in rrd");
-                        break;
-                         }
+            if (!skip_update[rra_idx]) {
+                if (*pcdp_summary != NULL) {
+                    rra_time = (current_time - current_time
+                                % (rrd->rra_def[rra_idx].pdp_cnt *
+                                   rrd->stat_head->pdp_step))
+                        -
+                        ((rra_step_cnt[rra_idx] -
+                          1) * rrd->rra_def[rra_idx].pdp_cnt *
+                         rrd->stat_head->pdp_step);
+                }
+                if (write_RRA_row
+                    (rrd_file, rrd, rra_idx, rra_current, CDP_primary_val,
+                     pcdp_summary, rra_time) == -1)
+                    return -1;
+            }
+
+            /* write other rows of the bulk update, if any */
+            for (; rra_step_cnt[rra_idx] > 1; rra_step_cnt[rra_idx]--) {
+                if (++rrd->rra_ptr[rra_idx].cur_row ==
+                    rrd->rra_def[rra_idx].row_cnt) {
 #ifdef DEBUG
-                 fprintf(stderr,"  -- Wraparound Postseek %ld\n",ftell(rrd_file));
+                    fprintf(stderr,
+                            "Wraparound for RRA %s, %lu updates left\n",
+                            rrd->rra_def[rra_idx].cf_nam,
+                            rra_step_cnt[rra_idx] - 1);
 #endif
-                         rra_current = rra_start;
-                  }
-                  if (pcdp_summary != NULL)
-                  {
-                     rra_time = (current_time - current_time 
-                     % (rrd.rra_def[i].pdp_cnt*rrd.stat_head->pdp_step))
-                     - ((rra_step_cnt[i]-2)*rrd.rra_def[i].pdp_cnt*rrd.stat_head->pdp_step);
-                  }
-#ifdef HAVE_MMAP
-                  pcdp_summary = write_RRA_row(&rrd, i, &rra_current, scratch_idx, rrd_file,
-                     pcdp_summary, &rra_time, rrd_mmaped_file);
-#else
-                  pcdp_summary = write_RRA_row(&rrd, i, &rra_current, scratch_idx, rrd_file,
-                     pcdp_summary, &rra_time);
+                    /* wrap */
+                    rrd->rra_ptr[rra_idx].cur_row = 0;
+                    /* seek back to beginning of current rra */
+                    if (rrd_seek(rrd_file, rra_start, SEEK_SET) != 0) {
+                        rrd_set_error("seek error in rrd");
+                        return -1;
+                    }
+#ifdef DEBUG
+                    fprintf(stderr, "  -- Wraparound Postseek %ld\n",
+                            rrd_file->pos);
 #endif
-               }
-               
-               if (rrd_test_error())
-                 break;
-               } /* RRA LOOP */
-
-           /* break out of the argument parsing loop if error_string is set */
-           if (rrd_test_error()){
-                  free(step_start);
-                  break;
-           } 
-           
-       } /* endif a pdp_st has occurred */ 
-       rrd.live_head->last_up = current_time;
-       rrd.live_head->last_up_usec = current_time_usec; 
-       free(step_start);
-    } /* function argument loop */
-
-    if (seasonal_coef != NULL) free(seasonal_coef);
-    if (last_seasonal_coef != NULL) free(last_seasonal_coef);
-       if (rra_step_cnt != NULL) free(rra_step_cnt);
-    rpnstack_free(&rpnstack);
-
-#ifdef HAVE_MMAP
-    if (munmap(rrd_mmaped_file, rrd_filesize) == -1) {
-            rrd_set_error("error writing(unmapping) file: %s", filename);
-    }
-#endif    
-    /* if we got here and if there is an error and if the file has not been
-     * written to, then close things up and return. */
-    if (rrd_test_error()) {
-       free(updvals);
-       free(tmpl_idx);
-       rrd_free(&rrd);
-       free(pdp_temp);
-       free(pdp_new);
-       fclose(rrd_file);
-       return(-1);
-    }
+                    *rra_current = rra_start;
+                }
+                if (!skip_update[rra_idx]) {
+                    if (*pcdp_summary != NULL) {
+                        rra_time = (current_time - current_time
+                                    % (rrd->rra_def[rra_idx].pdp_cnt *
+                                       rrd->stat_head->pdp_step))
+                            -
+                            ((rra_step_cnt[rra_idx] -
+                              2) * rrd->rra_def[rra_idx].pdp_cnt *
+                             rrd->stat_head->pdp_step);
+                    }
+                    if (write_RRA_row(rrd_file, rrd, rra_idx, rra_current,
+                                      CDP_secondary_val, pcdp_summary,
+                                      rra_time) == -1)
+                        return -1;
+                }
+            }
+        }
+        rra_start += rrd->rra_def[rra_idx].row_cnt * rrd->stat_head->ds_cnt *
+            sizeof(rrd_value_t);
+    }                   /* RRA LOOP */
 
-    /* aargh ... that was tough ... so many loops ... anyway, its done.
-     * we just need to write back the live header portion now*/
-
-    if (fseek(rrd_file, (sizeof(stat_head_t)
-                        + sizeof(ds_def_t)*rrd.stat_head->ds_cnt 
-                        + sizeof(rra_def_t)*rrd.stat_head->rra_cnt),
-             SEEK_SET) != 0) {
-       rrd_set_error("seek rrd for live header writeback");
-       free(updvals);
-       free(tmpl_idx);
-       rrd_free(&rrd);
-       free(pdp_temp);
-       free(pdp_new);
-       fclose(rrd_file);
-       return(-1);
-    }
+    return 0;
+}
 
-    if(version >= 3) {
-           if(fwrite( rrd.live_head,
-                      sizeof(live_head_t), 1, rrd_file) != 1){
-               rrd_set_error("fwrite live_head to rrd");
-               free(updvals);
-               rrd_free(&rrd);
-               free(tmpl_idx);
-               free(pdp_temp);
-               free(pdp_new);
-               fclose(rrd_file);
-               return(-1);
-           }
-    }
-    else {
-           if(fwrite( &rrd.live_head->last_up,
-                      sizeof(time_t), 1, rrd_file) != 1){
-               rrd_set_error("fwrite live_head to rrd");
-               free(updvals);
-               rrd_free(&rrd);
-               free(tmpl_idx);
-               free(pdp_temp);
-               free(pdp_new);
-               fclose(rrd_file);
-               return(-1);
-           }
-    }
-           
-
-    if(fwrite( rrd.pdp_prep,
-              sizeof(pdp_prep_t),
-              rrd.stat_head->ds_cnt, rrd_file) != rrd.stat_head->ds_cnt){
-       rrd_set_error("ftwrite pdp_prep to rrd");
-       free(updvals);
-       rrd_free(&rrd);
-       free(tmpl_idx);
-       free(pdp_temp);
-       free(pdp_new);
-       fclose(rrd_file);
-       return(-1);
-    }
+/*
+ * Write out one row of values (one value per DS) to the archive.
+ *
+ * Returns 0 on success, -1 on error.
+ */
+static int write_RRA_row(
+    rrd_file_t *rrd_file,
+    rrd_t *rrd,
+    unsigned long rra_idx,
+    unsigned long *rra_current,
+    unsigned short CDP_scratch_idx,
+    info_t **pcdp_summary,
+    time_t rra_time)
+{
+    unsigned long ds_idx, cdp_idx;
+    infoval   iv;
 
-    if(fwrite( rrd.cdp_prep,
-              sizeof(cdp_prep_t),
-              rrd.stat_head->rra_cnt *rrd.stat_head->ds_cnt, rrd_file) 
-       != rrd.stat_head->rra_cnt *rrd.stat_head->ds_cnt){
-
-       rrd_set_error("ftwrite cdp_prep to rrd");
-       free(updvals);
-       free(tmpl_idx);
-       rrd_free(&rrd);
-       free(pdp_temp);
-       free(pdp_new);
-       fclose(rrd_file);
-       return(-1);
+    for (ds_idx = 0; ds_idx < rrd->stat_head->ds_cnt; ds_idx++) {
+        /* compute the cdp index */
+        cdp_idx = rra_idx * (rrd->stat_head->ds_cnt) + ds_idx;
+#ifdef DEBUG
+        fprintf(stderr, "  -- RRA WRITE VALUE %e, at %ld CF:%s\n",
+                rrd->cdp_prep[cdp_idx].scratch[CDP_scratch_idx].u_val,
+                rrd_file->pos, rrd->rra_def[rra_idx].cf_nam);
+#endif
+        if (*pcdp_summary != NULL) {
+            iv.u_val = rrd->cdp_prep[cdp_idx].scratch[CDP_scratch_idx].u_val;
+            /* append info to the return hash */
+            *pcdp_summary = info_push(*pcdp_summary,
+                                      sprintf_alloc("[%d]RRA[%s][%lu]DS[%s]",
+                                                    rra_time,
+                                                    rrd->rra_def[rra_idx].
+                                                    cf_nam,
+                                                    rrd->rra_def[rra_idx].
+                                                    pdp_cnt,
+                                                    rrd->ds_def[ds_idx].
+                                                    ds_nam), RD_I_VAL, iv);
+        }
+        if (rrd_write(rrd_file,
+                      &(rrd->cdp_prep[cdp_idx].scratch[CDP_scratch_idx].
+                        u_val), sizeof(rrd_value_t)) != sizeof(rrd_value_t)) {
+            rrd_set_error("writing rrd: %s", rrd_strerror(errno));
+            return -1;
+        }
+        *rra_current += sizeof(rrd_value_t);
     }
+    return 0;
+}
 
-    if(fwrite( rrd.rra_ptr,
-              sizeof(rra_ptr_t), 
-              rrd.stat_head->rra_cnt,rrd_file) != rrd.stat_head->rra_cnt){
-       rrd_set_error("fwrite rra_ptr to rrd");
-       free(updvals);
-       free(tmpl_idx);
-       rrd_free(&rrd);
-       free(pdp_temp);
-       free(pdp_new);
-       fclose(rrd_file);
-       return(-1);
-    }
-    
-    /* OK now close the files and free the memory */
-    if(fclose(rrd_file) != 0){
-       rrd_set_error("closing rrd");
-       free(updvals);
-       free(tmpl_idx);
-       rrd_free(&rrd);
-       free(pdp_temp);
-       free(pdp_new);
-       return(-1);
-    }
+/*
+ * Call apply_smoother for all DEVSEASONAL and SEASONAL RRAs.
+ *
+ * Returns 0 on success, -1 otherwise
+ */
+static int smooth_all_rras(
+    rrd_t *rrd,
+    rrd_file_t *rrd_file,
+    unsigned long rra_begin)
+{
+    unsigned long rra_start = rra_begin;
+    unsigned long rra_idx;
 
-    /* calling the smoothing code here guarantees at most
-        * one smoothing operation per rrd_update call. Unfortunately,
-        * it is possible with bulk updates, or a long-delayed update
-        * for smoothing to occur off-schedule. This really isn't
-        * critical except during the burning cycles. */
-       if (schedule_smooth)
-       {
-         rrd_file = fopen(filename,"rb+");
-          
-
-         rra_start = rra_begin;
-         for (i = 0; i < rrd.stat_head -> rra_cnt; ++i)
-         {
-           if (cf_conv(rrd.rra_def[i].cf_nam) == CF_DEVSEASONAL ||
-               cf_conv(rrd.rra_def[i].cf_nam) == CF_SEASONAL)
-           {
+    for (rra_idx = 0; rra_idx < rrd->stat_head->rra_cnt; ++rra_idx) {
+        if (cf_conv(rrd->rra_def[rra_idx].cf_nam) == CF_DEVSEASONAL ||
+            cf_conv(rrd->rra_def[rra_idx].cf_nam) == CF_SEASONAL) {
 #ifdef DEBUG
-             fprintf(stderr,"Running smoother for rra %ld\n",i);
+            fprintf(stderr, "Running smoother for rra %lu\n", rra_idx);
 #endif
-             apply_smoother(&rrd,i,rra_start,rrd_file);
-             if (rrd_test_error())
-               break;
-           }
-           rra_start += rrd.rra_def[i].row_cnt
-             *rrd.stat_head->ds_cnt*sizeof(rrd_value_t);
-         }
-         fclose(rrd_file);
-       }
-    rrd_free(&rrd);
-    free(updvals);
-    free(tmpl_idx);
-    free(pdp_new);
-    free(pdp_temp);
-    return(0);
+            apply_smoother(rrd, rra_idx, rra_start, rrd_file);
+            if (rrd_test_error())
+                return -1;
+        }
+        rra_start += rrd->rra_def[rra_idx].row_cnt
+            * rrd->stat_head->ds_cnt * sizeof(rrd_value_t);
+    }
+    return 0;
 }
 
+#ifndef HAVE_MMAP
 /*
- * get exclusive lock to whole file.
- * lock gets removed when we close the file
+ * Flush changes to disk (unless we're using mmap)
  *
- * returns 0 on success
+ * Returns 0 on success, -1 otherwise
  */
-int
-LockRRD(FILE *rrdfile)
+static int write_changes_to_disk(
+    rrd_t *rrd,
+    rrd_file_t *rrd_file,
+    int version)
 {
-    int        rrd_fd;         /* File descriptor for RRD */
-    int        rcstat;
-
-    rrd_fd = fileno(rrdfile);
-
-       {
-#if defined(_WIN32) && !defined(__CYGWIN__) && !defined(__CYGWIN32__)
-    struct _stat st;
-
-    if ( _fstat( rrd_fd, &st ) == 0 ) {
-           rcstat = _locking ( rrd_fd, _LK_NBLCK, st.st_size );
+    /* we just need to write back the live header portion now */
+    if (rrd_seek(rrd_file, (sizeof(stat_head_t)
+                            + sizeof(ds_def_t) * rrd->stat_head->ds_cnt
+                            + sizeof(rra_def_t) * rrd->stat_head->rra_cnt),
+                 SEEK_SET) != 0) {
+        rrd_set_error("seek rrd for live header writeback");
+        return -1;
+    }
+    if (version >= 3) {
+        if (rrd_write(rrd_file, rrd->live_head,
+                      sizeof(live_head_t) * 1) != sizeof(live_head_t) * 1) {
+            rrd_set_error("rrd_write live_head to rrd");
+            return -1;
+        }
     } else {
-           rcstat = -1;
+        if (rrd_write(rrd_file, &rrd->live_head->last_up,
+                      sizeof(time_t) * 1) != sizeof(time_t) * 1) {
+            rrd_set_error("rrd_write live_head to rrd");
+            return -1;
+        }
     }
-#else
-    struct flock       lock;
-    lock.l_type = F_WRLCK;    /* exclusive write lock */
-    lock.l_len = 0;          /* whole file */
-    lock.l_start = 0;        /* start of file */
-    lock.l_whence = SEEK_SET;   /* end of file */
 
-    rcstat = fcntl(rrd_fd, F_SETLK, &lock);
-#endif
-       }
 
-    return(rcstat);
-}
+    if (rrd_write(rrd_file, rrd->pdp_prep,
+                  sizeof(pdp_prep_t) * rrd->stat_head->ds_cnt)
+        != (ssize_t) (sizeof(pdp_prep_t) * rrd->stat_head->ds_cnt)) {
+        rrd_set_error("rrd_write pdp_prep to rrd");
+        return -1;
+    }
 
+    if (rrd_write(rrd_file, rrd->cdp_prep,
+                  sizeof(cdp_prep_t) * rrd->stat_head->rra_cnt *
+                  rrd->stat_head->ds_cnt)
+        != (ssize_t) (sizeof(cdp_prep_t) * rrd->stat_head->rra_cnt *
+                      rrd->stat_head->ds_cnt)) {
 
-#ifdef HAVE_MMAP
-info_t
-*write_RRA_row (rrd_t *rrd, unsigned long rra_idx, unsigned long *rra_current,
-              unsigned short CDP_scratch_idx, 
-#ifndef DEBUG
-FILE UNUSED(*rrd_file),
-#else
-FILE *rrd_file,
-#endif
-                  info_t *pcdp_summary, time_t *rra_time, void *rrd_mmaped_file)
-#else
-info_t
-*write_RRA_row (rrd_t *rrd, unsigned long rra_idx, unsigned long *rra_current,
-              unsigned short CDP_scratch_idx, FILE *rrd_file,
-                  info_t *pcdp_summary, time_t *rra_time)
-#endif
-{
-   unsigned long ds_idx, cdp_idx;
-   infoval iv;
-  
-   for (ds_idx = 0; ds_idx < rrd -> stat_head -> ds_cnt; ds_idx++)
-   {
-      /* compute the cdp index */
-      cdp_idx =rra_idx * (rrd -> stat_head->ds_cnt) + ds_idx;
-#ifdef DEBUG
-         fprintf(stderr,"  -- RRA WRITE VALUE %e, at %ld CF:%s\n",
-            rrd -> cdp_prep[cdp_idx].scratch[CDP_scratch_idx].u_val,ftell(rrd_file),
-            rrd -> rra_def[rra_idx].cf_nam);
-#endif 
-      if (pcdp_summary != NULL)
-         {
-            iv.u_val = rrd -> cdp_prep[cdp_idx].scratch[CDP_scratch_idx].u_val;
-            /* append info to the return hash */
-                pcdp_summary = info_push(pcdp_summary,
-                sprintf_alloc("[%d]RRA[%s][%lu]DS[%s]",
-                *rra_time, rrd->rra_def[rra_idx].cf_nam, 
-                rrd->rra_def[rra_idx].pdp_cnt, rrd->ds_def[ds_idx].ds_nam),
-         RD_I_VAL, iv);
-         }
-#ifdef HAVE_MMAP
-         memcpy((char *)rrd_mmaped_file + *rra_current,
-                         &(rrd -> cdp_prep[cdp_idx].scratch[CDP_scratch_idx].u_val),
-                         sizeof(rrd_value_t));
-#else
-         if(fwrite(&(rrd -> cdp_prep[cdp_idx].scratch[CDP_scratch_idx].u_val),
-                sizeof(rrd_value_t),1,rrd_file) != 1)
-         { 
-            rrd_set_error("writing rrd");
-            return 0;
-         }
-#endif
-         *rra_current += sizeof(rrd_value_t);
-       }
-       return (pcdp_summary);
+        rrd_set_error("rrd_write cdp_prep to rrd");
+        return -1;
+    }
+
+    if (rrd_write(rrd_file, rrd->rra_ptr,
+                  sizeof(rra_ptr_t) * rrd->stat_head->rra_cnt)
+        != (ssize_t) (sizeof(rra_ptr_t) * rrd->stat_head->rra_cnt)) {
+        rrd_set_error("rrd_write rra_ptr to rrd");
+        return -1;
+    }
+    return 0;
 }
+#endif
index a2de839649381ba1f052f9a1b4597f22705f4022..ed1098c362f7331a089533dec73c78f55514b7ab 100644 (file)
@@ -1,5 +1,5 @@
 /*****************************************************************************
- * RRDtool 1.2.27  Copyright by Tobi Oetiker, 1997-2008
+ * RRDtool 1.3rc4  Copyright by Tobi Oetiker, 1997-2008
  *****************************************************************************
  * rrd_version Return
  *****************************************************************************
@@ -8,16 +8,14 @@
 
 #include "rrd_tool.h"
 
-double
-rrd_version(void)
+double rrd_version(
+    void)
 {
-  return NUMVERS;
+    return NUMVERS;
 }
 
-char *
-rrd_strversion(void)
+char     *rrd_strversion(
+    void)
 {
-  return PACKAGE_VERSION;
+    return PACKAGE_VERSION;
 }
-
-
index 0d4660e96f6067ad16f7940b69a05d18dd4bf258..a439b4a514b66998881c7206b0d694b54018c672 100644 (file)
@@ -1,5 +1,5 @@
 /****************************************************************************
- * RRDtool 1.2.27  Copyright by Tobi Oetiker, 1997-2008
+ * RRDtool 1.3rc4  Copyright by Tobi Oetiker, 1997-2008
  ****************************************************************************
  * rrd_xport.c  export RRD data 
  ****************************************************************************/
 #endif
 
 
-int rrd_xport(int, char **, int *,
-             time_t *, time_t *,
-             unsigned long *, unsigned long *,
-             char ***, rrd_value_t **);
-
-int rrd_xport_fn(image_desc_t *,
-                time_t *, time_t *,
-                unsigned long *, unsigned long *,
-                char ***, rrd_value_t **);
-
-
-
-
-int 
-rrd_xport(int argc, char **argv, int UNUSED(*xsize),
-         time_t         *start,
-         time_t         *end,        /* which time frame do you want ?
-                                      * will be changed to represent reality */
-         unsigned long  *step,       /* which stepsize do you want? 
-                                      * will be changed to represent reality */
-         unsigned long  *col_cnt,    /* number of data columns in the result */
-         char           ***legend_v, /* legend entries */
-         rrd_value_t    **data)      /* two dimensional array containing the data */
-
-{
-
-    image_desc_t   im;
-    time_t        start_tmp=0,end_tmp=0;
+int       rrd_xport(
+    int,
+    char **,
+    int *,
+    time_t *,
+    time_t *,
+    unsigned long *,
+    unsigned long *,
+    char ***,
+    rrd_value_t **);
+
+int       rrd_xport_fn(
+    image_desc_t *,
+    time_t *,
+    time_t *,
+    unsigned long *,
+    unsigned long *,
+    char ***,
+    rrd_value_t **);
+
+
+
+
+int rrd_xport(
+    int argc,
+    char **argv,
+    int UNUSED(*xsize),
+    time_t *start,
+    time_t *end,        /* which time frame do you want ?
+                         * will be changed to represent reality */
+    unsigned long *step,    /* which stepsize do you want? 
+                             * will be changed to represent reality */
+    unsigned long *col_cnt, /* number of data columns in the result */
+    char ***legend_v,   /* legend entries */
+    rrd_value_t **data)
+{                       /* two dimensional array containing the data */
+
+    image_desc_t im;
+    time_t    start_tmp = 0, end_tmp = 0;
     struct rrd_time_value start_tv, end_tv;
-    char           *parsetime_error = NULL;
-    optind = 0; opterr = 0;  /* initialize getopt */
+    char     *parsetime_error = NULL;
+    struct option long_options[] = {
+        {"start", required_argument, 0, 's'},
+        {"end", required_argument, 0, 'e'},
+        {"maxrows", required_argument, 0, 'm'},
+        {"step", required_argument, 0, 261},
+        {"enumds", no_argument, 0, 262},    /* these are handled in the frontend ... */
+        {0, 0, 0, 0}
+    };
+
+    optind = 0;
+    opterr = 0;         /* initialize getopt */
 
     rrd_graph_init(&im);
 
     parsetime("end-24h", &start_tv);
     parsetime("now", &end_tv);
 
-    while (1){
-       static struct option long_options[] =
-       {
-           {"start",      required_argument, 0,  's'},
-           {"end",        required_argument, 0,  'e'},
-           {"maxrows",    required_argument, 0,  'm'},
-           {"step",       required_argument, 0,   261},
-           {"enumds",     no_argument,       0,   262}, /* these are handled in the frontend ... */
-           {0,0,0,0}
-       };
-       int option_index = 0;
-       int opt;
-       
-       opt = getopt_long(argc, argv, "s:e:m:",
-                         long_options, &option_index);
-
-       if (opt == EOF)
-           break;
-       
-       switch(opt) {
-       case 261:
-           im.step =  atoi(optarg);
-           break;
-       case 262:
-           break;
-       case 's':
-           if ((parsetime_error = parsetime(optarg, &start_tv))) {
-               rrd_set_error( "start time: %s", parsetime_error );
-               return -1;
-           }
-           break;
-       case 'e':
-           if ((parsetime_error = parsetime(optarg, &end_tv))) {
-               rrd_set_error( "end time: %s", parsetime_error );
-               return -1;
-           }
-           break;
-       case 'm':
-           im.xsize = atol(optarg);
-           if (im.xsize < 10) {
-               rrd_set_error("maxrows below 10 rows");
-               return -1;
-           }
-           break;
-       case '?':
-            rrd_set_error("unknown option '%s'",argv[optind-1]);
+    while (1) {
+        int       option_index = 0;
+        int       opt;
+
+        opt = getopt_long(argc, argv, "s:e:m:", long_options, &option_index);
+
+        if (opt == EOF)
+            break;
+
+        switch (opt) {
+        case 261:
+            im.step = atoi(optarg);
+            break;
+        case 262:
+            break;
+        case 's':
+            if ((parsetime_error = parsetime(optarg, &start_tv))) {
+                rrd_set_error("start time: %s", parsetime_error);
+                return -1;
+            }
+            break;
+        case 'e':
+            if ((parsetime_error = parsetime(optarg, &end_tv))) {
+                rrd_set_error("end time: %s", parsetime_error);
+                return -1;
+            }
+            break;
+        case 'm':
+            im.xsize = atol(optarg);
+            if (im.xsize < 10) {
+                rrd_set_error("maxrows below 10 rows");
+                return -1;
+            }
+            break;
+        case '?':
+            rrd_set_error("unknown option '%s'", argv[optind - 1]);
             return -1;
-       }
+        }
+    }
+
+    if (proc_start_end(&start_tv, &end_tv, &start_tmp, &end_tmp) == -1) {
+        return -1;
     }
 
-    if (proc_start_end(&start_tv,&end_tv,&start_tmp,&end_tmp) == -1){
-       return -1;
-    }  
-    
-    if (start_tmp < 3600*24*365*10){
-       rrd_set_error("the first entry to fetch should be after 1980 (%ld)",start_tmp);
-       return -1;
+    if (start_tmp < 3600 * 24 * 365 * 10) {
+        rrd_set_error("the first entry to fetch should be after 1980 (%ld)",
+                      start_tmp);
+        return -1;
     }
-    
+
     if (end_tmp < start_tmp) {
-       rrd_set_error("start (%ld) should be less than end (%ld)", 
-              start_tmp, end_tmp);
-       return -1;
+        rrd_set_error("start (%ld) should be less than end (%ld)",
+                      start_tmp, end_tmp);
+        return -1;
     }
-    
+
     im.start = start_tmp;
     im.end = end_tmp;
-    im.step = max((long)im.step, (im.end-im.start)/im.xsize);
-    
-    rrd_graph_script(argc,argv,&im,0);
+    im.step = max((long) im.step, (im.end - im.start) / im.xsize);
+
+    rrd_graph_script(argc, argv, &im, 0);
     if (rrd_test_error()) {
-       im_free(&im);
-       return -1;
+        im_free(&im);
+        return -1;
     }
 
-    if (im.gdes_c == 0){
-       rrd_set_error("can't make a graph without contents");
-       im_free(&im);
-       return(-1); 
+    if (im.gdes_c == 0) {
+        rrd_set_error("can't make a graph without contents");
+        im_free(&im);
+        return (-1);
     }
-    
-    if (rrd_xport_fn(&im, start, end, step, col_cnt, legend_v, data) == -1){
-       im_free(&im);
-       return -1;
+
+    if (rrd_xport_fn(&im, start, end, step, col_cnt, legend_v, data) == -1) {
+        im_free(&im);
+        return -1;
     }
 
     im_free(&im);
@@ -146,98 +158,97 @@ rrd_xport(int argc, char **argv, int UNUSED(*xsize),
 
 
 
-int
-rrd_xport_fn(image_desc_t *im,
-            time_t         *start,
-            time_t         *end,        /* which time frame do you want ?
-                                         * will be changed to represent reality */
-            unsigned long  *step,       /* which stepsize do you want? 
-                                         * will be changed to represent reality */
-            unsigned long  *col_cnt,    /* number of data columns in the result */
-            char           ***legend_v, /* legend entries */
-            rrd_value_t    **data)      /* two dimensional array containing the data */
-{
+int rrd_xport_fn(
+    image_desc_t *im,
+    time_t *start,
+    time_t *end,        /* which time frame do you want ?
+                         * will be changed to represent reality */
+    unsigned long *step,    /* which stepsize do you want? 
+                             * will be changed to represent reality */
+    unsigned long *col_cnt, /* number of data columns in the result */
+    char ***legend_v,   /* legend entries */
+    rrd_value_t **data)
+{                       /* two dimensional array containing the data */
 
-    int            i = 0, j = 0;
-    unsigned long  *ds_cnt;    /* number of data sources in file */
-    unsigned long  col, dst_row, row_cnt;
-    rrd_value_t    *srcptr, *dstptr;
+    int       i = 0, j = 0;
+    unsigned long *ds_cnt;  /* number of data sources in file */
+    unsigned long col, dst_row, row_cnt;
+    rrd_value_t *srcptr, *dstptr;
 
     unsigned long nof_xports = 0;
     unsigned long xport_counter = 0;
-    int *ref_list;
+    int      *ref_list;
     rrd_value_t **srcptr_list;
-    char **legend_list;
-    int ii = 0;
+    char    **legend_list;
+    int       ii = 0;
 
-    time_t start_tmp = 0;
-    time_t end_tmp = 0;
+    time_t    start_tmp = 0;
+    time_t    end_tmp = 0;
     unsigned long step_tmp = 1;
 
     /* pull the data from the rrd files ... */
-    if(data_fetch(im)==-1)
-       return -1;
+    if (data_fetch(im) == -1)
+        return -1;
 
     /* evaluate CDEF  operations ... */
-    if(data_calc(im)==-1)
-       return -1;
+    if (data_calc(im) == -1)
+        return -1;
 
     /* how many xports? */
-    for(i = 0; i < im->gdes_c; i++) {  
-       switch(im->gdes[i].gf) {
-       case GF_XPORT:
-         nof_xports++;
-         break;
-       default:
-         break;
-       }
+    for (i = 0; i < im->gdes_c; i++) {
+        switch (im->gdes[i].gf) {
+        case GF_XPORT:
+            nof_xports++;
+            break;
+        default:
+            break;
+        }
     }
-
-    if(nof_xports == 0) {
-      rrd_set_error("no XPORT found, nothing to do");
-      return -1;
+    if (nof_xports == 0) {
+        rrd_set_error("no XPORT found, nothing to do");
+        return -1;
     }
 
     /* a list of referenced gdes */
     ref_list = malloc(sizeof(int) * nof_xports);
-    if(ref_list == NULL)
-      return -1;
+    if (ref_list == NULL)
+        return -1;
 
     /* a list to save pointers into each gdes data */
     srcptr_list = malloc(sizeof(srcptr) * nof_xports);
-    if(srcptr_list == NULL) {
-      free(ref_list);
-      return -1;
+    if (srcptr_list == NULL) {
+        free(ref_list);
+        return -1;
     }
 
     /* a list to save pointers to the column's legend entry */
     /* this is a return value! */
     legend_list = malloc(sizeof(char *) * nof_xports);
-    if(legend_list == NULL) {
-      free(srcptr_list);
-      free(ref_list);
-      return -1;
+    if (legend_list == NULL) {
+        free(srcptr_list);
+        free(ref_list);
+        return -1;
     }
 
     /* find referenced gdes and save their index and */
     /* a pointer into their data */
-    for(i = 0; i < im->gdes_c; i++) {  
-       switch(im->gdes[i].gf) {
-       case GF_XPORT:
-         ii = im->gdes[i].vidx;
-         if(xport_counter > nof_xports) {
-           rrd_set_error( "too many xports: should not happen. Hmmm");
-           free(srcptr_list);
-           free(ref_list);
-           free(legend_list);
-           return -1;
-         } 
-         srcptr_list[xport_counter] = im->gdes[ii].data;
-         ref_list[xport_counter++] = i;
-         break;
-       default:
-         break;
-       }
+    for (i = 0; i < im->gdes_c; i++) {
+        switch (im->gdes[i].gf) {
+        case GF_XPORT:
+            ii = im->gdes[i].vidx;
+            if (xport_counter > nof_xports) {
+                rrd_set_error("too many xports: should not happen. Hmmm");
+                free(srcptr_list);
+                free(ref_list);
+                free(legend_list);
+                return -1;
+            }
+            srcptr_list[xport_counter] = im->gdes[ii].data;
+            ref_list[xport_counter++] = i;
+            break;
+        default:
+            break;
+        }
     }
 
     start_tmp = im->gdes[0].start;
@@ -250,69 +261,75 @@ rrd_xport_fn(image_desc_t *im,
     *end = end_tmp;
     *step = step_tmp;
 
-    row_cnt = ((*end)-(*start))/(*step);
+    row_cnt = ((*end) - (*start)) / (*step);
 
     /* room for rearranged data */
     /* this is a return value! */
-    if (((*data) = malloc((*col_cnt) * row_cnt * sizeof(rrd_value_t)))==NULL){
+    if (((*data) =
+         malloc((*col_cnt) * row_cnt * sizeof(rrd_value_t))) == NULL) {
         free(srcptr_list);
         free(ref_list);
         free(legend_list);
         rrd_set_error("malloc xport data area");
-       return(-1);
+        return (-1);
     }
     dstptr = (*data);
 
     j = 0;
-    for(i = 0; i < im->gdes_c; i++) {  
-       switch(im->gdes[i].gf) {
-       case GF_XPORT:
-         /* reserve room for one legend entry */
-         /* is FMT_LEG_LEN + 5 the correct size? */
-         if ((legend_list[j] = malloc(sizeof(char) * (FMT_LEG_LEN+5)))==NULL) {
-           free(srcptr_list);
-           free(ref_list);
-           free(*data);  *data = NULL;
-           while (--j > -1) free(legend_list[j]);
-           free(legend_list);
-           rrd_set_error("malloc xport legend entry");
-           return(-1);
-         }
-
-         if (im->gdes[i].legend)
-           /* omit bounds check, should have the same size */
-           strcpy (legend_list[j++], im->gdes[i].legend);
-         else
-           legend_list[j++][0] = '\0';
-
-         break;
-       default:
-         break;
-       }
+    for (i = 0; i < im->gdes_c; i++) {
+        switch (im->gdes[i].gf) {
+        case GF_XPORT:
+            /* reserve room for one legend entry */
+            /* is FMT_LEG_LEN + 5 the correct size? */
+            if ((legend_list[j] =
+                 malloc(sizeof(char) * (FMT_LEG_LEN + 5))) == NULL) {
+                free(srcptr_list);
+                free(ref_list);
+                free(*data);
+                *data = NULL;
+                while (--j > -1)
+                    free(legend_list[j]);
+                free(legend_list);
+                rrd_set_error("malloc xport legend entry");
+                return (-1);
+            }
+
+            if (im->gdes[i].legend)
+                /* omit bounds check, should have the same size */
+                strcpy(legend_list[j++], im->gdes[i].legend);
+            else
+                legend_list[j++][0] = '\0';
+
+            break;
+        default:
+            break;
+        }
     }
 
     /* fill data structure */
-    for(dst_row = 0; (int)dst_row < (int)row_cnt; dst_row++) {
-      for(i = 0; i < (int)nof_xports; i++) {
-        j = ref_list[i];
-       ii = im->gdes[j].vidx;
-       ds_cnt = &im->gdes[ii].ds_cnt;
-
-       srcptr = srcptr_list[i];
-       for(col = 0; col < (*ds_cnt); col++) {
-         rrd_value_t newval = DNAN;
-         newval = srcptr[col];
-
-         if (im->gdes[ii].ds_namv && im->gdes[ii].ds_nam) {
-           if(strcmp(im->gdes[ii].ds_namv[col],im->gdes[ii].ds_nam) == 0)
-             (*dstptr++) = newval;
-         } else {
-           (*dstptr++) = newval;
-         }
-
-       }
-       srcptr_list[i] += (*ds_cnt);
-      }
+    for (dst_row = 0; (int) dst_row < (int) row_cnt; dst_row++) {
+        for (i = 0; i < (int) nof_xports; i++) {
+            j = ref_list[i];
+            ii = im->gdes[j].vidx;
+            ds_cnt = &im->gdes[ii].ds_cnt;
+
+            srcptr = srcptr_list[i];
+            for (col = 0; col < (*ds_cnt); col++) {
+                rrd_value_t newval = DNAN;
+
+                newval = srcptr[col];
+
+                if (im->gdes[ii].ds_namv && im->gdes[ii].ds_nam) {
+                    if (strcmp(im->gdes[ii].ds_namv[col], im->gdes[ii].ds_nam)
+                        == 0)
+                        (*dstptr++) = newval;
+                } else {
+                    (*dstptr++) = newval;
+                }
+
+            }
+            srcptr_list[i] += (*ds_cnt);
+        }
     }
 
     *legend_v = legend_list;
index 09fdeef1d6f43dbd230481872df4705a961135ed..b38d551cf721fb782ed4a0358811a46310862a85 100644 (file)
@@ -1,10 +1,10 @@
 /****************************************************************************
- * RRDtool 1.2.27  Copyright by Tobi Oetiker, 1997-2008
+ * RRDtool 1.3rc4  Copyright by Tobi Oetiker, 1997-2008
  ****************************************************************************
  * rrd_xport.h  contains XML related constants
  ****************************************************************************/
 #ifdef  __cplusplus
-extern "C" {
+extern    "C" {
 #endif
 
 #ifndef _RRD_XPORT_H
index f61061484600bf69e16795359e5f74153574455d..e0ff72f707c2a0af579957ce2bd14704d73d6594 100644 (file)
@@ -1,9 +1,9 @@
 /*****************************************************************************
- * RRDtool 1.2.27  Copyright by Tobi Oetiker, 1997-2008
+ * RRDtool 1.3rc4  Copyright by Tobi Oetiker, 1997-2008
  *****************************************************************************
  * rrdupdate.c  Main program for the (standalone) rrdupdate utility
  *****************************************************************************
- * $Id: rrdupdate.c 1286 2008-02-17 10:08:10Z oetiker $
+ * $Id: rrdupdate.c 1366 2008-05-18 13:06:44Z oetiker $
  *****************************************************************************/
 
 #if defined(_WIN32) && !defined(__CYGWIN__) && !defined(__CYGWIN32__) && !defined(HAVE_CONFIG_H)
 
 #include "rrd.h"
 
-int 
-main(int argc, char **argv){
-        rrd_update(argc,argv);
-        if (rrd_test_error()) {
-                printf("RRDtool " PACKAGE_VERSION "  Copyright by Tobi Oetiker, 1997-2008\n\n"
-                        "Usage: rrdupdate filename\n"
-                        "\t\t\t[--template|-t ds-name:ds-name:...]\n"
-                        "\t\t\ttime|N:value[:value...]\n\n"
-                        "\t\t\tat-time@value[:value...]\n\n"
-                        "\t\t\t[ time:value[:value...] ..]\n\n");
-                                   
-                printf("ERROR: %s\n",rrd_get_error());
-                rrd_clear_error();                                                            
-                return 1;
-        }
-        return 0;
+int main(
+    int argc,
+    char **argv)
+{
+    rrd_update(argc, argv);
+    if (rrd_test_error()) {
+        printf("RRDtool " PACKAGE_VERSION
+               "  Copyright by Tobi Oetiker, 1997-2008\n\n"
+               "Usage: rrdupdate filename\n"
+               "\t\t\t[--template|-t ds-name:ds-name:...]\n"
+               "\t\t\ttime|N:value[:value...]\n\n"
+               "\t\t\tat-time@value[:value...]\n\n"
+               "\t\t\t[ time:value[:value...] ..]\n\n");
+
+        printf("ERROR: %s\n", rrd_get_error());
+        rrd_clear_error();
+        return 1;
+    }
+    return 0;
 }
index c57a726fa4c6f2c1a398d50ffb516b4a7d39097b..3928a6f01f11a63c922b4080c33c9f11274a6e82 100644 (file)
@@ -19,7 +19,7 @@
 
 /* Define your own defaults in config.h if necessary */
 #if defined(TZNAME_STD) && defined(TZNAME_DST)
-char *tzname_[2] = {TZNAME_STD, TZNAME_DST};
+char     *tzname_[2] = { TZNAME_STD, TZNAME_DST };
 #else
 #define tzname_ tzname
 #endif
@@ -45,7 +45,10 @@ static char *month[] = {
 
 static char buf[26];
 
-static void strfmt(char *str, const char *fmt, ...);
+static void strfmt(
+    char *str,
+    const char *fmt,
+    ...);
 
 /**
  *
@@ -114,163 +117,161 @@ static void strfmt(char *str, const char *fmt, ...);
  *
 **/
 
-size_t strftime_(char *s, size_t maxs, const char *f, const struct tm *t)
+size_t strftime_(
+    char *s,
+    size_t maxs,
+    const char *f,
+    const struct tm *t)
 {
-      int w,d;
-      char *p, *q, *r;
-
-      p = s;
-      q = s + maxs - 1;
-      while ((*f != '\0'))
-      {
-            if (*f++ == '%')
-            {
-                  r = buf;
-                  switch (*f++)
-                  {
-                  case '%' :
-                        r = "%";
-                        break;
-
-                  case 'a' :
-                        r = aday[t->tm_wday];
-                        break;
-
-                  case 'A' :
-                        r = day[t->tm_wday];
-                        break;
-
-                  case 'b' :
-                        r = amonth[t->tm_mon];
-                        break;
-
-                  case 'B' :
-                        r = month[t->tm_mon];
-                        break;
-
-                  case 'c' :
-                        strfmt(r, "%0 %0 %2 %2:%2:%2 %4",
-                              aday[t->tm_wday], amonth[t->tm_mon],
-                              t->tm_mday,t->tm_hour, t->tm_min,
-                              t->tm_sec, t->tm_year+1900);
-                        break;
-
-                  case 'd' :
-                        strfmt(r,"%2",t->tm_mday);
-                        break;
-
-                  case 'H' :
-                        strfmt(r,"%2",t->tm_hour);
-                        break;
-
-                  case 'I' :
-                        strfmt(r,"%2",(t->tm_hour%12)?t->tm_hour%12:12);
-                        break;
-
-                  case 'j' :
-                        strfmt(r,"%3",t->tm_yday+1);
-                        break;
-
-                  case 'm' :
-                        strfmt(r,"%2",t->tm_mon+1);
-                        break;
-
-                  case 'M' :
-                        strfmt(r,"%2",t->tm_min);
-                        break;
-
-                  case 'p' :
-                        r = (t->tm_hour>11)?"PM":"AM";
-                        break;
-
-                  case 'S' :
-                        strfmt(r,"%2",t->tm_sec);
-                        break;
-
-                  case 'U' :
-                        w = t->tm_yday/7;
-                        if (t->tm_yday%7 > t->tm_wday)
-                              w++;
-                        strfmt(r, "%2", w);
-                        break;
-
-                  case 'W' :
-                        w = t->tm_yday/7;
-                        if (t->tm_yday%7 > (t->tm_wday+6)%7)
-                              w++;
-                        strfmt(r, "%2", w);
-                        break;
-
-                  case 'V':
-
-                        /* ISO 8601 Week Of Year:
-                           If the week (Monday - Sunday) containing January 1 has four or more
-                           days in the new year, then it is week 1; otherwise it is week 53 of
-                           the previous year and the next week is week one. */
-
-                       w  =  (t->tm_yday + 7 - (t->tm_wday ? t->tm_wday - 1 : 6)) / 7;
-                        d  =  (t->tm_yday + 7 - (t->tm_wday ? t->tm_wday - 1 : 6)) % 7;
-
-                        if (d >= 4) { w++; } else if (w == 0) { w = 53; }
-                        strfmt(r, "%2", w);
-                        break;
-
-                  case 'w' :
-                        strfmt(r,"%1",t->tm_wday);
-                        break;
-
-                  case 'x' :
-                        strfmt(r, "%3s %3s %2 %4", aday[t->tm_wday],
-                              amonth[t->tm_mon], t->tm_mday, t->tm_year+1900);
-                        break;
-
-                  case 'X' :
-                        strfmt(r, "%2:%2:%2", t->tm_hour,
-                              t->tm_min, t->tm_sec);
-                        break;
-
-                  case 'y' :
-                        strfmt(r,"%2",t->tm_year%100);
-                        break;
-
-                  case 'Y' :
-                        strfmt(r,"%4",t->tm_year+1900);
-                        break;
-
-                  case 'Z' :
-                        r = (t->tm_isdst && tzname_[1][0]) ?
-                              tzname_[1] : tzname_[0];
-                        break;
-
-                  default:
-                        buf[0] = '%';     /* reconstruct the format */
-                        buf[1] = f[-1];
-                        buf[2] = '\0';
-                        if (buf[1] == 0)
-                              f--;        /* back up if at end of string */
-                  }
-                  while (*r)
-                  {
-                        if (p == q)
-                        {
-                              *q = '\0';
-                              return 0;
-                        }
-                        *p++ = *r++;
-                  }
+    int       w, d;
+    char     *p, *q, *r;
+
+    p = s;
+    q = s + maxs - 1;
+    while ((*f != '\0')) {
+        if (*f++ == '%') {
+            r = buf;
+            switch (*f++) {
+            case '%':
+                r = "%";
+                break;
+
+            case 'a':
+                r = aday[t->tm_wday];
+                break;
+
+            case 'A':
+                r = day[t->tm_wday];
+                break;
+
+            case 'b':
+                r = amonth[t->tm_mon];
+                break;
+
+            case 'B':
+                r = month[t->tm_mon];
+                break;
+
+            case 'c':
+                strfmt(r, "%0 %0 %2 %2:%2:%2 %4",
+                       aday[t->tm_wday], amonth[t->tm_mon],
+                       t->tm_mday, t->tm_hour, t->tm_min,
+                       t->tm_sec, t->tm_year + 1900);
+                break;
+
+            case 'd':
+                strfmt(r, "%2", t->tm_mday);
+                break;
+
+            case 'H':
+                strfmt(r, "%2", t->tm_hour);
+                break;
+
+            case 'I':
+                strfmt(r, "%2", (t->tm_hour % 12) ? t->tm_hour % 12 : 12);
+                break;
+
+            case 'j':
+                strfmt(r, "%3", t->tm_yday + 1);
+                break;
+
+            case 'm':
+                strfmt(r, "%2", t->tm_mon + 1);
+                break;
+
+            case 'M':
+                strfmt(r, "%2", t->tm_min);
+                break;
+
+            case 'p':
+                r = (t->tm_hour > 11) ? "PM" : "AM";
+                break;
+
+            case 'S':
+                strfmt(r, "%2", t->tm_sec);
+                break;
+
+            case 'U':
+                w = t->tm_yday / 7;
+                if (t->tm_yday % 7 > t->tm_wday)
+                    w++;
+                strfmt(r, "%2", w);
+                break;
+
+            case 'W':
+                w = t->tm_yday / 7;
+                if (t->tm_yday % 7 > (t->tm_wday + 6) % 7)
+                    w++;
+                strfmt(r, "%2", w);
+                break;
+
+            case 'V':
+
+                /* ISO 8601 Week Of Year:
+                   If the week (Monday - Sunday) containing January 1 has four or more
+                   days in the new year, then it is week 1; otherwise it is week 53 of
+                   the previous year and the next week is week one. */
+
+                w = (t->tm_yday + 7 - (t->tm_wday ? t->tm_wday - 1 : 6)) / 7;
+                d = (t->tm_yday + 7 - (t->tm_wday ? t->tm_wday - 1 : 6)) % 7;
+
+                if (d >= 4) {
+                    w++;
+                } else if (w == 0) {
+                    w = 53;
+                }
+                strfmt(r, "%2", w);
+                break;
+
+            case 'w':
+                strfmt(r, "%1", t->tm_wday);
+                break;
+
+            case 'x':
+                strfmt(r, "%3s %3s %2 %4", aday[t->tm_wday],
+                       amonth[t->tm_mon], t->tm_mday, t->tm_year + 1900);
+                break;
+
+            case 'X':
+                strfmt(r, "%2:%2:%2", t->tm_hour, t->tm_min, t->tm_sec);
+                break;
+
+            case 'y':
+                strfmt(r, "%2", t->tm_year % 100);
+                break;
+
+            case 'Y':
+                strfmt(r, "%4", t->tm_year + 1900);
+                break;
+
+            case 'Z':
+                r = (t->tm_isdst && tzname_[1][0]) ? tzname_[1] : tzname_[0];
+                break;
+
+            default:
+                buf[0] = '%';   /* reconstruct the format */
+                buf[1] = f[-1];
+                buf[2] = '\0';
+                if (buf[1] == 0)
+                    f--;    /* back up if at end of string */
             }
-            else
-            {
-                  if (p == q)
-                  {
-                        *q = '\0';
-                        return 0;
-                  }
-                  *p++ = f[-1];
+            while (*r) {
+                if (p == q) {
+                    *q = '\0';
+                    return 0;
+                }
+                *p++ = *r++;
             }
-      }
-      *p = '\0';
-      return p - s;
+        } else {
+            if (p == q) {
+                *q = '\0';
+                return 0;
+            }
+            *p++ = f[-1];
+        }
+    }
+    *p = '\0';
+    return p - s;
 }
 
 /*
@@ -298,38 +299,38 @@ static int powers[5] = { 1, 10, 100, 1000, 10000 };
  *
 **/
 
-static void strfmt(char *str, const char *fmt, ...)
+static void strfmt(
+    char *str,
+    const char *fmt,
+    ...)
 {
-      int ival, ilen;
-      char *sval;
-      va_list vp;
-
-      va_start(vp, fmt);
-      while (*fmt)
-      {
-            if (*fmt++ == '%')
-            {
-                  ilen = *fmt++ - '0';
-                  if (ilen == 0)                /* zero means string arg */
-                  {
-                        sval = va_arg(vp, char*);
-                        while (*sval)
-                              *str++ = *sval++;
-                  }
-                  else                          /* always leading zeros */
-                  {
-                        ival = va_arg(vp, int);
-                        while (ilen)
-                        {
-                              ival %= powers[ilen--];
-                              *str++ = (char)('0' + ival / powers[ilen]);
-                        }
-                  }
+    int       ival, ilen;
+    char     *sval;
+    va_list   vp;
+
+    va_start(vp, fmt);
+    while (*fmt) {
+        if (*fmt++ == '%') {
+            ilen = *fmt++ - '0';
+            if (ilen == 0) {    /* zero means string arg */
+                sval = va_arg(vp, char *);
+
+                while (*sval)
+                    *str++ = *sval++;
+            } else {    /* always leading zeros */
+
+                ival = va_arg(vp, int);
+
+                while (ilen) {
+                    ival %= powers[ilen--];
+                    *str++ = (char) ('0' + ival / powers[ilen]);
+                }
             }
-            else  *str++ = fmt[-1];
-      }
-      *str = '\0';
-      va_end(vp);
+        } else
+            *str++ = fmt[-1];
+    }
+    *str = '\0';
+    va_end(vp);
 }
 
 #ifdef TEST
@@ -337,20 +338,22 @@ static void strfmt(char *str, const char *fmt, ...)
 #include <stdio.h>      /* for printf */
 #include <time.h>       /* for strftime */
 
-char test[80];
+char      test[80];
 
-int main(int argc, char *argv[])
+int main(
+    int argc,
+    char *argv[])
 {
-      int len;
-      char *fmt;
-      time_t now;
+    int       len;
+    char     *fmt;
+    time_t    now;
 
-      time(&now);
+    time(&now);
 
-      fmt = (argc == 1) ? "%I:%M %p\n%c\n" : argv[1];
-      len = strftime_(test,sizeof test, fmt, localtime(&now));
-      printf("%d: %s\n", len, test);
-      return !len;
+    fmt = (argc == 1) ? "%I:%M %p\n%c\n" : argv[1];
+    len = strftime_(test, sizeof test, fmt, localtime(&now));
+    printf("%d: %s\n", len, test);
+    return !len;
 }
 
-#endif /* TEST */
+#endif                          /* TEST */
index c9d45e3ba875166a3c342725c9490585e1469884..485dbdd933148948d389aa7cd8892c99b19290e8 100644 (file)
 #include <stddef.h>     /* for size_t */
 #include <time.h>       /* for struct tm */
 
-size_t strftime_(char *s, size_t maxs, const char *f, const struct tm *t);
+size_t    strftime_(
+    char *s,
+    size_t maxs,
+    const char *f,
+    const struct tm *t);
 
 #if defined(TZNAME_STD) && defined(TZNAME_DST)
-extern char * tzname_[2];
+extern char *tzname_[2];
 #endif
 
-#endif /* STRFTIME__H */
+#endif                          /* STRFTIME__H */
index b5ac8411dfb8ed819360bc65d85616d15e6eaccf..ecaa4de7649c1b47dae1b300c44d395c093ee3b2 100644 (file)
@@ -1,5 +1,8 @@
-/* define a macro to wrap variables in that would
-   otherwhise generate UNUSED variable warnings */
+/* define a macro to wrap variables that would
+   otherwise generate UNUSED variable warnings
+   Note that GCC's attribute unused only supresses the warning, so
+   it is perfectly safe to declare something unused although it is not.
+*/
 
 #ifdef UNUSED
 #elif defined(__GNUC__)
index 32f533726225bfa9b5c05efc0d897c0af53a8d76..457e69e518aa44b5d49cc5c2b37ee221beffad2c 100644 (file)
@@ -1,27 +1,39 @@
-// compatibility routines, non reentrant ....
+/* compatibility routines, non reentrant .... */
 
-#include <string.h> 
+#include <string.h>
 #include <time.h>
 
-struct tm* localtime_r(const time_t* t, struct tm* r) {
-  struct tm * temp;
-  temp = localtime(t);
-  memcpy(r,temp,sizeof(struct tm));
-  return(r);
+struct tm *localtime_r(
+    const time_t *t,
+    struct tm *r)
+{
+    struct tm *temp;
+
+    temp = localtime(t);
+    memcpy(r, temp, sizeof(struct tm));
+    return (r);
 }
 
-struct tm* gmtime_r(const time_t* t, struct tm* r) {
-  struct tm * temp;
-  temp = gmtime(t);
-  memcpy(r,temp,sizeof(struct tm));
-  return r;
+struct tm *gmtime_r(
+    const time_t *t,
+    struct tm *r)
+{
+    struct tm *temp;
+
+    temp = gmtime(t);
+    memcpy(r, temp, sizeof(struct tm));
+    return r;
 }
 
-char* ctime_r (const time_t* t, char* buf) {
-  char * temp;
-  temp = asctime(localtime(t));
-  strcpy(buf,temp);
-  return(buf);
+char     *ctime_r(
+    const time_t *t,
+    char *buf)
+{
+    char     *temp;
+
+    temp = asctime(localtime(t));
+    strcpy(buf, temp);
+    return (buf);
 }
 
 /*
@@ -36,32 +48,35 @@ char* ctime_r (const time_t* t, char* buf) {
 */
 
 
-char * strtok_r (char *s, const char *delim, char **save_ptr) {
-  char *token;
+char     *strtok_r(
+    char *s,
+    const char *delim,
+    char **save_ptr)
+{
+    char     *token;
 
-  if (s == NULL)  s = *save_ptr;
+    if (s == NULL)
+        s = *save_ptr;
 
-  /* Scan leading delimiters.  */
-  s += strspn(s, delim);
-  if (*s == '\0')
-    {
-      *save_ptr = s;
-      return NULL;
+    /* Scan leading delimiters.  */
+    s += strspn(s, delim);
+    if (*s == '\0') {
+        *save_ptr = s;
+        return NULL;
     }
 
-  /* Find the end of the token.  */
-  token = s;
-  s = strpbrk (token, delim);
-  if (s == NULL) {
-    /* This token finishes the string.  */
-         *save_ptr = token;
-         while (**save_ptr != '\0') (*save_ptr)++;
-  }  else
-    {
-      /* Terminate the token and make *SAVE_PTR point past it.  */
-      *s = '\0';
-      *save_ptr = s + 1;
+    /* Find the end of the token.  */
+    token = s;
+    s = strpbrk(token, delim);
+    if (s == NULL) {
+        /* This token finishes the string.  */
+        *save_ptr = token;
+        while (**save_ptr != '\0')
+            (*save_ptr)++;
+    } else {
+        /* Terminate the token and make *SAVE_PTR point past it.  */
+        *s = '\0';
+        *save_ptr = s + 1;
     }
-  return token;
+    return token;
 }
-
index 6e3dc2c7728d8f8110dd66614c4387e9d46df9de..8c392d55201ebbf044689c0a8043655b2feafd73 100644 (file)
@@ -33,12 +33,12 @@ endif
 # All library code is statically linked to avoid problems with other lib DLLs.
 # Edit the path below to point to your libpng sources or set environment var.
 ifndef LIBPNG
-LIBPNG = $(LIBBASE)/libpng-1.2.23
+LIBPNG = $(LIBBASE)/libpng-1.2.16
 endif
 # Edit the path below to point to your freetype sources or set environment var.
 ifndef LIBFT2
-#LIBFT2        = $(LIBBASE)/freetype-2.3.5
-LIBFT2 = $(LIBBASE)/../mingw32/freetype-2.3.5
+#LIBFT2        = $(LIBBASE)/freetype-2.3.4
+LIBFT2 = $(LIBBASE)/../mingw32/freetype-2.3.4
 endif
 # Edit the path below to point to your libart sources or set environment var.
 ifndef LIBART
@@ -53,17 +53,13 @@ endif
 ifndef DISTDIR
 DISTDIR        = rrdtool-$(RRD_VERSION_STR)-w32
 endif
-ifndef DISTARC
-DISTARC = $(DISTDIR).$(ARCEXT)
-endif
+DISTARC = $(DISTDIR).zip
 
 # Edit the path below to point to your distribution folder.
 ifndef DEVLDIR
 DEVLDIR        = rrdtool-$(RRD_VERSION_STR)-sdk-w32
 endif
-ifndef DEVLARC
-DEVLARC = $(DEVLDIR).$(ARCEXT)
-endif
+DEVLARC = $(DEVLDIR).zip
 
 # whatever...
 NO_NULL_REALLOC = 1
@@ -72,19 +68,14 @@ NO_NULL_REALLOC = 1
 ifdef METROWERKS
        CC = mwcc
 else
-       CC = $(CRPREFIX)gcc
+       CC = gcc
 endif
 # RM   = rm -f
 CP     = cp -afv
 # Here you can find a native Win32 binary of the original awk:
 # http://www.gknw.net/development/prgtools/awk.zip
 AWK    = awk
-ifndef ARCBIN
-ARCBIN = zip -qzr9
-ARCEXT = zip
-#ARCBIN        = 7za a
-#ARCEXT        = 7z
-endif
+ZIP    = zip -qzr9
 
 # must be equal to DEBUG or NDEBUG
 DB     = NDEBUG
@@ -123,8 +114,8 @@ CFLAGS      += -nostdinc -gccinc -msgstyle gcc -inline off -opt nointrinsics -proc 58
 CFLAGS += -ir "$(METROWERKS)/MSL" -ir "$(METROWERKS)/Win32-x86 Support"
 CFLAGS += -w on,nounused,nounusedexpr # -ansi strict
 else
-LD     = $(CRPREFIX)gcc
-RC     = $(CRPREFIX)windres
+LD     = gcc
+RC     = windres
 LDFLAGS        = -s
 AR     = ar
 ARFLAGS        = -cq
@@ -134,7 +125,7 @@ CFLAGS      += -fno-strict-aliasing
 CFLAGS += -Wall -Wno-unused # -pedantic
 endif
 
-ifdef __MSYS__
+ifeq ($(findstring msys,$(OSTYPE)),msys)
 DL     = '
 DS     = /
 else
@@ -262,7 +253,7 @@ dist: all $(DISTDIR) $(DISTDIR)/readme.txt
        @-$(CP) $(PROOT)/NEWS $(DISTDIR)
        @-$(CP) $(PROOT)/README $(DISTDIR)
        @echo Creating $(DISTARC)
-       @$(ARCBIN) $(DISTARC) $(DISTDIR)/* < $(DISTDIR)/readme.txt
+       @$(ZIP) $(DISTARC) $(DISTDIR)/* < $(DISTDIR)/readme.txt
 
 dev: librrd $(DEVLDIR) $(DEVLDIR)/readme.txt
        @-mkdir $(DEVLDIR)$(DS)include
@@ -278,7 +269,7 @@ dev: librrd $(DEVLDIR) $(DEVLDIR)/readme.txt
        @-$(CP) $(PROOT)/NEWS $(DEVLDIR)
        @-$(CP) $(PROOT)/README $(DEVLDIR)
        @echo Creating $(DEVLARC)
-       @$(ARCBIN) $(DEVLARC) $(DEVLDIR)/* < $(DEVLDIR)/readme.txt
+       @$(ZIP) $(DEVLARC) $(DEVLDIR)/* < $(DEVLDIR)/readme.txt
 
 clean:
        -$(RM) -r $(OBJDIR)
index 965d52528dde4bfe15df258b20417c1d3bcdbdb1..9d2603ea230a6db040aea7736ed795d0091417af 100644 (file)
 #define finite _finite
 #define snprintf _snprintf
 #define vsnprintf _vsnprintf
-#define strftime strftime_ 
+#define strftime strftime_
 
 #define NO_NULL_REALLOC 1
 #if NO_NULL_REALLOC
 # define rrd_realloc(a,b) ( (a) == NULL ? malloc( (b) ) : realloc( (a) , (b) ))
 #else
 # define rrd_realloc(a,b) realloc((a), (b))
-#endif      
+#endif
 
 /* Vertical label angle: 90.0 (default) or 270.0 */
 #define RRDGRAPH_YLEGEND_ANGLE 90.0
@@ -56,5 +56,4 @@
 
 /* #define DEBUG 1 */
 
-#endif /* CONFIG_H */
-
+#endif                          /* CONFIG_H */